better-effect 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Type your errors with `better-result`. Typecheck the rest of your application wiring with `better-effect`.
6
6
 
7
- Use Services directly inside `Effect.gen`, compose implementations into application environments, and let TypeScript catch missing dependencies before your application starts — while keeping Promises, `better-result`, and your DI backend.
7
+ Use Services directly inside `Effect.fn` Programs (or eager `Effect.gen` workflows), compose implementations into application environments, and let TypeScript catch missing dependencies before your application starts — while keeping Promises, `better-result`, and your DI backend.
8
8
 
9
9
  ```bash
10
10
  bun add better-effect better-result
@@ -34,7 +34,7 @@ class UserRepository extends Service<UserRepository>()('UserRepository') {
34
34
 
35
35
  const UserRepositoryLive = Layer.make(UserRepository)
36
36
 
37
- await Runtime.make(UserRepositoryLive, backend)
37
+ await Runtime.make(UserRepositoryLive)
38
38
  // ^^^^^^^^^^^^^^^^^^
39
39
  // Type error: Database is required but not provided
40
40
  ```
@@ -92,7 +92,7 @@ const DatabaseLive = Layer.make(Database)
92
92
 
93
93
  const AppLive = Layer.merge(DatabaseLive, UserRepositoryLive)
94
94
 
95
- const runtime = await Runtime.make(AppLive, backend)
95
+ const runtime = await Runtime.make(AppLive)
96
96
  ```
97
97
 
98
98
  And the contract does not disappear after startup.
@@ -100,15 +100,24 @@ And the contract does not disappear after startup.
100
100
  A Runtime also knows which Services exist in its environment:
101
101
 
102
102
  ```ts
103
- await runtime.run(() =>
104
- Effect.gen(async function* () {
105
- const database = yield* Database
103
+ const inspectDatabase = Effect.fn(async function* () {
104
+ const database = yield* Database
106
105
 
107
- return Result.ok(database)
108
- })
109
- )
106
+ return Result.ok(database)
107
+ })
108
+
109
+ await runtime.run(inspectDatabase)
110
110
  ```
111
111
 
112
+ `Effect.gen` remains eager for code that already runs inside a resolver and
113
+ Scope. `Effect.fn` captures the generator as a lazy `Program` for Runtime
114
+ boundaries; the callback form remains supported for compatibility.
115
+
116
+ `Runtime.make(AppLive)` and `Runtime.run(AppLive, program)` use the built-in
117
+ `MapLayerBackend`. Pass `{ backend: new ItiLayerBackend() }` when an external
118
+ container is needed; `MemoryLayerBackend` remains its compatibility alias from
119
+ `better-effect/testing`.
120
+
112
121
  If a program asks that Runtime for a Service its environment does not provide, TypeScript rejects the call.
113
122
 
114
123
  ```text
@@ -232,7 +241,7 @@ Others own connections, sessions, files or other resources.
232
241
  const DatabaseLive = Layer.scoped(
233
242
  Database,
234
243
  () => Database.connect(),
235
- (database) => database.close()
244
+ (database, outcome) => database.close(outcome)
236
245
  )
