fix(core): initialize fff lazily
This commit is contained in:
parent
04f9b15178
commit
7b49c490a5
2 changed files with 182 additions and 99 deletions
|
|
@ -1,10 +1,15 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { Effect } from "effect"
|
||||
import { Context, Effect, Layer, Scope } from "effect"
|
||||
import { FileFinder } from "@ff-labs/fff-bun"
|
||||
import "@opencode-ai/core/filesystem"
|
||||
import { Fff } from "@opencode-ai/core/filesystem/fff.bun"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Location } from "@opencode-ai/core/location"
|
||||
import { Ripgrep } from "@opencode-ai/core/ripgrep"
|
||||
import { AbsolutePath, RelativePath } from "@opencode-ai/core/schema"
|
||||
import { location } from "../fixture/location"
|
||||
import { tmpdir } from "../fixture/tmpdir"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
|
|
@ -42,3 +47,70 @@ describe("Ripgrep", () => {
|
|||
),
|
||||
)
|
||||
})
|
||||
|
||||
describe("FileSystemSearch", () => {
|
||||
it.live("initializes fff on the first search", () =>
|
||||
withTmp((directory) =>
|
||||
Effect.gen(function* () {
|
||||
if (!Fff.available()) return
|
||||
yield* Effect.promise(() => fs.writeFile(path.join(directory, "README.md"), "hello\n"))
|
||||
const { FileSystemSearch } = yield* Effect.promise(() => import("@opencode-ai/core/filesystem/search"))
|
||||
const create = FileFinder.create
|
||||
const calls = { create: 0, destroy: 0 }
|
||||
yield* Effect.acquireUseRelease(
|
||||
Effect.sync(() => {
|
||||
FileFinder.create = (options) => {
|
||||
calls.create++
|
||||
const result = create(options)
|
||||
if (!result.ok) return result
|
||||
const destroy = result.value.destroy.bind(result.value)
|
||||
result.value.destroy = () => {
|
||||
calls.destroy++
|
||||
destroy()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}),
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
yield* Effect.acquireUseRelease(
|
||||
Scope.make(),
|
||||
(scope) =>
|
||||
Effect.gen(function* () {
|
||||
const context = yield* Layer.buildWithScope(
|
||||
FileSystemSearch.fffLayer.pipe(
|
||||
Layer.provide(
|
||||
Layer.succeed(
|
||||
Location.Service,
|
||||
Location.Service.of(location(Location.Ref.make({ directory }))),
|
||||
),
|
||||
),
|
||||
),
|
||||
scope,
|
||||
)
|
||||
const service = Context.get(context, FileSystemSearch.Service)
|
||||
expect(calls.create).toBe(0)
|
||||
|
||||
yield* Effect.all(
|
||||
[
|
||||
service.find({ query: "", type: "file", limit: 1 }),
|
||||
service.find({ query: "", type: "file", limit: 1 }),
|
||||
],
|
||||
{ concurrency: "unbounded" },
|
||||
)
|
||||
expect(calls.create).toBe(1)
|
||||
|
||||
yield* service.find({ query: "", type: "file", limit: 1 })
|
||||
expect(calls.create).toBe(1)
|
||||
expect(calls.destroy).toBe(0)
|
||||
}),
|
||||
(scope, exit) => Scope.close(scope, exit),
|
||||
)
|
||||
expect(calls.destroy).toBe(1)
|
||||
}),
|
||||
() => Effect.sync(() => (FileFinder.create = create)),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue