watch.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { z } from "zod"
  2. import { Bus } from "../bus"
  3. import fs from "fs"
  4. import { App } from "../app/app"
  5. import { Log } from "../util/log"
  6. import { Flag } from "../flag/flag"
  7. export namespace FileWatcher {
  8. const log = Log.create({ service: "file.watcher" })
  9. export const Event = {
  10. Updated: Bus.event(
  11. "file.watcher.updated",
  12. z.object({
  13. file: z.string(),
  14. event: z.union([z.literal("rename"), z.literal("change")]),
  15. }),
  16. ),
  17. }
  18. const state = App.state(
  19. "file.watcher",
  20. () => {
  21. const app = App.use()
  22. if (!app.info.git) return {}
  23. try {
  24. const watcher = fs.watch(app.info.path.cwd, { recursive: true }, (event, file) => {
  25. log.info("change", { file, event })
  26. if (!file) return
  27. // for some reason async local storage is lost here
  28. // https://github.com/oven-sh/bun/issues/20754
  29. App.provideExisting(app, async () => {
  30. Bus.publish(Event.Updated, {
  31. file,
  32. event,
  33. })
  34. })
  35. })
  36. return { watcher }
  37. } catch {
  38. return {}
  39. }
  40. },
  41. async (state) => {
  42. state.watcher?.close()
  43. },
  44. )
  45. export function init() {
  46. if (Flag.OPENCODE_DISABLE_WATCHER || true) return
  47. state()
  48. }
  49. }