237
246
  ```
238
247
 
@@ -318,11 +327,11 @@ Application resources live with the Runtime. Execution resources live with the e
318
327
 
319
328
  ### better-result underneath
320
329
 
321
- **Result → Result.gen → Effect.gen → pipe**
330
+ **Result → Result.gen → Effect.gen / Effect.fn → pipe**
322
331
 
323
332
  Keep `better-result` as the source of truth for typed successes, failures, short-circuiting
324
333
  and generator control flow. `Effect.gen` delegates to `Result.gen`; it adds only the
325
- phantom Service requirements that TypeScript needs to check the application environment.
334
+ declaration-only Service requirements that TypeScript needs to check the application environment.
326
335
  At runtime, an `Effect<A, E, R>` is still a `better-result` Result; the requirements exist
327
336
  only in the type. `Effect.Requirements`, `Layer.Provided`, `Layer.Required` and
328
337
  `Runtime.For` expose tagged Service instance unions.
@@ -349,5 +358,6 @@ or already an `Err`. The pipeline carries the requirements of every step, so Run
349
358
  still rejects it when its Layer does not provide every required Service.
350
359
 
351
360
  Use `Effect.gen` for larger workflows with several intermediate values, branches or
352
- procedural logic. Use `pipe` for concise, linear composition; both are ways to compose
353
- `better-result` programs while keeping dependency checking in the `better-effect` layer.
361
+ procedural logic that already has a resolver. Use `Effect.fn` when the workflow should
362
+ start at a Runtime boundary. Use `pipe` for concise, linear composition; all three
363
+ keep dependency checking in the `better-effect` layer.
@@ -1,4 +1,5 @@
1
- import { d as LayerRegistration, t as LayerBackend, z as AnyServiceToken } from "../index-DMfjhNR_.mjs";
1
+ import { T as AnyServiceToken, a as LayerRegistration, n as LayerBackend } from "../map-layer-backend-7hQkf_QP.mjs";
2
+ import "../index-R3FdVmdr.mjs";
2
3
  //#region src/adapters/iti.d.ts
3
4
  /**
4
5
  * ITI-backed Layer backend.
@@ -1 +1 @@
1
- {"version":3,"file":"iti.d.mts","names":[],"sources":["../../src/adapters/iti.ts"],"mappings":";;;;;;;;cAsBa,2BAA2B;UAC9B;mBAES;mBAEA;UAET;;EAgBR,SAAS,cAAc;;EAuBvB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,aAAa,KAAK,YAAY,aAAa;;EAyBnF,cAAc"}
1
+ {"version":3,"file":"iti.d.mts","names":[],"sources":["../../src/adapters/iti.ts"],"mappings":";;;;;;;;;cAsBa,2BAA2B;UAC9B;mBAES;mBAEA;UAET;;EAgBR,SAAS,cAAc;;EAuBvB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,aAAa,KAAK,YAAY,aAAa;;EAyBnF,cAAc"}
@@ -1,6 +1,5 @@
1
- import { a as ServiceTagCollisionError, o as ServiceNotFoundError, t as DuplicateServiceError } from "../errors-GR3K_nRu.mjs";
1
+ import { l as ServiceNotFoundError, n as DuplicateServiceError, o as ServiceTagCollisionError, t as assertServiceCompatibility } from "../internal-identity-Cm4-KIUj.mjs";
2
2
  import { t as isPromiseLike } from "../runtime-CDcCF5cb.mjs";
3
- import { t as assertServiceCompatibility } from "../internal-identity-C6Awrc33.mjs";
4
3
  import { createContainer } from "iti";
5
4
  //#region src/adapters/iti.ts
6
5
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"iti.mjs","names":[],"sources":["../../src/adapters/iti.ts"],"sourcesContent":["import { createContainer } from 'iti'\n\nimport {\n DuplicateServiceError,\n ServiceTagCollisionError,\n type LayerBackend,\n type LayerRegistration\n} from '../layer'\n\nimport { ServiceNotFoundError, type AnyServiceToken } from '../service'\n\nimport { assertServiceCompatibility } from '../layer/internal-identity'\nimport { isPromiseLike } from '../utils/runtime'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\n/**\n * ITI-backed Layer backend.\n *\n * Install `iti` as the optional peer dependency and pass an instance to\n * `Runtime.make` when using ITI's container implementation.\n */\nexport class ItiLayerBackend implements LayerBackend {\n private container: any = createContainer()\n\n private readonly keys = new Map<string, string>()\n\n private readonly registered = new Map<string, AnyServiceToken>()\n\n private keyFor(token: AnyServiceToken): string {\n const tag = token.serviceTag\n const existing = this.keys.get(tag)\n\n if (existing) {\n return existing\n }\n\n const key = `better-effect:${tag}`\n\n this.keys.set(tag, key)\n\n return key\n }\n\n /** Register a Layer provider under its deterministic Service-tag key. */\n register(registration: LayerRegistration): void {\n const token = registration.service\n const tag = token.serviceTag\n const existing = this.registered.get(tag)\n\n if (existing === token) {\n throw new DuplicateServiceError(token)\n }\n\n if (existing) {\n throw new ServiceTagCollisionError(existing, token)\n }\n\n const key = this.keyFor(token)\n\n this.container = this.container.add({\n [key]: registration.acquire\n })\n\n this.registered.set(tag, token)\n }\n\n /** Resolve a registered Service through the ITI container. */\n resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>> {\n const registered = this.registered.get(token.serviceTag)\n\n if (registered === undefined) {\n throw new ServiceNotFoundError(token)\n }\n\n const key = this.keyFor(token)\n const resolved = this.container.get(key)\n\n const validate = (instance: LayerAcquiredValue): InstanceType<T> => {\n assertServiceCompatibility(token, registered, instance)\n\n // SAFETY: The registered tag and compatibility check establish the constructor-to-instance relationship after ITI erases it.\n return instance as InstanceType<T>\n }\n\n if (isPromiseLike(resolved)) {\n return Promise.resolve(resolved).then(validate)\n }\n\n return validate(resolved)\n }\n\n /** Dispose all ITI-managed provider instances. */\n async disposeAll(): Promise<void> {\n await this.container.disposeAll()\n }\n}\n"],"mappings":";;;;;;;;;;;AAsBA,IAAa,kBAAb,MAAqD;CACnD,YAAyB,gBAAgB;CAEzC,uBAAwB,IAAI,IAAoB;CAEhD,6BAA8B,IAAI,IAA6B;CAE/D,OAAe,OAAgC;EAC7C,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,KAAK,IAAI,GAAG;EAElC,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,iBAAiB;EAE7B,KAAK,KAAK,IAAI,KAAK,GAAG;EAEtB,OAAO;CACT;;CAGA,SAAS,cAAuC;EAC9C,MAAM,QAAQ,aAAa;EAC3B,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,WAAW,IAAI,GAAG;EAExC,IAAI,aAAa,OACf,MAAM,IAAI,sBAAsB,KAAK;EAGvC,IAAI,UACF,MAAM,IAAI,yBAAyB,UAAU,KAAK;EAGpD,MAAM,MAAM,KAAK,OAAO,KAAK;EAE7B,KAAK,YAAY,KAAK,UAAU,IAAI,GACjC,MAAM,aAAa,QACtB,CAAC;EAED,KAAK,WAAW,IAAI,KAAK,KAAK;CAChC;;CAGA,QAAmC,OAA0D;EAC3F,MAAM,aAAa,KAAK,WAAW,IAAI,MAAM,UAAU;EAEvD,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,MAAM,KAAK,OAAO,KAAK;EAC7B,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,MAAM,YAAY,aAAkD;GAClE,2BAA2B,OAAO,YAAY,QAAQ;GAGtD,OAAO;EACT;EAEA,IAAI,cAAc,QAAQ,GACxB,OAAO,QAAQ,QAAQ,QAAQ,CAAC,CAAC,KAAK,QAAQ;EAGhD,OAAO,SAAS,QAAQ;CAC1B;;CAGA,MAAM,aAA4B;EAChC,MAAM,KAAK,UAAU,WAAW;CAClC;AACF"}
1
+ {"version":3,"file":"iti.mjs","names":[],"sources":["../../src/adapters/iti.ts"],"sourcesContent":["import { createContainer } from 'iti'\n\nimport {\n DuplicateServiceError,\n ServiceTagCollisionError,\n type LayerBackend,\n type LayerRegistration\n} from '../layer'\n\nimport { ServiceNotFoundError, type AnyServiceToken } from '../service'\n\nimport { assertServiceCompatibility } from '../layer/internal-identity'\nimport { isPromiseLike } from '../utils/runtime'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\n/**\n * ITI-backed Layer backend.\n *\n * Install `iti` as the optional peer dependency and pass an instance to\n * `Runtime.make` when using ITI's container implementation.\n */\nexport class ItiLayerBackend implements LayerBackend {\n private container: any = createContainer()\n\n private readonly keys = new Map<string, string>()\n\n private readonly registered = new Map<string, AnyServiceToken>()\n\n private keyFor(token: AnyServiceToken): string {\n const tag = token.serviceTag\n const existing = this.keys.get(tag)\n\n if (existing) {\n return existing\n }\n\n const key = `better-effect:${tag}`\n\n this.keys.set(tag, key)\n\n return key\n }\n\n /** Register a Layer provider under its deterministic Service-tag key. */\n register(registration: LayerRegistration): void {\n const token = registration.service\n const tag = token.serviceTag\n const existing = this.registered.get(tag)\n\n if (existing === token) {\n throw new DuplicateServiceError(token)\n }\n\n if (existing) {\n throw new ServiceTagCollisionError(existing, token)\n }\n\n const key = this.keyFor(token)\n\n this.container = this.container.add({\n [key]: registration.acquire\n })\n\n this.registered.set(tag, token)\n }\n\n /** Resolve a registered Service through the ITI container. */\n resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>> {\n const registered = this.registered.get(token.serviceTag)\n\n if (registered === undefined) {\n throw new ServiceNotFoundError(token)\n }\n\n const key = this.keyFor(token)\n const resolved = this.container.get(key)\n\n const validate = (instance: LayerAcquiredValue): InstanceType<T> => {\n assertServiceCompatibility(token, registered, instance)\n\n // SAFETY: The registered tag and compatibility check establish the constructor-to-instance relationship after ITI erases it.\n return instance as InstanceType<T>\n }\n\n if (isPromiseLike(resolved)) {\n return Promise.resolve(resolved).then(validate)\n }\n\n return validate(resolved)\n }\n\n /** Dispose all ITI-managed provider instances. */\n async disposeAll(): Promise<void> {\n await this.container.disposeAll()\n }\n}\n"],"mappings":";;;;;;;;;;AAsBA,IAAa,kBAAb,MAAqD;CACnD,YAAyB,gBAAgB;CAEzC,uBAAwB,IAAI,IAAoB;CAEhD,6BAA8B,IAAI,IAA6B;CAE/D,OAAe,OAAgC;EAC7C,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,KAAK,IAAI,GAAG;EAElC,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,iBAAiB;EAE7B,KAAK,KAAK,IAAI,KAAK,GAAG;EAEtB,OAAO;CACT;;CAGA,SAAS,cAAuC;EAC9C,MAAM,QAAQ,aAAa;EAC3B,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,WAAW,IAAI,GAAG;EAExC,IAAI,aAAa,OACf,MAAM,IAAI,sBAAsB,KAAK;EAGvC,IAAI,UACF,MAAM,IAAI,yBAAyB,UAAU,KAAK;EAGpD,MAAM,MAAM,KAAK,OAAO,KAAK;EAE7B,KAAK,YAAY,KAAK,UAAU,IAAI,GACjC,MAAM,aAAa,QACtB,CAAC;EAED,KAAK,WAAW,IAAI,KAAK,KAAK;CAChC;;CAGA,QAAmC,OAA0D;EAC3F,MAAM,aAAa,KAAK,WAAW,IAAI,MAAM,UAAU;EAEvD,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,MAAM,KAAK,OAAO,KAAK;EAC7B,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,MAAM,YAAY,aAAkD;GAClE,2BAA2B,OAAO,YAAY,QAAQ;GAGtD,OAAO;EACT;EAEA,IAAI,cAAc,QAAQ,GACxB,OAAO,QAAQ,QAAQ,QAAQ,CAAC,CAAC,KAAK,QAAQ;EAGhD,OAAO,SAAS,QAAQ;CAC1B;;CAGA,MAAM,aAA4B;EAChC,MAAM,KAAK,UAAU,WAAW;CAClC;AACF"}
@@ -1,184 +1,4 @@
1
- import { Err, InferErr, InferOk, Result } from "better-result";
2
- //#region src/service/types.d.ts
3
- /** Internal type-only identity for the branded Service instance. */
4
- declare const ServiceIdentityTypeId: unique symbol;
5
- /** A branded Service instance identity carried by the literal Service tag. */
6
- interface ServiceIdentity<out Tag extends string = string> {
7
- readonly [ServiceIdentityTypeId]: Tag;
8
- }
9
- /** The widened Service instance constraint used by contextual APIs. */
10
- type AnyService = ServiceIdentity<string>;
11
- /** Remove the internal Service identity marker from an implementation contract. */
12
- type ServiceContract<S> = S extends unknown ? Omit<S, typeof ServiceIdentityTypeId> : never;
13
- type ServiceStatics<out Tag extends string, in out Instance extends AnyService> = {
14
- readonly name: string;
15
- readonly serviceTag: Tag;
16
- /** Type-check a structural implementation and return it unchanged. */
17
- readonly of: (this: void, implementation: ServiceContract<Instance>) => Instance;
18
- };
19
- type AbstractServiceConstructor<out Instance> = abstract new (...args: any[]) => Instance;
20
- /** A class constructor carrying a Service tag and its instance contract. */
21
- interface ServiceToken<out Tag extends string = string, in out Instance extends AnyService = any> extends AbstractServiceConstructor<Instance>, ServiceStatics<Tag, Instance> {}
22
- /** The widened token constraint used by generic Service infrastructure. */
23
- type AnyServiceToken = ServiceToken<string, any>;
24
- /** A concrete, constructible Service class accepted by a Layer provider. */
25
- type ServiceClass<Tag extends string = string, Instance extends AnyService = AnyService> = (new (...args: any[]) => Instance) & ServiceStatics<Tag, Instance>;
26
- /** Extract the instance type represented by a Service token. */
27
- type ServiceInstance<T extends AnyServiceToken> = InstanceType<T>;
28
- /** Extract the literal identity tag represented by a branded Service instance. */
29
- type ServiceTagOf<S extends AnyService> = S[typeof ServiceIdentityTypeId];
30
- /** Extract the Service token represented by a branded Service instance. */
31
- type ServiceTokenOf<S extends AnyService> = S extends AnyService ? ServiceToken<ServiceTagOf<S>, S> : never;
32
- /** Extract the literal identity tag represented by a Service instance or token. */
33
- type ServiceTag<T extends AnyService | AnyServiceToken> = T extends AnyService ? ServiceTagOf<T> : T extends AnyServiceToken ? T['serviceTag'] : never;
34
- type MethodRequirements<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => infer Return) ? EffectRequirements<Return> : never; }[keyof T];
35
- /**
36
- * Services required by the Effect-returning methods of a Service class.
37
- *
38
- * This type is used automatically by `Layer.make`, `Layer.gen`, and the other
39
- * provider constructors.
40
- */
41
- type ServiceRequirements<S extends AnyService> = MethodRequirements<S>;
42
- //#endregion
43
- //#region src/effect/types.d.ts
44
- /**
45
- * Type-only identity for a Service requirement yielded by a generator.
46
- *
47
- * The declaration has no runtime value. Service iterators return their
48
- * resolved instances without yielding a marker at runtime.
49
- */
50
- declare const ServiceRequirementTypeId: unique symbol;
51
- /** Type-only identity for requirement metadata attached to Effect results. */
52
- declare const EffectRequirementsTypeId: unique symbol;
53
- /**
54
- * Metadata carried by the yield type of a Service token.
55
- *
56
- * This interface is intentionally phantom: it is used only while TypeScript
57
- * infers a generator's yielded values.
58
- */
59
- interface ServiceRequirement<out T> {
60
- readonly [ServiceRequirementTypeId]: T;
61
- }
62
- /** A `better-result` Result with phantom metadata for required Services. */
63
- type Effect<A, E, R extends AnyService = never> = Result<A, E> & {
64
- readonly [EffectRequirementsTypeId]?: R;
65
- };
66
- /** An Effect with erased success, error, and Service requirements. */
67
- type AnyEffect = Effect<unknown, unknown, AnyService>;
68
- /** Values that an Effect generator may yield. */
69
- type EffectYield = Err<never, unknown> | ServiceRequirement<unknown>;
70
- /** Extract the error channel from Result values yielded by a generator. */
71
- type InferYieldError<Y> = Y extends Err<never, infer E> ? E : never;
72
- /** Extract branded Service instances carried by yielded Service requirements. */
73
- type InferYieldRequirements<Y> = Y extends ServiceRequirement<infer Requirement> ? Requirement extends AnyService ? Requirement : never : never;
74
- type InferEffectRequirements<T> = T extends unknown ? typeof EffectRequirementsTypeId extends keyof T ? T extends {
75
- readonly [EffectRequirementsTypeId]?: infer Requirements extends AnyService;
76
- } ? Requirements : never : never : never;
77
- /** Extract phantom Service requirements from an Effect or Promise. */
78
- type EffectRequirements<T> = InferEffectRequirements<Awaited<T>>;
79
- /** Extract the success value from an Effect or Promise. */
80
- type EffectSuccess<T> = Awaited<T> extends Result<infer A, unknown> ? A : never;
81
- /** Extract the error value from an Effect or Promise. */
82
- type EffectError<T> = Awaited<T> extends Result<unknown, infer E> ? E : never;
83
- /** Build the public Effect type produced from a generator. */
84
- type EffectFromGenerator<Yield, Returned extends Result<any, any>> = Effect<InferOk<Returned>, InferYieldError<Yield> | InferErr<Returned>, InferYieldRequirements<Yield> | EffectRequirements<Returned>>;
85
- //#endregion
86
- //#region src/service/service.d.ts
87
- type ServiceTagLiteral<Tag extends string> = string extends Tag ? never : Tag extends '' ? never : Tag;
88
- interface ServiceFactory<Self> {
89
- <const Tag extends string>(tag: ServiceTagLiteral<Tag>): (abstract new () => ServiceIdentity<Tag>) & {
90
- readonly name: string;
91
- readonly serviceTag: Tag;
92
- } & {
93
- readonly of: Service.FactoryOf<Self, Tag>;
94
- readonly [Symbol.asyncIterator]: (this: ServiceToken<Tag, Self & ServiceIdentity<Tag>>) => AsyncGenerator<ServiceRequirement<Self>, Self, unknown>;
95
- };
96
- }
97
- /**
98
- * Declare a class-backed Service with a stable string-literal identity.
99
- *
100
- * The returned class is simultaneously the implementation type, the runtime
101
- * dependency token, and the value yielded by `yield*` in an Effect generator.
102
- * The explicit self type preserves exact instance inference, while the second
103
- * call captures the tag as a literal for Layer composition and diagnostics.
104
- *
105
- * @example
106
- * ```ts
107
- * class Database extends Service<Database>()('Database') {
108
- * query(): string {
109
- * return 'ok'
110
- * }
111
- * }
112
- *
113
- * const database = yield* Database
114
- * database.query()
115
- * ```
116
- *
117
- * @typeParam Self The instance type implemented by the declared Service.
118
- */
119
- declare function Service<Self>(): ServiceFactory<Self>;
120
- /** Type-level aliases for Service tokens and their instance contracts. */
121
- declare namespace Service {
122
- /** The widened Service instance constraint. */
123
- type Any = AnyService;
124
- /** A class-backed Service token with a stable tag and instance contract. */
125
- type Token<Tag extends string = string, Instance extends AnyService = any> = ServiceToken<Tag, Instance>;
126
- /** A constructible Service class with a stable tag and instance contract. */
127
- type Class<Tag extends string = string, Instance extends AnyService = AnyService> = ServiceClass<Tag, Instance>;
128
- /** Extract the instance represented by a Service token. */
129
- type Instance<T extends AnyServiceToken> = ServiceInstance<T>;
130
- /** Extract the stable tag represented by a Service instance. */
131
- type Tag<S extends AnyService> = ServiceTag<S>;
132
- /** A branded Service instance identity with a stable tag. */
133
- type Identity<Tag extends string = string> = ServiceIdentity<Tag>;
134
- /** Remove the internal identity marker from a Service implementation contract. */
135
- type Contract<S extends AnyService> = ServiceContract<S>;
136
- /** Extract the Service token represented by a branded Service instance. */
137
- type TokenOf<S extends AnyService> = ServiceTokenOf<S>;
138
- /** Declaration bridge for the recursive structural `Service.of` signature. */
139
- type FactoryOf<Self, Tag extends string> = (this: void, implementation: ServiceContract<Self & ServiceIdentity<Tag>>) => Self;
140
- /** Extract Effect Service requirements from a Service instance. */
141
- type Requirements<S extends AnyService> = ServiceRequirements<S>;
142
- }
143
- //#endregion
144
- //#region src/service/runtime.d.ts
145
- /** Resolves class-backed Service tokens for a runtime execution. */
146
- interface ServiceResolver {
147
- /** Resolve a token to its corresponding Service instance. */
148
- resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>>;
149
- }
150
- /** Provides the resolver context used by Service tokens during execution. */
151
- declare class ServiceRuntime {
152
- /**
153
- * Run a callback with a resolver available to `yield* Service` expressions.
154
- *
155
- * The context is scoped to the callback and is restored afterward.
156
- *
157
- * @example
158
- * ```ts
159
- * const value = ServiceRuntime.run(resolver, () => {
160
- * return ServiceRuntime.resolve(Database)
161
- * })
162
- * ```
163
- */
164
- static run<A>(resolver: ServiceResolver, program: () => A): A;
165
- /** Return the resolver active in the current execution context. */
166
- static current(): ServiceResolver;
167
- /** Resolve a Service token using the active resolver. */
168
- static resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>>;
169
- }
170
- //#endregion
171
- //#region src/service/errors.d.ts
172
- /** Thrown when a Service is accessed without an active runtime resolver. */
173
- declare class ServiceRuntimeNotConfiguredError extends Error {
174
- constructor();
175
- }
176
- /** Thrown when a runtime has no provider for the requested Service tag. */
177
- declare class ServiceNotFoundError extends Error {
178
- readonly service: AnyServiceToken;
179
- constructor(service: AnyServiceToken);
180
- }
181
- //#endregion
1
+ import { A as ServiceRequirements, C as ServiceRequirement, D as ServiceContract, E as ServiceClass, M as ServiceTagOf, N as ServiceToken, P as ServiceTokenOf, T as AnyServiceToken, a as LayerRegistration, i as LayerGeneratorRequirements, n as LayerBackend, o as MaybePromise$1, r as LayerGenerator, v as EffectRequirements, w as AnyService } from "./map-layer-backend-7hQkf_QP.mjs";
182
2
  //#region src/scope/errors.d.ts
183
3
  /** Thrown when Scope context is accessed outside an active Scope execution. */
184
4
  declare class ScopeRuntimeNotConfiguredError extends Error {
@@ -200,7 +20,7 @@ declare class ResourceNotDisposableError extends Error {
200
20
  //#endregion
201
21
  //#region src/scope/types.d.ts
202
22
  /** A value that may be returned synchronously or asynchronously. */
203
- type MaybePromise$1<T> = T | PromiseLike<T>;
23
+ type MaybePromise<T> = T | PromiseLike<T>;
204
24
  /** Final outcome supplied to Scope finalizers and resource releases. */
205
25
  type ScopeOutcome = {
206
26
  /** Indicates that the owning program completed successfully. */
@@ -212,7 +32,7 @@ type ScopeOutcome = {
212
32
  readonly cause: unknown;
213
33
  };
214
34
  /** Cleanup callback registered with a Scope. */
215
- type ScopeFinalizer = (outcome: ScopeOutcome) => MaybePromise$1<void>;
35
+ type ScopeFinalizer = (outcome: ScopeOutcome) => MaybePromise<void>;
216
36
  /** Aggregated cleanup information reported at an execution boundary. */
217
37
  type CleanupFailureDiagnostic = {
218
38
  /** Outcome used for the Scope close that triggered cleanup. */
@@ -222,11 +42,11 @@ type CleanupFailureDiagnostic = {
222
42
  };
223
43
  type SyncDisposableResource = {
224
44
  [Symbol.dispose]: () => void;
225
- [Symbol.asyncDispose]?: () => MaybePromise$1<void>;
45
+ [Symbol.asyncDispose]?: () => MaybePromise<void>;
226
46
  };
227
47
  type AsyncDisposableResource = {
228
48
  [Symbol.dispose]?: () => void;
229
- [Symbol.asyncDispose]: () => MaybePromise$1<void>;
49
+ [Symbol.asyncDispose]: () => MaybePromise<void>;
230
50
  };
231
51
  /** A value implementing at least one JavaScript disposal protocol. */
232
52
  type DisposableResource = SyncDisposableResource | AsyncDisposableResource;
@@ -237,9 +57,6 @@ type Covariant<A> = () => A;
237
57
  /** Type-level marker that both consumes and produces `A`. */
238
58
  type Invariant<A> = (value: A) => A;
239
59
  //#endregion
240
- //#region src/utils/types.d.ts
241
- type MaybePromise<T> = T | PromiseLike<T>;
242
- //#endregion
243
60
  //#region src/internal/missing-dependencies.d.ts
244
61
  declare const MissingDependenciesTypeId: unique symbol;
245
62
  type MissingDependencies<Missing extends AnyService> = {
@@ -363,19 +180,6 @@ type CompleteExecutionWithRequirements<Provided extends AnyService, A, Required
363
180
  /** Keep execution callbacks unchanged when their Effect requirements are met. */
364
181
  type CompleteExecution<Provided extends AnyService, A> = CompleteExecutionWithRequirements<Provided, A, EffectRequirements<A>>;
365
182
  //#endregion
366
- //#region src/layer/types.d.ts
367
- /** Runtime-facing provider registration supplied by a Layer backend. */
368
- interface LayerRegistration {
369
- /** The class-backed Service token provided by this registration. */
370
- readonly service: ServiceClass<any, any>;
371
- /** Lazily acquire the Service instance; concrete types are erased at this backend boundary. */
372
- readonly acquire: () => MaybePromise<unknown>;
373
- }
374
- /** Generator shape used by `Layer.gen` and `Layer.scopedGen`. */
375
- type LayerGenerator<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown> = ServiceRequirement<unknown>> = () => AsyncGenerator<Yield, ServiceContract<InstanceType<S>>, unknown>;
376
- /** Service requirements inferred from a provider's methods and generator. */
377
- type LayerGeneratorRequirements<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>> = ServiceRequirements<InstanceType<S>> | InferYieldRequirements<Yield>;
378
- //#endregion
379
183
  //#region src/layer/layer.d.ts
380
184
  declare const LayerTypeId: unique symbol;
381
185
  interface LayerVariance<in out Provided, out Required> {
@@ -384,7 +188,7 @@ interface LayerVariance<in out Provided, out Required> {
384
188
  }
385
189
  interface LayerProvider extends LayerRegistration {
386
190
  /** Provider storage deliberately erases the concrete instance type. */
387
- readonly release?: (instance: unknown, outcome: ScopeOutcome) => MaybePromise<void>;
191
+ readonly release?: (instance: unknown, outcome: ScopeOutcome) => MaybePromise$1<void>;
388
192
  }
389
193
  /** A Service class whose constructor can be called without arguments. */
390
194
  type DefaultConstructibleServiceClass<Tag extends string = string, Instance extends AnyService = AnyService> = ServiceClass<Tag, Instance> & (new () => Instance);
@@ -412,13 +216,13 @@ declare class Layer<in out Provided extends AnyService = AnyService, out Require
412
216
  private constructor();
413
217
  /** Create a Layer that lazily acquires a Service instance. */
414
218
  static make<S extends DefaultConstructibleServiceClass<any, any>>(service: S): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
415
- static make<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
219
+ static make<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise$1<ServiceContract<InstanceType<S>>>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
416
220
  /** Create a Layer from an already-constructed Service instance. */
417
221
  static succeed<S extends ServiceClass<any, any>>(service: S, instance: ServiceContract<InstanceType<S>>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
418
222
  /** Define a provider with Runtime-root cleanup. */
419
- static scoped<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>, release: (instance: InstanceType<S>) => MaybePromise<void>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
223
+ static scoped<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise$1<ServiceContract<InstanceType<S>>>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise$1<void>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
420
224
  /** Define a provider whose acquisition can yield contextual Services. */
421
- static scopedGen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise<void>): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>;
225
+ static scopedGen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise$1<void>): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>;
422
226
  /** Define a provider whose acquisition can yield contextual Services. */
423
227
  static gen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>;
424
228
  /** Compose Layers without replacing providers. */
@@ -480,21 +284,14 @@ type RuntimeShutdownDiagnostic = {
480
284
  readonly error: LayerDisposeError;
481
285
  };
482
286
  /** Observer notified about cleanup failures without changing primary results. */
483
- type CleanupFailureObserver = (diagnostic: CleanupFailureDiagnostic | RuntimeShutdownDiagnostic) => MaybePromise$1<void>;
287
+ type CleanupFailureObserver = (diagnostic: CleanupFailureDiagnostic | RuntimeShutdownDiagnostic) => MaybePromise<void>;
484
288
  /** Optional Runtime configuration for cleanup diagnostics. */
485
289
  type RuntimeOptions = {
290
+ /** Backend used to register and resolve the Layer. Defaults to MapLayerBackend. */
291
+ readonly backend?: LayerBackend;
486
292
  /** Optional observer for best-effort cleanup diagnostics. */
487
293
  readonly onCleanupFailure?: CleanupFailureObserver;
488
294
  };
489
295
  //#endregion
490
- //#region src/layer/backend.d.ts
491
- /** Runtime adapter responsible for registering, resolving, and disposing Layer providers. */
492
- interface LayerBackend extends ServiceResolver {
493
- /** Register one Service provider with the backend. */
494
- register(registration: LayerRegistration): MaybePromise<void>;
495
- /** Dispose all backend-owned instances and provider registrations. */
496
- disposeAll(): MaybePromise<void>;
497
- }
498
- //#endregion
499
- export { AnyEffect as A, ServiceClass as B, ScopeClosedError as C, ServiceResolver as D, ServiceRuntimeNotConfiguredError as E, EffectSuccess as F, ServiceTag as G, ServiceIdentity as H, EffectYield as I, ServiceToken as K, ServiceRequirement as L, EffectError as M, EffectFromGenerator as N, ServiceRuntime as O, EffectRequirements as P, AnyService as R, ScopeCloseError as S, ServiceNotFoundError as T, ServiceInstance as U, ServiceContract as V, ServiceRequirements as W, DisposableResource as _, DuplicateServiceError as a, ScopeOutcome as b, LayerRegistrationError as c, LayerRegistration as d, CompleteExecution as f, CleanupFailureDiagnostic as g, ProvidedEnvironment as h, RuntimeShutdownDiagnostic as i, Effect as j, Service as k, ServiceTagCollisionError as l, LayerInput as m, CleanupFailureObserver as n, LayerDisposeError as o, CompleteInput as p, ServiceTokenOf as q, RuntimeOptions as r, LayerGeneratorYieldError as s, LayerBackend as t, Layer as u, MaybePromise$1 as v, ScopeRuntimeNotConfiguredError as w, ResourceNotDisposableError as x, ScopeFinalizer as y, AnyServiceToken as z };
500
- //# sourceMappingURL=index-DMfjhNR_.d.mts.map
296
+ export { ScopeRuntimeNotConfiguredError as S, ScopeFinalizer as _, LayerDisposeError as a, ScopeCloseError as b, ServiceTagCollisionError as c, CompleteInput as d, LayerInput as f, MaybePromise as g, DisposableResource as h, DuplicateServiceError as i, Layer as l, CleanupFailureDiagnostic as m, RuntimeOptions as n, LayerGeneratorYieldError as o, ProvidedEnvironment as p, RuntimeShutdownDiagnostic as r, LayerRegistrationError as s, CleanupFailureObserver as t, CompleteExecution as u, ScopeOutcome as v, ScopeClosedError as x, ResourceNotDisposableError as y };
297
+ //# sourceMappingURL=index-R3FdVmdr.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-R3FdVmdr.d.mts","names":[],"sources":["../src/scope/errors.ts","../src/scope/types.ts","../src/internal/variance.ts","../src/internal/missing-dependencies.ts","../src/layer/metadata.ts","../src/layer/inference.ts","../src/layer/layer.ts","../src/layer/errors.ts","../src/runtime/outcome.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { A as AnyEffect, B as ServiceClass, C as ScopeClosedError, D as ServiceResolver, E as ServiceRuntimeNotConfiguredError, F as EffectSuccess, G as ServiceTag, H as ServiceIdentity, I as EffectYield, K as ServiceToken, L as ServiceRequirement, M as EffectError, N as EffectFromGenerator, O as ServiceRuntime, P as EffectRequirements, R as AnyService, S as ScopeCloseError, T as ServiceNotFoundError, U as ServiceInstance, V as ServiceContract, W as ServiceRequirements, _ as DisposableResource, a as DuplicateServiceError, b as ScopeOutcome, c as LayerRegistrationError, d as LayerRegistration, f as CompleteExecution, g as CleanupFailureDiagnostic, h as ProvidedEnvironment, i as RuntimeShutdownDiagnostic, j as Effect$1, k as Service, l as ServiceTagCollisionError, m as LayerInput, n as CleanupFailureObserver, o as LayerDisposeError, p as CompleteInput, q as ServiceTokenOf, r as RuntimeOptions, s as LayerGeneratorYieldError, t as LayerBackend, u as Layer, v as MaybePromise$1, w as ScopeRuntimeNotConfiguredError, x as ResourceNotDisposableError, y as ScopeFinalizer, z as AnyServiceToken } from "./index-DMfjhNR_.mjs";
1
+ import { A as ServiceRequirements, C as ServiceRequirement, D as ServiceContract, E as ServiceClass, N as ServiceToken, O as ServiceIdentity, P as ServiceTokenOf, S as ProgramFromGenerator, T as AnyServiceToken, _ as EffectFromGenerator, a as LayerRegistration, b as EffectYield, c as ServiceAcquisitionError, d as ServiceResolver, f as ServiceRuntime, g as EffectError, h as Effect$1, j as ServiceTag, k as ServiceInstance, l as ServiceNotFoundError, m as AnyEffect, n as LayerBackend, p as Service, s as CircularDependencyError, t as MapLayerBackend, u as ServiceRuntimeNotConfiguredError, v as EffectRequirements, w as AnyService, x as Program, y as EffectSuccess } from "./map-layer-backend-7hQkf_QP.mjs";
2
+ import { S as ScopeRuntimeNotConfiguredError, _ as ScopeFinalizer, a as LayerDisposeError, b as ScopeCloseError, c as ServiceTagCollisionError, d as CompleteInput, f as LayerInput, g as MaybePromise$1, h as DisposableResource, i as DuplicateServiceError, l as Layer, m as CleanupFailureDiagnostic, n as RuntimeOptions, o as LayerGeneratorYieldError, p as ProvidedEnvironment, r as RuntimeShutdownDiagnostic, s as LayerRegistrationError, t as CleanupFailureObserver, u as CompleteExecution, v as ScopeOutcome, x as ScopeClosedError, y as ResourceNotDisposableError } from "./index-R3FdVmdr.mjs";
2
3
  import { Err, Result, UnhandledException } from "better-result";
3
4
  //#region src/scope/scope.d.ts
4
5
  /**
@@ -61,10 +62,10 @@ declare namespace Scope {
61
62
  }
62
63
  //#endregion
63
64
  //#region src/effect/combinators.d.ts
64
- type EffectInput<A, E, Requirements extends AnyService> = Effect$1<A, E, Requirements> | PromiseLike<Effect$1<A, E, Requirements>>;
65
- type AnyEffectInput = EffectInput<any, any, any>;
66
- type AnyEffectValue = Effect$1<any, any, any>;
67
- type AnyAsyncEffectInput = PromiseLike<AnyEffectValue>;
65
+ type EffectInput<A, E> = Result<A, E> | PromiseLike<Result<A, E>>;
66
+ type AnyEffectInput = EffectInput<any, any>;
67
+ type AnyEffectValue = Result<any, any>;
68
+ type AnyAsyncEffectInput = PromiseLike<Result<any, any>>;
68
69
  type PreserveAsync<Input, Output> = Input extends PromiseLike<unknown> ? Promise<Output> : Output;
69
70
  type MappedResult<Input, B> = Effect$1<B, EffectError<Input>, EffectRequirements<Input>>;
70
71
  type ErrorMappedResult<Input, E2> = Effect$1<EffectSuccess<Input>, E2, EffectRequirements<Input>>;
@@ -72,22 +73,22 @@ type ChainedResult<First, Next> = Effect$1<EffectSuccess<Next>, EffectError<Firs
72
73
  type ChainedOutput<First, Next> = ChainedResult<First, Next>;
73
74
  type AsyncChainedOutput<First, Next> = Promise<ChainedResult<First, Next>>;
74
75
  type MapOperation<A, B> = {
75
- <Input>(effect: Input & EffectInput<A, any, any>): PreserveAsync<Input, MappedResult<Input, B>>;
76
+ <Input>(effect: Input & EffectInput<A, any>): PreserveAsync<Input, MappedResult<Input, B>>;
76
77
  };
77
78
  type MapErrorOperation<E1, E2> = {
78
- <Input>(effect: Input & EffectInput<any, E1, any>): PreserveAsync<Input, ErrorMappedResult<Input, E2>>;
79
+ <Input>(effect: Input & EffectInput<any, E1>): PreserveAsync<Input, ErrorMappedResult<Input, E2>>;
79
80
  };
80
- type AndThenOperation<A, Next> = {
81
- <Input>(effect: Input & Effect$1<A, any, any>): ChainedOutput<Input, Next>;
81
+ type AndThenOperation<Next> = {
82
+ <Input>(effect: Input & AnyEffectValue): ChainedOutput<Input, Next>;
82
83
  };
83
84
  type AndThenAsyncOperation<A, Next> = {
84
- <Input>(effect: Input & EffectInput<A, any, any>): AsyncChainedOutput<Input, Next>;
85
+ <Input>(effect: Input & EffectInput<A, any>): AsyncChainedOutput<Input, Next>;
85
86
  };
86
87
  /**
87
88
  * Map the successful value of a Result or Effect result.
88
89
  *
89
90
  * Supports both data-first and data-last forms and preserves asynchronous
90
- * results and phantom Service requirements.
91
+ * results and declaration-only Service requirements.
91
92
  *
92
93
  * @example
93
94
  * ```ts
