import { Effect } from "effect" import { context, type InstanceContext } from "./instance-context" import { InstanceStore } from "./instance-store" export type { InstanceContext } from "./instance-context" export type { LoadInput } from "./instance-store" export const Instance = { async provide(input: { directory: string; init?: Effect.Effect; fn: () => R }): Promise { const ctx = await InstanceStore.runtime.runPromise((store) => store.load({ directory: input.directory, init: input.init }), ) return context.provide(ctx, async () => input.fn()) }, get current() { return context.use() }, get directory() { return context.use().directory }, get worktree() { return context.use().worktree }, get project() { return context.use().project }, /** * Captures the current instance ALS context and returns a wrapper that * restores it when called. Use this for callbacks that fire outside the * instance async context (native addons, event emitters, timers, etc.). */ bind any>(fn: F): F { const ctx = context.use() return ((...args: any[]) => context.provide(ctx, () => fn(...args))) as F }, /** * Run a synchronous function within the given instance context ALS. * Use this to bridge from Effect (where InstanceRef carries context) * back to sync code that reads Instance.directory from ALS. */ restore(ctx: InstanceContext, fn: () => R): R { return context.provide(ctx, fn) }, }