1import { Connection } from "@t3tools/client-runtime/connection";
2import { ShellSnapshotLoader } from "@t3tools/client-runtime/state/shell";
3import {
4 BoundedThreadSnapshotLoader,
5 ThreadHistoryController,
6} from "@t3tools/client-runtime/state/threads";
7import { PullRequestDiffLoader } from "@t3tools/client-runtime/state/pull-requests";
8import * as Effect from "effect/Effect";
9import * as Layer from "effect/Layer";
10import { Atom } from "effect/reactivity";
11
12import { isGuestPage } from "../guestPage";
13
14import * as Runtime from "../lib/runtime";
15import * as BackgroundActivityReporter from "../lib/backgroundActivityReporter";
16import * as ConnectionPlatform from "./platform";
17
18const layerProvidedConnectionPlatform = ConnectionPlatform.layer.pipe(Layer.provide(Runtime.layer));
19
20const layerSnapshotLoader = Layer.mergeAll(
21 BoundedThreadSnapshotLoader.layer,
22 ShellSnapshotLoader.layer,
23 ThreadHistoryController.layer,
24 PullRequestDiffLoader.layer,
25);
26
27type ConnectionLayerSource =
28 | typeof Connection.layer
29 | typeof layerSnapshotLoader
30 | typeof Runtime.layer
31 | typeof ConnectionPlatform.layer
32 | typeof BackgroundActivityReporter.layerObserver
33 | typeof BackgroundActivityReporter.layer;
34
35const layerProvidedClientConnection = layerSnapshotLoader.pipe(
36 Layer.provideMerge(
37 Connection.layerWithOptions({
38 environmentThemes: true,
39 usageLimitSources: true,
40 usageLimitsCommand: true,
41 }),
42 ),
43 Layer.provideMerge(
44 Layer.mergeAll(
45 Runtime.layer,
46 layerProvidedConnectionPlatform,
47 BackgroundActivityReporter.layerObserver,
48 ),
49 ),
50);
51
52const layerConnection = BackgroundActivityReporter.layer.pipe(
53 Layer.provideMerge(layerProvidedClientConnection),
54);
55
56/**
57 * A guest has no session here. Building the connection would open the page origin's environment
58 * with whatever cookie this browser holds, plus every environment saved in it, so on the guest
59 * page the runtime fails to build and every atom on it keeps its empty value.
60 */
61const layerForPage = Layer.unwrap(
62 Effect.suspend((): Effect.Effect<typeof layerConnection> =>
63 isGuestPage()
64 ? Effect.die(new Error("The guest page has no environment connection."))
65 : Effect.succeed(layerConnection),
66 ),
67);
68
69export const connectionAtomRuntime: Atom.AtomRuntime<
70 Layer.Success<ConnectionLayerSource>,
71 Layer.Error<ConnectionLayerSource>
72> = Atom.runtime(layerForPage);