364 lines · 12.0 KB · TypeScript
RawDownload
import {  ClientPresentation,  CloudSession,  EnvironmentOwnedDataCleanup,  PlatformConnectionSource,  PrimaryEnvironmentAuth,  RelayDeviceIdentity,  SshEnvironmentGateway,} from "@t3tools/client-runtime/platform";import {  ConnectionBlockedError,  ConnectionTransientError,  Connectivity,  mapRemoteEnvironmentError,  PrimaryConnectionRegistration,  PrimaryConnectionTarget,  Wakeups,} from "@t3tools/client-runtime/connection";import { fetchRemoteEnvironmentDescriptor } from "@t3tools/client-runtime/environment";import { managedRelayAccountChanges, managedRelaySessionAtom } from "@t3tools/client-runtime/relay";import { EnvironmentRpcRequestObserver } from "@t3tools/client-runtime/rpc";import {  AuthStandardClientScopes,  isDesktopSshPasswordPromptCancellationError,  type DesktopBridge,  type DesktopSshEnvironmentTarget,} from "@t3tools/contracts";import * as Context from "effect/Context";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Queue from "effect/Queue";import * as Schedule from "effect/Schedule";import * as Stream from "effect/Stream"; import { readDesktopPrimaryBearerToken } from "../environments/primary/desktopAuth";import { primaryEnvironmentHttpLayer } from "../environments/primary/httpLayer";import { readPrimaryEnvironmentTarget } from "../environments/primary/target";import { clearComposerDraftsEnvironment } from "../composerDraftStore";import { isHostedStaticApp } from "../hostedPairing";import { appAtomRegistry } from "../rpc/atomRegistry";import { acknowledgeRpcRequest, trackRpcRequestSent } from "../rpc/requestLatencyState";import { connectionStorageLayer } from "./storage"; let nextObservedRpcRequestId = 0; function currentNetworkStatus(): "unknown" | "offline" | "online" {  if (typeof navigator === "undefined") {    return "unknown";  }  return navigator.onLine ? "online" : "offline";} const connectivityLayer = Connectivity.layer({  status: Effect.sync(currentNetworkStatus),  changes: Stream.callback((queue) =>    Effect.acquireRelease(      Effect.sync(() => {        const online = () => Queue.offerUnsafe(queue, "online");        const offline = () => Queue.offerUnsafe(queue, "offline");        window.addEventListener("online", online);        window.addEventListener("offline", offline);        return { online, offline };      }),      ({ online, offline }) =>        Effect.sync(() => {          window.removeEventListener("online", online);          window.removeEventListener("offline", offline);        }),    ).pipe(Effect.asVoid),  ),}); const wakeupsLayer = Wakeups.layer({  changes: Stream.merge(    Stream.callback<"application-active">((queue) =>      Effect.acquireRelease(        Effect.sync(() => {          const listener = () => {            if (document.visibilityState === "visible") {              Queue.offerUnsafe(queue, "application-active");            }          };          document.addEventListener("visibilitychange", listener);          return listener;        }),        (listener) =>          Effect.sync(() => {            document.removeEventListener("visibilitychange", listener);          }),      ).pipe(Effect.asVoid),    ),    managedRelayAccountChanges(appAtomRegistry).pipe(      Stream.map(() => "credentials-changed" as const),    ),  ),}); function clientMetadata() {  const desktop = window.desktopBridge !== undefined;  const platform = navigator.platform.trim();  return {    label: desktop ? "T3 Code Desktop" : "T3 Code Web",    deviceType: "desktop" as const,    ...(platform === "" ? {} : { os: platform }),  };} const trySshPreparation = <A>(operation: () => Promise<A>) =>  Effect.tryPromise({    try: operation,    catch: (cause) =>      isDesktopSshPasswordPromptCancellationError(cause)        ? cause        : new ConnectionTransientError({            reason: "remote-unavailable",            detail: "Could not prepare the SSH environment.",            cause,          }),  }).pipe(    Effect.catchTags({      DesktopSshPasswordPromptCancellationError: (cause) =>        new ConnectionBlockedError({          reason: "authentication",          detail: cause.message,          cause,        }),    }),  ); export const provisionDesktopSshEnvironment = Effect.fn(  "web.connectionPlatform.ssh.provisionDesktop",)(function* (bridge: DesktopBridge, target: DesktopSshEnvironmentTarget) {  const bootstrap = yield* trySshPreparation(() =>    bridge.ensureSshEnvironment(target, {      issuePairingToken: true,    }),  );  const pairingToken = bootstrap.pairingToken;  if (pairingToken === null) {    return yield* new ConnectionBlockedError({      reason: "authentication",      detail: "The SSH environment did not issue a pairing credential.",    });  }  const descriptor = yield* trySshPreparation(() =>    bridge.fetchSshEnvironmentDescriptor(bootstrap.httpBaseUrl),  );  const access = yield* trySshPreparation(() =>    bridge.bootstrapSshBearerSession(bootstrap.httpBaseUrl, pairingToken),  );  return {    environmentId: descriptor.environmentId,    label: descriptor.label,    bootstrap,    bearerToken: access.access_token,  };}); const capabilitiesLayer = Layer.effectContext(  Effect.sync(() => {    const presentation = ClientPresentation.of({      metadata: clientMetadata(),      scopes: AuthStandardClientScopes,    });    const cloudSession = CloudSession.of({      clerkToken: Effect.gen(function* () {        const session = appAtomRegistry.get(managedRelaySessionAtom);        if (session === null) {          return yield* new ConnectionBlockedError({            reason: "authentication",            detail: "Sign in to T3 Cloud to connect this environment.",          });        }        const token = yield* session.readClerkToken().pipe(          Effect.mapError(            (error) =>              new ConnectionTransientError({                reason: "network",                detail: "Could not read the T3 Cloud session token.",                cause: error,              }),          ),        );        if (token === null) {          return yield* new ConnectionBlockedError({            reason: "authentication",            detail: "The T3 Cloud session is unavailable.",          });        }        return token;      }),    });    const identity = RelayDeviceIdentity.of({      deviceId: Effect.succeed(Option.none()),    });    const primaryAuth = PrimaryEnvironmentAuth.of({      bearerToken: Effect.tryPromise({        try: readDesktopPrimaryBearerToken,        catch: (cause) =>          new ConnectionTransientError({            reason: "remote-unavailable",            detail: "Could not load the desktop primary credential.",            cause,          }),      }).pipe(Effect.map(Option.fromNullishOr)),    });    const ssh = SshEnvironmentGateway.of({      provision: Effect.fn("web.connectionPlatform.ssh.provision")(function* (target) {        const bridge = window.desktopBridge;        if (bridge === undefined) {          return yield* new ConnectionBlockedError({            reason: "unsupported",            detail: "SSH environments are only available in the desktop app.",          });        }        return yield* provisionDesktopSshEnvironment(bridge, target);      }),      prepare: Effect.fn("web.connectionPlatform.ssh.prepare")(function* (input) {        const bridge = window.desktopBridge;        if (bridge === undefined) {          return yield* new ConnectionBlockedError({            reason: "unsupported",            detail: "SSH environments are only available in the desktop app.",          });        }        const bootstrap = yield* trySshPreparation(() =>          bridge.ensureSshEnvironment(input.target, {            issuePairingToken: true,          }),        );        if (bootstrap.pairingToken === null) {          return yield* new ConnectionBlockedError({            reason: "authentication",            detail: "The SSH environment did not issue a pairing credential.",          });        }        const access = yield* trySshPreparation(() =>          bridge.bootstrapSshBearerSession(bootstrap.httpBaseUrl, bootstrap.pairingToken!),        );        return {          bootstrap,          bearerToken: access.access_token,        };      }),      disconnect: Effect.fn("web.connectionPlatform.ssh.disconnect")(function* (target) {        const bridge = window.desktopBridge;        if (bridge === undefined) {          return;        }        yield* Effect.tryPromise({          try: () => bridge.disconnectSshEnvironment(target),          catch: (cause) =>            new ConnectionTransientError({              reason: "remote-unavailable",              detail: "Could not disconnect the SSH environment.",              cause,            }),        });      }),    });     return Context.make(CloudSession, cloudSession).pipe(      Context.add(PrimaryEnvironmentAuth, primaryAuth),      Context.add(RelayDeviceIdentity, identity),      Context.add(ClientPresentation, presentation),      Context.add(SshEnvironmentGateway, ssh),    );  }),); const loadPrimaryConnectionRegistration = Effect.fn(  "web.connectionPlatform.loadPrimaryConnectionRegistration",)(function* () {  const resolved = readPrimaryEnvironmentTarget();  if (resolved === null) {    return yield* new ConnectionBlockedError({      reason: "configuration",      detail: "Unable to resolve the primary environment endpoint.",    });  }  const descriptor = yield* fetchRemoteEnvironmentDescriptor({    httpBaseUrl: resolved.target.httpBaseUrl,  }).pipe(Effect.provide(primaryEnvironmentHttpLayer), Effect.mapError(mapRemoteEnvironmentError));  return new PrimaryConnectionRegistration({    target: new PrimaryConnectionTarget({      environmentId: descriptor.environmentId,      label: descriptor.label,      httpBaseUrl: resolved.target.httpBaseUrl,      wsBaseUrl: resolved.target.wsBaseUrl,    }),  });}); const primaryRegistrationRetrySchedule = Schedule.exponential("1 second").pipe(  Schedule.either(Schedule.spaced("16 seconds")),); const platformConnectionSourceLayer = Layer.sync(PlatformConnectionSource, () => {  if (isHostedStaticApp()) {    return PlatformConnectionSource.of({      registrations: Stream.empty,    });  }  return PlatformConnectionSource.of({    registrations: Stream.fromEffect(loadPrimaryConnectionRegistration()).pipe(      Stream.tapError((error) =>        Effect.logWarning("Could not discover the primary environment.", {          error,        }),      ),      Stream.retry(primaryRegistrationRetrySchedule),      Stream.catchCause(() => Stream.empty),    ),  });}); const environmentOwnedDataCleanupLayer = Layer.succeed(  EnvironmentOwnedDataCleanup,  EnvironmentOwnedDataCleanup.of({    clear: (environmentId) =>      Effect.sync(() => {        clearComposerDraftsEnvironment(environmentId);      }),  }),); const rpcRequestObserverLayer = Layer.succeed(  EnvironmentRpcRequestObserver,  EnvironmentRpcRequestObserver.of({    observe: ({ environmentId, method }) =>      Effect.sync(() => {        nextObservedRpcRequestId += 1;        const requestId = `${environmentId}:${nextObservedRpcRequestId}`;        trackRpcRequestSent(requestId, `${method} · ${environmentId}`);        return Effect.sync(() => {          acknowledgeRpcRequest(requestId);        });      }),  }),); type ConnectionPlatformLayerSource =  | typeof connectionStorageLayer  | typeof connectivityLayer  | typeof wakeupsLayer  | typeof capabilitiesLayer  | typeof platformConnectionSourceLayer  | typeof environmentOwnedDataCleanupLayer  | typeof rpcRequestObserverLayer; export const connectionPlatformLayer: Layer.Layer<  Layer.Success<ConnectionPlatformLayerSource>,  Layer.Error<ConnectionPlatformLayerSource>,  Layer.Services<ConnectionPlatformLayerSource>> = Layer.mergeAll(  connectionStorageLayer,  connectivityLayer,  wakeupsLayer,  capabilitiesLayer,  platformConnectionSourceLayer,  environmentOwnedDataCleanupLayer,  rpcRequestObserverLayer,);