feat(worktree): add managed workspace cloning (#30117)

This commit is contained in:
Dax 2026-05-31 11:57:44 -04:00 committed by GitHub
commit 5661af2034
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 2374 additions and 28 deletions

View file

@ -1,7 +1,7 @@
export * as State from "./state"
import { Effect, Scope, Semaphore } from "effect"
import { createDraft, finishDraft, type Draft, type Objectish } from "immer"
import type { Draft, Objectish } from "immer"
export type Transform<Editor> = (editor: Editor) => void
export type MakeEditor<State extends Objectish, Editor> = (draft: Draft<State>) => Editor
@ -24,17 +24,18 @@ export function create<State extends Objectish, Editor>(options: Options<State,
let transforms: { update: Transform<Editor> }[] = []
const semaphore = Semaphore.makeUnsafe(1)
const commit = Effect.fn("State.commit")(function* (draft: Draft<State>, reason?: string) {
const api = options.editor(draft)
const commit = Effect.fn("State.commit")(function* (next: State, reason?: string) {
const api = options.editor(next as Draft<State>)
if (options.finalize) yield* options.finalize(api, reason)
state = finishDraft(draft) as State
state = next
})
const rebuild = Effect.fn("State.rebuild")(function* () {
const draft = createDraft(options.initial())
const api = options.editor(draft)
for (const transform of transforms) transform.update(api)
yield* commit(draft)
const next = options.initial()
const api = options.editor(next as Draft<State>)
for (const transform of transforms)
yield* Effect.sync(() => transform.update(api)).pipe(Effect.withSpan("State.rebuild.update", {}))
yield* commit(next)
}, semaphore.withPermit)
return {
@ -55,9 +56,9 @@ export function create<State extends Objectish, Editor>(options: Options<State,
})
}),
update: Effect.fn("State.update")(function* (update, reason) {
const draft = createDraft(state)
yield* update(options.editor(draft))
yield* commit(draft, reason)
const api = options.editor(state as Draft<State>)
yield* update(api)
if (options.finalize) yield* options.finalize(api, reason)
}, semaphore.withPermit),
}
}