feat(plugin): add namespaced hook API (#33416)
This commit is contained in:
+15
-15
@@ -3,7 +3,7 @@ export * as State from "./state"
|
||||
import { Context, Effect, Scope, Semaphore } from "effect"
|
||||
|
||||
/**
|
||||
* A replayable transform applied to a draft during rebuild.
|
||||
* A replayable transform applied to a draft during reload.
|
||||
*
|
||||
* Domain drafts expose readable and writable state while preserving concise
|
||||
* plugin/config code. Transforms may perform Effects before returning.
|
||||
@@ -19,14 +19,14 @@ export type Transform<DraftApi> = (
|
||||
transform: TransformCallback<DraftApi>,
|
||||
) => Effect.Effect<Registration, never, Scope.Scope>
|
||||
|
||||
export type Rebuild = () => Effect.Effect<void>
|
||||
export type Reload = () => Effect.Effect<void>
|
||||
|
||||
export interface Transformable<DraftApi> {
|
||||
readonly transform: Transform<DraftApi>
|
||||
readonly rebuild: Rebuild
|
||||
readonly reload: Reload
|
||||
}
|
||||
|
||||
const CurrentBatch = Context.Reference<Set<Rebuild> | undefined>("@opencode/State/CurrentBatch", {
|
||||
const CurrentBatch = Context.Reference<Set<Reload> | undefined>("@opencode/State/CurrentBatch", {
|
||||
defaultValue: () => undefined,
|
||||
})
|
||||
|
||||
@@ -34,15 +34,15 @@ export function batch<A, E, R>(effect: Effect.Effect<A, E, R>) {
|
||||
return Effect.gen(function* () {
|
||||
const current = yield* CurrentBatch
|
||||
if (current) return yield* effect
|
||||
const rebuilds = new Set<Rebuild>()
|
||||
const result = yield* effect.pipe(Effect.provideService(CurrentBatch, rebuilds))
|
||||
yield* Effect.forEach(rebuilds, (rebuild) => rebuild(), { discard: true })
|
||||
const reloads = new Set<Reload>()
|
||||
const result = yield* effect.pipe(Effect.provideService(CurrentBatch, reloads))
|
||||
yield* Effect.forEach(reloads, (reload) => reload(), { discard: true })
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
export interface Options<State, DraftApi> {
|
||||
/** Creates the base value for initial state and every scoped-transform rebuild. */
|
||||
/** Creates the base value for initial state and every scoped-transform reload. */
|
||||
readonly initial: () => State
|
||||
/** Wraps mutable state in a domain-specific draft API. */
|
||||
readonly draft: MakeDraft<State, DraftApi>
|
||||
@@ -54,7 +54,7 @@ export interface Interface<State, DraftApi> extends Transformable<DraftApi> {
|
||||
readonly get: () => State
|
||||
/**
|
||||
* Registers and applies a scoped transform. Closing the owning Scope removes
|
||||
* the transform and rebuilds the materialized state.
|
||||
* the transform and reloads the materialized state.
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ export function create<State, DraftApi>(options: Options<State, DraftApi>): Inte
|
||||
const materialize = Effect.fnUntraced(function* () {
|
||||
const next = options.initial()
|
||||
const api = options.draft(next)
|
||||
for (const transform of transforms) yield* apply(transform.run, api).pipe(Effect.withSpan("State.rebuild.update"))
|
||||
for (const transform of transforms) yield* apply(transform.run, api).pipe(Effect.withSpan("State.reload.update"))
|
||||
yield* commit(next)
|
||||
})
|
||||
|
||||
const rebuild = () => semaphore.withPermit(materialize())
|
||||
const reload = () => semaphore.withPermit(materialize())
|
||||
|
||||
const result: Interface<State, DraftApi> = {
|
||||
get: () => state,
|
||||
@@ -101,7 +101,7 @@ export function create<State, DraftApi>(options: Options<State, DraftApi>): Inte
|
||||
return Effect.gen(function* () {
|
||||
const batch = yield* CurrentBatch
|
||||
if (batch) {
|
||||
batch.add(rebuild)
|
||||
batch.add(reload)
|
||||
return
|
||||
}
|
||||
yield* materialize()
|
||||
@@ -116,13 +116,13 @@ export function create<State, DraftApi>(options: Options<State, DraftApi>): Inte
|
||||
)
|
||||
yield* Scope.addFinalizer(scope, dispose)
|
||||
const batch = yield* CurrentBatch
|
||||
if (batch) batch.add(rebuild)
|
||||
else yield* rebuild()
|
||||
if (batch) batch.add(reload)
|
||||
else yield* reload()
|
||||
return { dispose }
|
||||
}),
|
||||
)
|
||||
}),
|
||||
rebuild,
|
||||
reload,
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user