import { createClerkBridge } from "@clerk/electron";import { storage } from "@clerk/electron/storage";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 Scope from "effect/Scope"; import { clerkFrontendApiHostnameFromPublishableKey } from "@t3tools/shared/relayAuth";import * as ElectronApp from "../electron/ElectronApp.ts";import * as ElectronProtocol from "../electron/ElectronProtocol.ts";import * as ElectronWindow from "../electron/ElectronWindow.ts";import * as DesktopEnvironment from "./DesktopEnvironment.ts"; declare const __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined; export class DesktopClerk extends Context.Service< DesktopClerk, { readonly configure: Effect.Effect< void, never, ElectronApp.ElectronApp | ElectronWindow.ElectronWindow | Scope.Scope >; }>()("@t3tools/desktop/app/DesktopClerk") {} export function resolveDesktopClerkFrontendApiHostname( publishableKey: string | undefined,): string | undefined { const normalizedKey = publishableKey?.trim(); if (!normalizedKey) return undefined; try { return clerkFrontendApiHostnameFromPublishableKey(normalizedKey); } catch { return undefined; }} export const desktopClerkFrontendApiHostname = resolveDesktopClerkFrontendApiHostname( typeof __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__ === "undefined" ? undefined : __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__,); export function createDesktopClerkBridge(stateDir: string, isDevelopment: boolean) { return createClerkBridge({ storage: storage({ path: stateDir }), passkeys: true, renderer: { scheme: ElectronProtocol.getDesktopScheme(isDevelopment), host: ElectronProtocol.DESKTOP_HOST, }, });} const make = Effect.gen(function* () { const environment = yield* DesktopEnvironment.DesktopEnvironment; yield* Effect.acquireRelease( Effect.sync(() => createDesktopClerkBridge(environment.stateDir, environment.isDevelopment)), (bridge) => Effect.sync(() => bridge.cleanup()), ); return DesktopClerk.of({ configure: Effect.gen(function* () { const electronApp = yield* ElectronApp.ElectronApp; const electronWindow = yield* ElectronWindow.ElectronWindow; const context = yield* Effect.context<ElectronWindow.ElectronWindow>(); const runPromise = Effect.runPromiseWith(context); if (!(yield* electronApp.requestSingleInstanceLock)) { yield* electronApp.quit; return yield* Effect.interrupt; } yield* electronApp.on("second-instance", () => { void runPromise( Effect.gen(function* () { const mainWindow = yield* electronWindow.currentMainOrFirst; if (Option.isSome(mainWindow)) { yield* electronWindow.reveal(mainWindow.value); } }), ); }); }).pipe(Effect.withSpan("desktop.clerk.configure")), });}); export const layer = Layer.effect(DesktopClerk, make);
import { createClerkBridge } from "@clerk/electron";
import { storage } from "@clerk/electron/storage";
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 Scope from "effect/Scope";
import { clerkFrontendApiHostnameFromPublishableKey } from "@t3tools/shared/relayAuth";
import * as ElectronApp from "../electron/ElectronApp.ts";
import * as ElectronProtocol from "../electron/ElectronProtocol.ts";
import * as ElectronWindow from "../electron/ElectronWindow.ts";
import * as DesktopEnvironment from "./DesktopEnvironment.ts";
declare const __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined;
export class DesktopClerk extends Context.Service<
DesktopClerk,
{
readonly configure: Effect.Effect<
void,
never,
ElectronApp.ElectronApp | ElectronWindow.ElectronWindow | Scope.Scope
>;
}
>()("@t3tools/desktop/app/DesktopClerk") {}
export function resolveDesktopClerkFrontendApiHostname(
publishableKey: string | undefined,
): string | undefined {
const normalizedKey = publishableKey?.trim();
if (!normalizedKey) return undefined;
try {
return clerkFrontendApiHostnameFromPublishableKey(normalizedKey);
} catch {
return undefined;
}
}
export const desktopClerkFrontendApiHostname = resolveDesktopClerkFrontendApiHostname(
typeof __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__ === "undefined"
? undefined
: __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__,
);
export function createDesktopClerkBridge(stateDir: string, isDevelopment: boolean) {
return createClerkBridge({
storage: storage({ path: stateDir }),
passkeys: true,
renderer: {
scheme: ElectronProtocol.getDesktopScheme(isDevelopment),
host: ElectronProtocol.DESKTOP_HOST,
},
});
}
const make = Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
yield* Effect.acquireRelease(
Effect.sync(() => createDesktopClerkBridge(environment.stateDir, environment.isDevelopment)),
(bridge) => Effect.sync(() => bridge.cleanup()),
);
return DesktopClerk.of({
configure: Effect.gen(function* () {
const electronApp = yield* ElectronApp.ElectronApp;
const electronWindow = yield* ElectronWindow.ElectronWindow;
const context = yield* Effect.context<ElectronWindow.ElectronWindow>();
const runPromise = Effect.runPromiseWith(context);
if (!(yield* electronApp.requestSingleInstanceLock)) {
yield* electronApp.quit;
return yield* Effect.interrupt;
}
yield* electronApp.on("second-instance", () => {
void runPromise(
Effect.gen(function* () {
const mainWindow = yield* electronWindow.currentMainOrFirst;
if (Option.isSome(mainWindow)) {
yield* electronWindow.reveal(mainWindow.value);
}
}),
);
});
}).pipe(Effect.withSpan("desktop.clerk.configure")),
});
});
export const layer = Layer.effect(DesktopClerk, make);