feat(app): draft prompt state (#31452)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||||
import { checksum } from "@opencode-ai/core/util/encode"
|
import { checksum } from "@opencode-ai/core/util/encode"
|
||||||
import { useParams } from "@solidjs/router"
|
import { useParams, useSearchParams } from "@solidjs/router"
|
||||||
import { batch, createMemo, createRoot, getOwner, onCleanup } from "solid-js"
|
import { batch, createMemo, createRoot, getOwner, onCleanup } from "solid-js"
|
||||||
import { createStore, type SetStoreFunction } from "solid-js/store"
|
import { createStore, type SetStoreFunction } from "solid-js/store"
|
||||||
import type { FileSelection } from "@/context/file"
|
import type { FileSelection } from "@/context/file"
|
||||||
@@ -153,9 +153,11 @@ const MAX_PROMPT_SESSIONS = 20
|
|||||||
|
|
||||||
type PromptSession = ReturnType<typeof createPromptSession>
|
type PromptSession = ReturnType<typeof createPromptSession>
|
||||||
|
|
||||||
type Scope = {
|
type Scope = { draftID: string } | { dir: string; id?: string }
|
||||||
dir: string
|
|
||||||
id?: string
|
function scopeKey(scope: Scope) {
|
||||||
|
if ("draftID" in scope) return `draft:${scope.draftID}`
|
||||||
|
return `${scope.dir}:${scope.id ?? WORKSPACE_KEY}`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PromptCacheEntry = {
|
type PromptCacheEntry = {
|
||||||
@@ -163,11 +165,15 @@ type PromptCacheEntry = {
|
|||||||
dispose: VoidFunction
|
dispose: VoidFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPromptSession(scope: ServerScope, dir: string, id: string | undefined) {
|
function promptTarget(serverScope: ServerScope, scope: Scope) {
|
||||||
const legacy = `${dir}/prompt${id ? "/" + id : ""}.v2`
|
if ("draftID" in scope) return Persist.draft(scope.draftID, "prompt")
|
||||||
|
const legacy = `${scope.dir}/prompt${scope.id ? "/" + scope.id : ""}.v2`
|
||||||
|
return Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy])
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPromptSession(serverScope: ServerScope, scope: Scope) {
|
||||||
const [store, setStore, _, ready] = persisted(
|
const [store, setStore, _, ready] = persisted(
|
||||||
Persist.serverScoped(scope, dir, id, "prompt", [legacy]),
|
promptTarget(serverScope, scope),
|
||||||
createStore<{
|
createStore<{
|
||||||
prompt: Prompt
|
prompt: Prompt
|
||||||
cursor?: number
|
cursor?: number
|
||||||
@@ -231,6 +237,7 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
|
|||||||
gate: false,
|
gate: false,
|
||||||
init: () => {
|
init: () => {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
|
const [search] = useSearchParams<{ draftId?: string }>()
|
||||||
const serverSDK = useServerSDK()
|
const serverSDK = useServerSDK()
|
||||||
const cache = new Map<string, PromptCacheEntry>()
|
const cache = new Map<string, PromptCacheEntry>()
|
||||||
|
|
||||||
@@ -254,8 +261,8 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const owner = getOwner()
|
const owner = getOwner()
|
||||||
const load = (dir: string, id: string | undefined) => {
|
const load = (scope: Scope) => {
|
||||||
const key = `${dir}:${id ?? WORKSPACE_KEY}`
|
const key = scopeKey(scope)
|
||||||
const existing = cache.get(key)
|
const existing = cache.get(key)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
cache.delete(key)
|
cache.delete(key)
|
||||||
@@ -265,7 +272,7 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
|
|||||||
|
|
||||||
const entry = createRoot(
|
const entry = createRoot(
|
||||||
(dispose) => ({
|
(dispose) => ({
|
||||||
value: createPromptSession(serverSDK.scope, dir, id),
|
value: createPromptSession(serverSDK.scope, scope),
|
||||||
dispose,
|
dispose,
|
||||||
}),
|
}),
|
||||||
owner,
|
owner,
|
||||||
@@ -276,8 +283,8 @@ export const { use: usePrompt, provider: PromptProvider } = createSimpleContext(
|
|||||||
return entry.value
|
return entry.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = createMemo(() => load(params.dir!, params.id))
|
const session = createMemo(() => load(search.draftId ? { draftID: search.draftId } : { dir: params.dir!, id: params.id }))
|
||||||
const pick = (scope?: Scope) => (scope ? load(scope.dir, scope.id) : session())
|
const pick = (scope?: Scope) => (scope ? load(scope) : session())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ready: () => session().ready,
|
ready: () => session().ready,
|
||||||
|
|||||||
Reference in New Issue
Block a user