diff --git a/packages/opencode/specs/effect-migration.md b/packages/opencode/specs/effect-migration.md index 37c70814a..d00bc766b 100644 --- a/packages/opencode/specs/effect-migration.md +++ b/packages/opencode/specs/effect-migration.md @@ -82,24 +82,33 @@ The `InstanceState.make` init callback receives a `Scope`, so you can use `Effec - **Subscriptions**: Use `Effect.acquireRelease` to subscribe and auto-unsubscribe: ```ts -const cache = yield* InstanceState.make( - Effect.fn("Foo.state")(function* (ctx) { - // ... load state ... +const cache = + yield * + InstanceState.make( + Effect.fn("Foo.state")(function* (ctx) { + // ... load state ... - yield* Effect.acquireRelease( - Effect.sync(() => Bus.subscribeAll((event) => { /* handle */ })), - (unsub) => Effect.sync(unsub), - ) + yield* Effect.acquireRelease( + Effect.sync(() => + Bus.subscribeAll((event) => { + /* handle */ + }), + ), + (unsub) => Effect.sync(unsub), + ) - return { /* state */ } - }), -) + return { + /* state */ + } + }), + ) ``` - **Background fibers**: Use `Effect.forkScoped` — the fiber is interrupted on disposal. - **Side effects at init**: Config notification, event wiring, etc. all belong in the init closure. Callers just do `InstanceState.get(cache)` to trigger everything, and `ScopedCache` deduplicates automatically. The key insight: don't split init into a separate method with a `started` flag. Put everything in the `InstanceState.make` closure and let `ScopedCache` handle the run-once semantics. + ## Scheduled Tasks For loops or periodic work, use `Effect.repeat` or `Effect.schedule` with `Effect.forkScoped` in the layer definition. diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 1aed1d5f5..57dcff8f6 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -24,9 +24,7 @@ export namespace Plugin { // Hook names that follow the (input, output) => Promise trigger pattern type TriggerName = { - [K in keyof Hooks]-?: NonNullable extends (input: any, output: any) => Promise - ? K - : never + [K in keyof Hooks]-?: NonNullable extends (input: any, output: any) => Promise ? K : never }[keyof Hooks] export interface Interface {