|
| 1 | +import type * as Effect from "../Effect.js" |
| 2 | +import type { Exit } from "../Exit.js" |
| 3 | +import type * as Fiber from "../Fiber.js" |
| 4 | +import type * as Layer from "../Layer.js" |
| 5 | +import type { ManagedRuntime } from "../ManagedRuntime.js" |
| 6 | +import { pipeArguments } from "../Pipeable.js" |
| 7 | +import type * as Runtime from "../Runtime.js" |
| 8 | +import * as Scope from "../Scope.js" |
| 9 | +import * as effect from "./core-effect.js" |
| 10 | +import * as core from "./core.js" |
| 11 | +import * as fiberRuntime from "./fiberRuntime.js" |
| 12 | +import * as internalLayer from "./layer.js" |
| 13 | +import * as internalRuntime from "./runtime.js" |
| 14 | + |
| 15 | +interface ManagedRuntimeImpl<R, E> extends ManagedRuntime<R, E> { |
| 16 | + readonly scope: Scope.CloseableScope |
| 17 | + cachedRuntime: Runtime.Runtime<R> | undefined |
| 18 | +} |
| 19 | + |
| 20 | +function provide<R, ER, A, E>( |
| 21 | + managed: ManagedRuntimeImpl<R, ER>, |
| 22 | + effect: Effect.Effect<A, E, R> |
| 23 | +): Effect.Effect<A, E | ER> { |
| 24 | + return core.flatMap( |
| 25 | + managed.runtimeEffect, |
| 26 | + (rt) => |
| 27 | + core.withFiberRuntime((fiber) => { |
| 28 | + fiber.setFiberRefs(rt.fiberRefs) |
| 29 | + fiber._runtimeFlags = rt.runtimeFlags |
| 30 | + return core.provideContext(effect, rt.context) |
| 31 | + }) |
| 32 | + ) |
| 33 | +} |
| 34 | + |
| 35 | +/** @internal */ |
| 36 | +export const make = <R, ER>( |
| 37 | + layer: Layer.Layer<R, ER, never>, |
| 38 | + memoMap?: Layer.MemoMap |
| 39 | +): ManagedRuntime<R, ER> => { |
| 40 | + memoMap = memoMap ?? internalLayer.unsafeMakeMemoMap() |
| 41 | + const scope = internalRuntime.unsafeRunSyncEffect(fiberRuntime.scopeMake()) |
| 42 | + const self: ManagedRuntimeImpl<R, ER> = { |
| 43 | + memoMap, |
| 44 | + scope, |
| 45 | + runtimeEffect: internalRuntime |
| 46 | + .unsafeRunSyncEffect( |
| 47 | + effect.memoize( |
| 48 | + core.tap( |
| 49 | + Scope.extend( |
| 50 | + internalLayer.toRuntimeWithMemoMap(layer, memoMap), |
| 51 | + scope |
| 52 | + ), |
| 53 | + (rt) => { |
| 54 | + self.cachedRuntime = rt |
| 55 | + } |
| 56 | + ) |
| 57 | + ) |
| 58 | + ), |
| 59 | + cachedRuntime: undefined, |
| 60 | + pipe() { |
| 61 | + return pipeArguments(this, arguments) |
| 62 | + }, |
| 63 | + runtime() { |
| 64 | + return self.cachedRuntime === undefined ? |
| 65 | + internalRuntime.unsafeRunPromiseEffect(self.runtimeEffect) : |
| 66 | + Promise.resolve(self.cachedRuntime) |
| 67 | + }, |
| 68 | + dispose(): Promise<void> { |
| 69 | + return internalRuntime.unsafeRunPromiseEffect(self.disposeEffect) |
| 70 | + }, |
| 71 | + disposeEffect: core.suspend(() => { |
| 72 | + ;(self as any).runtime = core.die("ManagedRuntime disposed") |
| 73 | + self.cachedRuntime = undefined |
| 74 | + return Scope.close(self.scope, core.exitUnit) |
| 75 | + }), |
| 76 | + runFork<A, E>(effect: Effect.Effect<A, E, R>, options?: Runtime.RunForkOptions): Fiber.RuntimeFiber<A, E | ER> { |
| 77 | + return self.cachedRuntime === undefined ? |
| 78 | + internalRuntime.unsafeForkEffect(provide(self, effect), options) : |
| 79 | + internalRuntime.unsafeFork(self.cachedRuntime)(effect, options) |
| 80 | + }, |
| 81 | + runSyncExit<A, E>(effect: Effect.Effect<A, E, R>): Exit<A, E | ER> { |
| 82 | + return self.cachedRuntime === undefined ? |
| 83 | + internalRuntime.unsafeRunSyncExitEffect(provide(self, effect)) : |
| 84 | + internalRuntime.unsafeRunSyncExit(self.cachedRuntime)(effect) |
| 85 | + }, |
| 86 | + runSync<A, E>(effect: Effect.Effect<A, E, R>): A { |
| 87 | + return self.cachedRuntime === undefined ? |
| 88 | + internalRuntime.unsafeRunSyncEffect(provide(self, effect)) : |
| 89 | + internalRuntime.unsafeRunSync(self.cachedRuntime)(effect) |
| 90 | + }, |
| 91 | + runPromiseExit<A, E>(effect: Effect.Effect<A, E, R>): Promise<Exit<A, E | ER>> { |
| 92 | + return self.cachedRuntime === undefined ? |
| 93 | + internalRuntime.unsafeRunPromiseExitEffect(provide(self, effect)) : |
| 94 | + internalRuntime.unsafeRunPromiseExit(self.cachedRuntime)(effect) |
| 95 | + }, |
| 96 | + runCallback<A, E>( |
| 97 | + effect: Effect.Effect<A, E, R>, |
| 98 | + options?: Runtime.RunCallbackOptions<A, E | ER> | undefined |
| 99 | + ): Runtime.Cancel<A, E | ER> { |
| 100 | + return self.cachedRuntime === undefined ? |
| 101 | + internalRuntime.unsafeRunCallback(internalRuntime.defaultRuntime)(provide(self, effect), options) : |
| 102 | + internalRuntime.unsafeRunCallback(self.cachedRuntime)(effect, options) |
| 103 | + }, |
| 104 | + runPromise<A, E>(effect: Effect.Effect<A, E, R>): Promise<A> { |
| 105 | + return self.cachedRuntime === undefined ? |
| 106 | + internalRuntime.unsafeRunPromiseEffect(provide(self, effect)) : |
| 107 | + internalRuntime.unsafeRunPromise(self.cachedRuntime)(effect) |
| 108 | + } |
| 109 | + } |
| 110 | + return self |
| 111 | +} |
0 commit comments