From 3446b4d56675633376b1243dadb03400081f90e6 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 17:09:16 +0000 Subject: [PATCH 01/19] Effect.provide(managedRuntime) --- packages/effect/src/Effect.ts | 8 +++++ packages/effect/src/ManagedRuntime.ts | 18 ++++++++++ packages/effect/src/internal/layer.ts | 34 +++++++++++++++---- .../effect/src/internal/managedRuntime.ts | 13 +++++-- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index ca890bbb2d..2a2f95508b 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -38,6 +38,7 @@ import * as _runtime from "./internal/runtime.js" import * as _schedule from "./internal/schedule.js" import type * as Layer from "./Layer.js" import type { LogLevel } from "./LogLevel.js" +import type * as ManagedRuntime from "./ManagedRuntime.js" import type * as Metric from "./Metric.js" import type * as MetricLabel from "./MetricLabel.js" import type * as Option from "./Option.js" @@ -3330,12 +3331,19 @@ export const provide: { ): (self: Effect) => Effect> (context: Context.Context): (self: Effect) => Effect> (runtime: Runtime.Runtime): (self: Effect) => Effect> + ( + managedRuntime: ManagedRuntime.ManagedRuntime + ): (self: Effect) => Effect> ( self: Effect, layer: Layer.Layer ): Effect> (self: Effect, context: Context.Context): Effect> (self: Effect, runtime: Runtime.Runtime): Effect> + ( + self: Effect, + runtime: ManagedRuntime.ManagedRuntime + ): Effect> } = layer.effect_provide /** diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index d66b50dbd9..9b664d904f 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -133,3 +133,21 @@ export const make: ( layer: Layer.Layer, memoMap?: Layer.MemoMap | undefined ) => ManagedRuntime = internal.make + +const TypeId: unique symbol = internal.TypeId as TypeId + +/** + * @since 2.0.0 + * @category symbol + */ +export type TypeId = typeof TypeId + +/** + * Checks if the provided argument is a `ManagedRuntime`. + * + * @param input - The value to be checked if it is a `ManagedRuntime`. + + * @since 2.0.0 + * @category guards + */ +export const isManagedRuntime: (input: unknown) => input is ManagedRuntime = internal.isManagedRuntime diff --git a/packages/effect/src/internal/layer.ts b/packages/effect/src/internal/layer.ts index ca60bd5414..b14a6abbac 100644 --- a/packages/effect/src/internal/layer.ts +++ b/packages/effect/src/internal/layer.ts @@ -10,6 +10,7 @@ import type { LazyArg } from "../Function.js" import { dual, pipe } from "../Function.js" import * as HashMap from "../HashMap.js" import type * as Layer from "../Layer.js" +import * as ManagedRuntime from "../ManagedRuntime.js" import { pipeArguments } from "../Pipeable.js" import { hasProperty } from "../Predicate.js" import type * as Runtime from "../Runtime.js" @@ -1300,6 +1301,9 @@ export const effect_provide = dual< ( runtime: Runtime.Runtime ): (self: Effect.Effect) => Effect.Effect> + ( + managedRuntime: ManagedRuntime.ManagedRuntime + ): (self: Effect.Effect) => Effect.Effect> }, { ( @@ -1314,16 +1318,32 @@ export const effect_provide = dual< self: Effect.Effect, runtime: Runtime.Runtime ): Effect.Effect> + ( + self: Effect.Effect, + managedRuntime: ManagedRuntime.ManagedRuntime + ): Effect.Effect> } >( 2, ( self: Effect.Effect, - source: Layer.Layer | Context.Context | Runtime.Runtime - ): Effect.Effect> => - isLayer(source) - ? provideSomeLayer(self, source as Layer.Layer) - : Context.isContext(source) - ? core.provideSomeContext(self, source) - : provideSomeRuntime(self, source as Runtime.Runtime) + source: + | Layer.Layer + | Context.Context + | Runtime.Runtime + | ManagedRuntime.ManagedRuntime + ): Effect.Effect> => { + if (isLayer(source)) { + return provideSomeLayer(self, source as Layer.Layer) + } else if (Context.isContext(source)) { + return core.provideSomeContext(self, source) + } else if (ManagedRuntime.isManagedRuntime(source)) { + return core.flatMap( + (source as ManagedRuntime.ManagedRuntime).runtimeEffect, + (rt) => provideSomeRuntime(self, rt) + ) + } else { + return provideSomeRuntime(self, source as Runtime.Runtime) + } + } ) diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index a647fabc57..262844ca86 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -2,8 +2,9 @@ import type * as Effect from "../Effect.js" import type { Exit } from "../Exit.js" import type * as Fiber from "../Fiber.js" import type * as Layer from "../Layer.js" -import type { ManagedRuntime } from "../ManagedRuntime.js" +import type * as M from "../ManagedRuntime.js" import { pipeArguments } from "../Pipeable.js" +import { hasProperty } from "../Predicate.js" import type * as Runtime from "../Runtime.js" import * as Scope from "../Scope.js" import * as effect from "./core-effect.js" @@ -12,7 +13,7 @@ import * as fiberRuntime from "./fiberRuntime.js" import * as internalLayer from "./layer.js" import * as internalRuntime from "./runtime.js" -interface ManagedRuntimeImpl extends ManagedRuntime { +interface ManagedRuntimeImpl extends M.ManagedRuntime { readonly scope: Scope.CloseableScope cachedRuntime: Runtime.Runtime | undefined } @@ -36,7 +37,7 @@ function provide( export const make = ( layer: Layer.Layer, memoMap?: Layer.MemoMap -): ManagedRuntime => { +): M.ManagedRuntime => { memoMap = memoMap ?? internalLayer.unsafeMakeMemoMap() const scope = internalRuntime.unsafeRunSyncEffect(fiberRuntime.scopeMake()) const self: ManagedRuntimeImpl = { @@ -113,3 +114,9 @@ export const make = ( } return self } + +/** @internal */ +export const TypeId: M.TypeId = Symbol.for("effect/ManagedRuntime") as M.TypeId + +/** @internal */ +export const isManagedRuntime = (u: unknown): u is M.ManagedRuntime => hasProperty(u, TypeId) From ac5b693789da206db11e56af32a8177370d19c33 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 12:12:54 -0500 Subject: [PATCH 02/19] Create smart-fishes-sit.md --- .changeset/smart-fishes-sit.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/smart-fishes-sit.md diff --git a/.changeset/smart-fishes-sit.md b/.changeset/smart-fishes-sit.md new file mode 100644 index 0000000000..a39b6dec0f --- /dev/null +++ b/.changeset/smart-fishes-sit.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +Effect.provide(managedRuntime) From 720031f5de727705936640c16cf2c76aa08f64a1 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 19:42:16 +0000 Subject: [PATCH 03/19] make managedRuntime subtype of effect --- packages/effect/dtslint/Unify.ts | 11 ++- packages/effect/src/ManagedRuntime.ts | 77 ++++++++++++++----- .../effect/src/internal/managedRuntime.ts | 54 ++++++++----- 3 files changed, 102 insertions(+), 40 deletions(-) diff --git a/packages/effect/dtslint/Unify.ts b/packages/effect/dtslint/Unify.ts index 734093ffe3..ffb64018c5 100644 --- a/packages/effect/dtslint/Unify.ts +++ b/packages/effect/dtslint/Unify.ts @@ -4,6 +4,7 @@ import * as Either from "effect/Either" import type * as Exit from "effect/Exit" import type * as Fiber from "effect/Fiber" import type * as FiberRef from "effect/FiberRef" +import type * as ManagedRuntime from "effect/ManagedRuntime" import type * as Micro from "effect/Micro" import type * as Option from "effect/Option" import type * as Queue from "effect/Queue" @@ -125,7 +126,13 @@ export type ResourceUnify = Unify.Unify< | Resource.Resource > -// $ExpectType 0 | Option | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Latch | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E"> +// $ExpectType ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> +export type ManagedRuntimeUnify = Unify.Unify< + | ManagedRuntime.ManagedRuntime<1, 2> + | ManagedRuntime.ManagedRuntime<"a", "b"> +> + +// $ExpectType 0 | Option | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Latch | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E"> export type AllUnify = Unify.Unify< | Either.Either<1, 0> | Either.Either<"A", "E"> @@ -158,5 +165,7 @@ export type AllUnify = Unify.Unify< | Resource.Resource<1, 2> | Resource.Resource<"a"> | Effect.Latch + | ManagedRuntime.ManagedRuntime<1, 2> + | ManagedRuntime.ManagedRuntime<"a", "b"> | 0 > diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index 9b664d904f..dc3caa202b 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -2,12 +2,33 @@ * @since 2.0.0 */ import type * as Effect from "./Effect.js" +import type * as effectable from "./Effectable.js" import type * as Exit from "./Exit.js" import type * as Fiber from "./Fiber.js" import * as internal from "./internal/managedRuntime.js" import type * as Layer from "./Layer.js" import type { Pipeable } from "./Pipeable.js" import type * as Runtime from "./Runtime.js" +import type * as Types from "./Types.js" +import type * as Unify from "./Unify.js" + +const TypeId: unique symbol = internal.TypeId as TypeId + +/** + * @since 2.0.0 + * @category symbol + */ +export type TypeId = typeof TypeId + +/** + * Checks if the provided argument is a `ManagedRuntime`. + * + * @param input - The value to be checked if it is a `ManagedRuntime`. + + * @since 2.0.0 + * @category guards + */ +export const isManagedRuntime: (input: unknown) => input is ManagedRuntime = internal.isManagedRuntime /** * @since 3.4.0 @@ -23,13 +44,29 @@ export declare namespace ManagedRuntime { * @since 3.4.0 */ export type Error> = [T] extends [ManagedRuntime] ? E : never + /** + * @since 2.0.0 + * @category models + */ + export interface Variance { + readonly [TypeId]: { + _R: Types.Invariant + _ER: Types.Invariant + } + } } /** * @since 2.0.0 * @category models */ -export interface ManagedRuntime extends Pipeable { +export interface ManagedRuntime + extends + Effect.Effect, ER, never>, + effectable.Class, ER, never>, + ManagedRuntime.Variance, + Pipeable +{ readonly memoMap: Layer.MemoMap readonly runtimeEffect: Effect.Effect, ER> readonly runtime: () => Promise> @@ -103,6 +140,26 @@ export interface ManagedRuntime extends Pipeable { * Dispose of the resources associated with the runtime. */ readonly disposeEffect: Effect.Effect + + readonly [Unify.typeSymbol]?: unknown + readonly [Unify.unifySymbol]?: ManagedRuntimeUnify + readonly [Unify.ignoreSymbol]?: ManagedRuntimeUnifyIgnore +} + +/** + * @category models + * @since 3.8.0 + */ +export interface ManagedRuntimeUnify extends Effect.EffectUnify { + ManagedRuntime?: () => Extract> +} + +/** + * @category models + * @since 3.8.0 + */ +export interface ManagedRuntimeUnifyIgnore extends Effect.EffectUnifyIgnore { + Effect?: true } /** @@ -133,21 +190,3 @@ export const make: ( layer: Layer.Layer, memoMap?: Layer.MemoMap | undefined ) => ManagedRuntime = internal.make - -const TypeId: unique symbol = internal.TypeId as TypeId - -/** - * @since 2.0.0 - * @category symbol - */ -export type TypeId = typeof TypeId - -/** - * Checks if the provided argument is a `ManagedRuntime`. - * - * @param input - The value to be checked if it is a `ManagedRuntime`. - - * @since 2.0.0 - * @category guards - */ -export const isManagedRuntime: (input: unknown) => input is ManagedRuntime = internal.isManagedRuntime diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index 262844ca86..23de9bcb79 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -1,4 +1,5 @@ import type * as Effect from "../Effect.js" +import * as Effectable from "../Effectable.js" import type { Exit } from "../Exit.js" import type * as Fiber from "../Fiber.js" import type * as Layer from "../Layer.js" @@ -18,6 +19,19 @@ interface ManagedRuntimeImpl extends M.ManagedRuntime { cachedRuntime: Runtime.Runtime | undefined } +/** @internal */ +export const TypeId: M.TypeId = Symbol.for("effect/ManagedRuntime") as M.TypeId + +/** @internal */ +export const isManagedRuntime = (u: unknown): u is M.ManagedRuntime => hasProperty(u, TypeId) + +const managedRuntimeVariance = { + /* c8 ignore next */ + _R: (_: any) => _, + /* c8 ignore next */ + _ER: (_: any) => _ +} + function provide( managed: ManagedRuntimeImpl, effect: Effect.Effect @@ -40,27 +54,33 @@ export const make = ( ): M.ManagedRuntime => { memoMap = memoMap ?? internalLayer.unsafeMakeMemoMap() const scope = internalRuntime.unsafeRunSyncEffect(fiberRuntime.scopeMake()) + const runtimeEffect = internalRuntime + .unsafeRunSyncEffect( + effect.memoize( + core.tap( + Scope.extend( + internalLayer.toRuntimeWithMemoMap(layer, memoMap), + scope + ), + (rt) => { + self.cachedRuntime = rt + } + ) + ) + ) const self: ManagedRuntimeImpl = { + ...Effectable.CommitPrototype, + [TypeId]: managedRuntimeVariance, memoMap, scope, - runtimeEffect: internalRuntime - .unsafeRunSyncEffect( - effect.memoize( - core.tap( - Scope.extend( - internalLayer.toRuntimeWithMemoMap(layer, memoMap), - scope - ), - (rt) => { - self.cachedRuntime = rt - } - ) - ) - ), + runtimeEffect, cachedRuntime: undefined, pipe() { return pipeArguments(this, arguments) }, + commit() { + return runtimeEffect + }, runtime() { return self.cachedRuntime === undefined ? internalRuntime.unsafeRunPromiseEffect(self.runtimeEffect) : @@ -114,9 +134,3 @@ export const make = ( } return self } - -/** @internal */ -export const TypeId: M.TypeId = Symbol.for("effect/ManagedRuntime") as M.TypeId - -/** @internal */ -export const isManagedRuntime = (u: unknown): u is M.ManagedRuntime => hasProperty(u, TypeId) From 45fb7482280ab09be103409fa149f7a2a96252e5 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 14:46:28 -0500 Subject: [PATCH 04/19] Update smart-fishes-sit.md --- .changeset/smart-fishes-sit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/smart-fishes-sit.md b/.changeset/smart-fishes-sit.md index a39b6dec0f..c278791d15 100644 --- a/.changeset/smart-fishes-sit.md +++ b/.changeset/smart-fishes-sit.md @@ -2,4 +2,4 @@ "effect": patch --- -Effect.provide(managedRuntime) +`Effect.provide(managedRuntime)` and `ManagedRuntime` is subtype of `Effect, E, never>` From 064db6eb1438800ab316c02291eebc98207a276d Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 19:47:56 +0000 Subject: [PATCH 05/19] make diff better --- packages/effect/dtslint/Unify.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/effect/dtslint/Unify.ts b/packages/effect/dtslint/Unify.ts index ffb64018c5..d1b2668264 100644 --- a/packages/effect/dtslint/Unify.ts +++ b/packages/effect/dtslint/Unify.ts @@ -101,7 +101,11 @@ export type RuntimeFiberUnify = Unify.Unify< | Fiber.RuntimeFiber<1, 2> | Fiber.RuntimeFiber<"a", "b"> > - +// $ExpectType ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> +export type ManagedRuntimeUnify = Unify.Unify< + | ManagedRuntime.ManagedRuntime<1, 2> + | ManagedRuntime.ManagedRuntime<"a", "b"> +> // $ExpectType Queue<1> | Queue<"a"> export type QueueUnify = Unify.Unify< | Queue.Queue<1> @@ -126,13 +130,7 @@ export type ResourceUnify = Unify.Unify< | Resource.Resource > -// $ExpectType ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> -export type ManagedRuntimeUnify = Unify.Unify< - | ManagedRuntime.ManagedRuntime<1, 2> - | ManagedRuntime.ManagedRuntime<"a", "b"> -> - -// $ExpectType 0 | Option | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Latch | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E"> +// $ExpectType 0 | Option | Ref<1> | SynchronizedRef<1> | SubscriptionRef<1> | Deferred<1, 2> | Deferred<"a", "b"> | Fiber<"a" | 1, "b" | 2> | RuntimeFiber<"a" | 1, "b" | 2> | ManagedRuntime<1, 2> | ManagedRuntime<"a", "b"> | Queue<1> | Queue<"a"> | Dequeue<"a" | 1> | ScopedRef<1> | ScopedRef<"a"> | Resource<1, 2> | Ref<"A"> | SynchronizedRef<"A"> | SubscriptionRef<"A"> | FiberRef<12> | FiberRef<"a2"> | Resource<"a", never> | Latch | Either<1 | "A", 0 | "E"> | Effect<1 | "A", 0 | "E", "R" | "R1"> | RcRef<1 | "A", 0 | "E"> export type AllUnify = Unify.Unify< | Either.Either<1, 0> | Either.Either<"A", "E"> From 3400eb76da5dc0b3a1c6043d08243a185063599b Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 19:51:33 +0000 Subject: [PATCH 06/19] remove `.runtimeEffect` from flatMap now that Managedruntime is subtype of effect --- packages/effect/src/internal/layer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/effect/src/internal/layer.ts b/packages/effect/src/internal/layer.ts index b14a6abbac..6a75579bda 100644 --- a/packages/effect/src/internal/layer.ts +++ b/packages/effect/src/internal/layer.ts @@ -1339,7 +1339,7 @@ export const effect_provide = dual< return core.provideSomeContext(self, source) } else if (ManagedRuntime.isManagedRuntime(source)) { return core.flatMap( - (source as ManagedRuntime.ManagedRuntime).runtimeEffect, + source as ManagedRuntime.ManagedRuntime, (rt) => provideSomeRuntime(self, rt) ) } else { From 03aed97f663149c8332a60291b4f1e6c713007ad Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 19:54:42 +0000 Subject: [PATCH 07/19] fix `@since`s --- .changeset/smart-fishes-sit.md | 2 +- packages/effect/src/ManagedRuntime.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.changeset/smart-fishes-sit.md b/.changeset/smart-fishes-sit.md index c278791d15..290d0d5937 100644 --- a/.changeset/smart-fishes-sit.md +++ b/.changeset/smart-fishes-sit.md @@ -1,5 +1,5 @@ --- -"effect": patch +"effect": minor --- `Effect.provide(managedRuntime)` and `ManagedRuntime` is subtype of `Effect, E, never>` diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index dc3caa202b..2312425794 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -15,7 +15,7 @@ import type * as Unify from "./Unify.js" const TypeId: unique symbol = internal.TypeId as TypeId /** - * @since 2.0.0 + * @since 3.9.0 * @category symbol */ export type TypeId = typeof TypeId @@ -25,7 +25,7 @@ export type TypeId = typeof TypeId * * @param input - The value to be checked if it is a `ManagedRuntime`. - * @since 2.0.0 + * @since 3.9.0 * @category guards */ export const isManagedRuntime: (input: unknown) => input is ManagedRuntime = internal.isManagedRuntime @@ -45,7 +45,7 @@ export declare namespace ManagedRuntime { */ export type Error> = [T] extends [ManagedRuntime] ? E : never /** - * @since 2.0.0 + * @since 3.9.0 * @category models */ export interface Variance { @@ -148,7 +148,7 @@ export interface ManagedRuntime /** * @category models - * @since 3.8.0 + * @since 3.9.0 */ export interface ManagedRuntimeUnify extends Effect.EffectUnify { ManagedRuntime?: () => Extract> @@ -156,7 +156,7 @@ export interface ManagedRuntimeUnify ext /** * @category models - * @since 3.8.0 + * @since 3.9.0 */ export interface ManagedRuntimeUnifyIgnore extends Effect.EffectUnifyIgnore { Effect?: true From 1b0f3f46f7994db98984cdd141f46a97d721db66 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 16:58:45 -0500 Subject: [PATCH 08/19] Apply suggestions from code review Co-authored-by: Tim --- packages/effect/src/ManagedRuntime.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index 2312425794..6e519c890b 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -2,7 +2,7 @@ * @since 2.0.0 */ import type * as Effect from "./Effect.js" -import type * as effectable from "./Effectable.js" +import type * as Effectable from "./Effectable.js" import type * as Exit from "./Exit.js" import type * as Fiber from "./Fiber.js" import * as internal from "./internal/managedRuntime.js" @@ -60,12 +60,9 @@ export declare namespace ManagedRuntime { * @since 2.0.0 * @category models */ -export interface ManagedRuntime +export interface ManagedRuntime extends - Effect.Effect, ER, never>, - effectable.Class, ER, never>, - ManagedRuntime.Variance, - Pipeable + Effect.Effect, ER> { readonly memoMap: Layer.MemoMap readonly runtimeEffect: Effect.Effect, ER> From fbf4e7f3e59b0fd711bb707b72b07f31ab71d783 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:03:00 +0000 Subject: [PATCH 09/19] export typeId and remove variance --- packages/effect/src/ManagedRuntime.ts | 21 +++---------------- .../effect/src/internal/managedRuntime.ts | 9 +------- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index 6e519c890b..d870a70292 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -2,17 +2,14 @@ * @since 2.0.0 */ import type * as Effect from "./Effect.js" -import type * as Effectable from "./Effectable.js" import type * as Exit from "./Exit.js" import type * as Fiber from "./Fiber.js" import * as internal from "./internal/managedRuntime.js" import type * as Layer from "./Layer.js" -import type { Pipeable } from "./Pipeable.js" import type * as Runtime from "./Runtime.js" -import type * as Types from "./Types.js" import type * as Unify from "./Unify.js" -const TypeId: unique symbol = internal.TypeId as TypeId +export const TypeId: unique symbol = internal.TypeId as TypeId /** * @since 3.9.0 @@ -44,26 +41,14 @@ export declare namespace ManagedRuntime { * @since 3.4.0 */ export type Error> = [T] extends [ManagedRuntime] ? E : never - /** - * @since 3.9.0 - * @category models - */ - export interface Variance { - readonly [TypeId]: { - _R: Types.Invariant - _ER: Types.Invariant - } - } } /** * @since 2.0.0 * @category models */ -export interface ManagedRuntime - extends - Effect.Effect, ER> -{ +export interface ManagedRuntime extends Effect.Effect, ER> { + readonly [TypeId]: TypeId readonly memoMap: Layer.MemoMap readonly runtimeEffect: Effect.Effect, ER> readonly runtime: () => Promise> diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index 23de9bcb79..9fb3fcd5ca 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -25,13 +25,6 @@ export const TypeId: M.TypeId = Symbol.for("effect/ManagedRuntime") as M.TypeId /** @internal */ export const isManagedRuntime = (u: unknown): u is M.ManagedRuntime => hasProperty(u, TypeId) -const managedRuntimeVariance = { - /* c8 ignore next */ - _R: (_: any) => _, - /* c8 ignore next */ - _ER: (_: any) => _ -} - function provide( managed: ManagedRuntimeImpl, effect: Effect.Effect @@ -70,7 +63,7 @@ export const make = ( ) const self: ManagedRuntimeImpl = { ...Effectable.CommitPrototype, - [TypeId]: managedRuntimeVariance, + [TypeId]: TypeId, memoMap, scope, runtimeEffect, From 81607ec54c5d08b8ec55fd2c061c532052f76278 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:06:13 +0000 Subject: [PATCH 10/19] add source.runtimeEffect back --- packages/effect/src/internal/layer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/effect/src/internal/layer.ts b/packages/effect/src/internal/layer.ts index 6a75579bda..b14a6abbac 100644 --- a/packages/effect/src/internal/layer.ts +++ b/packages/effect/src/internal/layer.ts @@ -1339,7 +1339,7 @@ export const effect_provide = dual< return core.provideSomeContext(self, source) } else if (ManagedRuntime.isManagedRuntime(source)) { return core.flatMap( - source as ManagedRuntime.ManagedRuntime, + (source as ManagedRuntime.ManagedRuntime).runtimeEffect, (rt) => provideSomeRuntime(self, rt) ) } else { From 73df65d1357e51f1c667e8b0ee092fb97ecd7a7f Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:08:58 +0000 Subject: [PATCH 11/19] fix type errors --- packages/effect/src/internal/managedRuntime.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index 9fb3fcd5ca..99a96a0c99 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -8,15 +8,20 @@ import { pipeArguments } from "../Pipeable.js" import { hasProperty } from "../Predicate.js" import type * as Runtime from "../Runtime.js" import * as Scope from "../Scope.js" +import type * as Unify from "../Unify.js" import * as effect from "./core-effect.js" import * as core from "./core.js" import * as fiberRuntime from "./fiberRuntime.js" import * as internalLayer from "./layer.js" import * as internalRuntime from "./runtime.js" -interface ManagedRuntimeImpl extends M.ManagedRuntime { +interface ManagedRuntimeImpl extends M.ManagedRuntime, Effectable.Class, E, never> { readonly scope: Scope.CloseableScope cachedRuntime: Runtime.Runtime | undefined + + readonly [Unify.typeSymbol]?: unknown + readonly [Unify.unifySymbol]?: M.ManagedRuntimeUnify + readonly [Unify.ignoreSymbol]?: M.ManagedRuntimeUnifyIgnore } /** @internal */ From 375dcf59a7932b89ebc8ab193a55aba114cbaf24 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:11:56 +0000 Subject: [PATCH 12/19] run docgen and add missing docs --- packages/effect/src/ManagedRuntime.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index d870a70292..968fb4a393 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -9,6 +9,10 @@ import type * as Layer from "./Layer.js" import type * as Runtime from "./Runtime.js" import type * as Unify from "./Unify.js" +/** + * @since 3.9.0 + * @category symbol + */ export const TypeId: unique symbol = internal.TypeId as TypeId /** From 9433b7c93db66795f3b1125af593a2073e4c415d Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:14:37 +0000 Subject: [PATCH 13/19] keep pipable --- packages/effect/src/ManagedRuntime.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index 968fb4a393..c028136e87 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -6,6 +6,7 @@ import type * as Exit from "./Exit.js" import type * as Fiber from "./Fiber.js" import * as internal from "./internal/managedRuntime.js" import type * as Layer from "./Layer.js" +import type { Pipeable } from "./Pipeable.js" import type * as Runtime from "./Runtime.js" import type * as Unify from "./Unify.js" @@ -51,7 +52,7 @@ export declare namespace ManagedRuntime { * @since 2.0.0 * @category models */ -export interface ManagedRuntime extends Effect.Effect, ER> { +export interface ManagedRuntime extends Pipeable, Effect.Effect, ER> { readonly [TypeId]: TypeId readonly memoMap: Layer.MemoMap readonly runtimeEffect: Effect.Effect, ER> From 7d37445b416572ed35425997e38d21343ca512e5 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:29:44 +0000 Subject: [PATCH 14/19] add test case --- packages/effect/test/ManagedRuntime.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/effect/test/ManagedRuntime.test.ts b/packages/effect/test/ManagedRuntime.test.ts index 4877112a1b..defe8e4445 100644 --- a/packages/effect/test/ManagedRuntime.test.ts +++ b/packages/effect/test/ManagedRuntime.test.ts @@ -3,6 +3,7 @@ import * as Context from "effect/Context" import * as Effect from "effect/Effect" import * as FiberRef from "effect/FiberRef" import * as Layer from "effect/Layer" +import * as it from "effect/test/utils/extend" import { assert, describe, test } from "vitest" describe.concurrent("ManagedRuntime", () => { @@ -48,4 +49,17 @@ describe.concurrent("ManagedRuntime", () => { await runtimeB.dispose() assert.strictEqual(count, 1) }) + + it.effect( + "is subtype of effect", + () => + Effect.gen(function*() { + const tag = Context.GenericTag("string") + const layer = Layer.succeed(tag, "test") + const managedRuntime = ManagedRuntime.make(layer) + const runtime = yield* managedRuntime + const result = Context.get(runtime.context, tag) + assert.strictEqual(result, "test") + }) + ) }) From 9022dd61a14f78e0d0556334aa993074798c12d1 Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:32:25 +0000 Subject: [PATCH 15/19] remove pipable --- packages/effect/src/ManagedRuntime.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/effect/src/ManagedRuntime.ts b/packages/effect/src/ManagedRuntime.ts index c028136e87..968fb4a393 100644 --- a/packages/effect/src/ManagedRuntime.ts +++ b/packages/effect/src/ManagedRuntime.ts @@ -6,7 +6,6 @@ import type * as Exit from "./Exit.js" import type * as Fiber from "./Fiber.js" import * as internal from "./internal/managedRuntime.js" import type * as Layer from "./Layer.js" -import type { Pipeable } from "./Pipeable.js" import type * as Runtime from "./Runtime.js" import type * as Unify from "./Unify.js" @@ -52,7 +51,7 @@ export declare namespace ManagedRuntime { * @since 2.0.0 * @category models */ -export interface ManagedRuntime extends Pipeable, Effect.Effect, ER> { +export interface ManagedRuntime extends Effect.Effect, ER> { readonly [TypeId]: TypeId readonly memoMap: Layer.MemoMap readonly runtimeEffect: Effect.Effect, ER> From 802a4dc7f33e23ddd2351d874e8cff5792387a5e Mon Sep 17 00:00:00 2001 From: Leo Conforti Date: Tue, 24 Sep 2024 22:53:50 +0000 Subject: [PATCH 16/19] apply diff --- .../effect/src/internal/managedRuntime.ts | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index 99a96a0c99..ff7ecbc4d9 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -8,20 +8,15 @@ import { pipeArguments } from "../Pipeable.js" import { hasProperty } from "../Predicate.js" import type * as Runtime from "../Runtime.js" import * as Scope from "../Scope.js" -import type * as Unify from "../Unify.js" import * as effect from "./core-effect.js" import * as core from "./core.js" import * as fiberRuntime from "./fiberRuntime.js" import * as internalLayer from "./layer.js" import * as internalRuntime from "./runtime.js" -interface ManagedRuntimeImpl extends M.ManagedRuntime, Effectable.Class, E, never> { +interface ManagedRuntimeImpl extends M.ManagedRuntime { readonly scope: Scope.CloseableScope cachedRuntime: Runtime.Runtime | undefined - - readonly [Unify.typeSymbol]?: unknown - readonly [Unify.unifySymbol]?: M.ManagedRuntimeUnify - readonly [Unify.ignoreSymbol]?: M.ManagedRuntimeUnifyIgnore } /** @internal */ @@ -45,6 +40,25 @@ function provide( ) } +const ManagedRuntimeProto = { + ...Effectable.CommitPrototype, + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + }, + commit(this: ManagedRuntimeImpl) { + return this.runtimeEffect + }, + runtime(this: ManagedRuntimeImpl) { + return this.cachedRuntime === undefined ? + internalRuntime.unsafeRunPromiseEffect(this.runtimeEffect) : + Promise.resolve(this.cachedRuntime) + }, + dispose(this: ManagedRuntimeImpl): Promise { + return internalRuntime.unsafeRunPromiseEffect(this.disposeEffect) + } +} + /** @internal */ export const make = ( layer: Layer.Layer, @@ -52,41 +66,24 @@ export const make = ( ): M.ManagedRuntime => { memoMap = memoMap ?? internalLayer.unsafeMakeMemoMap() const scope = internalRuntime.unsafeRunSyncEffect(fiberRuntime.scopeMake()) - const runtimeEffect = internalRuntime - .unsafeRunSyncEffect( - effect.memoize( - core.tap( - Scope.extend( - internalLayer.toRuntimeWithMemoMap(layer, memoMap), - scope - ), - (rt) => { - self.cachedRuntime = rt - } - ) + const runtimeEffect = internalRuntime.unsafeRunSyncEffect( + effect.memoize( + core.tap( + Scope.extend( + internalLayer.toRuntimeWithMemoMap(layer, memoMap), + scope + ), + (rt) => { + self.cachedRuntime = rt + } ) ) - const self: ManagedRuntimeImpl = { - ...Effectable.CommitPrototype, - [TypeId]: TypeId, + ) + const self: ManagedRuntimeImpl = Object.assign(Object.create(ManagedRuntimeProto), { memoMap, scope, runtimeEffect, cachedRuntime: undefined, - pipe() { - return pipeArguments(this, arguments) - }, - commit() { - return runtimeEffect - }, - runtime() { - return self.cachedRuntime === undefined ? - internalRuntime.unsafeRunPromiseEffect(self.runtimeEffect) : - Promise.resolve(self.cachedRuntime) - }, - dispose(): Promise { - return internalRuntime.unsafeRunPromiseEffect(self.disposeEffect) - }, disposeEffect: core.suspend(() => { ;(self as any).runtime = core.die("ManagedRuntime disposed") self.cachedRuntime = undefined @@ -129,6 +126,6 @@ export const make = ( internalRuntime.unsafeRunPromiseEffect(provide(self, effect), options) : internalRuntime.unsafeRunPromise(self.cachedRuntime)(effect, options) } - } + }) return self } From 3b95e9bb772be158f72f590db11822bc6c01e4c1 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 25 Sep 2024 11:03:56 +1200 Subject: [PATCH 17/19] fix circular import --- packages/effect/src/internal/layer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/effect/src/internal/layer.ts b/packages/effect/src/internal/layer.ts index b14a6abbac..985e10a149 100644 --- a/packages/effect/src/internal/layer.ts +++ b/packages/effect/src/internal/layer.ts @@ -10,7 +10,7 @@ import type { LazyArg } from "../Function.js" import { dual, pipe } from "../Function.js" import * as HashMap from "../HashMap.js" import type * as Layer from "../Layer.js" -import * as ManagedRuntime from "../ManagedRuntime.js" +import type * as ManagedRuntime from "../ManagedRuntime.js" import { pipeArguments } from "../Pipeable.js" import { hasProperty } from "../Predicate.js" import type * as Runtime from "../Runtime.js" @@ -1289,6 +1289,8 @@ const provideSomeRuntime = dual< ) }) +const ManagedRuntimeTypeId: ManagedRuntime.TypeId = Symbol.for("effect/ManagedRuntime") as ManagedRuntime.TypeId + /** @internal */ export const effect_provide = dual< { @@ -1337,7 +1339,7 @@ export const effect_provide = dual< return provideSomeLayer(self, source as Layer.Layer) } else if (Context.isContext(source)) { return core.provideSomeContext(self, source) - } else if (ManagedRuntime.isManagedRuntime(source)) { + } else if (ManagedRuntimeTypeId in source) { return core.flatMap( (source as ManagedRuntime.ManagedRuntime).runtimeEffect, (rt) => provideSomeRuntime(self, rt) From 68f2a5b1b1ac1fe8f427d627c4f42650b7d2eac6 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 25 Sep 2024 11:14:29 +1200 Subject: [PATCH 18/19] split changesets --- .changeset/purple-beans-jog.md | 5 +++++ .changeset/smart-fishes-sit.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/purple-beans-jog.md diff --git a/.changeset/purple-beans-jog.md b/.changeset/purple-beans-jog.md new file mode 100644 index 0000000000..b04f03b001 --- /dev/null +++ b/.changeset/purple-beans-jog.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +support ManagedRuntime in Effect.provide diff --git a/.changeset/smart-fishes-sit.md b/.changeset/smart-fishes-sit.md index 290d0d5937..4b2f2750f3 100644 --- a/.changeset/smart-fishes-sit.md +++ b/.changeset/smart-fishes-sit.md @@ -2,4 +2,4 @@ "effect": minor --- -`Effect.provide(managedRuntime)` and `ManagedRuntime` is subtype of `Effect, E, never>` +`ManagedRuntime` is subtype of `Effect, E, never>` From a1b3b6051610405ef98d1e0a4394d8d7d2def461 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 25 Sep 2024 11:23:30 +1200 Subject: [PATCH 19/19] allow .runtime & .dispose to be destructured --- packages/effect/src/internal/managedRuntime.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/effect/src/internal/managedRuntime.ts b/packages/effect/src/internal/managedRuntime.ts index ff7ecbc4d9..c9a38711d5 100644 --- a/packages/effect/src/internal/managedRuntime.ts +++ b/packages/effect/src/internal/managedRuntime.ts @@ -48,14 +48,6 @@ const ManagedRuntimeProto = { }, commit(this: ManagedRuntimeImpl) { return this.runtimeEffect - }, - runtime(this: ManagedRuntimeImpl) { - return this.cachedRuntime === undefined ? - internalRuntime.unsafeRunPromiseEffect(this.runtimeEffect) : - Promise.resolve(this.cachedRuntime) - }, - dispose(this: ManagedRuntimeImpl): Promise { - return internalRuntime.unsafeRunPromiseEffect(this.disposeEffect) } } @@ -84,6 +76,14 @@ export const make = ( scope, runtimeEffect, cachedRuntime: undefined, + runtime() { + return self.cachedRuntime === undefined ? + internalRuntime.unsafeRunPromiseEffect(self.runtimeEffect) : + Promise.resolve(self.cachedRuntime) + }, + dispose(): Promise { + return internalRuntime.unsafeRunPromiseEffect(self.disposeEffect) + }, disposeEffect: core.suspend(() => { ;(self as any).runtime = core.die("ManagedRuntime disposed") self.cachedRuntime = undefined