|
|
@@ -6,6 +6,8 @@ import { useSync } from "@tui/context/sync"
|
|
|
import { useProject } from "@tui/context/project"
|
|
|
import { createMemo, createSignal, onMount } from "solid-js"
|
|
|
import { setTimeout as sleep } from "node:timers/promises"
|
|
|
+import { errorData, errorMessage } from "@/util/error"
|
|
|
+import * as Log from "@/util/log"
|
|
|
import { useSDK } from "../context/sdk"
|
|
|
import { useToast } from "../ui/toast"
|
|
|
|
|
|
@@ -15,6 +17,8 @@ type Adaptor = {
|
|
|
description: string
|
|
|
}
|
|
|
|
|
|
+const log = Log.Default.clone().tag("service", "tui-workspace")
|
|
|
+
|
|
|
function scoped(sdk: ReturnType<typeof useSDK>, sync: ReturnType<typeof useSync>, workspaceID: string) {
|
|
|
return createOpencodeClient({
|
|
|
baseUrl: sdk.url,
|
|
|
@@ -33,8 +37,20 @@ export async function openWorkspaceSession(input: {
|
|
|
workspaceID: string
|
|
|
}) {
|
|
|
const client = scoped(input.sdk, input.sync, input.workspaceID)
|
|
|
+ log.info("workspace session create requested", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ })
|
|
|
+
|
|
|
+ console.log("opening!")
|
|
|
while (true) {
|
|
|
- const result = await client.session.create({ workspaceID: input.workspaceID }).catch(() => undefined)
|
|
|
+ console.log("creating")
|
|
|
+ const result = await client.session.create({ workspace: input.workspaceID }).catch((err) => {
|
|
|
+ log.error("workspace session create request failed", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ error: errorData(err),
|
|
|
+ })
|
|
|
+ return undefined
|
|
|
+ })
|
|
|
if (!result) {
|
|
|
input.toast.show({
|
|
|
message: "Failed to create workspace session",
|
|
|
@@ -42,26 +58,113 @@ export async function openWorkspaceSession(input: {
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
- if (result.response.status >= 500 && result.response.status < 600) {
|
|
|
+ log.info("workspace session create response", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ status: result.response?.status,
|
|
|
+ sessionID: result.data?.id,
|
|
|
+ })
|
|
|
+ if (result.response?.status && result.response.status >= 500 && result.response.status < 600) {
|
|
|
+ log.warn("workspace session create retrying after server error", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ status: result.response.status,
|
|
|
+ })
|
|
|
await sleep(1000)
|
|
|
continue
|
|
|
}
|
|
|
if (!result.data) {
|
|
|
+ log.error("workspace session create returned no data", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ status: result.response?.status,
|
|
|
+ })
|
|
|
input.toast.show({
|
|
|
message: "Failed to create workspace session",
|
|
|
variant: "error",
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
input.route.navigate({
|
|
|
type: "session",
|
|
|
sessionID: result.data.id,
|
|
|
})
|
|
|
+ log.info("workspace session create complete", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: result.data.id,
|
|
|
+ })
|
|
|
input.dialog.clear()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+export async function restoreWorkspaceSession(input: {
|
|
|
+ dialog: ReturnType<typeof useDialog>
|
|
|
+ sdk: ReturnType<typeof useSDK>
|
|
|
+ sync: ReturnType<typeof useSync>
|
|
|
+ project: ReturnType<typeof useProject>
|
|
|
+ toast: ReturnType<typeof useToast>
|
|
|
+ workspaceID: string
|
|
|
+ sessionID: string
|
|
|
+ done?: () => void
|
|
|
+}) {
|
|
|
+ log.info("session restore requested", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ })
|
|
|
+ const result = await input.sdk.client.experimental.workspace
|
|
|
+ .sessionRestore({ id: input.workspaceID, sessionID: input.sessionID })
|
|
|
+ .catch((err) => {
|
|
|
+ log.error("session restore request failed", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ error: errorData(err),
|
|
|
+ })
|
|
|
+ return undefined
|
|
|
+ })
|
|
|
+ if (!result?.data) {
|
|
|
+ log.error("session restore failed", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ status: result?.response?.status,
|
|
|
+ error: result?.error ? errorData(result.error) : undefined,
|
|
|
+ })
|
|
|
+ input.toast.show({
|
|
|
+ message: `Failed to restore session: ${errorMessage(result?.error ?? "no response")}`,
|
|
|
+ variant: "error",
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("session restore response", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ status: result.response?.status,
|
|
|
+ total: result.data.total,
|
|
|
+ })
|
|
|
+
|
|
|
+ await Promise.all([input.project.workspace.sync(), input.sync.session.refresh()]).catch((err) => {
|
|
|
+ log.error("session restore refresh failed", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ error: errorData(err),
|
|
|
+ })
|
|
|
+ throw err
|
|
|
+ })
|
|
|
+
|
|
|
+ log.info("session restore complete", {
|
|
|
+ workspaceID: input.workspaceID,
|
|
|
+ sessionID: input.sessionID,
|
|
|
+ total: result.data.total,
|
|
|
+ })
|
|
|
+
|
|
|
+ input.toast.show({
|
|
|
+ message: "Session restored into the new workspace",
|
|
|
+ variant: "success",
|
|
|
+ })
|
|
|
+ input.done?.()
|
|
|
+ if (input.done) return
|
|
|
+ input.dialog.clear()
|
|
|
+}
|
|
|
+
|
|
|
export function DialogWorkspaceCreate(props: { onSelect: (workspaceID: string) => Promise<void> | void }) {
|
|
|
const dialog = useDialog()
|
|
|
const sync = useSync()
|
|
|
@@ -123,18 +226,43 @@ export function DialogWorkspaceCreate(props: { onSelect: (workspaceID: string) =
|
|
|
const create = async (type: string) => {
|
|
|
if (creating()) return
|
|
|
setCreating(type)
|
|
|
+ log.info("workspace create requested", {
|
|
|
+ type,
|
|
|
+ })
|
|
|
+
|
|
|
+ const result = await sdk.client.experimental.workspace.create({ type, branch: null }).catch((err) => {
|
|
|
+ log.error("workspace create request failed", {
|
|
|
+ type,
|
|
|
+ error: errorData(err),
|
|
|
+ })
|
|
|
+ return undefined
|
|
|
+ })
|
|
|
|
|
|
- const result = await sdk.client.experimental.workspace.create({ type, branch: null }).catch(() => undefined)
|
|
|
const workspace = result?.data
|
|
|
if (!workspace) {
|
|
|
setCreating(undefined)
|
|
|
+ log.error("workspace create failed", {
|
|
|
+ type,
|
|
|
+ status: result?.response.status,
|
|
|
+ error: result?.error ? errorData(result.error) : undefined,
|
|
|
+ })
|
|
|
toast.show({
|
|
|
- message: "Failed to create workspace",
|
|
|
+ message: `Failed to create workspace: ${errorMessage(result?.error ?? "no response")}`,
|
|
|
variant: "error",
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
+ log.info("workspace create response", {
|
|
|
+ type,
|
|
|
+ workspaceID: workspace.id,
|
|
|
+ status: result.response?.status,
|
|
|
+ })
|
|
|
+
|
|
|
await project.workspace.sync()
|
|
|
+ log.info("workspace create synced", {
|
|
|
+ type,
|
|
|
+ workspaceID: workspace.id,
|
|
|
+ })
|
|
|
await props.onSelect(workspace.id)
|
|
|
setCreating(undefined)
|
|
|
}
|