@@ -99,7 +100,7 @@ declare function map<A, B>(fn: (value: A) => B): MapOperation<A, B>;
99
100
  declare function map<Input, B>(effect: Input & AnyEffectInput, fn: (value: EffectSuccess<Input>) => B): PreserveAsync<Input, MappedResult<Input, B>>;
100
101
  /**
101
102
  * Map the error value of a Result or Effect result while preserving its
102
- * successful value, asynchronous shape, and Service requirements.
103
+ * successful value, asynchronous shape, and declaration-only Service requirements.
103
104
  *
104
105
  * @example
105
106
  * ```ts
@@ -119,7 +120,7 @@ declare function mapError<Input, E2>(effect: Input & AnyEffectInput, fn: (error:
119
120
  * const user = Effect.andThen(Result.ok('u1'), (id) => repository.find(id))
120
121
  * ```
121
122
  */
122
- declare function andThen<A, Next extends AnyEffectValue>(next: (value: A) => Next): AndThenOperation<A, Next>;
123
+ declare function andThen<A, Next extends AnyEffectValue>(next: (value: A) => Next): AndThenOperation<Next>;
123
124
  declare function andThen<Input, Next extends AnyEffectValue>(effect: Input & AnyEffectValue, next: (value: EffectSuccess<Input>) => Next): ChainedOutput<Input, Next>;
