mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-03 03:21:46 +02:00
Flush model writes before sending HTTP requests
This commit is contained in:
@@ -1,40 +1,32 @@
|
|||||||
import type { HttpResponse } from "@yaakapp-internal/models";
|
import type { HttpResponse } from "@yaakapp-internal/models";
|
||||||
import { getModel } from "@yaakapp-internal/models";
|
import { flushAllModelWrites } from "@yaakapp-internal/models";
|
||||||
import { invokeCmd } from "../lib/tauri";
|
import { invokeCmd } from "../lib/tauri";
|
||||||
import { getActiveCookieJar } from "./useActiveCookieJar";
|
import { getActiveCookieJar } from "./useActiveCookieJar";
|
||||||
import { getActiveEnvironment } from "./useActiveEnvironment";
|
import { getActiveEnvironment } from "./useActiveEnvironment";
|
||||||
import { createFastMutation, useFastMutation } from "./useFastMutation";
|
import { createFastMutation, useFastMutation } from "./useFastMutation";
|
||||||
|
|
||||||
|
async function sendAnyHttpRequestById(id: string | null): Promise<HttpResponse | null> {
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await flushAllModelWrites();
|
||||||
|
|
||||||
|
return invokeCmd("cmd_send_http_request", {
|
||||||
|
requestId: id,
|
||||||
|
environmentId: getActiveEnvironment()?.id,
|
||||||
|
cookieJarId: getActiveCookieJar()?.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function useSendAnyHttpRequest() {
|
export function useSendAnyHttpRequest() {
|
||||||
return useFastMutation<HttpResponse | null, string, string | null>({
|
return useFastMutation<HttpResponse | null, string, string | null>({
|
||||||
mutationKey: ["send_any_request"],
|
mutationKey: ["send_any_request"],
|
||||||
mutationFn: async (id) => {
|
mutationFn: sendAnyHttpRequestById,
|
||||||
const request = getModel("http_request", id ?? "n/a");
|
|
||||||
if (request == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return invokeCmd("cmd_send_http_request", {
|
|
||||||
request,
|
|
||||||
environmentId: getActiveEnvironment()?.id,
|
|
||||||
cookieJarId: getActiveCookieJar()?.id,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendAnyHttpRequest = createFastMutation<HttpResponse | null, string, string | null>({
|
export const sendAnyHttpRequest = createFastMutation<HttpResponse | null, string, string | null>({
|
||||||
mutationKey: ["send_any_request"],
|
mutationKey: ["send_any_request"],
|
||||||
mutationFn: async (id) => {
|
mutationFn: sendAnyHttpRequestById,
|
||||||
const request = getModel("http_request", id ?? "n/a");
|
|
||||||
if (request == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return invokeCmd("cmd_send_http_request", {
|
|
||||||
request,
|
|
||||||
environmentId: getActiveEnvironment()?.id,
|
|
||||||
cookieJarId: getActiveCookieJar()?.id,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1425,11 +1425,10 @@ async fn cmd_send_http_request<R: Runtime>(
|
|||||||
window: WebviewWindow<R>,
|
window: WebviewWindow<R>,
|
||||||
environment_id: Option<&str>,
|
environment_id: Option<&str>,
|
||||||
cookie_jar_id: Option<&str>,
|
cookie_jar_id: Option<&str>,
|
||||||
// NOTE: We receive the entire request because to account for the race
|
request_id: String,
|
||||||
// condition where the user may have just edited a field before sending
|
|
||||||
// that has not yet been saved in the DB.
|
|
||||||
request: HttpRequest,
|
|
||||||
) -> YaakResult<HttpResponse> {
|
) -> YaakResult<HttpResponse> {
|
||||||
|
let request = app_handle.db().get_http_request(&request_id)?;
|
||||||
|
|
||||||
let blobs = app_handle.blob_manager();
|
let blobs = app_handle.blob_manager();
|
||||||
let response = app_handle.db().upsert_http_response(
|
let response = app_handle.db().upsert_http_response(
|
||||||
&HttpResponse {
|
&HttpResponse {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { newStoreData } from "./util";
|
|||||||
|
|
||||||
let _store: JotaiStore | null = null;
|
let _store: JotaiStore | null = null;
|
||||||
|
|
||||||
|
const pendingModelWrites = new Set<Promise<unknown>>();
|
||||||
|
|
||||||
export function initModelStore(store: JotaiStore) {
|
export function initModelStore(store: JotaiStore) {
|
||||||
_store = store;
|
_store = store;
|
||||||
|
|
||||||
@@ -42,6 +44,23 @@ function mustStore(): JotaiStore {
|
|||||||
return _store;
|
return _store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function trackModelWrite<T>(write: Promise<T>): Promise<T> {
|
||||||
|
const tracked = write.finally(() => {
|
||||||
|
pendingModelWrites.delete(tracked);
|
||||||
|
});
|
||||||
|
|
||||||
|
pendingModelWrites.add(tracked);
|
||||||
|
return tracked;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function flushAllModelWrites(): Promise<void> {
|
||||||
|
const results = await Promise.allSettled([...pendingModelWrites]);
|
||||||
|
const rejected = results.find((result) => result.status === "rejected");
|
||||||
|
if (rejected?.status === "rejected") {
|
||||||
|
throw rejected.reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let _activeWorkspaceId: string | null = null;
|
let _activeWorkspaceId: string | null = null;
|
||||||
|
|
||||||
export async function changeModelStoreWorkspace(workspaceId: string | null) {
|
export async function changeModelStoreWorkspace(workspaceId: string | null) {
|
||||||
@@ -117,7 +136,7 @@ export async function patchModel<M extends AnyModel["model"], T extends ExtractM
|
|||||||
export async function updateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
|
export async function updateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
|
||||||
model: T,
|
model: T,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return invoke<string>("models_upsert", { model });
|
return trackModelWrite(invoke<string>("models_upsert", { model }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteModelById<
|
export async function deleteModelById<
|
||||||
@@ -134,7 +153,7 @@ export async function deleteModel<M extends AnyModel["model"], T extends Extract
|
|||||||
if (model == null) {
|
if (model == null) {
|
||||||
throw new Error("Failed to delete null model");
|
throw new Error("Failed to delete null model");
|
||||||
}
|
}
|
||||||
await invoke<string>("models_delete", { model });
|
await trackModelWrite(invoke<string>("models_delete", { model }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function duplicateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
|
export function duplicateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
|
||||||
@@ -174,19 +193,19 @@ export function duplicateModel<M extends AnyModel["model"], T extends ExtractMod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return invoke<string>("models_duplicate", { model: { ...model, name } });
|
return trackModelWrite(invoke<string>("models_duplicate", { model: { ...model, name } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createGlobalModel<T extends Exclude<AnyModel, { workspaceId: string }>>(
|
export async function createGlobalModel<T extends Exclude<AnyModel, { workspaceId: string }>>(
|
||||||
patch: Partial<T> & Pick<T, "model">,
|
patch: Partial<T> & Pick<T, "model">,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return invoke<string>("models_upsert", { model: patch });
|
return trackModelWrite(invoke<string>("models_upsert", { model: patch }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createWorkspaceModel<T extends Extract<AnyModel, { workspaceId: string }>>(
|
export async function createWorkspaceModel<T extends Extract<AnyModel, { workspaceId: string }>>(
|
||||||
patch: Partial<T> & Pick<T, "model" | "workspaceId">,
|
patch: Partial<T> & Pick<T, "model" | "workspaceId">,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return invoke<string>("models_upsert", { model: patch });
|
return trackModelWrite(invoke<string>("models_upsert", { model: patch }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function replaceModelsInStore<
|
export function replaceModelsInStore<
|
||||||
|
|||||||
Reference in New Issue
Block a user