import { useAtomValue } from "@effect/atom-react";import type { DesktopBridge, DesktopUpdateState } from "@t3tools/contracts";import * as Effect from "effect/Effect";import * as Queue from "effect/Queue";import * as Stream from "effect/Stream";import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";import { Atom } from "effect/unstable/reactivity"; type DesktopUpdateBridge = Pick<DesktopBridge, "getUpdateState" | "onUpdateState">; function getDesktopUpdateBridge(): DesktopUpdateBridge | undefined { return typeof window === "undefined" ? undefined : window.desktopBridge;} export function createDesktopUpdateStateAtom(getBridge: () => DesktopUpdateBridge | undefined) { const updates = Stream.callback<DesktopUpdateState | null>((queue) => Effect.gen(function* () { const bridge = getBridge(); if (!bridge) { Queue.offerUnsafe(queue, null); return yield* Effect.never; } let receivedUpdate = false; yield* Effect.acquireRelease( Effect.sync(() => bridge.onUpdateState((state) => { receivedUpdate = true; Queue.offerUnsafe(queue, state); }), ), (unsubscribe) => Effect.sync(unsubscribe), ); const initialState = yield* Effect.tryPromise(() => bridge.getUpdateState()).pipe( Effect.retry({ times: 2 }), Effect.orElseSucceed(() => null), ); if (!receivedUpdate && initialState !== null) { Queue.offerUnsafe(queue, initialState); } return yield* Effect.never; }), ); return Atom.make(updates, { initialValue: null }).pipe( Atom.keepAlive, Atom.withLabel("desktop:update-state"), );} const desktopUpdateStateAtom = createDesktopUpdateStateAtom(getDesktopUpdateBridge); export function useDesktopUpdateState(): DesktopUpdateState | null { return AsyncResult.getOrElse(useAtomValue(desktopUpdateStateAtom), () => null);}
import { useAtomValue } from "@effect/atom-react";
import type { DesktopBridge, DesktopUpdateState } from "@t3tools/contracts";
import * as Effect from "effect/Effect";
import * as Queue from "effect/Queue";
import * as Stream from "effect/Stream";
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
import { Atom } from "effect/unstable/reactivity";
type DesktopUpdateBridge = Pick<DesktopBridge, "getUpdateState" | "onUpdateState">;
function getDesktopUpdateBridge(): DesktopUpdateBridge | undefined {
return typeof window === "undefined" ? undefined : window.desktopBridge;
}
export function createDesktopUpdateStateAtom(getBridge: () => DesktopUpdateBridge | undefined) {
const updates = Stream.callback<DesktopUpdateState | null>((queue) =>
Effect.gen(function* () {
const bridge = getBridge();
if (!bridge) {
Queue.offerUnsafe(queue, null);
return yield* Effect.never;
}
let receivedUpdate = false;
yield* Effect.acquireRelease(
Effect.sync(() =>
bridge.onUpdateState((state) => {
receivedUpdate = true;
Queue.offerUnsafe(queue, state);
}),
),
(unsubscribe) => Effect.sync(unsubscribe),
);
const initialState = yield* Effect.tryPromise(() => bridge.getUpdateState()).pipe(
Effect.retry({ times: 2 }),
Effect.orElseSucceed(() => null),
);
if (!receivedUpdate && initialState !== null) {
Queue.offerUnsafe(queue, initialState);
}
return yield* Effect.never;
}),
);
return Atom.make(updates, { initialValue: null }).pipe(
Atom.keepAlive,
Atom.withLabel("desktop:update-state"),
);
}
const desktopUpdateStateAtom = createDesktopUpdateStateAtom(getDesktopUpdateBridge);
export function useDesktopUpdateState(): DesktopUpdateState | null {
return AsyncResult.getOrElse(useAtomValue(desktopUpdateStateAtom), () => null);
}