124
125
  /**
125
126
  * Chain an asynchronous Result-producing operation after a successful result.
@@ -137,14 +138,16 @@ declare function andThenAsync<Input, Next extends AnyAsyncEffectInput>(effect: I
137
138
  //#endregion
138
139
  //#region src/effect/effect.d.ts
139
140
  type Effect<A, E, R extends AnyService = never> = Effect$1<A, E, R>;
141
+ type LazyProgram<A, E, R extends AnyService = never> = Program<A, E, R>;
140
142
  type AnyResult = Result<any, any>;
141
143
  /**
142
144
  * Compose `better-result` operations while preserving Service requirements in
143
- * a phantom type channel.
145
+ * a declaration-only type channel.
144
146
  *
145
147
  * A generator may yield Service tokens and Result operations. It must return a
146
148
  * `Result` as its final value; Service yields are resolved by the active
147
149
  * Runtime and do not add runtime values to the Result stream.
150
+ * Use `fn` when generator execution should wait for a Runtime boundary.
148
151
  *
149
152
  * @example
150
153
  * ```ts
@@ -158,6 +161,9 @@ type AnyResult = Result<any, any>;
158
161
  */
159
162
  declare function gen<Yield extends EffectYield, Returned extends AnyResult>(body: () => Generator<Yield, Returned, unknown>): EffectFromGenerator<Yield, Returned>;
