// @generated by FORGE - DO NOT EDIT
import type { SubscriptionStore, ForgeError } from "@forge-rs/svelte";
import type { SubscriptionResult } from "@forge-rs/svelte";
import { ForgeClientError } from "@forge-rs/svelte";

export interface ReactiveQuery<T> extends SubscriptionResult<T> {
  unsubscribe: () => void;
}

export function toReactive<T>(store: SubscriptionStore<T>): ReactiveQuery<T> {
  const state: ReactiveQuery<T> = $state({
    loading: true,
    data: null,
    error: null,
    stale: false,
    unsubscribe: () => {},
  });

  $effect(() => {
    const unsubCallback = store.subscribe((s) => {
      state.loading = s.loading;
      state.data = s.data;
      state.error = s.error;
      state.stale = s.stale;
    });

    const cleanup = () => {
      unsubCallback();
      store.unsubscribe();
    };

    state.unsubscribe = cleanup;
    return cleanup;
  });

  return state;
}

export interface ReactiveMutation<TArgs, TResult> {
  mutate: (args: TArgs) => Promise<TResult>;
  pending: boolean;
  error: ForgeError | null;
}

export function toReactiveMutation<TArgs, TResult>(
  fn: (args: TArgs) => Promise<TResult>,
): ReactiveMutation<TArgs, TResult> {
  const state: ReactiveMutation<TArgs, TResult> = $state({
    mutate: async (args: TArgs) => {
      state.pending = true;
      state.error = null;
      try {
        return await fn(args);
      } catch (e) {
        const err =
          e instanceof ForgeClientError
            ? e
            : new ForgeClientError("UNKNOWN", String(e));
        state.error = err;
        throw e;
      } finally {
        state.pending = false;
      }
    },
    pending: false,
    error: null,
  });
  return state;
}
