mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-21 18:26:09 +00:00
fix(core): defer cyclic layer dependencies
This commit is contained in:
@@ -74,7 +74,7 @@ type MakeInput<
|
||||
T extends Tag | undefined = undefined,
|
||||
> = NodeIdentity & {
|
||||
readonly layer: Implementation
|
||||
readonly deps: Items & CheckDependencies<Implementation, NoInfer<Items>>
|
||||
readonly deps: (Items | (() => Items)) & CheckDependencies<Implementation, NoInfer<Items>>
|
||||
readonly tag?: T
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ export function make<
|
||||
name: input.service !== undefined ? input.service.key : input.name,
|
||||
service: input.service,
|
||||
implementation: input.layer,
|
||||
dependencies: input.deps,
|
||||
get dependencies() {
|
||||
return typeof input.deps === "function" ? input.deps() : input.deps
|
||||
},
|
||||
tag: input.tag,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,8 @@ const SHELL_MAX_CAPTURE_BYTES = 1024 * 1024
|
||||
export const node = makeGlobalNode({
|
||||
service: Service,
|
||||
layer: layer.pipe(Layer.orDie),
|
||||
deps: [
|
||||
// Defer the execution node across the Session/runner module cycle until the graph is compiled.
|
||||
deps: () => [
|
||||
Job.node,
|
||||
Database.node,
|
||||
EventV2.node,
|
||||
|
||||
@@ -32,6 +32,7 @@ const b = make({ service: B, layer: bLayer, deps: [a] })
|
||||
const c = make({ service: C, layer: cLayer, deps: [a, b] })
|
||||
const failing = make({ service: A, layer: failingA, deps: [] })
|
||||
const dependent = make({ service: B, layer: bLayer, deps: [failing] })
|
||||
make({ service: B, layer: bLayer, deps: () => [a] })
|
||||
const inputA = LayerNode.unbound(A, tags.values.app)
|
||||
const inputDependent = make({ service: B, layer: bLayer, deps: [inputA] })
|
||||
|
||||
@@ -46,6 +47,9 @@ make({ service: A, name: "a", layer: aLayer, deps: [] })
|
||||
// @ts-expect-error B requires A
|
||||
make({ service: B, layer: bLayer, deps: [] })
|
||||
|
||||
// @ts-expect-error Lazy dependencies must still provide A
|
||||
make({ service: B, layer: bLayer, deps: () => [] })
|
||||
|
||||
// @ts-expect-error C requires A and B
|
||||
make({ service: C, layer: cLayer, deps: [a] })
|
||||
|
||||
|
||||
@@ -37,6 +37,12 @@ describe("layer node", () => {
|
||||
expect(await Effect.runPromise(program)).toBe("hello production")
|
||||
})
|
||||
|
||||
test("resolves lazy dependencies when compiling", async () => {
|
||||
const greeting = make({ service: Greeting, layer: greetingLayer, deps: () => [value] })
|
||||
const program = Effect.map(Greeting, (item) => item.value).pipe(Effect.provide(build(greeting)))
|
||||
expect(await Effect.runPromise(program)).toBe("hello production")
|
||||
})
|
||||
|
||||
test("exposes roots but hides transitive dependencies", () => {
|
||||
const layer = build(LayerNode.group([greeting]))
|
||||
const check: Layer.Layer<Greeting> = layer
|
||||
|
||||
Reference in New Issue
Block a user