160
163
  declare function gen<Yield extends EffectYield, Returned extends AnyResult>(body: () => AsyncGenerator<Yield, Returned, unknown>): Promise<EffectFromGenerator<Yield, Returned>>;
164
+ /** Build a lazy Program without running its generator. */
165
+ declare function fn<Yield extends EffectYield, Returned extends AnyResult>(body: () => Generator<Yield, Returned, unknown>): ProgramFromGenerator<Yield, Returned>;
166
+ declare function fn<Yield extends EffectYield, Returned extends AnyResult>(body: () => AsyncGenerator<Yield, Returned, unknown>): ProgramFromGenerator<Yield, Returned>;
161
167
  /**
162
168
  * Acquire a resource in the current Scope and register its release callback.
163
169
  *
@@ -196,6 +202,8 @@ declare function add<R extends DisposableResource>(resource: R): AsyncGenerator<
196
202
  declare const Effect: {
197
203
  /** Compose a generator-based Effect program. */
198
204
  readonly gen: typeof gen;
205
+ /** Build a lazy Program from a generator. */
206
+ readonly fn: typeof fn;
199
207
  /** Acquire and register a resource in the current Scope. */
200
208
  readonly acquireRelease: typeof acquireRelease;
201
209
  /** Register an already-acquired disposable in the current Scope. */
