summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/utils/worktree.ts
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-22 22:09:18 -0600
committerAdam <[email protected]>2026-01-23 05:18:42 -0600
commitc4d223eb99c4f677ff9f540cbef1f71e8a502ac8 (patch)
tree577e50e95bc5e101e46eb9e88ec5d99d14e646dd /packages/app/src/utils/worktree.ts
parent3fbda540457ac1db860a2c011d3a9d62b650381c (diff)
downloadopencode-c4d223eb99c4f677ff9f540cbef1f71e8a502ac8.tar.gz
opencode-c4d223eb99c4f677ff9f540cbef1f71e8a502ac8.zip
perf(app): faster workspace creation
Diffstat (limited to 'packages/app/src/utils/worktree.ts')
-rw-r--r--packages/app/src/utils/worktree.ts58
1 files changed, 58 insertions, 0 deletions
diff --git a/packages/app/src/utils/worktree.ts b/packages/app/src/utils/worktree.ts
new file mode 100644
index 000000000..7c0055920
--- /dev/null
+++ b/packages/app/src/utils/worktree.ts
@@ -0,0 +1,58 @@
+const normalize = (directory: string) => directory.replace(/[\\/]+$/, "")
+
+type State =
+ | {
+ status: "pending"
+ }
+ | {
+ status: "ready"
+ }
+ | {
+ status: "failed"
+ message: string
+ }
+
+const state = new Map<string, State>()
+const waiters = new Map<string, Array<(state: State) => void>>()
+
+export const Worktree = {
+ get(directory: string) {
+ return state.get(normalize(directory))
+ },
+ pending(directory: string) {
+ const key = normalize(directory)
+ const current = state.get(key)
+ if (current && current.status !== "pending") return
+ state.set(key, { status: "pending" })
+ },
+ ready(directory: string) {
+ const key = normalize(directory)
+ state.set(key, { status: "ready" })
+ const list = waiters.get(key)
+ if (!list) return
+ waiters.delete(key)
+ for (const fn of list) fn({ status: "ready" })
+ },
+ failed(directory: string, message: string) {
+ const key = normalize(directory)
+ state.set(key, { status: "failed", message })
+ const list = waiters.get(key)
+ if (!list) return
+ waiters.delete(key)
+ for (const fn of list) fn({ status: "failed", message })
+ },
+ wait(directory: string) {
+ const key = normalize(directory)
+ const current = state.get(key)
+ if (current && current.status !== "pending") return Promise.resolve(current)
+
+ return new Promise<State>((resolve) => {
+ const list = waiters.get(key)
+ if (!list) {
+ waiters.set(key, [resolve])
+ return
+ }
+ list.push(resolve)
+ })
+ },
+}