1import { createDeviceEnvironmentAtoms } from "@t3tools/client-runtime/state/device";
2import { resolveDeviceHubAccess } from "@t3tools/client-runtime/state/deviceHubAccess";
3import type { EnvironmentId } from "@t3tools/contracts";
4import * as Effect from "effect/Effect";
5import * as Option from "effect/Option";
6import { Atom } from "effect/reactivity";
7import { useMemo } from "react";
8
9import { connectionAtomRuntime } from "../connection/runtime";
10import { appAtomRegistry } from "./atom-registry";
11import { useEnvironmentQuery } from "./query";
12import { environmentSession, usePreparedConnection } from "./session";
13
14export const deviceEnvironment = createDeviceEnvironmentAtoms(connectionAtomRuntime);
15
16const deviceHubAccessAtom = Atom.family((environmentId: EnvironmentId) =>
17 connectionAtomRuntime
18 .atom((get) => {
19 const prepared = Option.getOrNull(
20 get(environmentSession.preparedConnectionValueAtom(environmentId)),
21 );
22 return prepared === null
23 ? Effect.never
24 : resolveDeviceHubAccess({ prepared, hubBasePath: "/api/device-hub" });
25 })
26 .pipe(Atom.setIdleTTL(60_000), Atom.withLabel(`mobile-device-hub-access:${environmentId}`)),
27);
28
29export function refreshDeviceHubAccess(environmentId: EnvironmentId) {
30 appAtomRegistry.refresh(deviceHubAccessAtom(environmentId));
31}
32
33export function useDeviceHubAccess(environmentId: EnvironmentId, hostId: string) {
34 const prepared = usePreparedConnection(environmentId);
35 const query = useEnvironmentQuery(deviceHubAccessAtom(environmentId));
36 const access = useMemo(
37 () =>
38 query.data && query.error === null && Option.isSome(prepared)
39 ? { ...query.data, query: { ...query.data.query, hostId } }
40 : null,
41 [query.data, query.error, prepared, hostId],
42 );
43 return { access, error: query.error, refresh: query.refresh };
44}