import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";import * as NodeRuntime from "@effect/platform-node/NodeRuntime";import * as NodeServices from "@effect/platform-node/NodeServices";import * as NodeOS from "node:os";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option"; import * as Electron from "electron"; import * as NetService from "@t3tools/shared/Net";import { resolveRemoteT3CliPackageSpec } from "@t3tools/ssh/command";import type { RemoteT3RunnerOptions } from "@t3tools/ssh/tunnel"; import type { DesktopSettings as DesktopSettingsValue } from "./settings/DesktopAppSettings.ts";import * as DesktopIpc from "./ipc/DesktopIpc.ts";import * as ElectronApp from "./electron/ElectronApp.ts";import * as ElectronDialog from "./electron/ElectronDialog.ts";import * as ElectronMenu from "./electron/ElectronMenu.ts";import * as ElectronProtocol from "./electron/ElectronProtocol.ts";import * as DesktopSecretStorage from "./electron/ElectronSafeStorage.ts";import * as ElectronShell from "./electron/ElectronShell.ts";import * as ElectronTheme from "./electron/ElectronTheme.ts";import * as ElectronUpdater from "./electron/ElectronUpdater.ts";import * as ElectronWindow from "./electron/ElectronWindow.ts";import * as DesktopApp from "./app/DesktopApp.ts";import * as DesktopAppIdentity from "./app/DesktopAppIdentity.ts";import * as DesktopApplicationMenu from "./window/DesktopApplicationMenu.ts";import * as DesktopAssets from "./app/DesktopAssets.ts";import * as DesktopBackendConfiguration from "./backend/DesktopBackendConfiguration.ts";import * as DesktopBackendManager from "./backend/DesktopBackendManager.ts";import * as DesktopEnvironment from "./app/DesktopEnvironment.ts";import * as DesktopLifecycle from "./app/DesktopLifecycle.ts";import * as DesktopObservability from "./app/DesktopObservability.ts";import * as DesktopServerExposure from "./backend/DesktopServerExposure.ts";import * as DesktopClientSettings from "./settings/DesktopClientSettings.ts";import * as DesktopSavedEnvironments from "./settings/DesktopSavedEnvironments.ts";import * as DesktopAppSettings from "./settings/DesktopAppSettings.ts";import * as DesktopShellEnvironment from "./shell/DesktopShellEnvironment.ts";import * as DesktopSshEnvironment from "./ssh/DesktopSshEnvironment.ts";import * as DesktopSshPasswordPrompts from "./ssh/DesktopSshPasswordPrompts.ts";import * as DesktopSshRemoteApi from "./ssh/DesktopSshRemoteApi.ts";import * as DesktopState from "./app/DesktopState.ts";import * as DesktopUpdates from "./updates/DesktopUpdates.ts";import * as DesktopWindow from "./window/DesktopWindow.ts"; const desktopEnvironmentLayer = Layer.unwrap( Effect.gen(function* () { const metadata = yield* Effect.service(ElectronApp.ElectronApp).pipe( Effect.flatMap((app) => app.metadata), ); return DesktopEnvironment.layer({ dirname: __dirname, homeDirectory: NodeOS.homedir(), platform: process.platform, processArch: process.arch, ...metadata, }); }),); const resolveDesktopSshCliRunner = ( environment: DesktopEnvironment.DesktopEnvironmentShape, settings: DesktopSettingsValue,): RemoteT3RunnerOptions => { const devRemoteEntryPath = Option.getOrUndefined(environment.devRemoteT3ServerEntryPath); if (environment.isDevelopment && devRemoteEntryPath !== undefined) { return { nodeScriptPath: devRemoteEntryPath }; } return { packageSpec: resolveRemoteT3CliPackageSpec({ appVersion: environment.appVersion, updateChannel: settings.updateChannel, isDevelopment: environment.isDevelopment, }), };}; const desktopSshEnvironmentLayer = Layer.unwrap( Effect.gen(function* () { const environment = yield* DesktopEnvironment.DesktopEnvironment; const settings = yield* DesktopAppSettings.DesktopAppSettings; return DesktopSshEnvironment.layer({ resolveCliRunner: settings.get.pipe( Effect.map((currentSettings) => resolveDesktopSshCliRunner(environment, currentSettings)), ), }); }),); const electronLayer = Layer.mergeAll( ElectronApp.layer, ElectronDialog.layer, ElectronMenu.layer, ElectronProtocol.layer, DesktopSecretStorage.layer, ElectronShell.layer, ElectronTheme.layer, ElectronUpdater.layer, ElectronWindow.layer, Layer.succeed(DesktopIpc.DesktopIpc, DesktopIpc.make(Electron.ipcMain)),); const desktopFoundationLayer = Layer.mergeAll( DesktopState.layer, DesktopLifecycle.layerShutdown, DesktopAppSettings.layer, DesktopClientSettings.layer, DesktopSavedEnvironments.layer, DesktopAssets.layer, DesktopObservability.layer,).pipe(Layer.provideMerge(desktopEnvironmentLayer)); const desktopSshLayer = Layer.mergeAll(desktopSshEnvironmentLayer, DesktopSshRemoteApi.layer).pipe( Layer.provideMerge(DesktopSshPasswordPrompts.layer()),); const desktopServerExposureLayer = DesktopServerExposure.layer.pipe( Layer.provideMerge(DesktopServerExposure.networkInterfacesLayer), Layer.provideMerge(desktopFoundationLayer),); const desktopWindowLayer = DesktopWindow.layer.pipe(Layer.provideMerge(desktopServerExposureLayer)); const desktopBackendLayer = DesktopBackendManager.layer.pipe( Layer.provideMerge(DesktopAppIdentity.layer), Layer.provideMerge(DesktopBackendConfiguration.layer), Layer.provideMerge(desktopWindowLayer),); const desktopApplicationLayer = Layer.mergeAll( DesktopLifecycle.layer, DesktopApplicationMenu.layer, DesktopShellEnvironment.layer, desktopSshLayer,).pipe(Layer.provideMerge(DesktopUpdates.layer), Layer.provideMerge(desktopBackendLayer)); const desktopRuntimeLayer = ElectronProtocol.layerSchemePrivileges.pipe( Layer.flatMap(() => desktopApplicationLayer.pipe( Layer.provideMerge(NodeServices.layer), Layer.provideMerge(NodeHttpClient.layerUndici), Layer.provideMerge(NetService.layer), Layer.provideMerge(electronLayer), ), ),); DesktopApp.program.pipe(Effect.provide(desktopRuntimeLayer), NodeRuntime.runMain);
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
import * as NodeServices from "@effect/platform-node/NodeServices";
import * as NodeOS from "node:os";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Electron from "electron";
import * as NetService from "@t3tools/shared/Net";
import { resolveRemoteT3CliPackageSpec } from "@t3tools/ssh/command";
import type { RemoteT3RunnerOptions } from "@t3tools/ssh/tunnel";
import type { DesktopSettings as DesktopSettingsValue } from "./settings/DesktopAppSettings.ts";
import * as DesktopIpc from "./ipc/DesktopIpc.ts";
import * as ElectronApp from "./electron/ElectronApp.ts";
import * as ElectronDialog from "./electron/ElectronDialog.ts";
import * as ElectronMenu from "./electron/ElectronMenu.ts";
import * as ElectronProtocol from "./electron/ElectronProtocol.ts";
import * as DesktopSecretStorage from "./electron/ElectronSafeStorage.ts";
import * as ElectronShell from "./electron/ElectronShell.ts";
import * as ElectronTheme from "./electron/ElectronTheme.ts";
import * as ElectronUpdater from "./electron/ElectronUpdater.ts";
import * as ElectronWindow from "./electron/ElectronWindow.ts";
import * as DesktopApp from "./app/DesktopApp.ts";
import * as DesktopAppIdentity from "./app/DesktopAppIdentity.ts";
import * as DesktopApplicationMenu from "./window/DesktopApplicationMenu.ts";
import * as DesktopAssets from "./app/DesktopAssets.ts";
import * as DesktopBackendConfiguration from "./backend/DesktopBackendConfiguration.ts";
import * as DesktopBackendManager from "./backend/DesktopBackendManager.ts";
import * as DesktopEnvironment from "./app/DesktopEnvironment.ts";
import * as DesktopLifecycle from "./app/DesktopLifecycle.ts";
import * as DesktopObservability from "./app/DesktopObservability.ts";
import * as DesktopServerExposure from "./backend/DesktopServerExposure.ts";
import * as DesktopClientSettings from "./settings/DesktopClientSettings.ts";
import * as DesktopSavedEnvironments from "./settings/DesktopSavedEnvironments.ts";
import * as DesktopAppSettings from "./settings/DesktopAppSettings.ts";
import * as DesktopShellEnvironment from "./shell/DesktopShellEnvironment.ts";
import * as DesktopSshEnvironment from "./ssh/DesktopSshEnvironment.ts";
import * as DesktopSshPasswordPrompts from "./ssh/DesktopSshPasswordPrompts.ts";
import * as DesktopSshRemoteApi from "./ssh/DesktopSshRemoteApi.ts";
import * as DesktopState from "./app/DesktopState.ts";
import * as DesktopUpdates from "./updates/DesktopUpdates.ts";
import * as DesktopWindow from "./window/DesktopWindow.ts";
const desktopEnvironmentLayer = Layer.unwrap(
Effect.gen(function* () {
const metadata = yield* Effect.service(ElectronApp.ElectronApp).pipe(
Effect.flatMap((app) => app.metadata),
);
return DesktopEnvironment.layer({
dirname: __dirname,
homeDirectory: NodeOS.homedir(),
platform: process.platform,
processArch: process.arch,
...metadata,
});
}),
);
const resolveDesktopSshCliRunner = (
environment: DesktopEnvironment.DesktopEnvironmentShape,
settings: DesktopSettingsValue,
): RemoteT3RunnerOptions => {
const devRemoteEntryPath = Option.getOrUndefined(environment.devRemoteT3ServerEntryPath);
if (environment.isDevelopment && devRemoteEntryPath !== undefined) {
return { nodeScriptPath: devRemoteEntryPath };
}
return {
packageSpec: resolveRemoteT3CliPackageSpec({
appVersion: environment.appVersion,
updateChannel: settings.updateChannel,
isDevelopment: environment.isDevelopment,
}),
};
};
const desktopSshEnvironmentLayer = Layer.unwrap(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const settings = yield* DesktopAppSettings.DesktopAppSettings;
return DesktopSshEnvironment.layer({
resolveCliRunner: settings.get.pipe(
Effect.map((currentSettings) => resolveDesktopSshCliRunner(environment, currentSettings)),
),
});
}),
);
const electronLayer = Layer.mergeAll(
ElectronApp.layer,
ElectronDialog.layer,
ElectronMenu.layer,
ElectronProtocol.layer,
DesktopSecretStorage.layer,
ElectronShell.layer,
ElectronTheme.layer,
ElectronUpdater.layer,
ElectronWindow.layer,
Layer.succeed(DesktopIpc.DesktopIpc, DesktopIpc.make(Electron.ipcMain)),
);
const desktopFoundationLayer = Layer.mergeAll(
DesktopState.layer,
DesktopLifecycle.layerShutdown,
DesktopAppSettings.layer,
DesktopClientSettings.layer,
DesktopSavedEnvironments.layer,
DesktopAssets.layer,
DesktopObservability.layer,
).pipe(Layer.provideMerge(desktopEnvironmentLayer));
const desktopSshLayer = Layer.mergeAll(desktopSshEnvironmentLayer, DesktopSshRemoteApi.layer).pipe(
Layer.provideMerge(DesktopSshPasswordPrompts.layer()),
);
const desktopServerExposureLayer = DesktopServerExposure.layer.pipe(
Layer.provideMerge(DesktopServerExposure.networkInterfacesLayer),
Layer.provideMerge(desktopFoundationLayer),
);
const desktopWindowLayer = DesktopWindow.layer.pipe(Layer.provideMerge(desktopServerExposureLayer));
const desktopBackendLayer = DesktopBackendManager.layer.pipe(
Layer.provideMerge(DesktopAppIdentity.layer),
Layer.provideMerge(DesktopBackendConfiguration.layer),
Layer.provideMerge(desktopWindowLayer),
);
const desktopApplicationLayer = Layer.mergeAll(
DesktopLifecycle.layer,
DesktopApplicationMenu.layer,
DesktopShellEnvironment.layer,
desktopSshLayer,
).pipe(Layer.provideMerge(DesktopUpdates.layer), Layer.provideMerge(desktopBackendLayer));
const desktopRuntimeLayer = ElectronProtocol.layerSchemePrivileges.pipe(
Layer.flatMap(() =>
desktopApplicationLayer.pipe(
Layer.provideMerge(NodeServices.layer),
Layer.provideMerge(NodeHttpClient.layerUndici),
Layer.provideMerge(NetService.layer),
Layer.provideMerge(electronLayer),
),
),
);
DesktopApp.program.pipe(Effect.provide(desktopRuntimeLayer), NodeRuntime.runMain);