| author | |
| committer | |
| log | 93fd9721086d4325794830a29a7df0592d120683 |
| tree | a3cc79870cd7682171dcf0a46b2f25f2eb16dd0d |
| parent | df1540f3ac8fd70877a83e91bd0be182ebf5022c |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: codex <codex@users.noreply.github.com>4 files changed, 50 insertions(+), 52 deletions(-)
apps/desktop/src/updates/DesktopUpdates.ts+30-29| ... | ... | @@ -7,7 +7,6 @@ import type { |
| 7 | 7 | } from "@t3tools/contracts"; |
| 8 | 8 | import * as Cause from "effect/Cause"; |
| 9 | 9 | import * as Context from "effect/Context"; |
| 10 | import * as Data from "effect/Data"; | |
| 11 | 10 | import * as DateTime from "effect/DateTime"; |
| 12 | 11 | import * as Duration from "effect/Duration"; |
| 13 | 12 | import * as Effect from "effect/Effect"; |
| ... | ... | @@ -60,23 +59,26 @@ const decodeDownloadProgressInfo = Schema.decodeUnknownEffect(DownloadProgressIn |
| 60 | 59 | |
| 61 | 60 | const currentIsoTimestamp = DateTime.now.pipe(Effect.map(DateTime.formatIso)); |
| 62 | 61 | |
| 63 | export class DesktopUpdateActionInProgressError extends Data.TaggedError( | |
| 62 | export class DesktopUpdateActionInProgressError extends Schema.TaggedErrorClass<DesktopUpdateActionInProgressError>()( | |
| 64 | 63 | "DesktopUpdateActionInProgressError", |
| 65 | )<{ | |
| 66 | readonly action: "check" | "download" | "install"; | |
| 67 | }> { | |
| 68 | override get message() { | |
| 64 | { | |
| 65 | action: Schema.Literals(["check", "download", "install"]), | |
| 66 | }, | |
| 67 | ) { | |
| 68 | override get message(): string { | |
| 69 | 69 | return `Cannot change update tracks while an update ${this.action} action is in progress.`; |
| 70 | 70 | } |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | export class DesktopUpdatePersistenceError extends Data.TaggedError( | |
| 73 | export class DesktopUpdatePersistenceError extends Schema.TaggedErrorClass<DesktopUpdatePersistenceError>()( | |
| 74 | 74 | "DesktopUpdatePersistenceError", |
| 75 | )<{ | |
| 76 | readonly cause: DesktopAppSettings.DesktopSettingsWriteError; | |
| 77 | }> { | |
| 78 | override get message() { | |
| 79 | return "Failed to persist desktop update settings."; | |
| 75 | { | |
| 76 | cause: Schema.Defect(), | |
| 77 | }, | |
| 78 | ) { | |
| 79 | override get message(): string { | |
| 80 | const detail = this.cause instanceof Error ? this.cause.message : String(this.cause); | |
| 81 | return `Failed to persist desktop update settings: ${detail}`; | |
| 80 | 82 | } |
| 81 | 83 | } |
| 82 | 84 | |
| ... | ... | @@ -86,22 +88,21 @@ export type DesktopUpdateSetChannelError = |
| 86 | 88 | | DesktopUpdateActionInProgressError |
| 87 | 89 | | DesktopUpdatePersistenceError; |
| 88 | 90 | |
| 89 | export interface DesktopUpdatesShape { | |
| 90 | readonly getState: Effect.Effect<DesktopUpdateState>; | |
| 91 | readonly emitState: Effect.Effect<void>; | |
| 92 | readonly disabledReason: Effect.Effect<Option.Option<string>>; | |
| 93 | readonly configure: Effect.Effect<void, DesktopUpdateConfigureError, Scope.Scope>; | |
| 94 | readonly setChannel: ( | |
| 95 | channel: DesktopUpdateChannel, | |
| 96 | ) => Effect.Effect<DesktopUpdateState, DesktopUpdateSetChannelError>; | |
| 97 | readonly check: (reason: string) => Effect.Effect<DesktopUpdateCheckResult>; | |
| 98 | readonly download: Effect.Effect<DesktopUpdateActionResult>; | |
| 99 | readonly install: Effect.Effect<DesktopUpdateActionResult>; | |
| 100 | } | |
| 101 | ||
| 102 | export class DesktopUpdates extends Context.Service<DesktopUpdates, DesktopUpdatesShape>()( | |
| 103 | "@t3tools/desktop/updates/DesktopUpdates", | |
| 104 | ) {} | |
| 91 | export class DesktopUpdates extends Context.Service< | |
| 92 | DesktopUpdates, | |
| 93 | { | |
| 94 | readonly getState: Effect.Effect<DesktopUpdateState>; | |
| 95 | readonly emitState: Effect.Effect<void>; | |
| 96 | readonly disabledReason: Effect.Effect<Option.Option<string>>; | |
| 97 | readonly configure: Effect.Effect<void, DesktopUpdateConfigureError, Scope.Scope>; | |
| 98 | readonly setChannel: ( | |
| 99 | channel: DesktopUpdateChannel, | |
| 100 | ) => Effect.Effect<DesktopUpdateState, DesktopUpdateSetChannelError>; | |
| 101 | readonly check: (reason: string) => Effect.Effect<DesktopUpdateCheckResult>; | |
| 102 | readonly download: Effect.Effect<DesktopUpdateActionResult>; | |
| 103 | readonly install: Effect.Effect<DesktopUpdateActionResult>; | |
| 104 | } | |
| 105 | >()("@t3tools/desktop/updates/DesktopUpdates") {} | |
| 105 | 106 | |
| 106 | 107 | const { |
| 107 | 108 | logInfo: logUpdaterInfo, |
| ... | ... | @@ -185,7 +186,7 @@ function isArm64HostRunningIntelBuild(runtimeInfo: DesktopRuntimeInfo): boolean |
| 185 | 186 | return runtimeInfo.hostArch === "arm64" && runtimeInfo.appArch === "x64"; |
| 186 | 187 | } |
| 187 | 188 | |
| 188 | const make = Effect.gen(function* () { | |
| 189 | export const make = Effect.gen(function* () { | |
| 189 | 190 | const config = yield* DesktopConfig.DesktopConfig; |
| 190 | 191 | const backendManager = yield* DesktopBackendManager.DesktopBackendManager; |
| 191 | 192 | const desktopState = yield* DesktopState.DesktopState; |
apps/desktop/src/window/DesktopApplicationMenu.test.ts+2-2| ... | ... | @@ -64,7 +64,7 @@ const desktopUpdatesLayer = Layer.succeed(DesktopUpdates.DesktopUpdates, { |
| 64 | 64 | check: () => Effect.die("unexpected check"), |
| 65 | 65 | download: Effect.die("unexpected download"), |
| 66 | 66 | install: Effect.die("unexpected install"), |
| 67 | } satisfies DesktopUpdates.DesktopUpdatesShape); | |
| 67 | } satisfies DesktopUpdates.DesktopUpdates["Service"]); | |
| 68 | 68 | |
| 69 | 69 | const makeDesktopWindowLayer = (selectedAction: Deferred.Deferred<string>) => |
| 70 | 70 | Layer.succeed(DesktopWindow.DesktopWindow, { |
| ... | ... | @@ -76,7 +76,7 @@ const makeDesktopWindowLayer = (selectedAction: Deferred.Deferred<string>) => |
| 76 | 76 | handleBackendReady: Effect.void, |
| 77 | 77 | dispatchMenuAction: (action) => Deferred.succeed(selectedAction, action).pipe(Effect.asVoid), |
| 78 | 78 | syncAppearance: Effect.void, |
| 79 | } satisfies DesktopWindow.DesktopWindowShape); | |
| 79 | } satisfies DesktopWindow.DesktopWindow["Service"]); | |
| 80 | 80 | |
| 81 | 81 | const makeElectronMenuLayer = ( |
| 82 | 82 | applicationMenuTemplate: Deferred.Deferred<readonly Electron.MenuItemConstructorOptions[]>, |
apps/desktop/src/window/DesktopApplicationMenu.ts+4-6| ... | ... | @@ -14,13 +14,11 @@ import * as DesktopEnvironment from "../app/DesktopEnvironment.ts"; |
| 14 | 14 | import * as DesktopUpdates from "../updates/DesktopUpdates.ts"; |
| 15 | 15 | import * as DesktopWindow from "./DesktopWindow.ts"; |
| 16 | 16 | |
| 17 | export interface DesktopApplicationMenuShape { | |
| 18 | readonly configure: Effect.Effect<void>; | |
| 19 | } | |
| 20 | ||
| 21 | 17 | export class DesktopApplicationMenu extends Context.Service< |
| 22 | 18 | DesktopApplicationMenu, |
| 23 | DesktopApplicationMenuShape | |
| 19 | { | |
| 20 | readonly configure: Effect.Effect<void>; | |
| 21 | } | |
| 24 | 22 | >()("@t3tools/desktop/window/DesktopApplicationMenu") {} |
| 25 | 23 | |
| 26 | 24 | type DesktopApplicationMenuRuntimeServices = |
| ... | ... | @@ -94,7 +92,7 @@ const handleCheckForUpdatesMenuClick: Effect.Effect< |
| 94 | 92 | yield* checkForUpdatesFromMenu; |
| 95 | 93 | }).pipe(Effect.withSpan("desktop.menu.handleCheckForUpdatesClick")); |
| 96 | 94 | |
| 97 | const make = Effect.gen(function* () { | |
| 95 | export const make = Effect.gen(function* () { | |
| 98 | 96 | const electronApp = yield* ElectronApp.ElectronApp; |
| 99 | 97 | const electronMenu = yield* ElectronMenu.ElectronMenu; |
| 100 | 98 | const environment = yield* DesktopEnvironment.DesktopEnvironment; |
apps/desktop/src/window/DesktopWindow.ts+14-15| ... | ... | @@ -42,20 +42,19 @@ export type DesktopWindowError = |
| 42 | 42 | | ElectronWindow.ElectronWindowCreateError |
| 43 | 43 | | PreviewManager.PreviewManagerError; |
| 44 | 44 | |
| 45 | export interface DesktopWindowShape { | |
| 46 | readonly createMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 47 | readonly ensureMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 48 | readonly revealOrCreateMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 49 | readonly activate: Effect.Effect<void, DesktopWindowError>; | |
| 50 | readonly createMainIfBackendReady: Effect.Effect<void, DesktopWindowError>; | |
| 51 | readonly handleBackendReady: Effect.Effect<void, DesktopWindowError>; | |
| 52 | readonly dispatchMenuAction: (action: string) => Effect.Effect<void, DesktopWindowError>; | |
| 53 | readonly syncAppearance: Effect.Effect<void>; | |
| 54 | } | |
| 55 | ||
| 56 | export class DesktopWindow extends Context.Service<DesktopWindow, DesktopWindowShape>()( | |
| 57 | "@t3tools/desktop/window/DesktopWindow", | |
| 58 | ) {} | |
| 45 | export class DesktopWindow extends Context.Service< | |
| 46 | DesktopWindow, | |
| 47 | { | |
| 48 | readonly createMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 49 | readonly ensureMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 50 | readonly revealOrCreateMain: Effect.Effect<Electron.BrowserWindow, DesktopWindowError>; | |
| 51 | readonly activate: Effect.Effect<void, DesktopWindowError>; | |
| 52 | readonly createMainIfBackendReady: Effect.Effect<void, DesktopWindowError>; | |
| 53 | readonly handleBackendReady: Effect.Effect<void, DesktopWindowError>; | |
| 54 | readonly dispatchMenuAction: (action: string) => Effect.Effect<void, DesktopWindowError>; | |
| 55 | readonly syncAppearance: Effect.Effect<void>; | |
| 56 | } | |
| 57 | >()("@t3tools/desktop/window/DesktopWindow") {} | |
| 59 | 58 | |
| 60 | 59 | const { logInfo: logWindowInfo, logWarning: logWindowWarning } = |
| 61 | 60 | DesktopObservability.makeComponentLogger("desktop-window"); |
| ... | ... | @@ -143,7 +142,7 @@ function bindFirstRevealTrigger( |
| 143 | 142 | } |
| 144 | 143 | } |
| 145 | 144 | |
| 146 | const make = Effect.gen(function* () { | |
| 145 | export const make = Effect.gen(function* () { | |
| 147 | 146 | const environment = yield* DesktopEnvironment.DesktopEnvironment; |
| 148 | 147 | const assets = yield* DesktopAssets.DesktopAssets; |
| 149 | 148 | const electronMenu = yield* ElectronMenu.ElectronMenu; |