@@ -211,6 +219,8 @@ declare const Effect: {
211
219
  };
212
220
  /** Type-level aliases for inspecting Effect result channels and requirements. */
213
221
  declare namespace Effect {
222
+ /** A nominal lazy computation that produces an Effect when invoked. */
223
+ type Program<A, E, R extends AnyService = never> = LazyProgram<A, E, R>;
214
224
  /** Extract the success channel from an Effect result or Promise. */
215
225
  type Success<T> = EffectSuccess<T>;
216
226
  /** Extract the error channel from an Effect result or Promise. */
@@ -297,7 +307,7 @@ type RuntimeFor<L extends LayerInput> = Runtime<Layer.Provided<L>>;
297
307
  *
298
308
  * @example
299
309
  * ```ts
300
- * const runtime = await Runtime.make(AppLive, new MemoryLayerBackend())
310
+ * const runtime = await Runtime.make(AppLive)
301
311
  * const result = await runtime.run(loadUser('u1'))
302
312
  * await runtime.dispose()
303
313
  * ```
@@ -312,12 +322,13 @@ declare class Runtime<Provided extends AnyService = any> {
312
322
  *
313
323
  * @example
314
324
  * ```ts
315
- * const runtime = await Runtime.make(AppLive, backend)
325
+ * const runtime = await Runtime.make(AppLive)
316
326
  * const result = await runtime.run(program)
317
327
  * await runtime.dispose()
318
328
  * ```
319
329
  */
320
330
  static make<L extends LayerInput>(layer: L & CompleteInput<L>, backend: LayerBackend, options?: RuntimeOptions): Promise<Runtime<ProvidedEnvironment<L>>>;
331
+ static make<L extends LayerInput>(layer: L & CompleteInput<L>, options?: RuntimeOptions): Promise<Runtime<ProvidedEnvironment<L>>>;
321
332
  /**
322
333
  * Run one program and dispose its Layer resources before resolving.
323
334
  *
@@ -325,6 +336,8 @@ declare class Runtime<Provided extends AnyService = any> {
325
336
  * Runtime should not outlive the operation.
326
337
  */
327
338
  static run<A, L extends LayerInput>(layer: L & CompleteInput<L>, backend: LayerBackend, program: CompleteExecution<ProvidedEnvironment<L>, A>, options?: RuntimeOptions): Promise<Awaited<A>>;
339
+ static run<A, L extends LayerInput>(layer: L & CompleteInput<L>, program: CompleteExecution<ProvidedEnvironment<L>, A>, options?: RuntimeOptions): Promise<Awaited<A>>;
340
+ static run<A, L extends LayerInput>(layer: L & CompleteInput<L>, options: RuntimeOptions, program: CompleteExecution<ProvidedEnvironment<L>, A>): Promise<Awaited<A>>;
328
341
  /** Run one execution in this Runtime's child Scope. */
329
342
  run<A>(program: CompleteExecution<Provided, A>): Promise<Awaited<A>>;
330
343
  private runUnchecked;
@@ -342,5 +355,5 @@ declare namespace Runtime {
342
355
  type ShutdownDiagnostic = RuntimeShutdownDiagnostic;
343
356
  }
344
357
  //#endregion
345
- export { type AcquireUseReleaseOptions, type AnyEffect, type AnyService, type AnyServiceToken, type AsyncResult, type CleanupFailureDiagnostic, type CleanupFailureObserver, type CloseableScope, type DisposableResource, DuplicateServiceError, Effect, type EffectError, type EffectRequirements, type EffectSuccess, type EffectYield, Layer, type LayerBackend, LayerDisposeError, LayerGeneratorYieldError, type LayerRegistration, LayerRegistrationError, type ReleaseFailureObserver, type ReleaseOutcome, Resource, ResourceNotDisposableError, ResourceReleaseFailure, Runtime, type RuntimeFor, type RuntimeOptions, type RuntimeShutdownDiagnostic, Scope, ScopeCloseError, ScopeClosedError, type ScopeFinalizer, type ScopeOutcome, ScopeRuntimeNotConfiguredError, Service, type ServiceClass, type ServiceContract, type ServiceIdentity, type ServiceInstance, ServiceNotFoundError, type ServiceRequirement, type ServiceRequirements, type ServiceResolver, ServiceRuntime, ServiceRuntimeNotConfiguredError, type ServiceTag, ServiceTagCollisionError, type ServiceToken, type ServiceTokenOf, pipe };
358
+ export { type AcquireUseReleaseOptions, type AnyEffect, type AnyService, type AnyServiceToken, type AsyncResult, CircularDependencyError, type CleanupFailureDiagnostic, type CleanupFailureObserver, type CloseableScope, type DisposableResource, DuplicateServiceError, Effect, type EffectError, type EffectRequirements, type EffectSuccess, type EffectYield, Layer, type LayerBackend, LayerDisposeError, LayerGeneratorYieldError, type LayerRegistration, LayerRegistrationError, MapLayerBackend, type Program, type ReleaseFailureObserver, type ReleaseOutcome, Resource, ResourceNotDisposableError, ResourceReleaseFailure, Runtime, type RuntimeFor, type RuntimeOptions, type RuntimeShutdownDiagnostic, Scope, ScopeCloseError, ScopeClosedError, type ScopeFinalizer, type ScopeOutcome, ScopeRuntimeNotConfiguredError, Service, ServiceAcquisitionError, type ServiceClass, type ServiceContract, type ServiceIdentity, type ServiceInstance, ServiceNotFoundError, type ServiceRequirement, type ServiceRequirements, type ServiceResolver, ServiceRuntime, ServiceRuntimeNotConfiguredError, type ServiceTag, ServiceTagCollisionError, type ServiceToken, type ServiceTokenOf, pipe };
346
359
  //# sourceMappingURL=index.d.mts.map