| ... | ... | @@ -37,7 +37,6 @@ import { |
| 37 | 37 | import * as Cause from "effect/Cause"; |
| 38 | 38 | import * as Clock from "effect/Clock"; |
| 39 | 39 | import * as Context from "effect/Context"; |
| 40 | | import * as Data from "effect/Data"; |
| 41 | 40 | import * as DateTime from "effect/DateTime"; |
| 42 | 41 | import * as Effect from "effect/Effect"; |
| 43 | 42 | import * as Exit from "effect/Exit"; |
| ... | ... | @@ -432,15 +431,17 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 432 | 431 | ) { |
| 433 | 432 | const tabs = yield* SynchronizedRef.get(tabsRef); |
| 434 | 433 | const tab = tabs.get(tabId); |
| 435 | | if (!tab) return yield* fail("requireWebContents", new PreviewTabNotFoundError(tabId)); |
| 434 | if (!tab) { |
| 435 | return yield* fail("requireWebContents", new PreviewTabNotFoundError({ tabId })); |
| 436 | } |
| 436 | 437 | if (tab.webContentsId == null) { |
| 437 | | return yield* fail("requireWebContents", new PreviewWebviewNotInitializedError(tabId)); |
| 438 | return yield* fail("requireWebContents", new PreviewWebviewNotInitializedError({ tabId })); |
| 438 | 439 | } |
| 439 | 440 | const wc = webContents.fromId(tab.webContentsId); |
| 440 | 441 | if (!wc) { |
| 441 | 442 | return yield* fail( |
| 442 | 443 | "requireWebContents", |
| 443 | | new PreviewWebContentsNotFoundError(tabId, tab.webContentsId), |
| 444 | new PreviewWebContentsNotFoundError({ tabId, webContentsId: tab.webContentsId }), |
| 444 | 445 | ); |
| 445 | 446 | } |
| 446 | 447 | return wc; |
| ... | ... | @@ -845,7 +846,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 845 | 846 | }); |
| 846 | 847 | } else { |
| 847 | 848 | const error = Option.getOrNull(Cause.findErrorOption(exit.cause)); |
| 848 | | const underlying = error instanceof PreviewManagerError ? error.cause : error; |
| 849 | const underlying = isPreviewManagerError(error) ? error.cause : error; |
| 849 | 850 | const interrupted = |
| 850 | 851 | underlying instanceof Error && |
| 851 | 852 | underlying.name === "PreviewAutomationControlInterruptedError"; |
| ... | ... | @@ -1161,7 +1162,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 1161 | 1162 | ) { |
| 1162 | 1163 | const tab = (yield* SynchronizedRef.get(tabsRef)).get(tabId); |
| 1163 | 1164 | if (!tab) { |
| 1164 | | return yield* fail("registerWebview", new PreviewTabNotFoundError(tabId)); |
| 1165 | return yield* fail("registerWebview", new PreviewTabNotFoundError({ tabId })); |
| 1165 | 1166 | } |
| 1166 | 1167 | const wc = webContents.fromId(webContentsId); |
| 1167 | 1168 | const mainWindow = yield* Ref.get(mainWindowRef); |
| ... | ... | @@ -1172,7 +1173,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 1172 | 1173 | ) { |
| 1173 | 1174 | return yield* fail( |
| 1174 | 1175 | "registerWebview", |
| 1175 | | new PreviewWebContentsNotFoundError(tabId, webContentsId), |
| 1176 | new PreviewWebContentsNotFoundError({ tabId, webContentsId }), |
| 1176 | 1177 | ); |
| 1177 | 1178 | } |
| 1178 | 1179 | const attached = yield* Ref.get(attachedRef); |
| ... | ... | @@ -1224,7 +1225,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 1224 | 1225 | ] as const; |
| 1225 | 1226 | }); |
| 1226 | 1227 | if (Option.isNone(registration)) { |
| 1227 | | return yield* fail("registerWebview", new PreviewTabNotFoundError(tabId)); |
| 1228 | return yield* fail("registerWebview", new PreviewTabNotFoundError({ tabId })); |
| 1228 | 1229 | } |
| 1229 | 1230 | const { state: registered, pendingUrl } = registration.value; |
| 1230 | 1231 | yield* emit(tabId, registered); |
| ... | ... | @@ -2200,129 +2201,131 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function |
| 2200 | 2201 | }; |
| 2201 | 2202 | }); |
| 2202 | 2203 | |
| 2203 | | export class PreviewTabNotFoundError extends Error { |
| 2204 | | readonly tabId: string; |
| 2205 | | constructor(tabId: string) { |
| 2206 | | super(`Preview tab not found: ${tabId}`); |
| 2207 | | this.name = "PreviewTabNotFoundError"; |
| 2208 | | this.tabId = tabId; |
| 2204 | export class PreviewTabNotFoundError extends Schema.TaggedErrorClass<PreviewTabNotFoundError>()( |
| 2205 | "PreviewTabNotFoundError", |
| 2206 | { tabId: Schema.String }, |
| 2207 | ) { |
| 2208 | override get message(): string { |
| 2209 | return `Preview tab not found: ${this.tabId}`; |
| 2209 | 2210 | } |
| 2210 | 2211 | } |
| 2211 | 2212 | |
| 2212 | | export class PreviewWebContentsNotFoundError extends Error { |
| 2213 | | readonly tabId: string; |
| 2214 | | readonly webContentsId: number; |
| 2215 | | constructor(tabId: string, webContentsId: number) { |
| 2216 | | super(`WebContents ${webContentsId} not found for preview tab ${tabId}`); |
| 2217 | | this.name = "PreviewWebContentsNotFoundError"; |
| 2218 | | this.tabId = tabId; |
| 2219 | | this.webContentsId = webContentsId; |
| 2213 | export class PreviewWebContentsNotFoundError extends Schema.TaggedErrorClass<PreviewWebContentsNotFoundError>()( |
| 2214 | "PreviewWebContentsNotFoundError", |
| 2215 | { tabId: Schema.String, webContentsId: Schema.Number }, |
| 2216 | ) { |
| 2217 | override get message(): string { |
| 2218 | return `WebContents ${this.webContentsId} not found for preview tab ${this.tabId}`; |
| 2220 | 2219 | } |
| 2221 | 2220 | } |
| 2222 | 2221 | |
| 2223 | | export class PreviewWebviewNotInitializedError extends Error { |
| 2224 | | readonly tabId: string; |
| 2225 | | constructor(tabId: string) { |
| 2226 | | super(`Preview tab "${tabId}" has no webview registered`); |
| 2227 | | this.name = "PreviewWebviewNotInitializedError"; |
| 2228 | | this.tabId = tabId; |
| 2222 | export class PreviewWebviewNotInitializedError extends Schema.TaggedErrorClass<PreviewWebviewNotInitializedError>()( |
| 2223 | "PreviewWebviewNotInitializedError", |
| 2224 | { tabId: Schema.String }, |
| 2225 | ) { |
| 2226 | override get message(): string { |
| 2227 | return `Preview tab "${this.tabId}" has no webview registered`; |
| 2229 | 2228 | } |
| 2230 | 2229 | } |
| 2231 | 2230 | |
| 2232 | | export class PreviewManagerError extends Data.TaggedError("PreviewManagerError")<{ |
| 2233 | | readonly operation: string; |
| 2234 | | readonly cause: unknown; |
| 2235 | | }> { |
| 2236 | | override get message() { |
| 2231 | export class PreviewManagerError extends Schema.TaggedErrorClass<PreviewManagerError>()( |
| 2232 | "PreviewManagerError", |
| 2233 | { |
| 2234 | operation: Schema.String, |
| 2235 | cause: Schema.Defect(), |
| 2236 | }, |
| 2237 | ) { |
| 2238 | override get message(): string { |
| 2237 | 2239 | return `Desktop preview operation failed: ${this.operation}`; |
| 2238 | 2240 | } |
| 2239 | 2241 | } |
| 2240 | 2242 | |
| 2241 | | export interface PreviewManagerShape { |
| 2242 | | readonly setMainWindow: (window: BrowserWindow) => Effect.Effect<void, PreviewManagerError>; |
| 2243 | | readonly getBrowserSession: (scope?: string) => Effect.Effect<Session, PreviewManagerError>; |
| 2244 | | readonly isBrowserPartition: (partition: string) => boolean; |
| 2245 | | readonly createTab: (tabId: string) => Effect.Effect<PreviewTabState, PreviewManagerError>; |
| 2246 | | readonly closeTab: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2247 | | readonly registerWebview: ( |
| 2248 | | tabId: string, |
| 2249 | | webContentsId: number, |
| 2250 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2251 | | readonly navigate: (tabId: string, url: string) => Effect.Effect<void, PreviewManagerError>; |
| 2252 | | readonly goBack: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2253 | | readonly goForward: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2254 | | readonly refresh: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2255 | | readonly zoomIn: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2256 | | readonly zoomOut: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2257 | | readonly resetZoom: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2258 | | readonly hardReload: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2259 | | readonly openDevTools: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2260 | | readonly clearCookies: () => Effect.Effect<void, PreviewManagerError>; |
| 2261 | | readonly clearCache: () => Effect.Effect<void, PreviewManagerError>; |
| 2262 | | readonly getBrowserPartition: (scope?: string) => Effect.Effect<string, PreviewManagerError>; |
| 2263 | | readonly setAnnotationTheme: ( |
| 2264 | | theme: DesktopPreviewAnnotationTheme, |
| 2265 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2266 | | readonly pickElement: ( |
| 2267 | | tabId: string, |
| 2268 | | ) => Effect.Effect<PreviewAnnotationPayload | null, PreviewManagerError>; |
| 2269 | | readonly cancelPickElement: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2270 | | readonly captureScreenshot: ( |
| 2271 | | tabId: string, |
| 2272 | | ) => Effect.Effect<DesktopPreviewScreenshotArtifact, PreviewManagerError>; |
| 2273 | | readonly revealArtifact: (path: string) => Effect.Effect<void, PreviewManagerError>; |
| 2274 | | readonly copyArtifactToClipboard: (path: string) => Effect.Effect<void, PreviewManagerError>; |
| 2275 | | readonly startRecording: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2276 | | readonly stopRecording: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2277 | | readonly saveRecording: ( |
| 2278 | | tabId: string, |
| 2279 | | mimeType: string, |
| 2280 | | data: Uint8Array, |
| 2281 | | ) => Effect.Effect<DesktopPreviewRecordingArtifact, PreviewManagerError>; |
| 2282 | | readonly automationStatus: ( |
| 2283 | | tabId: string, |
| 2284 | | ) => Effect.Effect<PreviewAutomationStatus, PreviewManagerError>; |
| 2285 | | readonly automationSnapshot: ( |
| 2286 | | tabId: string, |
| 2287 | | ) => Effect.Effect<PreviewAutomationSnapshot, PreviewManagerError>; |
| 2288 | | readonly automationClick: ( |
| 2289 | | tabId: string, |
| 2290 | | input: PreviewAutomationClickInput, |
| 2291 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2292 | | readonly automationType: ( |
| 2293 | | tabId: string, |
| 2294 | | input: PreviewAutomationTypeInput, |
| 2295 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2296 | | readonly automationPress: ( |
| 2297 | | tabId: string, |
| 2298 | | input: PreviewAutomationPressInput, |
| 2299 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2300 | | readonly automationScroll: ( |
| 2301 | | tabId: string, |
| 2302 | | input: PreviewAutomationScrollInput, |
| 2303 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2304 | | readonly automationEvaluate: ( |
| 2305 | | tabId: string, |
| 2306 | | input: PreviewAutomationEvaluateInput, |
| 2307 | | ) => Effect.Effect<unknown, PreviewManagerError>; |
| 2308 | | readonly automationWaitFor: ( |
| 2309 | | tabId: string, |
| 2310 | | input: PreviewAutomationWaitForInput, |
| 2311 | | ) => Effect.Effect<void, PreviewManagerError>; |
| 2312 | | readonly subscribeStateChanges: (listener: Listener) => Effect.Effect<void, never, Scope.Scope>; |
| 2313 | | readonly subscribePointerEvents: ( |
| 2314 | | listener: PointerEventListener, |
| 2315 | | ) => Effect.Effect<void, never, Scope.Scope>; |
| 2316 | | readonly subscribeRecordingFrames: ( |
| 2317 | | listener: RecordingFrameListener, |
| 2318 | | ) => Effect.Effect<void, never, Scope.Scope>; |
| 2319 | | } |
| 2320 | | |
| 2321 | | export class PreviewManager extends Context.Service<PreviewManager, PreviewManagerShape>()( |
| 2322 | | "@t3tools/desktop/preview/Manager/PreviewManager", |
| 2323 | | ) {} |
| 2243 | const isPreviewManagerError = Schema.is(PreviewManagerError); |
| 2244 | |
| 2245 | export class PreviewManager extends Context.Service< |
| 2246 | PreviewManager, |
| 2247 | { |
| 2248 | readonly setMainWindow: (window: BrowserWindow) => Effect.Effect<void, PreviewManagerError>; |
| 2249 | readonly getBrowserSession: (scope?: string) => Effect.Effect<Session, PreviewManagerError>; |
| 2250 | readonly isBrowserPartition: (partition: string) => boolean; |
| 2251 | readonly createTab: (tabId: string) => Effect.Effect<PreviewTabState, PreviewManagerError>; |
| 2252 | readonly closeTab: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2253 | readonly registerWebview: ( |
| 2254 | tabId: string, |
| 2255 | webContentsId: number, |
| 2256 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2257 | readonly navigate: (tabId: string, url: string) => Effect.Effect<void, PreviewManagerError>; |
| 2258 | readonly goBack: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2259 | readonly goForward: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2260 | readonly refresh: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2261 | readonly zoomIn: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2262 | readonly zoomOut: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2263 | readonly resetZoom: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2264 | readonly hardReload: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2265 | readonly openDevTools: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2266 | readonly clearCookies: () => Effect.Effect<void, PreviewManagerError>; |
| 2267 | readonly clearCache: () => Effect.Effect<void, PreviewManagerError>; |
| 2268 | readonly getBrowserPartition: (scope?: string) => Effect.Effect<string, PreviewManagerError>; |
| 2269 | readonly setAnnotationTheme: ( |
| 2270 | theme: DesktopPreviewAnnotationTheme, |
| 2271 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2272 | readonly pickElement: ( |
| 2273 | tabId: string, |
| 2274 | ) => Effect.Effect<PreviewAnnotationPayload | null, PreviewManagerError>; |
| 2275 | readonly cancelPickElement: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2276 | readonly captureScreenshot: ( |
| 2277 | tabId: string, |
| 2278 | ) => Effect.Effect<DesktopPreviewScreenshotArtifact, PreviewManagerError>; |
| 2279 | readonly revealArtifact: (path: string) => Effect.Effect<void, PreviewManagerError>; |
| 2280 | readonly copyArtifactToClipboard: (path: string) => Effect.Effect<void, PreviewManagerError>; |
| 2281 | readonly startRecording: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2282 | readonly stopRecording: (tabId: string) => Effect.Effect<void, PreviewManagerError>; |
| 2283 | readonly saveRecording: ( |
| 2284 | tabId: string, |
| 2285 | mimeType: string, |
| 2286 | data: Uint8Array, |
| 2287 | ) => Effect.Effect<DesktopPreviewRecordingArtifact, PreviewManagerError>; |
| 2288 | readonly automationStatus: ( |
| 2289 | tabId: string, |
| 2290 | ) => Effect.Effect<PreviewAutomationStatus, PreviewManagerError>; |
| 2291 | readonly automationSnapshot: ( |
| 2292 | tabId: string, |
| 2293 | ) => Effect.Effect<PreviewAutomationSnapshot, PreviewManagerError>; |
| 2294 | readonly automationClick: ( |
| 2295 | tabId: string, |
| 2296 | input: PreviewAutomationClickInput, |
| 2297 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2298 | readonly automationType: ( |
| 2299 | tabId: string, |
| 2300 | input: PreviewAutomationTypeInput, |
| 2301 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2302 | readonly automationPress: ( |
| 2303 | tabId: string, |
| 2304 | input: PreviewAutomationPressInput, |
| 2305 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2306 | readonly automationScroll: ( |
| 2307 | tabId: string, |
| 2308 | input: PreviewAutomationScrollInput, |
| 2309 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2310 | readonly automationEvaluate: ( |
| 2311 | tabId: string, |
| 2312 | input: PreviewAutomationEvaluateInput, |
| 2313 | ) => Effect.Effect<unknown, PreviewManagerError>; |
| 2314 | readonly automationWaitFor: ( |
| 2315 | tabId: string, |
| 2316 | input: PreviewAutomationWaitForInput, |
| 2317 | ) => Effect.Effect<void, PreviewManagerError>; |
| 2318 | readonly subscribeStateChanges: (listener: Listener) => Effect.Effect<void, never, Scope.Scope>; |
| 2319 | readonly subscribePointerEvents: ( |
| 2320 | listener: PointerEventListener, |
| 2321 | ) => Effect.Effect<void, never, Scope.Scope>; |
| 2322 | readonly subscribeRecordingFrames: ( |
| 2323 | listener: RecordingFrameListener, |
| 2324 | ) => Effect.Effect<void, never, Scope.Scope>; |
| 2325 | } |
| 2326 | >()("@t3tools/desktop/preview/Manager/PreviewManager") {} |
| 2324 | 2327 | |
| 2325 | | const make = Effect.gen(function* PreviewManagerMake() { |
| 2328 | export const make = Effect.gen(function* PreviewManagerMake() { |
| 2326 | 2329 | const environment = yield* DesktopEnvironment.DesktopEnvironment; |
| 2327 | 2330 | const browserSession = yield* BrowserSession.BrowserSession; |
| 2328 | 2331 | const operations = yield* makeNativeOperations(environment.browserArtifactsDir); |