better-effect 0.11.0 → 0.13.0
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 +544 -10
- package/dist/adapters/iti.d.mts +3 -2
- package/dist/adapters/iti.d.mts.map +1 -1
- package/dist/adapters/iti.mjs +11 -10
- package/dist/adapters/iti.mjs.map +1 -1
- package/dist/bun.d.mts +43 -0
- package/dist/bun.d.mts.map +1 -0
- package/dist/bun.mjs +40 -0
- package/dist/bun.mjs.map +1 -0
- package/dist/{context-BUEf1qjL.mjs → context-BphfFUMO.mjs} +4 -2
- package/dist/context-BphfFUMO.mjs.map +1 -0
- package/dist/current-request-CIU7AHhF.d.mts +22 -0
- package/dist/current-request-CIU7AHhF.d.mts.map +1 -0
- package/dist/current-request-DDKNyymv.mjs +20 -0
- package/dist/current-request-DDKNyymv.mjs.map +1 -0
- package/dist/disposable-CP-Q2H3l.mjs +57 -0
- package/dist/disposable-CP-Q2H3l.mjs.map +1 -0
- package/dist/{effect-2ZcGZI8A.mjs → effect-CPdV7Yv8.mjs} +56 -10
- package/dist/effect-CPdV7Yv8.mjs.map +1 -0
- package/dist/hono.d.mts +7 -5
- package/dist/hono.d.mts.map +1 -1
- package/dist/hono.mjs +88 -30
- package/dist/hono.mjs.map +1 -1
- package/dist/{index-heuaRmXR.d.mts → index-AiKM71-u.d.mts} +3 -1
- package/dist/{index-heuaRmXR.d.mts.map → index-AiKM71-u.d.mts.map} +1 -1
- package/dist/index-BodMy6rO.d.mts +180 -0
- package/dist/index-BodMy6rO.d.mts.map +1 -0
- package/dist/{index-C7Qild0_.d.mts → index-CCi07kUw.d.mts} +15 -151
- package/dist/index-CCi07kUw.d.mts.map +1 -0
- package/dist/index-DAKn0qHk.d.mts +19 -0
- package/dist/index-DAKn0qHk.d.mts.map +1 -0
- package/dist/{index-DStz0JMN.d.mts → index-cXgyMa0v.d.mts} +75 -22
- package/dist/index-cXgyMa0v.d.mts.map +1 -0
- package/dist/index.d.mts +7 -4
- package/dist/index.mjs +8 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{internal-identity-DmUpBeeL.mjs → internal-identity-CbXoZIfw.mjs} +3 -3
- package/dist/internal-identity-CbXoZIfw.mjs.map +1 -0
- package/dist/{signal-B97cs85Z.mjs → layer-D16GKxuX.mjs} +31 -112
- package/dist/layer-D16GKxuX.mjs.map +1 -0
- package/dist/next.d.mts +116 -0
- package/dist/next.d.mts.map +1 -0
- package/dist/next.mjs +68 -0
- package/dist/next.mjs.map +1 -0
- package/dist/node-context-Ca18oNSg.mjs +25 -0
- package/dist/node-context-Ca18oNSg.mjs.map +1 -0
- package/dist/node-context-DczjAcrX.d.mts +12 -0
- package/dist/node-context-DczjAcrX.d.mts.map +1 -0
- package/dist/node.d.mts +51 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +233 -0
- package/dist/node.mjs.map +1 -0
- package/dist/observer-9nhbL7Pr.d.mts +68 -0
- package/dist/observer-9nhbL7Pr.d.mts.map +1 -0
- package/dist/opentelemetry.d.mts +94 -0
- package/dist/opentelemetry.d.mts.map +1 -0
- package/dist/opentelemetry.mjs +453 -0
- package/dist/opentelemetry.mjs.map +1 -0
- package/dist/{index-rQhZk3Nt.d.mts → outcome-DI8LPIQ4.d.mts} +27 -72
- package/dist/outcome-DI8LPIQ4.d.mts.map +1 -0
- package/dist/{scope-GGnmTQck.mjs → program-metadata-BxjGkT17.mjs} +19 -4
- package/dist/program-metadata-BxjGkT17.mjs.map +1 -0
- package/dist/registration-drnZk0SY.mjs +182 -0
- package/dist/registration-drnZk0SY.mjs.map +1 -0
- package/dist/runtime/explicit.d.mts +1 -1
- package/dist/runtime/explicit.mjs +1 -1
- package/dist/runtime/node.d.mts +3 -12
- package/dist/runtime/node.mjs +2 -24
- package/dist/{runtime-DnMn0X0X.mjs → runtime-C_55ofnL.mjs} +245 -67
- package/dist/runtime-C_55ofnL.mjs.map +1 -0
- package/dist/signal-nfgFyNCk.mjs +52 -0
- package/dist/signal-nfgFyNCk.mjs.map +1 -0
- package/dist/{standard-services-BFBq-4lo.mjs → standard-services-vnGIafkS.mjs} +200 -30
- package/dist/standard-services-vnGIafkS.mjs.map +1 -0
- package/dist/standard-services.d.mts +4 -3
- package/dist/standard-services.mjs +4 -3
- package/dist/testing.d.mts +67 -7
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.mjs +192 -9
- package/dist/testing.mjs.map +1 -1
- package/dist/types-oihI-ESv.d.mts +54 -0
- package/dist/types-oihI-ESv.d.mts.map +1 -0
- package/dist/web-Bq3MfMrj.mjs +147 -0
- package/dist/web-Bq3MfMrj.mjs.map +1 -0
- package/dist/web.d.mts +47 -0
- package/dist/web.d.mts.map +1 -0
- package/dist/web.mjs +2 -0
- package/package.json +39 -3
- package/dist/context-BUEf1qjL.mjs.map +0 -1
- package/dist/effect-2ZcGZI8A.mjs.map +0 -1
- package/dist/errors-Dnjhzbt0.mjs +0 -99
- package/dist/errors-Dnjhzbt0.mjs.map +0 -1
- package/dist/index-C7Qild0_.d.mts.map +0 -1
- package/dist/index-DStz0JMN.d.mts.map +0 -1
- package/dist/index-rQhZk3Nt.d.mts.map +0 -1
- package/dist/internal-identity-DmUpBeeL.mjs.map +0 -1
- package/dist/runtime/node.d.mts.map +0 -1
- package/dist/runtime/node.mjs.map +0 -1
- package/dist/runtime-DnMn0X0X.mjs.map +0 -1
- package/dist/scope-GGnmTQck.mjs.map +0 -1
- package/dist/signal-B97cs85Z.mjs.map +0 -1
- package/dist/standard-services-BFBq-4lo.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { h as RuntimeContextNotConfiguredError } from "./context-
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
5
|
-
import { i as
|
|
6
|
-
import { n as
|
|
1
|
+
import { a as LayerGeneratorYieldError, c as CircularDependencyError, d as ServiceRuntimeNotConfiguredError, i as LayerDisposeError, l as ServiceAcquisitionError, o as LayerRegistrationError, r as DuplicateServiceError, s as ServiceTagCollisionError, u as ServiceNotFoundError } from "./registration-drnZk0SY.mjs";
|
|
2
|
+
import { h as RuntimeContextNotConfiguredError } from "./context-BphfFUMO.mjs";
|
|
3
|
+
import { a as ScopeClosedError, i as ScopeCloseError, o as ScopeRuntimeNotConfiguredError, r as ResourceNotDisposableError, t as disposeResource } from "./disposable-CP-Q2H3l.mjs";
|
|
4
|
+
import { n as Service, r as ServiceRuntime, t as Layer } from "./layer-D16GKxuX.mjs";
|
|
5
|
+
import { i as Scope } from "./program-metadata-BxjGkT17.mjs";
|
|
6
|
+
import { i as MapLayerBackend, n as RuntimeObserver, t as Runtime } from "./runtime-C_55ofnL.mjs";
|
|
7
|
+
import { n as Program, t as Effect } from "./effect-CPdV7Yv8.mjs";
|
|
8
|
+
import { t as CurrentAbortSignal } from "./signal-nfgFyNCk.mjs";
|
|
7
9
|
import { Result, TaggedError } from "better-result";
|
|
8
10
|
//#region src/function/pipe.ts
|
|
9
11
|
function pipe(value, ...operations) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/function/pipe.ts","../src/resource/errors.ts","../src/resource/internal.ts","../src/resource/resource.ts"],"sourcesContent":["type Unary<A, B> = (value: A) => B\n\n/**\n * Compose a value through a sequence of unary functions.\n *\n * `pipe` is deliberately independent of Effect, Result, Promise, Scope, and\n * Service metadata.\n *\n * @example\n * ```ts\n * const label = pipe(\n * 'alice',\n * (name) => name.trim(),\n * (name) => name.toUpperCase()\n * )\n * ```\n */\ntype PipeRuntimeValue = Parameters<Unary<any, any>>[0]\n\ntype PipeRuntimeOperation = Unary<PipeRuntimeValue, PipeRuntimeValue>\n\nexport function pipe<A>(value: A): A\nexport function pipe<A, B>(value: A, ab: Unary<A, B>): B\nexport function pipe<A, B, C>(value: A, ab: Unary<A, B>, bc: Unary<B, C>): C\nexport function pipe<A, B, C, D>(value: A, ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>): D\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>\n): E\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>\n): F\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>\n): G\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>\n): H\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>\n): I\nexport function pipe<A, B, C, D, E, F, G, H, I, J>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>,\n ij: Unary<I, J>\n): J\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>,\n ij: Unary<I, J>,\n jk: Unary<J, K>\n): K\nexport function pipe(\n value: PipeRuntimeValue,\n ...operations: ReadonlyArray<PipeRuntimeOperation>\n): PipeRuntimeValue {\n return operations.reduce((current, operation) => operation(current), value)\n}\n","import { TaggedError } from 'better-result'\n\n/** Describes a failure encountered while releasing a Resource. */\nexport class ResourceReleaseFailure extends TaggedError('ResourceReleaseFailure')<{\n readonly resource: string\n readonly cause: unknown\n readonly message: string\n}> {}\n","import { Result, type Result as ResultType, type UnhandledException } from 'better-result'\n\nimport { ResourceReleaseFailure } from './errors'\n\nimport { disposeResource } from '../scope/disposable'\n\nexport { disposeResource }\n\nimport type { AsyncResult, MaybePromise, ReleaseFailureObserver, ReleaseOutcome } from './types'\n\nconst toReleaseFailure = (resource: string, cause: unknown): ResourceReleaseFailure =>\n new ResourceReleaseFailure({\n resource,\n cause,\n message: `Failed to release resource: ${resource}`\n })\n\nexport const runResult = async <T, E>(\n operation: () => AsyncResult<T, E>\n): Promise<ResultType<T, E | UnhandledException>> => {\n const execution = await Result.tryPromise(() => Promise.resolve(operation()))\n\n return execution.andThen((result) => result)\n}\n\nconst normalizeReleaseOutcome = (\n name: string,\n outcome: ReleaseOutcome\n): ResultType<void, ResourceReleaseFailure> => {\n if (outcome === undefined) {\n return Result.ok()\n }\n\n return outcome.mapError((cause) => toReleaseFailure(name, cause))\n}\n\nexport const runRelease = async <R>(\n name: string,\n resource: R,\n release: (resource: R) => MaybePromise<ReleaseOutcome>\n): Promise<ResultType<void, ResourceReleaseFailure>> => {\n const execution = await Result.tryPromise({\n try: () => Promise.resolve(release(resource)),\n catch: (cause) => toReleaseFailure(name, cause)\n })\n\n return execution.andThen((outcome) => normalizeReleaseOutcome(name, outcome))\n}\n\nconst notifyReleaseFailure = async (\n observer: ReleaseFailureObserver | undefined,\n\n failure: ResourceReleaseFailure\n): Promise<void> => {\n if (!observer) {\n return\n }\n\n try {\n await observer(failure)\n } catch {\n /*\n * Diagnostics must never replace\n * the actual operation error.\n */\n }\n}\n\nexport const combineUseAndRelease = async <A, E>(\n used: ResultType<A, E>,\n\n released: ResultType<void, ResourceReleaseFailure>,\n\n onReleaseFailure?: ReleaseFailureObserver\n): Promise<ResultType<A, E | ResourceReleaseFailure>> => {\n if (Result.isError(used)) {\n if (Result.isError(released)) {\n await notifyReleaseFailure(onReleaseFailure, released.error)\n }\n\n return Result.err<A, E | ResourceReleaseFailure>(used.error)\n }\n\n if (Result.isError(released)) {\n await notifyReleaseFailure(onReleaseFailure, released.error)\n\n return Result.err<A, E | ResourceReleaseFailure>(released.error)\n }\n\n return Result.ok<A, E | ResourceReleaseFailure>(used.value)\n}\n","import { Result, type Result as ResultType, type UnhandledException } from 'better-result'\n\nimport { Scope } from '../scope'\n\nimport { ResourceReleaseFailure } from './errors'\n\nimport { combineUseAndRelease, disposeResource, runRelease, runResult } from './internal'\n\nimport type { AcquireUseReleaseOptions } from './types'\n\n/**\n * Acquire a resource, use it, and always attempt release afterward.\n *\n * Acquisition, use, and release may be synchronous or asynchronous Result\n * operations. If both use and release fail, the use error remains primary and\n * `onReleaseFailure` receives the cleanup failure as a diagnostic.\n *\n * When `release` is omitted, `Symbol.asyncDispose` is preferred over\n * `Symbol.dispose`.\n *\n * @example\n * ```ts\n * const result = await Resource.acquireUseRelease({\n * name: 'database connection',\n * acquire: () => connect(),\n * use: (connection) => query(connection),\n * release: (connection) => connection.close()\n * })\n * ```\n */\nconst acquireUseRelease = <R, A, AcquireError, UseError>({\n name,\n acquire,\n use,\n release = disposeResource,\n onReleaseFailure\n}: AcquireUseReleaseOptions<R, A, AcquireError, UseError>): Promise<\n ResultType<A, AcquireError | UseError | UnhandledException | ResourceReleaseFailure>\n> =>\n Result.gen(async function* () {\n const resource = yield* Result.await(runResult(acquire))\n\n const scope = Scope.make()\n\n let released: ResultType<void, ResourceReleaseFailure> = Result.ok()\n\n scope.addFinalizer(async () => {\n released = await runRelease(name, resource, release)\n })\n\n const used = await runResult(() => use(resource))\n\n await scope.close()\n\n return await combineUseAndRelease(used, released, onReleaseFailure)\n })\n\nexport const Resource = {\n /** Acquire, use, and release a resource with deterministic error precedence. */\n acquireUseRelease\n} as const\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/function/pipe.ts","../src/resource/errors.ts","../src/resource/internal.ts","../src/resource/resource.ts"],"sourcesContent":["type Unary<A, B> = (value: A) => B\n\n/**\n * Compose a value through a sequence of unary functions.\n *\n * `pipe` is deliberately independent of Effect, Result, Promise, Scope, and\n * Service metadata.\n *\n * @example\n * ```ts\n * const label = pipe(\n * 'alice',\n * (name) => name.trim(),\n * (name) => name.toUpperCase()\n * )\n * ```\n */\ntype PipeRuntimeValue = Parameters<Unary<any, any>>[0]\n\ntype PipeRuntimeOperation = Unary<PipeRuntimeValue, PipeRuntimeValue>\n\nexport function pipe<A>(value: A): A\nexport function pipe<A, B>(value: A, ab: Unary<A, B>): B\nexport function pipe<A, B, C>(value: A, ab: Unary<A, B>, bc: Unary<B, C>): C\nexport function pipe<A, B, C, D>(value: A, ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>): D\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>\n): E\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>\n): F\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>\n): G\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>\n): H\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>\n): I\nexport function pipe<A, B, C, D, E, F, G, H, I, J>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>,\n ij: Unary<I, J>\n): J\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K>(\n value: A,\n ab: Unary<A, B>,\n bc: Unary<B, C>,\n cd: Unary<C, D>,\n de: Unary<D, E>,\n ef: Unary<E, F>,\n fg: Unary<F, G>,\n gh: Unary<G, H>,\n hi: Unary<H, I>,\n ij: Unary<I, J>,\n jk: Unary<J, K>\n): K\nexport function pipe(\n value: PipeRuntimeValue,\n ...operations: ReadonlyArray<PipeRuntimeOperation>\n): PipeRuntimeValue {\n return operations.reduce((current, operation) => operation(current), value)\n}\n","import { TaggedError } from 'better-result'\n\n/** Describes a failure encountered while releasing a Resource. */\nexport class ResourceReleaseFailure extends TaggedError('ResourceReleaseFailure')<{\n readonly resource: string\n readonly cause: unknown\n readonly message: string\n}> {}\n","import { Result, type Result as ResultType, type UnhandledException } from 'better-result'\n\nimport { ResourceReleaseFailure } from './errors'\n\nimport { disposeResource } from '../scope/disposable'\n\nexport { disposeResource }\n\nimport type { AsyncResult, MaybePromise, ReleaseFailureObserver, ReleaseOutcome } from './types'\n\nconst toReleaseFailure = (resource: string, cause: unknown): ResourceReleaseFailure =>\n new ResourceReleaseFailure({\n resource,\n cause,\n message: `Failed to release resource: ${resource}`\n })\n\nexport const runResult = async <T, E>(\n operation: () => AsyncResult<T, E>\n): Promise<ResultType<T, E | UnhandledException>> => {\n const execution = await Result.tryPromise(() => Promise.resolve(operation()))\n\n return execution.andThen((result) => result)\n}\n\nconst normalizeReleaseOutcome = (\n name: string,\n outcome: ReleaseOutcome\n): ResultType<void, ResourceReleaseFailure> => {\n if (outcome === undefined) {\n return Result.ok()\n }\n\n return outcome.mapError((cause) => toReleaseFailure(name, cause))\n}\n\nexport const runRelease = async <R>(\n name: string,\n resource: R,\n release: (resource: R) => MaybePromise<ReleaseOutcome>\n): Promise<ResultType<void, ResourceReleaseFailure>> => {\n const execution = await Result.tryPromise({\n try: () => Promise.resolve(release(resource)),\n catch: (cause) => toReleaseFailure(name, cause)\n })\n\n return execution.andThen((outcome) => normalizeReleaseOutcome(name, outcome))\n}\n\nconst notifyReleaseFailure = async (\n observer: ReleaseFailureObserver | undefined,\n\n failure: ResourceReleaseFailure\n): Promise<void> => {\n if (!observer) {\n return\n }\n\n try {\n await observer(failure)\n } catch {\n /*\n * Diagnostics must never replace\n * the actual operation error.\n */\n }\n}\n\nexport const combineUseAndRelease = async <A, E>(\n used: ResultType<A, E>,\n\n released: ResultType<void, ResourceReleaseFailure>,\n\n onReleaseFailure?: ReleaseFailureObserver\n): Promise<ResultType<A, E | ResourceReleaseFailure>> => {\n if (Result.isError(used)) {\n if (Result.isError(released)) {\n await notifyReleaseFailure(onReleaseFailure, released.error)\n }\n\n return Result.err<A, E | ResourceReleaseFailure>(used.error)\n }\n\n if (Result.isError(released)) {\n await notifyReleaseFailure(onReleaseFailure, released.error)\n\n return Result.err<A, E | ResourceReleaseFailure>(released.error)\n }\n\n return Result.ok<A, E | ResourceReleaseFailure>(used.value)\n}\n","import { Result, type Result as ResultType, type UnhandledException } from 'better-result'\n\nimport { Scope } from '../scope'\n\nimport { ResourceReleaseFailure } from './errors'\n\nimport { combineUseAndRelease, disposeResource, runRelease, runResult } from './internal'\n\nimport type { AcquireUseReleaseOptions } from './types'\n\n/**\n * Acquire a resource, use it, and always attempt release afterward.\n *\n * Acquisition, use, and release may be synchronous or asynchronous Result\n * operations. If both use and release fail, the use error remains primary and\n * `onReleaseFailure` receives the cleanup failure as a diagnostic.\n *\n * When `release` is omitted, `Symbol.asyncDispose` is preferred over\n * `Symbol.dispose`.\n *\n * @example\n * ```ts\n * const result = await Resource.acquireUseRelease({\n * name: 'database connection',\n * acquire: () => connect(),\n * use: (connection) => query(connection),\n * release: (connection) => connection.close()\n * })\n * ```\n */\nconst acquireUseRelease = <R, A, AcquireError, UseError>({\n name,\n acquire,\n use,\n release = disposeResource,\n onReleaseFailure\n}: AcquireUseReleaseOptions<R, A, AcquireError, UseError>): Promise<\n ResultType<A, AcquireError | UseError | UnhandledException | ResourceReleaseFailure>\n> =>\n Result.gen(async function* () {\n const resource = yield* Result.await(runResult(acquire))\n\n const scope = Scope.make()\n\n let released: ResultType<void, ResourceReleaseFailure> = Result.ok()\n\n scope.addFinalizer(async () => {\n released = await runRelease(name, resource, release)\n })\n\n const used = await runResult(() => use(resource))\n\n await scope.close()\n\n return await combineUseAndRelease(used, released, onReleaseFailure)\n })\n\nexport const Resource = {\n /** Acquire, use, and release a resource with deterministic error precedence. */\n acquireUseRelease\n} as const\n"],"mappings":";;;;;;;;;;AA+FA,SAAgB,KACd,OACA,GAAG,YACe;CAClB,OAAO,WAAW,QAAQ,SAAS,cAAc,UAAU,OAAO,GAAG,KAAK;AAC5E;;;;ACjGA,IAAa,yBAAb,cAA4C,YAAY,wBAAwB,CAAC,CAI9E,CAAC;;;ACGJ,MAAM,oBAAoB,UAAkB,UAC1C,IAAI,uBAAuB;CACzB;CACA;CACA,SAAS,+BAA+B;AAC1C,CAAC;AAEH,MAAa,YAAY,OACvB,cACmD;CAGnD,QAAO,MAFiB,OAAO,iBAAiB,QAAQ,QAAQ,UAAU,CAAC,CAAC,EAAA,CAE3D,SAAS,WAAW,MAAM;AAC7C;AAEA,MAAM,2BACJ,MACA,YAC6C;CAC7C,IAAI,YAAY,KAAA,GACd,OAAO,OAAO,GAAG;CAGnB,OAAO,QAAQ,UAAU,UAAU,iBAAiB,MAAM,KAAK,CAAC;AAClE;AAEA,MAAa,aAAa,OACxB,MACA,UACA,YACsD;CAMtD,QAAO,MALiB,OAAO,WAAW;EACxC,WAAW,QAAQ,QAAQ,QAAQ,QAAQ,CAAC;EAC5C,QAAQ,UAAU,iBAAiB,MAAM,KAAK;CAChD,CAAC,EAAA,CAEgB,SAAS,YAAY,wBAAwB,MAAM,OAAO,CAAC;AAC9E;AAEA,MAAM,uBAAuB,OAC3B,UAEA,YACkB;CAClB,IAAI,CAAC,UACH;CAGF,IAAI;EACF,MAAM,SAAS,OAAO;CACxB,QAAQ,CAKR;AACF;AAEA,MAAa,uBAAuB,OAClC,MAEA,UAEA,qBACuD;CACvD,IAAI,OAAO,QAAQ,IAAI,GAAG;EACxB,IAAI,OAAO,QAAQ,QAAQ,GACzB,MAAM,qBAAqB,kBAAkB,SAAS,KAAK;EAG7D,OAAO,OAAO,IAAmC,KAAK,KAAK;CAC7D;CAEA,IAAI,OAAO,QAAQ,QAAQ,GAAG;EAC5B,MAAM,qBAAqB,kBAAkB,SAAS,KAAK;EAE3D,OAAO,OAAO,IAAmC,SAAS,KAAK;CACjE;CAEA,OAAO,OAAO,GAAkC,KAAK,KAAK;AAC5D;;;;;;;;;;;;;;;;;;;;;;;AC5DA,MAAM,qBAAmD,EACvD,MACA,SACA,KACA,UAAU,iBACV,uBAIA,OAAO,IAAI,mBAAmB;CAC5B,MAAM,WAAW,OAAO,OAAO,MAAM,UAAU,OAAO,CAAC;CAEvD,MAAM,QAAQ,MAAM,KAAK;CAEzB,IAAI,WAAqD,OAAO,GAAG;CAEnE,MAAM,aAAa,YAAY;EAC7B,WAAW,MAAM,WAAW,MAAM,UAAU,OAAO;CACrD,CAAC;CAED,MAAM,OAAO,MAAM,gBAAgB,IAAI,QAAQ,CAAC;CAEhD,MAAM,MAAM,MAAM;CAElB,OAAO,MAAM,qBAAqB,MAAM,UAAU,gBAAgB;AACpE,CAAC;AAEH,MAAa,WAAW;;AAEtB,kBACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as captureServiceTag, s as ServiceTagCollisionError } from "./registration-drnZk0SY.mjs";
|
|
2
2
|
//#region src/layer/internal-identity.ts
|
|
3
3
|
const serviceMemberNames = (token) => {
|
|
4
4
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -16,7 +16,7 @@ const serviceMemberNames = (token) => {
|
|
|
16
16
|
* check catches the common incompatible-method collision after erasure.
|
|
17
17
|
*/
|
|
18
18
|
const assertServiceCompatibility = (requested, registered, instance) => {
|
|
19
|
-
if (requested === registered || requested
|
|
19
|
+
if (requested === registered || captureServiceTag(requested) !== captureServiceTag(registered)) return;
|
|
20
20
|
const candidate = Object(instance);
|
|
21
21
|
if (candidate !== instance) throw new ServiceTagCollisionError(registered, requested);
|
|
22
22
|
for (const name of serviceMemberNames(requested)) if (!(name in candidate)) throw new ServiceTagCollisionError(registered, requested);
|
|
@@ -24,4 +24,4 @@ const assertServiceCompatibility = (requested, registered, instance) => {
|
|
|
24
24
|
//#endregion
|
|
25
25
|
export { assertServiceCompatibility as t };
|
|
26
26
|
|
|
27
|
-
//# sourceMappingURL=internal-identity-
|
|
27
|
+
//# sourceMappingURL=internal-identity-CbXoZIfw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-identity-CbXoZIfw.mjs","names":[],"sources":["../src/layer/internal-identity.ts"],"sourcesContent":["import { captureServiceTag } from '../service/tag'\nimport type { AnyServiceToken } from '../service'\n\nimport { ServiceTagCollisionError } from './errors'\n\nimport type { LayerRegistration } from './types'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\nconst serviceMemberNames = (token: AnyServiceToken): readonly (string | symbol)[] => {\n const names = new Set<string | symbol>()\n let prototype = token.prototype\n\n while (prototype && prototype !== Object.prototype) {\n for (const name of Object.getOwnPropertyNames(prototype)) {\n if (name !== 'constructor') {\n names.add(name)\n }\n }\n\n for (const symbol of Object.getOwnPropertySymbols(prototype)) {\n names.add(symbol)\n }\n\n prototype = Object.getPrototypeOf(prototype)\n }\n\n return [...names]\n}\n\n/**\n * Check the runtime portion of a same-tag association before returning it.\n * TypeScript remains authoritative for full structural compatibility; this\n * check catches the common incompatible-method collision after erasure.\n */\nexport const assertServiceCompatibility = (\n requested: AnyServiceToken,\n registered: AnyServiceToken,\n instance: LayerAcquiredValue\n): void => {\n if (requested === registered || captureServiceTag(requested) !== captureServiceTag(registered)) {\n return\n }\n\n const candidate = Object(instance)\n\n // SAFETY: Service providers are object instances; Object() lets this runtime boundary reject rogue primitive values without trusting their static type.\n if (candidate !== instance) {\n throw new ServiceTagCollisionError(registered, requested)\n }\n\n for (const name of serviceMemberNames(requested)) {\n if (!(name in candidate)) {\n throw new ServiceTagCollisionError(registered, requested)\n }\n }\n}\n"],"mappings":";;AASA,MAAM,sBAAsB,UAAyD;CACnF,MAAM,wBAAQ,IAAI,IAAqB;CACvC,IAAI,YAAY,MAAM;CAEtB,OAAO,aAAa,cAAc,OAAO,WAAW;EAClD,KAAK,MAAM,QAAQ,OAAO,oBAAoB,SAAS,GACrD,IAAI,SAAS,eACX,MAAM,IAAI,IAAI;EAIlB,KAAK,MAAM,UAAU,OAAO,sBAAsB,SAAS,GACzD,MAAM,IAAI,MAAM;EAGlB,YAAY,OAAO,eAAe,SAAS;CAC7C;CAEA,OAAO,CAAC,GAAG,KAAK;AAClB;;;;;;AAOA,MAAa,8BACX,WACA,YACA,aACS;CACT,IAAI,cAAc,cAAc,kBAAkB,SAAS,MAAM,kBAAkB,UAAU,GAC3F;CAGF,MAAM,YAAY,OAAO,QAAQ;CAGjC,IAAI,cAAc,UAChB,MAAM,IAAI,yBAAyB,YAAY,SAAS;CAG1D,KAAK,MAAM,QAAQ,mBAAmB,SAAS,GAC7C,IAAI,EAAE,QAAQ,YACZ,MAAM,IAAI,yBAAyB,YAAY,SAAS;AAG9D"}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
//#region src/runtime/default.ts
|
|
5
|
-
/** The Node/Bun storage used by the main Runtime entrypoint. */
|
|
6
|
-
const defaultRuntimeContextStorage = nodeRuntimeContextStorage;
|
|
7
|
-
setDefaultRuntimeContextStorage(defaultRuntimeContextStorage);
|
|
8
|
-
//#endregion
|
|
1
|
+
import { a as LayerGeneratorYieldError, d as ServiceRuntimeNotConfiguredError, f as captureServiceTag, m as validateServiceTag, p as registerServiceTag, r as DuplicateServiceError, s as ServiceTagCollisionError, t as captureLayerRegistrationTag } from "./registration-drnZk0SY.mjs";
|
|
2
|
+
import { h as RuntimeContextNotConfiguredError, i as getRuntimeContext, l as makeRuntimeContext, n as currentRuntimeContext, u as runRuntimeContext } from "./context-BphfFUMO.mjs";
|
|
3
|
+
import { n as getDisposeFinalizer, r as ResourceNotDisposableError, s as defaultRuntimeContextStorage } from "./disposable-CP-Q2H3l.mjs";
|
|
9
4
|
//#region src/service/runtime.ts
|
|
10
5
|
/** Provides the resolver context used by Service tokens during execution. */
|
|
11
6
|
var ServiceRuntime = class ServiceRuntime {
|
|
@@ -23,7 +18,7 @@ var ServiceRuntime = class ServiceRuntime {
|
|
|
23
18
|
*/
|
|
24
19
|
static run(resolver, program, storage = defaultRuntimeContextStorage) {
|
|
25
20
|
const current = getRuntimeContext(storage);
|
|
26
|
-
const context = makeRuntimeContext(resolver, current?.scope, current?.resolver === resolver ? current.resolutionPath : [], current?.signal, current?.resolver === resolver ? current : void 0);
|
|
21
|
+
const context = makeRuntimeContext(resolver, current?.scope, current?.resolver === resolver ? current.resolutionPath : [], current?.signal, current?.resolver === resolver ? current : void 0, current?.executionId);
|
|
27
22
|
return runRuntimeContext(storage, context, program);
|
|
28
23
|
}
|
|
29
24
|
/** Return the resolver active in the current execution context. */
|
|
@@ -40,6 +35,7 @@ var ServiceRuntime = class ServiceRuntime {
|
|
|
40
35
|
}
|
|
41
36
|
/** Resolve a Service token using the active resolver. */
|
|
42
37
|
static async resolve(token) {
|
|
38
|
+
captureServiceTag(token);
|
|
43
39
|
return await ServiceRuntime.current().resolve(token);
|
|
44
40
|
}
|
|
45
41
|
};
|
|
@@ -69,7 +65,7 @@ var ServiceRuntime = class ServiceRuntime {
|
|
|
69
65
|
*/
|
|
70
66
|
function Service() {
|
|
71
67
|
return function(tag) {
|
|
72
|
-
|
|
68
|
+
validateServiceTag(tag);
|
|
73
69
|
class BaseService {
|
|
74
70
|
/** The stable logical identity used by Layers and resolver backends. */
|
|
75
71
|
static serviceTag = tag;
|
|
@@ -104,57 +100,11 @@ function Service() {
|
|
|
104
100
|
return await ServiceRuntime.resolve(this);
|
|
105
101
|
}
|
|
106
102
|
}
|
|
103
|
+
registerServiceTag(BaseService, tag);
|
|
107
104
|
return BaseService;
|
|
108
105
|
};
|
|
109
106
|
}
|
|
110
107
|
//#endregion
|
|
111
|
-
//#region src/scope/errors.ts
|
|
112
|
-
/** Thrown when Scope context is accessed outside an active Scope execution. */
|
|
113
|
-
var ScopeRuntimeNotConfiguredError = class extends Error {
|
|
114
|
-
constructor() {
|
|
115
|
-
super("No Scope is available in the current execution context");
|
|
116
|
-
this.name = "ScopeRuntimeNotConfiguredError";
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
/** Thrown when a resource or finalizer is added after Scope closure begins. */
|
|
120
|
-
var ScopeClosedError = class extends Error {
|
|
121
|
-
constructor() {
|
|
122
|
-
super("Cannot add resources or finalizers to a closed Scope");
|
|
123
|
-
this.name = "ScopeClosedError";
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
/** Aggregates finalizer failures encountered while closing a Scope. */
|
|
127
|
-
var ScopeCloseError = class extends Error {
|
|
128
|
-
causes;
|
|
129
|
-
constructor(causes) {
|
|
130
|
-
super(`Failed to close Scope (${causes.length} finalizer${causes.length === 1 ? "" : "s"} failed)`);
|
|
131
|
-
this.causes = causes;
|
|
132
|
-
this.name = "ScopeCloseError";
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
/** Thrown when a value has neither Symbol.dispose nor Symbol.asyncDispose. */
|
|
136
|
-
var ResourceNotDisposableError = class extends Error {
|
|
137
|
-
constructor() {
|
|
138
|
-
super("Resource does not implement Symbol.dispose or Symbol.asyncDispose");
|
|
139
|
-
this.name = "ResourceNotDisposableError";
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
//#endregion
|
|
143
|
-
//#region src/scope/disposable.ts
|
|
144
|
-
const SCOPE_SUCCESS = { status: "success" };
|
|
145
|
-
/** Return a Scope finalizer for a value's async or sync disposal protocol. */
|
|
146
|
-
const getDisposeFinalizer = (resource) => {
|
|
147
|
-
const candidate = Object(resource);
|
|
148
|
-
const asyncDispose = candidate[Symbol.asyncDispose];
|
|
149
|
-
if (asyncDispose instanceof Function) return () => asyncDispose.call(resource);
|
|
150
|
-
const dispose = candidate[Symbol.dispose];
|
|
151
|
-
if (dispose instanceof Function) return () => dispose.call(resource);
|
|
152
|
-
};
|
|
153
|
-
/** Dispose a value immediately when it implements a disposal protocol. */
|
|
154
|
-
const disposeResource = (resource) => {
|
|
155
|
-
return getDisposeFinalizer(resource)?.(SCOPE_SUCCESS);
|
|
156
|
-
};
|
|
157
|
-
//#endregion
|
|
158
108
|
//#region src/layer/internal.ts
|
|
159
109
|
const runLayerGenerator = async (service, factory) => {
|
|
160
110
|
const iterator = factory();
|
|
@@ -189,39 +139,49 @@ var Layer = class Layer {
|
|
|
189
139
|
/** The provider registrations retained by this Layer. */
|
|
190
140
|
providers;
|
|
191
141
|
constructor(providers) {
|
|
192
|
-
this.providers = Object.freeze(
|
|
142
|
+
this.providers = Object.freeze(providers.map((provider) => Object.freeze({
|
|
143
|
+
...provider,
|
|
144
|
+
serviceTag: captureLayerRegistrationTag(provider)
|
|
145
|
+
})));
|
|
193
146
|
}
|
|
194
147
|
/** A stable provider-free Layer for composition roots with no Services. */
|
|
195
148
|
static empty = Object.freeze(new Layer([]));
|
|
196
149
|
static make(service, acquire) {
|
|
150
|
+
const serviceTag = captureServiceTag(service);
|
|
197
151
|
const defaultAcquire = () => {
|
|
198
152
|
return new service();
|
|
199
153
|
};
|
|
200
154
|
const normalizedAcquire = normalizeAcquire(acquire ?? defaultAcquire);
|
|
201
155
|
return new Layer([{
|
|
202
156
|
service,
|
|
157
|
+
serviceTag,
|
|
203
158
|
acquire: normalizedAcquire
|
|
204
159
|
}]);
|
|
205
160
|
}
|
|
206
161
|
/** Create a Layer from an already-constructed Service instance. */
|
|
207
162
|
static succeed(service, instance) {
|
|
163
|
+
const serviceTag = captureServiceTag(service);
|
|
208
164
|
const normalizedAcquire = normalizeAcquire(() => instance);
|
|
209
165
|
return new Layer([{
|
|
210
166
|
service,
|
|
167
|
+
serviceTag,
|
|
211
168
|
acquire: normalizedAcquire
|
|
212
169
|
}]);
|
|
213
170
|
}
|
|
214
171
|
/** Alias a source Service under a compatible target contract. */
|
|
215
172
|
static alias(options) {
|
|
216
173
|
const { from, to } = options;
|
|
174
|
+
captureServiceTag(from);
|
|
217
175
|
return Layer.gen(to, async function* () {
|
|
218
176
|
return await ServiceRuntime.resolve(from);
|
|
219
177
|
});
|
|
220
178
|
}
|
|
221
179
|
/** Define a provider with Runtime-root cleanup. */
|
|
222
180
|
static scoped(service, acquire, release) {
|
|
181
|
+
const serviceTag = captureServiceTag(service);
|
|
223
182
|
return new Layer([{
|
|
224
183
|
service,
|
|
184
|
+
serviceTag,
|
|
225
185
|
acquire: normalizeAcquire(acquire),
|
|
226
186
|
release: (instance, outcome) => {
|
|
227
187
|
return release(instance, outcome);
|
|
@@ -239,16 +199,20 @@ var Layer = class Layer {
|
|
|
239
199
|
release: finalizer
|
|
240
200
|
};
|
|
241
201
|
};
|
|
202
|
+
const serviceTag = captureServiceTag(service);
|
|
242
203
|
return new Layer([{
|
|
243
204
|
service,
|
|
205
|
+
serviceTag,
|
|
244
206
|
acquire: async () => (await acquireWithRelease()).instance,
|
|
245
207
|
acquireWithRelease
|
|
246
208
|
}]);
|
|
247
209
|
}
|
|
248
210
|
/** Define a provider whose acquisition can yield contextual Services. */
|
|
249
211
|
static scopedGen(service, factory, release) {
|
|
212
|
+
const serviceTag = captureServiceTag(service);
|
|
250
213
|
return new Layer([{
|
|
251
214
|
service,
|
|
215
|
+
serviceTag,
|
|
252
216
|
acquire: () => runLayerGenerator(service, factory),
|
|
253
217
|
release: (instance, outcome) => {
|
|
254
218
|
return release(instance, outcome);
|
|
@@ -257,8 +221,10 @@ var Layer = class Layer {
|
|
|
257
221
|
}
|
|
258
222
|
/** Define a provider whose acquisition can yield contextual Services. */
|
|
259
223
|
static gen(service, factory) {
|
|
224
|
+
const serviceTag = captureServiceTag(service);
|
|
260
225
|
return new Layer([{
|
|
261
226
|
service,
|
|
227
|
+
serviceTag,
|
|
262
228
|
acquire: () => runLayerGenerator(service, factory)
|
|
263
229
|
}]);
|
|
264
230
|
}
|
|
@@ -267,12 +233,13 @@ var Layer = class Layer {
|
|
|
267
233
|
const providers = /* @__PURE__ */ new Map();
|
|
268
234
|
for (const layer of layers) for (const provider of layer.providers) {
|
|
269
235
|
const service = provider.service;
|
|
270
|
-
const
|
|
236
|
+
const serviceTag = captureLayerRegistrationTag(provider);
|
|
237
|
+
const existing = providers.get(serviceTag);
|
|
271
238
|
if (existing) {
|
|
272
239
|
if (existing.service !== service) throw new ServiceTagCollisionError(existing.service, service);
|
|
273
240
|
throw new DuplicateServiceError(service);
|
|
274
241
|
}
|
|
275
|
-
providers.set(
|
|
242
|
+
providers.set(serviceTag, provider);
|
|
276
243
|
}
|
|
277
244
|
return new Layer([...providers.values()]);
|
|
278
245
|
}
|
|
@@ -282,8 +249,8 @@ var Layer = class Layer {
|
|
|
282
249
|
}
|
|
283
250
|
static override(base, ...overrides) {
|
|
284
251
|
const providers = /* @__PURE__ */ new Map();
|
|
285
|
-
for (const provider of base.providers) providers.set(provider
|
|
286
|
-
for (const layer of overrides) for (const provider of layer.providers) providers.set(provider
|
|
252
|
+
for (const provider of base.providers) providers.set(captureLayerRegistrationTag(provider), provider);
|
|
253
|
+
for (const layer of overrides) for (const provider of layer.providers) providers.set(captureLayerRegistrationTag(provider), provider);
|
|
287
254
|
return new Layer([...providers.values()]);
|
|
288
255
|
}
|
|
289
256
|
};
|
|
@@ -297,54 +264,6 @@ const normalizeAcquire = (acquire) => () => {
|
|
|
297
264
|
return acquire();
|
|
298
265
|
};
|
|
299
266
|
//#endregion
|
|
300
|
-
|
|
301
|
-
const neverAbortedSignal = new AbortController().signal;
|
|
302
|
-
/** Link caller, Runtime and shutdown signals without owning the caller's controller. */
|
|
303
|
-
const linkAbortSignals = (...signals) => {
|
|
304
|
-
const active = signals.filter((signal) => signal !== void 0);
|
|
305
|
-
if (active.length === 0) return {
|
|
306
|
-
signal: neverAbortedSignal,
|
|
307
|
-
dispose: () => {}
|
|
308
|
-
};
|
|
309
|
-
if (active.length === 1) return {
|
|
310
|
-
signal: active[0],
|
|
311
|
-
dispose: () => {}
|
|
312
|
-
};
|
|
313
|
-
const controller = new AbortController();
|
|
314
|
-
const listeners = [];
|
|
315
|
-
let disposed = false;
|
|
316
|
-
const dispose = () => {
|
|
317
|
-
if (disposed) return;
|
|
318
|
-
disposed = true;
|
|
319
|
-
for (const [source, listener] of listeners) source.removeEventListener("abort", listener);
|
|
320
|
-
listeners.length = 0;
|
|
321
|
-
};
|
|
322
|
-
const abortFrom = (source) => {
|
|
323
|
-
if (controller.signal.aborted) return;
|
|
324
|
-
controller.abort(source.reason);
|
|
325
|
-
dispose();
|
|
326
|
-
};
|
|
327
|
-
for (const source of active) {
|
|
328
|
-
if (source.aborted) {
|
|
329
|
-
abortFrom(source);
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
const listener = () => abortFrom(source);
|
|
333
|
-
listeners.push([source, listener]);
|
|
334
|
-
source.addEventListener("abort", listener, { once: true });
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
signal: controller.signal,
|
|
338
|
-
dispose
|
|
339
|
-
};
|
|
340
|
-
};
|
|
341
|
-
/** Return the current cooperative-cancellation signal. */
|
|
342
|
-
const currentAbortSignal = () => currentRuntimeContext().signal ?? neverAbortedSignal;
|
|
343
|
-
/** Yieldable access to the signal of the current Runtime execution. */
|
|
344
|
-
const CurrentAbortSignal = { *[Symbol.iterator]() {
|
|
345
|
-
return currentAbortSignal();
|
|
346
|
-
} };
|
|
347
|
-
//#endregion
|
|
348
|
-
export { getDisposeFinalizer as a, ScopeClosedError as c, ServiceRuntime as d, defaultRuntimeContextStorage as f, disposeResource as i, ScopeRuntimeNotConfiguredError as l, linkAbortSignals as n, ResourceNotDisposableError as o, Layer as r, ScopeCloseError as s, CurrentAbortSignal as t, Service as u };
|
|
267
|
+
export { Service as n, ServiceRuntime as r, Layer as t };
|
|
349
268
|
|
|
350
|
-
//# sourceMappingURL=
|
|
269
|
+
//# sourceMappingURL=layer-D16GKxuX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer-D16GKxuX.mjs","names":["Constructor"],"sources":["../src/service/runtime.ts","../src/service/service.ts","../src/layer/internal.ts","../src/layer/layer.ts"],"sourcesContent":["import { ServiceRuntimeNotConfiguredError } from './errors'\nimport { captureServiceTag } from './tag'\n\nimport { RuntimeContextNotConfiguredError } from '../runtime/errors'\n\nimport {\n currentRuntimeContext,\n getRuntimeContext,\n makeRuntimeContext,\n runRuntimeContext\n} from '../runtime/context'\n\nimport { defaultRuntimeContextStorage } from '../runtime/default'\n\nimport type { AnyServiceToken } from './types'\n\nimport type { RuntimeContextStorage } from '../runtime/context'\n\n/** Resolves class-backed Service tokens for a runtime execution. */\nexport interface ServiceResolver {\n /** Resolve a token to its corresponding Service instance. */\n resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>>\n}\n\n/** Provides the resolver context used by Service tokens during execution. */\nexport class ServiceRuntime {\n /**\n * Run a callback with a resolver available to `yield* Service` expressions.\n *\n * The context is scoped to the callback and is restored afterward.\n *\n * @example\n * ```ts\n * const value = ServiceRuntime.run(resolver, () => {\n * return ServiceRuntime.resolve(Database)\n * })\n * ```\n */\n static run<A>(\n resolver: ServiceResolver,\n program: () => A,\n storage: RuntimeContextStorage = defaultRuntimeContextStorage\n ): A {\n const current = getRuntimeContext(storage)\n const context = makeRuntimeContext(\n resolver,\n current?.scope,\n current?.resolver === resolver ? current.resolutionPath : [],\n current?.signal,\n current?.resolver === resolver ? current : undefined,\n current?.executionId\n )\n\n return runRuntimeContext(storage, context, program)\n }\n\n /** Return the resolver active in the current execution context. */\n static current(): ServiceResolver {\n let context\n\n try {\n context = currentRuntimeContext()\n } catch (cause) {\n if (cause instanceof RuntimeContextNotConfiguredError) {\n throw new ServiceRuntimeNotConfiguredError()\n }\n\n throw cause\n }\n\n if (!context.resolver) {\n throw new ServiceRuntimeNotConfiguredError()\n }\n\n return context.resolver\n }\n\n /** Resolve a Service token using the active resolver. */\n static async resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>> {\n captureServiceTag(token)\n const resolver = ServiceRuntime.current()\n\n return await resolver.resolve(token)\n }\n}\n","import { ServiceRuntime } from './runtime'\nimport { registerServiceTag, validateServiceTag } from './tag'\n\nimport type { ServiceRequirement } from '../effect/types'\n\nimport type {\n AnyService,\n AnyServiceToken,\n ServiceClass,\n ServiceContract,\n ServiceIdentity,\n ServiceIdentityTypeId,\n ServiceInstance,\n ServiceRequirements,\n ServiceTag,\n ServiceToken,\n ServiceTokenOf\n} from './types'\n\ntype ServiceTagLiteral<Tag extends string> = string extends Tag\n ? never\n : Tag extends ''\n ? never\n : Tag\n\ninterface ServiceFactory<Self> {\n <const Tag extends string>(\n tag: ServiceTagLiteral<Tag>\n ): (abstract new () => ServiceIdentity<Tag>) & {\n readonly name: string\n readonly serviceTag: Tag\n } & {\n readonly of: Service.FactoryOf<Self, Tag>\n readonly [Symbol.asyncIterator]: (\n this: ServiceToken<Tag, Self & ServiceIdentity<Tag>>\n ) => AsyncGenerator<ServiceRequirement<Self>, Self, unknown>\n }\n}\n\n/**\n * Declare a class-backed Service with a stable string-literal identity.\n *\n * The returned class is simultaneously the implementation type, the runtime\n * dependency token, and the value yielded by `yield*` in an Effect generator.\n * The explicit self type preserves exact instance inference, while the second\n * call captures the tag as a literal for Layer composition and diagnostics.\n *\n * @example\n * ```ts\n * class Database extends Service<Database>()('Database') {\n * query(): string {\n * return 'ok'\n * }\n * }\n *\n * const database = yield* Database\n * database.query()\n * ```\n *\n * @typeParam Self The instance type implemented by the declared Service.\n */\nexport function Service<Self>(): ServiceFactory<Self> {\n return function <const Tag extends string>(tag: ServiceTagLiteral<Tag>) {\n validateServiceTag(tag)\n\n abstract class BaseService implements ServiceIdentity<Tag> {\n /** The stable logical identity used by Layers and resolver backends. */\n static readonly serviceTag: Tag = tag\n declare readonly [ServiceIdentityTypeId]: Tag\n\n /**\n * Type-check a structural implementation of this Service.\n *\n * This is an identity helper. It returns the supplied value unchanged\n * and does not invoke a constructor or modify its prototype.\n *\n * @example\n * ```ts\n * class Database extends Service<Database>()('Database') {\n * query(sql: string): string {\n * return sql\n * }\n * }\n *\n * const database = Database.of({\n * query: (sql) => `Result: ${sql}`\n * })\n *\n * database.query('SELECT 1')\n * // 'Result: SELECT 1'\n * // database is the original object, not an instance of Database\n * ```\n */\n static of(this: void, implementation: ServiceContract<Self & ServiceIdentity<Tag>>): Self {\n // SAFETY: ServiceContract removes only the phantom marker; this boundary restores Self.\n return implementation as Self\n }\n\n /** Resolve this Service from the resolver active in the current runtime. */\n // oxlint-disable-next-line require-yield\n static async *[Symbol.asyncIterator](\n this: ServiceToken<Tag, Self & ServiceIdentity<Tag>>\n ): AsyncGenerator<ServiceRequirement<Self>, Self, unknown> {\n return await ServiceRuntime.resolve(this)\n }\n }\n\n registerServiceTag(BaseService, tag)\n\n return BaseService\n }\n}\n\n/** Type-level aliases for Service tokens and their instance contracts. */\nexport declare namespace Service {\n /** The widened Service instance constraint. */\n export type Any = AnyService\n\n /** A class-backed Service token with a stable tag and instance contract. */\n export type Token<Tag extends string = string, Instance extends AnyService = any> = ServiceToken<\n Tag,\n Instance\n >\n\n /** A constructible Service class with a stable tag and instance contract. */\n export type Class<\n Tag extends string = string,\n Instance extends AnyService = AnyService\n > = ServiceClass<Tag, Instance>\n\n /** Extract the instance represented by a Service token. */\n export type Instance<T extends AnyServiceToken> = ServiceInstance<T>\n\n /** Extract the stable tag represented by a Service instance. */\n export type Tag<S extends AnyService> = ServiceTag<S>\n\n /** A branded Service instance identity with a stable tag. */\n export type Identity<Tag extends string = string> = ServiceIdentity<Tag>\n\n /** Remove the internal identity marker from a Service implementation contract. */\n export type Contract<S extends AnyService> = ServiceContract<S>\n\n /** Extract the Service token represented by a branded Service instance. */\n export type TokenOf<S extends AnyService> = ServiceTokenOf<S>\n\n /** Declaration bridge for the recursive structural `Service.of` signature. */\n export type FactoryOf<Self, Tag extends string> = (\n this: void,\n implementation: ServiceContract<Self & ServiceIdentity<Tag>>\n ) => Self\n\n /** Extract Effect Service requirements from a Service instance. */\n export type Requirements<S extends AnyService> = ServiceRequirements<S>\n}\n","import { LayerGeneratorYieldError } from './errors'\n\nimport type { ServiceRequirement } from '../effect/types'\nimport type { ServiceClass } from '../service'\n\nimport type { LayerGenerator } from './types'\n\nexport const runLayerGenerator = async <\n S extends ServiceClass<any, any>,\n Yield extends ServiceRequirement<unknown>\n>(\n service: S,\n factory: LayerGenerator<S, Yield>\n): Promise<InstanceType<S>> => {\n const iterator = factory()\n\n const state = await iterator.next()\n\n if (!state.done) {\n try {\n // SAFETY: The iterator is closed only to discard an invalid yield; its return value is ignored.\n await iterator.return(undefined as never)\n } finally {\n // oxlint-disable-next-line no-unsafe-finally\n throw new LayerGeneratorYieldError(service)\n }\n }\n\n // SAFETY: The public generator boundary accepts only the requested Service contract.\n return state.value as InstanceType<S>\n}\n","import type { ServiceRequirement } from '../effect/types'\nimport { ServiceRuntime } from '../service'\nimport { captureServiceTag } from '../service/tag'\nimport type { AnyService, ServiceClass, ServiceContract, ServiceRequirements } from '../service'\nimport { ResourceNotDisposableError } from '../scope'\nimport { getDisposeFinalizer } from '../scope/disposable'\n\nimport type { DisposableResource, ScopeFinalizer, ScopeOutcome } from '../scope'\nimport type { Covariant, Invariant } from '../internal/variance'\nimport type { MaybePromise } from '../utils/types'\n\nimport { DuplicateServiceError, ServiceTagCollisionError } from './errors'\nimport { runLayerGenerator } from './internal'\nimport { captureLayerRegistrationTag } from './registration'\n\nimport type {\n LayerInput,\n CompleteInput,\n LayerResult,\n MergeResult,\n OverrideLayerResult,\n ValidateLayerInput,\n ValidateLayerTuple,\n ValidateOverrides,\n ProvidedEnvironment,\n RequiredEnvironment\n} from './inference'\nimport type { ProviderEntry } from './metadata'\nimport type { LayerGenerator, LayerGeneratorRequirements, LayerRegistration } from './types'\n\ndeclare const LayerTypeId: unique symbol\n\ninterface LayerVariance<in out Provided, out Required> {\n readonly _Provided: Invariant<Provided>\n readonly _Required: Covariant<Required>\n}\n\ntype CapturedLayerAcquisition = {\n readonly instance: unknown\n readonly release: ScopeFinalizer\n}\n\ninterface LayerProvider extends LayerRegistration {\n /** The tag captured before this provider can cross an asynchronous boundary. */\n readonly serviceTag: string\n\n /** Provider storage deliberately erases the concrete instance type. */\n // oxlint-disable-next-line anti-slop/no-unknown-parameters\n readonly release?: (instance: unknown, outcome: ScopeOutcome) => MaybePromise<void>\n\n /** Capture acquisition-local cleanup without retaining the acquired instance. */\n readonly acquireWithRelease?: () => MaybePromise<CapturedLayerAcquisition>\n}\n\n/** A Service class whose constructor can be called without arguments. */\ntype DefaultConstructibleServiceClass<\n Tag extends string = string,\n Instance extends AnyService = AnyService\n> = ServiceClass<Tag, Instance> & (new () => Instance)\n\ntype IsUnion<Type, Candidate = Type> = Type extends unknown\n ? [Candidate] extends [Type]\n ? false\n : true\n : never\n\ntype InvalidUnionAliasToken = {\n readonly __betterEffectUnionLayerAliasToken: unique symbol\n}\n\ntype RejectUnionAliasToken<Token> = IsUnion<Token> extends true ? InvalidUnionAliasToken : unknown\n\ntype LayerAliasOptions<From extends ServiceClass<any, any>, To extends ServiceClass<any, any>> = {\n readonly from: From\n readonly to: To\n} & RejectUnionAliasToken<From> &\n RejectUnionAliasToken<To> &\n ([ServiceContract<InstanceType<From>>] extends [ServiceContract<InstanceType<To>>]\n ? unknown\n : {\n readonly __betterEffectIncompatibleLayerAlias: unique symbol\n })\n\n/**\n * Declarative collection of Service providers.\n *\n * A Layer describes how to acquire implementations; it does not execute\n * providers until a `Runtime` is created. Use `merge` to compose distinct\n * providers and `override` when replacing an existing provider intentionally.\n *\n * @example\n * ```ts\n * const AppLive = Layer.merge(\n * Layer.succeed(Database, database),\n * Layer.make(UserRepository)\n * )\n *\n * const runtime = await Runtime.make(AppLive, backend)\n * ```\n */\nexport class Layer<\n in out Provided extends AnyService = AnyService,\n out Required extends AnyService = AnyService\n> {\n declare readonly [LayerTypeId]: LayerVariance<Provided, Required>\n\n /** The provider registrations retained by this Layer. */\n readonly providers: readonly LayerProvider[]\n\n private constructor(providers: readonly LayerProvider[]) {\n this.providers = Object.freeze(\n providers.map((provider) =>\n Object.freeze({\n ...provider,\n serviceTag: captureLayerRegistrationTag(provider)\n })\n )\n )\n }\n\n /** A stable provider-free Layer for composition roots with no Services. */\n static readonly empty: Layer<never, never> = Object.freeze(new Layer<never, never>([]))\n\n /** Create a Layer that lazily acquires a Service instance. */\n static make<S extends DefaultConstructibleServiceClass<any, any>>(\n service: S\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n\n static make<S extends ServiceClass<any, any>>(\n service: S,\n acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n\n static make<S extends ServiceClass<any, any>>(\n service: S,\n acquire?: () => MaybePromise<ServiceContract<InstanceType<S>>>\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>> {\n const serviceTag = captureServiceTag(service)\n const defaultAcquire = (): InstanceType<S> => {\n // SAFETY: The no-argument overload constrains `service` to a default constructible class.\n const Constructor = service as new () => InstanceType<S>\n\n return new Constructor()\n }\n\n const normalizedAcquire = normalizeAcquire<S>(acquire ?? defaultAcquire)\n\n // SAFETY: Runtime storage erases only the concrete provider metadata; the public constructor result restores its typed provenance.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: normalizedAcquire\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n }\n\n /** Create a Layer from an already-constructed Service instance. */\n static succeed<S extends ServiceClass<any, any>>(\n service: S,\n instance: ServiceContract<InstanceType<S>>\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>> {\n const serviceTag = captureServiceTag(service)\n const normalizedAcquire = normalizeAcquire<S>(() => instance)\n\n // SAFETY: The structural instance has been checked against the requested Service contract.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: normalizedAcquire\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n }\n\n /** Alias a source Service under a compatible target contract. */\n static alias<From extends ServiceClass<any, any>, To extends ServiceClass<any, any>>(\n options: LayerAliasOptions<From, To>\n ): LayerResult<\n ProviderEntry<InstanceType<To>, InstanceType<From> | ServiceRequirements<InstanceType<To>>>\n > {\n const { from, to } = options\n void captureServiceTag(from)\n\n // Keep alias acquisition in the normal Layer generator path so Runtime supplies the active resolver and resolution diagnostics.\n // oxlint-disable-next-line require-yield\n const alias = Layer.gen(to, async function* () {\n const source = await ServiceRuntime.resolve(from)\n\n // SAFETY: LayerAliasOptions checks that the source implementation satisfies the target contract.\n return source as ServiceContract<InstanceType<To>>\n })\n\n // SAFETY: The alias factory resolves the declared source token before returning the target contract.\n return alias as LayerResult<\n ProviderEntry<InstanceType<To>, InstanceType<From> | ServiceRequirements<InstanceType<To>>>\n >\n }\n\n /** Define a provider with Runtime-root cleanup. */\n static scoped<S extends ServiceClass<any, any>>(\n service: S,\n acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>,\n release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise<void>\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>> {\n const serviceTag = captureServiceTag(service)\n\n // SAFETY: The public callbacks constrain acquisition and release to the requested Service.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: normalizeAcquire<S>(acquire),\n release: (instance, outcome) => {\n // SAFETY: The backend invokes release with the instance acquired for this token.\n return release(instance as InstanceType<S>, outcome)\n }\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n }\n\n /** Define a provider with Runtime-root cleanup through its disposal protocol. */\n static scopedDisposable<S extends ServiceClass<any, any>>(\n service: S,\n acquire: () => MaybePromise<ServiceContract<InstanceType<S>> & DisposableResource>\n ): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>> {\n const acquireWithRelease = async (): Promise<CapturedLayerAcquisition> => {\n const instance = await acquire()\n const finalizer = getDisposeFinalizer(instance)\n\n if (!finalizer) {\n throw new ResourceNotDisposableError()\n }\n\n return { instance, release: finalizer }\n }\n\n const serviceTag = captureServiceTag(service)\n\n // SAFETY: The public callback constrains the acquired value and this runtime-only carrier is erased at the Layer boundary.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: async () => (await acquireWithRelease()).instance,\n acquireWithRelease\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>\n }\n\n /** Define a provider whose acquisition can yield contextual Services. */\n static scopedGen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(\n service: S,\n factory: LayerGenerator<S, Yield>,\n release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise<void>\n ): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>> {\n const serviceTag = captureServiceTag(service)\n\n // SAFETY: The generator and release callback are checked against the requested Service.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: () => runLayerGenerator(service, factory),\n release: (instance, outcome) => {\n // SAFETY: The backend invokes release with the instance acquired for this token.\n return release(instance as InstanceType<S>, outcome)\n }\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>\n }\n\n /** Define a provider whose acquisition can yield contextual Services. */\n static gen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(\n service: S,\n factory: LayerGenerator<S, Yield>\n ): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>> {\n const serviceTag = captureServiceTag(service)\n\n // SAFETY: The generator result is normalized to the requested Service at the runtime boundary.\n return new Layer([\n {\n service,\n serviceTag,\n acquire: () => runLayerGenerator(service, factory)\n }\n ]) as LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>\n }\n\n /** Compose Layers without replacing providers. */\n static merge<const Layers extends readonly LayerInput[]>(\n ...layers: Layers & ValidateLayerTuple<Layers>\n ): MergeResult<Layers> {\n const providers = new Map<string, LayerProvider>()\n\n for (const layer of layers) {\n for (const provider of layer.providers) {\n const service = provider.service\n const serviceTag = captureLayerRegistrationTag(provider)\n const existing = providers.get(serviceTag)\n\n if (existing) {\n if (existing.service !== service) {\n throw new ServiceTagCollisionError(existing.service, service)\n }\n\n throw new DuplicateServiceError(service)\n }\n\n providers.set(serviceTag, provider)\n }\n }\n\n // SAFETY: The heterogeneous provider list is erased only at this internal storage boundary.\n return new Layer([...providers.values()]) as MergeResult<Layers>\n }\n\n /** Mark a Layer composition root as complete without changing its runtime value. */\n static complete<L extends LayerInput>(layer: L & CompleteInput<L>): L {\n return layer\n }\n\n /** Replace providers in a base Layer, using tag identity and compatible contracts. */\n static override<Base extends LayerInput>(\n base: Base & ValidateLayerInput<Base>\n ): OverrideLayerResult<Base, readonly []>\n\n static override<\n Base extends LayerInput,\n const Overrides extends readonly [LayerInput, ...LayerInput[]]\n >(\n base: Base & ValidateLayerInput<Base>,\n ...overrides: Overrides & ValidateOverrides<Base, Overrides>\n ): OverrideLayerResult<Base, Overrides>\n\n static override<Base extends LayerInput, const Overrides extends readonly LayerInput[]>(\n base: Base & ValidateLayerInput<Base>,\n ...overrides: Overrides & ValidateOverrides<Base, Overrides>\n ): OverrideLayerResult<Base, Overrides>\n\n static override(base: LayerInput, ...overrides: readonly LayerInput[]): Layer<any, any> {\n const providers = new Map<string, LayerProvider>()\n\n for (const provider of base.providers) {\n providers.set(captureLayerRegistrationTag(provider), provider)\n }\n\n for (const layer of overrides) {\n for (const provider of layer.providers) {\n providers.set(captureLayerRegistrationTag(provider), provider)\n }\n }\n\n // SAFETY: Runtime provider replacement preserves the computed override metadata.\n return new Layer([...providers.values()]) as Layer<any, any>\n }\n}\n\n// TypeScript's `readonly` does not affect the runtime property descriptor. Keep\n// the class field's enumerable behavior while locking the singleton binding.\nObject.defineProperty(Layer, 'empty', {\n value: Layer.empty,\n writable: false,\n enumerable: true,\n configurable: false\n})\n\nconst normalizeAcquire =\n <S extends ServiceClass<any, any>>(\n acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>\n ): (() => MaybePromise<InstanceType<S>>) =>\n () => {\n // SAFETY: ServiceContract removes only the declaration-only identity; runtime values are unchanged.\n return acquire() as MaybePromise<InstanceType<S>>\n }\n\n/** Type-level aliases for inspecting Layer environments and completeness. */\nexport declare namespace Layer {\n /** The widened Layer shape accepted by generic Layer infrastructure. */\n export type Any = LayerInput\n\n /** Extract the branded Service instances provided by a Layer. */\n export type Provided<L extends LayerInput> = ProvidedEnvironment<L>\n\n /** Extract the external Service requirements of a Layer. */\n export type Required<L extends LayerInput> = RequiredEnvironment<L>\n\n /** Extract the Services still missing from a Layer composition. */\n export type Missing<L extends LayerInput> = RequiredEnvironment<L>\n\n /** Validate a Layer's requirements and input shape. */\n export type Complete<L extends LayerInput> = CompleteInput<L>\n}\n"],"mappings":"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"}
|
package/dist/next.d.mts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { A as ProgramFromGenerator, C as EffectError, D as EffectYield, E as EffectSuccess, M as AnyService, k as Program } from "./index-AiKM71-u.mjs";
|
|
2
|
+
import { j as MissingDependencies, v as ExecutionMissing, w as ProvidedEnvironment, y as LayerInput } from "./outcome-DI8LPIQ4.mjs";
|
|
3
|
+
import { l as Runtime } from "./index-BodMy6rO.mjs";
|
|
4
|
+
import { t as CurrentRequest } from "./current-request-CIU7AHhF.mjs";
|
|
5
|
+
import { c as WebJsonValue, u as WebRequestLayerChecks } from "./types-oihI-ESv.mjs";
|
|
6
|
+
import { Result } from "better-result";
|
|
7
|
+
//#region src/next/types.d.ts
|
|
8
|
+
/** Route parameters exposed by Next.js App Router contexts. */
|
|
9
|
+
type NextEffectParams = {
|
|
10
|
+
readonly [key: string]: string | readonly string[] | undefined;
|
|
11
|
+
};
|
|
12
|
+
/** The explicit context passed to an App Router Route Handler factory. */
|
|
13
|
+
type NextEffectContext<Params extends object = NextEffectParams> = {
|
|
14
|
+
readonly params: Promise<Params>;
|
|
15
|
+
};
|
|
16
|
+
/** A native Route Handler function returned by this adapter. */
|
|
17
|
+
type NextRouteHandler<Context extends object = NextEffectContext> = (request: Request, context: Context) => Promise<Response>;
|
|
18
|
+
/** A native Web Response returned synchronously or asynchronously by a policy. */
|
|
19
|
+
type ResponseLike = Response | PromiseLike<Response>;
|
|
20
|
+
/** The value passed to a Next success policy. */
|
|
21
|
+
type NextEffectSuccess<A = unknown> = {
|
|
22
|
+
readonly value: A;
|
|
23
|
+
};
|
|
24
|
+
/** A lazy Result-valued Program accepted by the Next boundary. */
|
|
25
|
+
type NextEffectProgram<A = unknown, E = unknown, R extends AnyService = never> = Program<A, E, R>;
|
|
26
|
+
/** @internal */
|
|
27
|
+
type AnyProgram = NextEffectProgram<any, any, AnyService>;
|
|
28
|
+
/** @internal */
|
|
29
|
+
type AnyResult = Result<any, any>;
|
|
30
|
+
/** The request Layer installed when no custom Layer is supplied. */
|
|
31
|
+
type DefaultRequestLayer = ReturnType<typeof CurrentRequest.layer>;
|
|
32
|
+
/** Services available to a route Program after its request Layer is installed. */
|
|
33
|
+
type AvailableServices<Provided extends AnyService, RequestLayer extends LayerInput> = Provided | InstanceType<typeof CurrentRequest> | ProvidedEnvironment<RequestLayer>;
|
|
34
|
+
/** Validate a request Layer against a Runtime and the built-in CurrentRequest provider. */
|
|
35
|
+
type NextRequestLayerChecks<Provided extends AnyService, RequestLayer extends LayerInput> = WebRequestLayerChecks<Provided, RequestLayer>;
|
|
36
|
+
type InvalidFailure<Actual, Expected> = {
|
|
37
|
+
readonly __betterEffectInvalidNextFailure: {
|
|
38
|
+
readonly actual: Actual;
|
|
39
|
+
readonly expected: Expected;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
type FailureCheck<Failure, Actual> = [Actual] extends [Failure] ? unknown : InvalidFailure<Actual, Failure>;
|
|
43
|
+
/** Services and failures checked for one route Program. */
|
|
44
|
+
type NextProgramChecks<Provided extends AnyService, RequestLayer extends LayerInput, Program extends AnyProgram, Failure = unknown> = (ExecutionMissing<AvailableServices<Provided, RequestLayer>, Program> extends never ? unknown : MissingDependencies<ExecutionMissing<AvailableServices<Provided, RequestLayer>, Program>>) & FailureCheck<Failure, EffectError<Program>>;
|
|
45
|
+
/** A route Program after its Service and Failure channels have been checked. */
|
|
46
|
+
type CompleteNextProgram<Provided extends AnyService, RequestLayer extends LayerInput, Program extends AnyProgram, Failure = unknown> = Program & NextProgramChecks<Provided, RequestLayer, Program, Failure>;
|
|
47
|
+
/** Convert a route Program factory into a checked factory at the public boundary. */
|
|
48
|
+
type NextHandlerFactory<Context extends object, Provided extends AnyService, RequestLayer extends LayerInput, Failure, ProgramFactory extends (request: Request, context: Context) => AnyProgram> = ProgramFactory & ([ReturnType<ProgramFactory>] extends [CompleteNextProgram<Provided, RequestLayer, ReturnType<ProgramFactory>, Failure>] ? unknown : (request: Request, context: Context) => CompleteNextProgram<Provided, RequestLayer, ReturnType<ProgramFactory>, Failure>);
|
|
49
|
+
/** A generator body used by `NextEffect.gen`. */
|
|
50
|
+
type GeneratorBody<Context extends object, Yield extends EffectYield, Returned extends AnyResult> = (request: Request, context: Context) => Generator<Yield, Returned, unknown> | AsyncGenerator<Yield, Returned, unknown>;
|
|
51
|
+
/** Options shared by every Route Handler created by a NextEffect instance. */
|
|
52
|
+
type NextEffectOptions<Failure = unknown, RequestLayer extends LayerInput = ReturnType<typeof CurrentRequest.layer>, Context extends object = NextEffectContext> = {
|
|
53
|
+
/** Build a request-local Layer once for each native Request. */
|
|
54
|
+
readonly requestLayer?: (request: Request, context: Context) => RequestLayer;
|
|
55
|
+
/** Convert a successful value to a native Response. */
|
|
56
|
+
readonly onSuccess?: (result: NextEffectSuccess<unknown>, request: Request, context: Context) => ResponseLike;
|
|
57
|
+
/** Convert a typed Program failure to a native Response. */
|
|
58
|
+
readonly onFailure?: (error: Failure, request: Request, context: Context) => ResponseLike;
|
|
59
|
+
};
|
|
60
|
+
/** Options for one typed route success policy. */
|
|
61
|
+
type NextEffectRouteSuccessPolicy<A, Context extends object> = {
|
|
62
|
+
/** Handle the success value directly and return a native Response. */
|
|
63
|
+
readonly respond: (value: A, request: Request, context: Context) => ResponseLike;
|
|
64
|
+
readonly serialize?: never;
|
|
65
|
+
readonly onSuccess?: never;
|
|
66
|
+
} | {
|
|
67
|
+
readonly respond?: never;
|
|
68
|
+
/** Convert the success value to the JSON-safe body wrapped by WebEffect. */
|
|
69
|
+
readonly serialize: (value: A, request: Request, context: Context) => WebJsonValue;
|
|
70
|
+
readonly onSuccess?: never;
|
|
71
|
+
} | {
|
|
72
|
+
readonly respond?: never;
|
|
73
|
+
readonly serialize?: never;
|
|
74
|
+
/** Replace the shared success policy for this route. */
|
|
75
|
+
readonly onSuccess: (result: NextEffectSuccess<A>, request: Request, context: Context) => ResponseLike;
|
|
76
|
+
} | {
|
|
77
|
+
/** Use the shared or default success policy for this route. */
|
|
78
|
+
readonly respond?: never;
|
|
79
|
+
readonly serialize?: never;
|
|
80
|
+
readonly onSuccess?: never;
|
|
81
|
+
};
|
|
82
|
+
type NextEffectRouteOptions<A, Context extends object = NextEffectContext> = NextEffectRouteSuccessPolicy<A, Context>;
|
|
83
|
+
/** Service and Failure checks for a generator-created route Program. */
|
|
84
|
+
type NextGeneratorChecks<Provided extends AnyService, RequestLayer extends LayerInput, Yield extends EffectYield, Returned extends AnyResult, Failure = unknown> = NextProgramChecks<Provided, RequestLayer, ProgramFromGenerator<Yield, Returned>, Failure>;
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/next/next-effect.d.ts
|
|
87
|
+
/** Run Result-valued Programs inside one Runtime boundary per Next request. */
|
|
88
|
+
declare class NextEffect<Provided extends AnyService = AnyService, Failure = unknown, RequestLayer extends LayerInput = DefaultRequestLayer, Context extends object = NextEffectContext> {
|
|
89
|
+
readonly runtime: Runtime<Provided>;
|
|
90
|
+
private readonly onSuccess;
|
|
91
|
+
private readonly onFailure;
|
|
92
|
+
private readonly requestLayer;
|
|
93
|
+
private constructor();
|
|
94
|
+
/** Bind an application-owned Runtime to App Router Route Handler factories. */
|
|
95
|
+
static make<Provided extends AnyService, Failure = unknown, RequestLayer extends LayerInput = DefaultRequestLayer, Context extends object = NextEffectContext>(runtime: Runtime<Provided>, options?: NextEffectOptions<Failure, RequestLayer, Context> & NextRequestLayerChecks<Provided, RequestLayer>): NextEffect<Provided, Failure, RequestLayer, Context>;
|
|
96
|
+
/** Create a native Route Handler from an explicit Request/context Program factory. */
|
|
97
|
+
handler<Program extends AnyProgram>(makeProgram: (request: Request, context: Context) => CompleteNextProgram<Provided, RequestLayer, Program, Failure>, options?: NextEffectRouteOptions<EffectSuccess<Program>, Context>): NextRouteHandler<Context>;
|
|
98
|
+
handler<const HandlerContext extends object, const ProgramFactory extends (request: Request, context: HandlerContext) => AnyProgram>(makeProgram: NextHandlerFactory<HandlerContext, Provided, RequestLayer, Failure, ProgramFactory>, options?: NextEffectRouteOptions<EffectSuccess<ReturnType<ProgramFactory>>, HandlerContext>): NextRouteHandler<HandlerContext>;
|
|
99
|
+
/** Create a native Route Handler from a Request/context generator body. */
|
|
100
|
+
gen<const HandlerContext extends object = Context, const Yield extends EffectYield = EffectYield, const Returned extends AnyResult = AnyResult>(body: GeneratorBody<HandlerContext, Yield, Returned> & NextGeneratorChecks<Provided, RequestLayer, Yield, Returned, Failure>, options?: NextEffectRouteOptions<EffectSuccess<ProgramFromGenerator<Yield, Returned>>, HandlerContext>): NextRouteHandler<HandlerContext>;
|
|
101
|
+
gen<const CustomContext extends object, const CustomYield extends EffectYield, const CustomReturned extends AnyResult>(body: GeneratorBody<CustomContext, CustomYield, CustomReturned> & NextGeneratorChecks<Provided, RequestLayer, CustomYield, CustomReturned, Failure>, options?: NextEffectRouteOptions<EffectSuccess<ProgramFromGenerator<CustomYield, CustomReturned>>, CustomContext>): NextRouteHandler<CustomContext>;
|
|
102
|
+
private makeHandler;
|
|
103
|
+
}
|
|
104
|
+
declare namespace NextEffect {
|
|
105
|
+
/** Options shared by all handlers created from a bound Runtime. */
|
|
106
|
+
type Options<Failure = unknown, RequestLayer extends LayerInput = DefaultRequestLayer, Context extends object = NextEffectContext> = NextEffectOptions<Failure, RequestLayer, Context>;
|
|
107
|
+
/** A typed per-route success policy. */
|
|
108
|
+
type RouteOptions<A, Context extends object = NextEffectContext> = NextEffectRouteOptions<A, Context>;
|
|
109
|
+
/** The explicit App Router context passed to route factories. */
|
|
110
|
+
type Context<Params extends object = NextEffectParams> = NextEffectContext<Params>;
|
|
111
|
+
/** The native handler returned by `handler` and `gen`. */
|
|
112
|
+
type Handler<Context extends object = NextEffectContext> = NextRouteHandler<Context>;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { NextEffect, type NextEffectContext, type NextEffectOptions, type NextEffectParams, type NextEffectProgram, type NextEffectRouteOptions, type NextEffectSuccess, type NextRouteHandler, type ResponseLike };
|
|
116
|
+
//# sourceMappingURL=next.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.d.mts","names":[],"sources":["../src/next/types.ts","../src/next/next-effect.ts"],"mappings":"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"}
|
package/dist/next.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { t as Effect } from "./effect-CPdV7Yv8.mjs";
|
|
2
|
+
import { t as WebEffect } from "./web-Bq3MfMrj.mjs";
|
|
3
|
+
import { Result } from "better-result";
|
|
4
|
+
//#region src/next/next-effect.ts
|
|
5
|
+
const routeSuccessPolicyNames = [
|
|
6
|
+
"respond",
|
|
7
|
+
"serialize",
|
|
8
|
+
"onSuccess"
|
|
9
|
+
];
|
|
10
|
+
const assertExclusiveRouteSuccessPolicy = (options) => {
|
|
11
|
+
const configuredPolicies = routeSuccessPolicyNames.filter((name) => options[name] !== void 0);
|
|
12
|
+
if (configuredPolicies.length > 1) throw new TypeError(`NextEffect route options must configure at most one success policy; received ${configuredPolicies.join(", ")}`);
|
|
13
|
+
};
|
|
14
|
+
/** Run Result-valued Programs inside one Runtime boundary per Next request. */
|
|
15
|
+
var NextEffect = class NextEffect {
|
|
16
|
+
runtime;
|
|
17
|
+
onSuccess;
|
|
18
|
+
onFailure;
|
|
19
|
+
requestLayer;
|
|
20
|
+
constructor(runtime, options) {
|
|
21
|
+
this.runtime = runtime;
|
|
22
|
+
this.onSuccess = options.onSuccess;
|
|
23
|
+
this.onFailure = options.onFailure;
|
|
24
|
+
this.requestLayer = options.requestLayer;
|
|
25
|
+
}
|
|
26
|
+
/** Bind an application-owned Runtime to App Router Route Handler factories. */
|
|
27
|
+
static make(runtime, options) {
|
|
28
|
+
return new NextEffect(runtime, options ?? {});
|
|
29
|
+
}
|
|
30
|
+
handler(...args) {
|
|
31
|
+
const makeProgram = args[0];
|
|
32
|
+
const options = args[1] ?? {};
|
|
33
|
+
return this.makeHandler(makeProgram, options);
|
|
34
|
+
}
|
|
35
|
+
gen(...args) {
|
|
36
|
+
const body = args[0];
|
|
37
|
+
const options = args[1] ?? {};
|
|
38
|
+
return this.makeHandler((request, context) => {
|
|
39
|
+
return Effect.fn(() => body(request, context));
|
|
40
|
+
}, options);
|
|
41
|
+
}
|
|
42
|
+
makeHandler(makeProgram, routeOptions) {
|
|
43
|
+
assertExclusiveRouteSuccessPolicy(routeOptions);
|
|
44
|
+
return async (request, context) => {
|
|
45
|
+
const program = makeProgram(request, context);
|
|
46
|
+
const effectiveProgram = routeOptions.serialize !== void 0 ? async () => {
|
|
47
|
+
const result = await program();
|
|
48
|
+
if (Result.isError(result)) return result;
|
|
49
|
+
return Result.ok(routeOptions.serialize(result.value, request, context));
|
|
50
|
+
} : program;
|
|
51
|
+
const webOptions = {};
|
|
52
|
+
if (this.requestLayer !== void 0) webOptions.requestLayer = () => this.requestLayer(request, context);
|
|
53
|
+
if (routeOptions.respond !== void 0) webOptions.onSuccess = ({ value }) => routeOptions.respond(value, request, context);
|
|
54
|
+
else if (routeOptions.onSuccess !== void 0) webOptions.onSuccess = (result) => routeOptions.onSuccess(result, request, context);
|
|
55
|
+
else if (this.onSuccess !== void 0) webOptions.onSuccess = (result) => {
|
|
56
|
+
return this.onSuccess(result, request, context);
|
|
57
|
+
};
|
|
58
|
+
if (this.onFailure !== void 0) webOptions.onFailure = (error) => {
|
|
59
|
+
return this.onFailure(error, request, context);
|
|
60
|
+
};
|
|
61
|
+
return await WebEffect.handle(this.runtime, request, effectiveProgram, webOptions);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { NextEffect };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=next.mjs.map
|