| import type { FileNode } from "@opencode-ai/sdk/v2" |
|
|
| type WatcherEvent = { |
| type: string |
| properties: unknown |
| } |
|
|
| type WatcherOps = { |
| normalize: (input: string) => string |
| hasFile: (path: string) => boolean |
| isOpen?: (path: string) => boolean |
| loadFile: (path: string) => void |
| node: (path: string) => FileNode | undefined |
| isDirLoaded: (path: string) => boolean |
| refreshDir: (path: string) => void |
| } |
|
|
| export function invalidateFromWatcher(event: WatcherEvent, ops: WatcherOps) { |
| if (event.type !== "file.watcher.updated") return |
| const props = |
| typeof event.properties === "object" && event.properties ? (event.properties as Record<string, unknown>) : undefined |
| const rawPath = typeof props?.file === "string" ? props.file : undefined |
| const kind = typeof props?.event === "string" ? props.event : undefined |
| if (!rawPath) return |
| if (!kind) return |
|
|
| const path = ops.normalize(rawPath) |
| if (!path) return |
| if (path.startsWith(".git/")) return |
|
|
| if (ops.hasFile(path) || ops.isOpen?.(path)) { |
| ops.loadFile(path) |
| } |
|
|
| if (kind === "change") { |
| const dir = (() => { |
| if (path === "") return "" |
| const node = ops.node(path) |
| if (node?.type !== "directory") return |
| return path |
| })() |
| if (dir === undefined) return |
| if (!ops.isDirLoaded(dir)) return |
| ops.refreshDir(dir) |
| return |
| } |
| if (kind !== "add" && kind !== "unlink") return |
|
|
| const parent = path.split("/").slice(0, -1).join("/") |
| if (!ops.isDirLoaded(parent)) return |
|
|
| ops.refreshDir(parent) |
| } |
|
|