@nicolastoulemont/std 0.7.0 → 0.7.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 +0 -6
- package/dist/context-CCHj1nab.mjs.map +1 -1
- package/dist/data/index.d.mts +1 -1
- package/dist/data/index.mjs +1 -1
- package/dist/{data-CJxw6al9.mjs → data-BLXO4XwS.mjs} +2 -2
- package/dist/{data-CJxw6al9.mjs.map → data-BLXO4XwS.mjs.map} +1 -1
- package/dist/data.tagged-error.types-CGiKD-ES.d.mts +29 -0
- package/dist/data.tagged-error.types-CGiKD-ES.d.mts.map +1 -0
- package/dist/either/index.d.mts +1 -1
- package/dist/either/index.mjs +1 -1
- package/dist/{either-6BwadiFj.mjs → either-BMLPfvMl.mjs} +2 -2
- package/dist/either-BMLPfvMl.mjs.map +1 -0
- package/dist/fx/index.d.mts +1 -1
- package/dist/fx/index.mjs +1 -1
- package/dist/{fx-BzxLbf1Q.mjs → fx-K-a9Smhn.mjs} +2 -2
- package/dist/fx-K-a9Smhn.mjs.map +1 -0
- package/dist/{fx.runtime-BcC6yMSy.mjs → fx.runtime-DclEDyjY.mjs} +2 -2
- package/dist/{fx.runtime-BcC6yMSy.mjs.map → fx.runtime-DclEDyjY.mjs.map} +1 -1
- package/dist/{index-DSsDFLGw.d.mts → index-B1-tBzc0.d.mts} +2 -2
- package/dist/{index-DSsDFLGw.d.mts.map → index-B1-tBzc0.d.mts.map} +1 -1
- package/dist/{index-CugDqdx6.d.mts → index-BNQ9xSAz.d.mts} +2 -2
- package/dist/{index-CugDqdx6.d.mts.map → index-BNQ9xSAz.d.mts.map} +1 -1
- package/dist/index-By6dNRc4.d.mts.map +1 -1
- package/dist/{index-DaTvFhZ8.d.mts → index-CGiLfREk.d.mts} +37 -37
- package/dist/{index-DaTvFhZ8.d.mts.map → index-CGiLfREk.d.mts.map} +1 -1
- package/dist/{index-CCo85AdC.d.mts → index-Cq2IFito.d.mts} +2 -2
- package/dist/{index-CCo85AdC.d.mts.map → index-Cq2IFito.d.mts.map} +1 -1
- package/dist/index-DEAWPlcI.d.mts.map +1 -1
- package/dist/{index-Dm2dFysv.d.mts → index-UzMbg1dh.d.mts} +2 -2
- package/dist/{index-Dm2dFysv.d.mts.map → index-UzMbg1dh.d.mts.map} +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +1 -1
- package/dist/layer-BttmtDrs.mjs.map +1 -1
- package/dist/multithread-xUUh4eLn.mjs.map +1 -1
- package/dist/option/index.d.mts +1 -1
- package/dist/option/index.mjs +1 -1
- package/dist/{option-Qt1H-u7c.mjs → option-Tfbo4wty.mjs} +2 -2
- package/dist/option-Tfbo4wty.mjs.map +1 -0
- package/dist/option.types-D1mm0zUb.mjs +2 -0
- package/dist/option.types-D1mm0zUb.mjs.map +1 -0
- package/dist/{option.types-DlAb6Sr0.d.mts → option.types-qPevEZQd.d.mts} +5 -10
- package/dist/option.types-qPevEZQd.d.mts.map +1 -0
- package/dist/order-D5c4QChk.mjs.map +1 -1
- package/dist/provide/index.mjs +1 -1
- package/dist/{provide-B_SqJpCd.mjs → provide-C2cWOx2B.mjs} +2 -2
- package/dist/provide-C2cWOx2B.mjs.map +1 -0
- package/dist/queue/index.d.mts +1 -1
- package/dist/queue/index.mjs +1 -1
- package/dist/{queue-CG5izEBS.mjs → queue-Sg6KJerl.mjs} +2 -2
- package/dist/{queue-CG5izEBS.mjs.map → queue-Sg6KJerl.mjs.map} +1 -1
- package/dist/result-BEzV0DYC.mjs.map +1 -1
- package/dist/result.types-_xDAei3-.d.mts.map +1 -1
- package/dist/scope/index.mjs +1 -1
- package/dist/{scope-qwL1VUh2.mjs → scope-D_kzd1nT.mjs} +2 -2
- package/dist/scope-D_kzd1nT.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/data.tagged-error.types-CLlJJ3n5.d.mts +0 -50
- package/dist/data.tagged-error.types-CLlJJ3n5.d.mts.map +0 -1
- package/dist/either-6BwadiFj.mjs.map +0 -1
- package/dist/fx-BzxLbf1Q.mjs.map +0 -1
- package/dist/option-Qt1H-u7c.mjs.map +0 -1
- package/dist/option.types-DRUm2QiI.mjs +0 -2
- package/dist/option.types-DRUm2QiI.mjs.map +0 -1
- package/dist/option.types-DlAb6Sr0.d.mts.map +0 -1
- package/dist/provide-B_SqJpCd.mjs.map +0 -1
- package/dist/scope-qwL1VUh2.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provide-C2cWOx2B.mjs","names":["layer","service","makeScope","layer","fxGen","fxResult","service"],"sources":["../src/provide/memo-map.ts","../src/provide/provide.ts"],"sourcesContent":["import type { Context } from \"../context/context\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { Layer } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport type { ScopeService } from \"../scope/scope\"\nimport { asServiceRequest } from \"../service/service-resolution\"\n\n/* oxlint-disable no-unsafe-type-assertion, only-throw-error -- MemoMap bridges erased generic Fx channels and re-emits typed domain errors from generator boundaries. */\n\n// ============================================================================\n// MemoMap\n// ============================================================================\n\ntype AnyLayer = Layer<unknown, unknown, unknown>\n\n/**\n * MemoMap caches built layers so each layer is only built once.\n * Multiple dependents share the same service instance.\n *\n * This implements the \"service singleton\" pattern where a service\n * is instantiated once and shared across all consumers.\n *\n * @example\n * ```ts\n * // Database is built once, shared by DocumentService and TeamService\n * const AppLayer = Layer.merge(\n * ConfigLive,\n * LoggerLive,\n * DatabaseLive, // Built once\n * DocumentServiceLive, // Uses shared Database\n * TeamServiceLive, // Uses same Database instance\n * )\n * ```\n */\nexport class MemoMap {\n private cache = new Map<\n AnyLayer,\n {\n promise?: Promise<Context<unknown>>\n context?: Context<unknown>\n building?: boolean\n }\n >()\n\n /**\n * Get a cached context or build the layer if not cached.\n *\n * @param layer - The layer to get or build\n * @param scope - The scope for resource management\n * @param deps - Context containing the layer's dependencies\n * @returns A RunnableFx producing the layer's context\n */\n getOrBuild<ROut, E, RIn>(\n layer: Layer<ROut, E, RIn>,\n scope: ScopeService,\n deps: Context<RIn>,\n ): RunnableFx<Context<ROut>, E> {\n const cached = this.cache.get(layer as AnyLayer)\n\n // Already built - return cached context\n if (cached?.context) {\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => cached.context as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => ok(cached.context as Context<ROut>),\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n return cached.context as Context<ROut>\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n // Building in progress (async) - wait for it\n if (cached?.promise) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n const ctx = await cached.promise!\n return ok(ctx as Context<ROut>)\n },\n // oxlint-disable-next-line require-yield\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n const ctx = await cached.promise!\n return ctx as Context<ROut>\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Need to build - mark as building\n this.cache.set(layer as AnyLayer, { building: true })\n\n // Build the layer with provided dependencies\n const buildFx = layer.build(this, scope)\n const cacheRef = this.cache\n\n // Determine if async\n if (buildFx._tag === \"AsyncFx\") {\n // Create a promise for the build\n const buildPromise = (async () => {\n const gen = buildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - rethrow\n throw yielded\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ctx\n })()\n\n this.cache.set(layer as AnyLayer, { promise: buildPromise })\n\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: async () => {\n try {\n const ctx = await buildPromise\n return ok(ctx)\n } catch (e) {\n return {\n ok: false,\n error: e as E,\n *[Symbol.iterator]() {\n yield e as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, Context<ROut>, unknown> {\n try {\n const ctx = await buildPromise\n return ctx\n } catch (e) {\n yield e as E\n throw new Error(\"Unreachable\", { cause: e })\n }\n },\n } as AsyncFx<Context<ROut>, E>\n }\n\n // Sync build\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as Context<ROut>,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n run: () => {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error\n return {\n ok: false,\n error: yielded as E,\n *[Symbol.iterator]() {\n yield yielded as E\n throw new Error(\"Unreachable\")\n },\n }\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n const ctx = result.value\n cacheRef.set(layer as AnyLayer, { context: ctx })\n return ok(ctx)\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, Context<ROut>, unknown> {\n const gen = buildFx[Symbol.iterator]()\n let result = gen.next()\n\n // Resolve service requests from deps\n while (result.done !== true) {\n const yielded = result.value\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n // It's an error - yield it\n yield yielded as E\n throw new Error(\"Unreachable\")\n }\n const service = deps._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found during layer build`)\n }\n result = gen.next(service)\n }\n\n cacheRef.set(layer as AnyLayer, { context: result.value })\n return result.value\n },\n } as SyncFx<Context<ROut>, E>\n }\n\n /**\n * Clear the cache.\n * Useful for testing.\n */\n clear(): void {\n this.cache.clear()\n }\n\n /**\n * Get the number of cached layers.\n */\n get size(): number {\n return this.cache.size\n }\n}\n\n/* oxlint-enable no-unsafe-type-assertion, only-throw-error */\n","import type { Context } from \"../context/context\"\nimport { runSync, runAsync } from \"../fx/fx.runtime\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { RunnableFx, SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { Layer } from \"../layer/layer.types\"\nimport { ok } from \"../result/result\"\nimport { make as makeScope } from \"../scope/scope\"\nimport type { ServiceClass } from \"../service/service\"\nimport { asServiceRequest, resolveService } from \"../service/service-resolution\"\nimport { MemoMap } from \"./memo-map\"\n\n/* oxlint-disable no-unsafe-type-assertion -- layer/service re-thread generic Fx channels through runtime service injection points. */\n\n// ============================================================================\n// Provide Layer\n// ============================================================================\n\n/**\n * Extract the value type from an Fx.\n */\ntype FxValueType<F> = F extends RunnableFx<infer A, unknown, unknown> ? A : never\n\n/**\n * Extract the error type from an Fx.\n */\ntype FxErrorType<F> = F extends RunnableFx<unknown, infer E, unknown> ? E : never\n\n/**\n * Type for the result of provide based on layer sync and fx type.\n * Uses infer to extract A and E from the actual Fx type.\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n */\ntype ProvideResult<\n E2,\n LayerSync extends boolean,\n Fx extends RunnableFx<unknown, unknown, unknown>,\n> = LayerSync extends true\n ? Fx[\"_tag\"] extends \"SyncFx\"\n ? SyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : LayerSync extends false\n ? AsyncFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n : RunnableFx<FxValueType<Fx>, FxErrorType<Fx> | E2>\n\n/**\n * Provide a layer to an Fx computation, resolving all service requirements.\n * Creates a new scope for resource management.\n *\n * Type preservation:\n * - Sync layer + SyncFx → SyncFx\n * - Sync layer + AsyncFx → AsyncFx\n * - Async layer + any fx → AsyncFx\n * - Unknown sync layer + any fx → RunnableFx (fallback)\n *\n * @param layer - The layer providing services (must have no external requirements)\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Provide } from \"@nicolastoulemont/std\"\n *\n * import { Fx, Layer, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const portLayer = Layer.ok(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.layer(portLayer)(readPort)\n * // => Fx with Port dependency resolved\n * ```\n *\n * @category Utilities\n */\nexport function layer<ROut, E2, LayerSync extends boolean>(\n layer: Layer<ROut, E2, never, LayerSync>,\n): <Fx extends RunnableFx<unknown, unknown, ROut>>(fx: Fx) => ProvideResult<E2, LayerSync, Fx>\nexport function layer<ROut, E2>(layer: Layer<ROut, E2>) {\n return <A, E, R extends ROut>(fx: RunnableFx<A, E, R>): RunnableFx<A, E | E2> => {\n // Determine if the layer or fx is async\n const memoMap = new MemoMap()\n const scope = makeScope()\n const layerBuildFx = layer.build(memoMap, scope)\n\n if (layerBuildFx._tag === \"AsyncFx\" || fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n try {\n // Build the layer\n let ctx: Context<ROut>\n\n if (layerBuildFx._tag === \"AsyncFx\") {\n const gen = layerBuildFx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n }\n ctx = result.value\n } else {\n const gen = layerBuildFx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n yield result.value as E2\n result = gen.next(undefined)\n }\n ctx = result.value\n }\n\n // Run the fx with the context\n if (fx._tag === \"AsyncFx\") {\n const fxGen = fx[Symbol.asyncIterator]()\n let fxResult = await fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(service)\n continue\n }\n\n // Pass through (error or unsatisfied service)\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n // oxlint-disable-next-line no-await-in-loop\n fxResult = await fxGen.next(value)\n }\n\n return fxResult.value\n }\n\n // Sync fx\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n if (closeResult._tag === \"AsyncFx\") {\n await runAsync(closeResult)\n } else {\n runSync(closeResult)\n }\n }\n },\n } as AsyncFx<A, E | E2>\n }\n\n // Both sync\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E | E2,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E | E2, Exclude<R, ROut>>, A, unknown> {\n try {\n // Build the layer\n const layerGen = layerBuildFx[Symbol.iterator]()\n let layerResult = layerGen.next()\n\n while (layerResult.done !== true) {\n yield layerResult.value as E2\n layerResult = layerGen.next(undefined)\n }\n\n const ctx = layerResult.value\n\n // Run the fx with the context\n const fxGen = fx[Symbol.iterator]()\n let fxResult = fxGen.next()\n\n while (fxResult.done !== true) {\n const yielded = fxResult.value\n\n const service = resolveService(ctx, yielded)\n if (service !== undefined) {\n fxResult = fxGen.next(service)\n continue\n }\n\n const value = yield yielded as FxYield<E, Exclude<R, ROut>>\n fxResult = fxGen.next(value)\n }\n\n return fxResult.value\n } finally {\n const closeResult = scope.close(ok(undefined))\n // In sync-only branch, closeResult is always SyncFx\n runSync(closeResult as SyncFx<void>)\n }\n },\n } as SyncFx<A, E | E2>\n }\n}\n\n// ============================================================================\n// Provide Context\n// ============================================================================\n\n/**\n * Provide a context directly to an Fx computation.\n *\n * @param ctx - The context containing services\n * @returns A function that takes an Fx and returns an Fx with dependencies resolved\n *\n * @example\n * ```ts\n * import { Provide } from \"@nicolastoulemont/std\"\n *\n * import { Context, Fx, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const ctx = Context.make(Port, 3000)\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.context(ctx)(readPort)\n * // => Fx runnable without Port requirement\n * ```\n *\n * @category Utilities\n */\nexport const context =\n <R>(ctx: Context<R>) =>\n <A, E>(fx: RunnableFx<A, E, R>): RunnableFx<A, E> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(service)\n }\n\n return result.value\n },\n } as AsyncFx<A, E>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<FxYield<E, never>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest === undefined) {\n yield yielded as E\n result = gen.next(undefined)\n continue\n }\n const service = ctx._services.get(serviceRequest.key)\n if (service === undefined) {\n throw new Error(`Service \"${serviceRequest.key}\" not found`)\n }\n result = gen.next(service)\n }\n\n return result.value\n },\n } as SyncFx<A, E>\n }\n\n// ============================================================================\n// Provide Service\n// ============================================================================\n\n/**\n * Provide a single service to an Fx computation.\n *\n * @param service - The service class (tag)\n * @param impl - The service implementation\n * @returns A function that takes an Fx and returns an Fx with the service provided\n *\n * @example\n * ```ts\n * import { Provide } from \"@nicolastoulemont/std\"\n *\n * import { Fx, Service } from \"@nicolastoulemont/std\"\n *\n * const Port = Service.tag<number>(\"Port\")\n * const readPort = Fx.gen(function* () {\n * return yield* Port\n * })\n * const provided = Provide.service(Port, 3000)(readPort)\n * // => Fx runnable without Port requirement\n * ```\n *\n * @category Utilities\n */\nexport const service =\n <S>(service: ServiceClass<S>, impl: S) =>\n <A, E, R>(fx: RunnableFx<A, E, R | S>): RunnableFx<A, E, Exclude<R, S>> => {\n if (fx._tag === \"AsyncFx\") {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.asyncIterator]()\n let result = await gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n // oxlint-disable-next-line no-await-in-loop\n result = await gen.next(value)\n }\n }\n\n return result.value\n },\n } as AsyncFx<A, E, Exclude<R, S>>\n }\n\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as unknown as A,\n _E: () => undefined as unknown as E,\n _R: () => undefined as unknown as Exclude<R, S>,\n },\n *[Symbol.iterator](): Generator<FxYield<E, Exclude<R, S>>, A, unknown> {\n const gen = fx[Symbol.iterator]()\n let result = gen.next()\n\n while (result.done !== true) {\n const yielded = result.value\n\n const serviceRequest = asServiceRequest(yielded)\n if (serviceRequest?.key === service.key) {\n result = gen.next(impl)\n } else {\n const value = yield yielded as FxYield<E, Exclude<R, S>>\n result = gen.next(value)\n }\n }\n\n return result.value\n },\n } as SyncFx<A, E, Exclude<R, S>>\n }\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
|
package/dist/queue/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as queue_d_exports } from "../index-
|
|
1
|
+
import { t as queue_d_exports } from "../index-Cq2IFito.mjs";
|
|
2
2
|
export { queue_d_exports as Queue };
|
package/dist/queue/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"../queue-
|
|
1
|
+
import{a as e}from"../queue-Sg6KJerl.mjs";export{e as Queue};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./chunk-C934ptG5.mjs";import{t}from"./data-
|
|
2
|
-
//# sourceMappingURL=queue-
|
|
1
|
+
import{t as e}from"./chunk-C934ptG5.mjs";import{t}from"./data-BLXO4XwS.mjs";var n=e({QueueAbortedError:()=>i,QueueClosedError:()=>r,QueueTaskAbortedError:()=>a,bounded:()=>h,is:()=>f,make:()=>m,unbounded:()=>g}),r=class extends t(`QueueClosedError`){},i=class extends t(`QueueAbortedError`){},a=class extends t(`QueueTaskAbortedError`){};const o=e=>{let t=e??`unbounded`;if(t===`unbounded`)return 1/0;if(!Number.isInteger(t)||t<=0)throw RangeError(`Queue concurrency must be a positive integer or "unbounded", received: ${String(t)}`);return t},s=e=>{if(e!==1/0&&(!Number.isInteger(e)||e<0))throw RangeError(`Queue maxSize must be an integer >= 0, received: ${String(e)}`)},c=e=>new a({reason:e.reason}),l=e=>new r({state:e}),u=e=>e instanceof Error?e:Error(`Queue rejection reason was not an Error`,{cause:e}),d=(e,t)=>{if(t===void 0)return e;if(t.aborted)return t;if(e.aborted)return e;let n=new AbortController,r=()=>{n.abort(e.reason),t.removeEventListener(`abort`,i)},i=()=>{n.abort(t.reason),e.removeEventListener(`abort`,r)};return e.addEventListener(`abort`,r,{once:!0}),t.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,()=>{e.removeEventListener(`abort`,r),t.removeEventListener(`abort`,i)},{once:!0}),n.signal},f=e=>typeof e==`object`&&!!e&&`_tag`in e&&e._tag===`Queue`,p=(e,t)=>{s(e);let n=o(t?.concurrency),r=`open`,a,f=t?.autoStart===!1,p=0,m=!1,h=[],g=[],_=new Set,v=new AbortController,y,b,x=()=>{if(!(p!==0||h.length>0)){for(let e of _)e();_.clear(),(r===`draining`||r===`aborted`)&&(r=`closed`,y?.(),y=void 0)}},S=e=>{if(g.length===0)return;let t=g.splice(0);for(let n of t)n.reject(e)},C=()=>{if(!(!Number.isFinite(e)||g.length===0))for(;g.length>0&&h.length<e&&r===`open`;){let e=g.shift();e!==void 0&&e.resolve()}},w=e=>{if(h.length===0)return;let t=new i({reason:e}),n=h.splice(0);for(let e of n)e.reject(t)},T=t=>!Number.isFinite(e)||h.length<e?Promise.resolve():new Promise((e,n)=>{let r={resolve:()=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),e()},reject:e=>{t!==void 0&&i!==void 0&&t.removeEventListener(`abort`,i),n(e)},signal:t},i=t===void 0?void 0:()=>{let e=g.indexOf(r);e!==-1&&g.splice(e,1),n(c(t))};if(t!==void 0&&t.aborted){n(c(t));return}t!==void 0&&i!==void 0&&t.addEventListener(`abort`,i,{once:!0}),g.push(r)}),E=()=>{(r===`draining`||r===`aborted`)&&p===0&&h.length===0&&x()},D=e=>{p+=1;let t=d(v.signal,e.signal),n;if(t.aborted)n=Promise.reject(c(t));else try{n=Promise.resolve(e.task({signal:t}))}catch(e){n=Promise.reject(u(e))}n.then(t=>{e.resolve(t)},t=>{e.reject(u(t))}).finally(()=>{--p,C(),O(),x()})},O=()=>{if(!m){m=!0;try{if(r===`aborted`){E();return}for(;!f&&p<n&&h.length>0;){let e=h.shift();if(e===void 0)break;C(),D(e)}E()}finally{m=!1}}},k=()=>l(a===void 0?r===`aborted`?`aborted`:r===`draining`?`draining`:r===`closed`?a??`draining`:`draining`:a);return{_tag:`Queue`,get pending(){return p},get size(){return h.length},get isPaused(){return f},get isShutdown(){return r!==`open`},enqueue(t,n){let i=n?.signal;if(i!==void 0&&i.aborted)return Promise.reject(c(i));if(r!==`open`)return Promise.reject(k());let a=()=>new Promise((e,n)=>{let r={task:t,resolve:e,reject:n,signal:i};h.push(r),O()});return!Number.isFinite(e)||h.length<e?a():T(i).then(()=>{if(i!==void 0&&i.aborted)throw c(i);if(r!==`open`)throw k();return a()})},pause(){f=!0},resume(){f&&(f=!1,O())},awaitIdle(){return p===0&&h.length===0?Promise.resolve():new Promise(e=>{_.add(e)})},shutdown(e){let t=e?.mode??`drain`;return b!==void 0&&(r===`draining`||r===`aborted`||r===`closed`)?(t===`abort`&&a!==`aborted`&&(a=`aborted`,r=`aborted`,v.abort(e?.reason),w(e?.reason),S(l(`aborted`)),E()),b):(b??=new Promise(e=>{y=e}),t===`abort`?(a=`aborted`,r=`aborted`,f=!1,v.abort(e?.reason),w(e?.reason),S(l(`aborted`))):(a=`draining`,r===`open`&&(r=`draining`),f=!1,S(l(`draining`))),O(),x(),b)}}},m=e=>p(1/0,e),h=(e,t)=>p(e,t),g=e=>p(1/0,e);export{n as a,m as i,r as n,a as r,i as t};
|
|
2
|
+
//# sourceMappingURL=queue-Sg6KJerl.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-CG5izEBS.mjs","names":["Data.TaggedError","options"],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Promise-based work queue with bounded/unbounded capacity and shutdown modes.\n *\n * **Mental model**\n * - A queue coordinates concurrent task execution with backpressure.\n * - Enqueue returns a promise for each task result.\n *\n * **Common tasks**\n * - Create queues via `Queue.make`, `Queue.bounded`, or `Queue.unbounded`.\n * - Pause/resume processing and await idle state.\n * - Shutdown with drain or abort semantics.\n *\n * **Gotchas**\n * - Bounded queues can block enqueue when capacity is reached.\n * - Aborted queues reject queued and future tasks.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @module\n */\nimport { Data } from \"../data\"\nimport type {\n Concurrency,\n Queue as QueueType,\n QueueBoundedOptions,\n QueueOptions,\n QueueShutdownMode,\n QueueShutdownOptions,\n QueueTask,\n} from \"./queue.types\"\n\n/* oxlint-disable max-classes-per-file -- Queue exports dedicated error classes for precise instanceof checks at call sites. */\n/**\n * Error raised when enqueueing into a non-open queue.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueClosedError({ state: \"draining\" })\n * // => { _tag: \"QueueClosedError\", state: \"draining\" }\n * ```\n *\n * @category Models\n */\nexport class QueueClosedError extends Data.TaggedError(\"QueueClosedError\")<{ state: \"draining\" | \"aborted\" }> {}\n/**\n * Error raised when queue processing is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueAbortedError({ reason: \"manual\" })\n * // => { _tag: \"QueueAbortedError\", reason: \"manual\" }\n * ```\n *\n * @category Models\n */\nexport class QueueAbortedError extends Data.TaggedError(\"QueueAbortedError\")<{ reason?: unknown }> {}\n/**\n * Error raised when a specific task is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueTaskAbortedError({ reason: \"signal\" })\n * // => { _tag: \"QueueTaskAbortedError\", reason: \"signal\" }\n * ```\n *\n * @category Models\n */\nexport class QueueTaskAbortedError extends Data.TaggedError(\"QueueTaskAbortedError\")<{ reason?: unknown }> {}\n\ntype QueueState = \"open\" | \"draining\" | \"aborted\" | \"closed\"\n\ntype TaskEntry<A> = {\n readonly task: QueueTask<A>\n resolve(value: A | PromiseLike<A>): void\n reject(reason: unknown): void\n readonly signal: AbortSignal | undefined\n}\n\ntype CapacityWaiter = {\n resolve(): void\n reject(reason: Error): void\n readonly signal: AbortSignal | undefined\n}\n\nconst asConcurrencyLimit = (concurrency: Concurrency | undefined): number => {\n const resolved = concurrency ?? \"unbounded\"\n if (resolved === \"unbounded\") {\n return Number.POSITIVE_INFINITY\n }\n\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new RangeError(`Queue concurrency must be a positive integer or \"unbounded\", received: ${String(resolved)}`)\n }\n\n return resolved\n}\n\nconst assertMaxSize = (maxSize: number) => {\n if (maxSize === Number.POSITIVE_INFINITY) {\n return\n }\n\n if (!Number.isInteger(maxSize) || maxSize < 0) {\n throw new RangeError(`Queue maxSize must be an integer >= 0, received: ${String(maxSize)}`)\n }\n}\n\nconst queueTaskAbortedError = (signal: AbortSignal): QueueTaskAbortedError =>\n new QueueTaskAbortedError({ reason: signal.reason })\n\nconst queueClosedError = (state: \"draining\" | \"aborted\"): QueueClosedError => new QueueClosedError({ state })\n\nconst toError = (reason: unknown): Error =>\n reason instanceof Error ? reason : new Error(\"Queue rejection reason was not an Error\", { cause: reason })\n\nconst composeSignals = (queueSignal: AbortSignal, taskSignal: AbortSignal | undefined): AbortSignal => {\n if (taskSignal === undefined) {\n return queueSignal\n }\n\n if (taskSignal.aborted) {\n return taskSignal\n }\n\n if (queueSignal.aborted) {\n return queueSignal\n }\n\n const composite = new AbortController()\n\n const onQueueAbort = () => {\n composite.abort(queueSignal.reason)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n }\n\n const onTaskAbort = () => {\n composite.abort(taskSignal.reason)\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n }\n\n queueSignal.addEventListener(\"abort\", onQueueAbort, { once: true })\n taskSignal.addEventListener(\"abort\", onTaskAbort, { once: true })\n\n composite.signal.addEventListener(\n \"abort\",\n () => {\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n },\n { once: true },\n )\n\n return composite.signal\n}\n\n/**\n * Check if a value is a `Queue`.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const isQueue = Queue.is(queue)\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const is = (value: unknown): value is QueueType =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Queue\"\n\nconst createQueue = (maxSize: number, options?: QueueOptions): QueueType => {\n assertMaxSize(maxSize)\n\n const concurrencyLimit = asConcurrencyLimit(options?.concurrency)\n let state: QueueState = \"open\"\n let closeState: \"draining\" | \"aborted\" | undefined\n let paused = options?.autoStart === false\n let pending = 0\n let draining = false\n\n const queuedTasks: TaskEntry<unknown>[] = []\n const capacityWaiters: CapacityWaiter[] = []\n const idleWaiters = new Set<() => void>()\n\n const queueAbortController = new AbortController()\n\n let shutdownResolver: (() => void) | undefined\n let shutdownPromise: Promise<void> | undefined\n\n const resolveIdleIfNeeded = () => {\n if (pending !== 0 || queuedTasks.length > 0) {\n return\n }\n\n for (const resolve of idleWaiters) {\n resolve()\n }\n idleWaiters.clear()\n\n if (state === \"draining\" || state === \"aborted\") {\n state = \"closed\"\n shutdownResolver?.()\n shutdownResolver = undefined\n }\n }\n\n const rejectCapacityWaiters = (reason: Error) => {\n if (capacityWaiters.length === 0) {\n return\n }\n\n const waiters = capacityWaiters.splice(0)\n for (const waiter of waiters) {\n waiter.reject(reason)\n }\n }\n\n const releaseCapacityWaiters = () => {\n if (!Number.isFinite(maxSize) || capacityWaiters.length === 0) {\n return\n }\n\n while (capacityWaiters.length > 0 && queuedTasks.length < maxSize && state === \"open\") {\n const waiter = capacityWaiters.shift()\n if (waiter !== undefined) {\n waiter.resolve()\n }\n }\n }\n\n const applyAbortToQueuedTasks = (reason: unknown) => {\n if (queuedTasks.length === 0) {\n return\n }\n\n const error = new QueueAbortedError({ reason })\n const tasks = queuedTasks.splice(0)\n for (const entry of tasks) {\n entry.reject(error)\n }\n }\n\n const waitForCapacity = (signal: AbortSignal | undefined): Promise<void> => {\n if (!Number.isFinite(maxSize)) {\n return Promise.resolve()\n }\n\n if (queuedTasks.length < maxSize) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter: CapacityWaiter = {\n resolve: () => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n resolve()\n },\n reject: (error) => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n reject(error)\n },\n signal,\n }\n\n const onAbort =\n signal === undefined\n ? undefined\n : () => {\n const index = capacityWaiters.indexOf(waiter)\n if (index !== -1) {\n capacityWaiters.splice(index, 1)\n }\n reject(queueTaskAbortedError(signal))\n }\n\n if (signal !== undefined && signal.aborted) {\n reject(queueTaskAbortedError(signal))\n return\n }\n\n if (signal !== undefined && onAbort !== undefined) {\n signal.addEventListener(\"abort\", onAbort, { once: true })\n }\n\n capacityWaiters.push(waiter)\n })\n }\n\n const closeIfNeeded = () => {\n if ((state === \"draining\" || state === \"aborted\") && pending === 0 && queuedTasks.length === 0) {\n resolveIdleIfNeeded()\n }\n }\n\n const runTask = <A>(entry: TaskEntry<A>) => {\n pending += 1\n\n const taskSignal = composeSignals(queueAbortController.signal, entry.signal)\n\n let taskResult: Promise<A>\n if (taskSignal.aborted) {\n taskResult = Promise.reject(queueTaskAbortedError(taskSignal))\n } else {\n try {\n taskResult = Promise.resolve(entry.task({ signal: taskSignal }))\n } catch (error) {\n taskResult = Promise.reject(toError(error))\n }\n }\n\n void taskResult\n .then(\n (value) => {\n entry.resolve(value)\n return undefined\n },\n (error: unknown) => {\n entry.reject(toError(error))\n return undefined\n },\n )\n .finally(() => {\n pending -= 1\n releaseCapacityWaiters()\n drainQueue()\n resolveIdleIfNeeded()\n })\n }\n\n const drainQueue = () => {\n if (draining) {\n return\n }\n\n draining = true\n try {\n if (state === \"aborted\") {\n closeIfNeeded()\n return\n }\n\n while (!paused && pending < concurrencyLimit && queuedTasks.length > 0) {\n const entry = queuedTasks.shift()\n if (entry === undefined) {\n break\n }\n releaseCapacityWaiters()\n runTask(entry)\n }\n\n closeIfNeeded()\n } finally {\n draining = false\n }\n }\n\n const enqueueErrorForState = (): QueueClosedError => {\n if (closeState !== undefined) {\n return queueClosedError(closeState)\n }\n\n if (state === \"aborted\") {\n return queueClosedError(\"aborted\")\n }\n\n if (state === \"draining\") {\n return queueClosedError(\"draining\")\n }\n\n if (state === \"closed\") {\n return queueClosedError(closeState ?? \"draining\")\n }\n\n return queueClosedError(\"draining\")\n }\n\n const queue: QueueType = {\n _tag: \"Queue\",\n\n get pending(): number {\n return pending\n },\n\n get size(): number {\n return queuedTasks.length\n },\n\n get isPaused(): boolean {\n return paused\n },\n\n get isShutdown(): boolean {\n return state !== \"open\"\n },\n\n enqueue<A>(task: QueueTask<A>, options?: { readonly signal?: AbortSignal }): Promise<A> {\n const signal = options?.signal\n\n if (signal !== undefined && signal.aborted) {\n return Promise.reject(queueTaskAbortedError(signal))\n }\n\n if (state !== \"open\") {\n return Promise.reject(enqueueErrorForState())\n }\n\n const enqueueTask = () =>\n new Promise<A>((resolve, reject) => {\n const entry: TaskEntry<A> = {\n task,\n resolve,\n reject,\n signal,\n }\n\n queuedTasks.push(entry)\n drainQueue()\n })\n\n if (!Number.isFinite(maxSize) || queuedTasks.length < maxSize) {\n return enqueueTask()\n }\n\n return waitForCapacity(signal).then(() => {\n if (signal !== undefined && signal.aborted) {\n throw queueTaskAbortedError(signal)\n }\n\n if (state !== \"open\") {\n throw enqueueErrorForState()\n }\n\n return enqueueTask()\n })\n },\n\n pause(): void {\n paused = true\n },\n\n resume(): void {\n if (!paused) {\n return\n }\n\n paused = false\n drainQueue()\n },\n\n awaitIdle(): Promise<void> {\n if (pending === 0 && queuedTasks.length === 0) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve) => {\n idleWaiters.add(resolve)\n })\n },\n\n shutdown(options?: QueueShutdownOptions): Promise<void> {\n const mode: QueueShutdownMode = options?.mode ?? \"drain\"\n\n if (shutdownPromise !== undefined && (state === \"draining\" || state === \"aborted\" || state === \"closed\")) {\n if (mode === \"abort\" && closeState !== \"aborted\") {\n closeState = \"aborted\"\n state = \"aborted\"\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n closeIfNeeded()\n }\n\n return shutdownPromise\n }\n\n shutdownPromise =\n shutdownPromise ??\n new Promise<void>((resolve) => {\n shutdownResolver = resolve\n })\n\n if (mode === \"abort\") {\n closeState = \"aborted\"\n state = \"aborted\"\n paused = false\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n } else {\n closeState = \"draining\"\n if (state === \"open\") {\n state = \"draining\"\n }\n paused = false\n rejectCapacityWaiters(queueClosedError(\"draining\"))\n }\n\n drainQueue()\n resolveIdleIfNeeded()\n\n return shutdownPromise\n },\n }\n\n return queue\n}\n\n/**\n * Create a queue with default unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @category Constructors\n */\nexport const make = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/**\n * Create a queue with bounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.bounded(2)\n * const size = queue.size\n * // => 0\n * ```\n *\n * @category Constructors\n */\nexport const bounded = (maxSize: number, options?: QueueBoundedOptions): QueueType => createQueue(maxSize, options)\n\n/**\n * Create a queue with explicit unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.unbounded()\n * const paused = queue.isPaused\n * // => false\n * ```\n *\n * @category Constructors\n */\nexport const unbounded = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/* oxlint-enable max-classes-per-file */\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"queue-Sg6KJerl.mjs","names":["Data.TaggedError","options"],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Promise-based work queue with bounded/unbounded capacity and shutdown modes.\n *\n * **Mental model**\n * - A queue coordinates concurrent task execution with backpressure.\n * - Enqueue returns a promise for each task result.\n *\n * **Common tasks**\n * - Create queues via `Queue.make`, `Queue.bounded`, or `Queue.unbounded`.\n * - Pause/resume processing and await idle state.\n * - Shutdown with drain or abort semantics.\n *\n * **Gotchas**\n * - Bounded queues can block enqueue when capacity is reached.\n * - Aborted queues reject queued and future tasks.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @module\n */\nimport { Data } from \"../data\"\nimport type {\n Concurrency,\n Queue as QueueType,\n QueueBoundedOptions,\n QueueOptions,\n QueueShutdownMode,\n QueueShutdownOptions,\n QueueTask,\n} from \"./queue.types\"\n\n/* oxlint-disable max-classes-per-file -- Queue exports dedicated error classes for precise instanceof checks at call sites. */\n/**\n * Error raised when enqueueing into a non-open queue.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueClosedError({ state: \"draining\" })\n * // => { _tag: \"QueueClosedError\", state: \"draining\" }\n * ```\n *\n * @category Models\n */\nexport class QueueClosedError extends Data.TaggedError(\"QueueClosedError\")<{ state: \"draining\" | \"aborted\" }> {}\n/**\n * Error raised when queue processing is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueAbortedError({ reason: \"manual\" })\n * // => { _tag: \"QueueAbortedError\", reason: \"manual\" }\n * ```\n *\n * @category Models\n */\nexport class QueueAbortedError extends Data.TaggedError(\"QueueAbortedError\")<{ reason?: unknown }> {}\n/**\n * Error raised when a specific task is aborted.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const error = new Queue.QueueTaskAbortedError({ reason: \"signal\" })\n * // => { _tag: \"QueueTaskAbortedError\", reason: \"signal\" }\n * ```\n *\n * @category Models\n */\nexport class QueueTaskAbortedError extends Data.TaggedError(\"QueueTaskAbortedError\")<{ reason?: unknown }> {}\n\ntype QueueState = \"open\" | \"draining\" | \"aborted\" | \"closed\"\n\ntype TaskEntry<A> = {\n readonly task: QueueTask<A>\n resolve(value: A | PromiseLike<A>): void\n reject(reason: unknown): void\n readonly signal: AbortSignal | undefined\n}\n\ntype CapacityWaiter = {\n resolve(): void\n reject(reason: Error): void\n readonly signal: AbortSignal | undefined\n}\n\nconst asConcurrencyLimit = (concurrency: Concurrency | undefined): number => {\n const resolved = concurrency ?? \"unbounded\"\n if (resolved === \"unbounded\") {\n return Number.POSITIVE_INFINITY\n }\n\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new RangeError(`Queue concurrency must be a positive integer or \"unbounded\", received: ${String(resolved)}`)\n }\n\n return resolved\n}\n\nconst assertMaxSize = (maxSize: number) => {\n if (maxSize === Number.POSITIVE_INFINITY) {\n return\n }\n\n if (!Number.isInteger(maxSize) || maxSize < 0) {\n throw new RangeError(`Queue maxSize must be an integer >= 0, received: ${String(maxSize)}`)\n }\n}\n\nconst queueTaskAbortedError = (signal: AbortSignal): QueueTaskAbortedError =>\n new QueueTaskAbortedError({ reason: signal.reason })\n\nconst queueClosedError = (state: \"draining\" | \"aborted\"): QueueClosedError => new QueueClosedError({ state })\n\nconst toError = (reason: unknown): Error =>\n reason instanceof Error ? reason : new Error(\"Queue rejection reason was not an Error\", { cause: reason })\n\nconst composeSignals = (queueSignal: AbortSignal, taskSignal: AbortSignal | undefined): AbortSignal => {\n if (taskSignal === undefined) {\n return queueSignal\n }\n\n if (taskSignal.aborted) {\n return taskSignal\n }\n\n if (queueSignal.aborted) {\n return queueSignal\n }\n\n const composite = new AbortController()\n\n const onQueueAbort = () => {\n composite.abort(queueSignal.reason)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n }\n\n const onTaskAbort = () => {\n composite.abort(taskSignal.reason)\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n }\n\n queueSignal.addEventListener(\"abort\", onQueueAbort, { once: true })\n taskSignal.addEventListener(\"abort\", onTaskAbort, { once: true })\n\n composite.signal.addEventListener(\n \"abort\",\n () => {\n queueSignal.removeEventListener(\"abort\", onQueueAbort)\n taskSignal.removeEventListener(\"abort\", onTaskAbort)\n },\n { once: true },\n )\n\n return composite.signal\n}\n\n/**\n * Check if a value is a `Queue`.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const isQueue = Queue.is(queue)\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const is = (value: unknown): value is QueueType =>\n typeof value === \"object\" && value !== null && \"_tag\" in value && value._tag === \"Queue\"\n\nconst createQueue = (maxSize: number, options?: QueueOptions): QueueType => {\n assertMaxSize(maxSize)\n\n const concurrencyLimit = asConcurrencyLimit(options?.concurrency)\n let state: QueueState = \"open\"\n let closeState: \"draining\" | \"aborted\" | undefined\n let paused = options?.autoStart === false\n let pending = 0\n let draining = false\n\n const queuedTasks: TaskEntry<unknown>[] = []\n const capacityWaiters: CapacityWaiter[] = []\n const idleWaiters = new Set<() => void>()\n\n const queueAbortController = new AbortController()\n\n let shutdownResolver: (() => void) | undefined\n let shutdownPromise: Promise<void> | undefined\n\n const resolveIdleIfNeeded = () => {\n if (pending !== 0 || queuedTasks.length > 0) {\n return\n }\n\n for (const resolve of idleWaiters) {\n resolve()\n }\n idleWaiters.clear()\n\n if (state === \"draining\" || state === \"aborted\") {\n state = \"closed\"\n shutdownResolver?.()\n shutdownResolver = undefined\n }\n }\n\n const rejectCapacityWaiters = (reason: Error) => {\n if (capacityWaiters.length === 0) {\n return\n }\n\n const waiters = capacityWaiters.splice(0)\n for (const waiter of waiters) {\n waiter.reject(reason)\n }\n }\n\n const releaseCapacityWaiters = () => {\n if (!Number.isFinite(maxSize) || capacityWaiters.length === 0) {\n return\n }\n\n while (capacityWaiters.length > 0 && queuedTasks.length < maxSize && state === \"open\") {\n const waiter = capacityWaiters.shift()\n if (waiter !== undefined) {\n waiter.resolve()\n }\n }\n }\n\n const applyAbortToQueuedTasks = (reason: unknown) => {\n if (queuedTasks.length === 0) {\n return\n }\n\n const error = new QueueAbortedError({ reason })\n const tasks = queuedTasks.splice(0)\n for (const entry of tasks) {\n entry.reject(error)\n }\n }\n\n const waitForCapacity = (signal: AbortSignal | undefined): Promise<void> => {\n if (!Number.isFinite(maxSize)) {\n return Promise.resolve()\n }\n\n if (queuedTasks.length < maxSize) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve, reject) => {\n const waiter: CapacityWaiter = {\n resolve: () => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n resolve()\n },\n reject: (error) => {\n if (signal !== undefined && onAbort !== undefined) {\n signal.removeEventListener(\"abort\", onAbort)\n }\n reject(error)\n },\n signal,\n }\n\n const onAbort =\n signal === undefined\n ? undefined\n : () => {\n const index = capacityWaiters.indexOf(waiter)\n if (index !== -1) {\n capacityWaiters.splice(index, 1)\n }\n reject(queueTaskAbortedError(signal))\n }\n\n if (signal !== undefined && signal.aborted) {\n reject(queueTaskAbortedError(signal))\n return\n }\n\n if (signal !== undefined && onAbort !== undefined) {\n signal.addEventListener(\"abort\", onAbort, { once: true })\n }\n\n capacityWaiters.push(waiter)\n })\n }\n\n const closeIfNeeded = () => {\n if ((state === \"draining\" || state === \"aborted\") && pending === 0 && queuedTasks.length === 0) {\n resolveIdleIfNeeded()\n }\n }\n\n const runTask = <A>(entry: TaskEntry<A>) => {\n pending += 1\n\n const taskSignal = composeSignals(queueAbortController.signal, entry.signal)\n\n let taskResult: Promise<A>\n if (taskSignal.aborted) {\n taskResult = Promise.reject(queueTaskAbortedError(taskSignal))\n } else {\n try {\n taskResult = Promise.resolve(entry.task({ signal: taskSignal }))\n } catch (error) {\n taskResult = Promise.reject(toError(error))\n }\n }\n\n void taskResult\n .then(\n (value) => {\n entry.resolve(value)\n return undefined\n },\n (error: unknown) => {\n entry.reject(toError(error))\n return undefined\n },\n )\n .finally(() => {\n pending -= 1\n releaseCapacityWaiters()\n drainQueue()\n resolveIdleIfNeeded()\n })\n }\n\n const drainQueue = () => {\n if (draining) {\n return\n }\n\n draining = true\n try {\n if (state === \"aborted\") {\n closeIfNeeded()\n return\n }\n\n while (!paused && pending < concurrencyLimit && queuedTasks.length > 0) {\n const entry = queuedTasks.shift()\n if (entry === undefined) {\n break\n }\n releaseCapacityWaiters()\n runTask(entry)\n }\n\n closeIfNeeded()\n } finally {\n draining = false\n }\n }\n\n const enqueueErrorForState = (): QueueClosedError => {\n if (closeState !== undefined) {\n return queueClosedError(closeState)\n }\n\n if (state === \"aborted\") {\n return queueClosedError(\"aborted\")\n }\n\n if (state === \"draining\") {\n return queueClosedError(\"draining\")\n }\n\n if (state === \"closed\") {\n return queueClosedError(closeState ?? \"draining\")\n }\n\n return queueClosedError(\"draining\")\n }\n\n const queue: QueueType = {\n _tag: \"Queue\",\n\n get pending(): number {\n return pending\n },\n\n get size(): number {\n return queuedTasks.length\n },\n\n get isPaused(): boolean {\n return paused\n },\n\n get isShutdown(): boolean {\n return state !== \"open\"\n },\n\n enqueue<A>(task: QueueTask<A>, options?: { readonly signal?: AbortSignal }): Promise<A> {\n const signal = options?.signal\n\n if (signal !== undefined && signal.aborted) {\n return Promise.reject(queueTaskAbortedError(signal))\n }\n\n if (state !== \"open\") {\n return Promise.reject(enqueueErrorForState())\n }\n\n const enqueueTask = () =>\n new Promise<A>((resolve, reject) => {\n const entry: TaskEntry<A> = {\n task,\n resolve,\n reject,\n signal,\n }\n\n queuedTasks.push(entry)\n drainQueue()\n })\n\n if (!Number.isFinite(maxSize) || queuedTasks.length < maxSize) {\n return enqueueTask()\n }\n\n return waitForCapacity(signal).then(() => {\n if (signal !== undefined && signal.aborted) {\n throw queueTaskAbortedError(signal)\n }\n\n if (state !== \"open\") {\n throw enqueueErrorForState()\n }\n\n return enqueueTask()\n })\n },\n\n pause(): void {\n paused = true\n },\n\n resume(): void {\n if (!paused) {\n return\n }\n\n paused = false\n drainQueue()\n },\n\n awaitIdle(): Promise<void> {\n if (pending === 0 && queuedTasks.length === 0) {\n return Promise.resolve()\n }\n\n return new Promise<void>((resolve) => {\n idleWaiters.add(resolve)\n })\n },\n\n shutdown(options?: QueueShutdownOptions): Promise<void> {\n const mode: QueueShutdownMode = options?.mode ?? \"drain\"\n\n if (shutdownPromise !== undefined && (state === \"draining\" || state === \"aborted\" || state === \"closed\")) {\n if (mode === \"abort\" && closeState !== \"aborted\") {\n closeState = \"aborted\"\n state = \"aborted\"\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n closeIfNeeded()\n }\n\n return shutdownPromise\n }\n\n shutdownPromise =\n shutdownPromise ??\n new Promise<void>((resolve) => {\n shutdownResolver = resolve\n })\n\n if (mode === \"abort\") {\n closeState = \"aborted\"\n state = \"aborted\"\n paused = false\n queueAbortController.abort(options?.reason)\n applyAbortToQueuedTasks(options?.reason)\n rejectCapacityWaiters(queueClosedError(\"aborted\"))\n } else {\n closeState = \"draining\"\n if (state === \"open\") {\n state = \"draining\"\n }\n paused = false\n rejectCapacityWaiters(queueClosedError(\"draining\"))\n }\n\n drainQueue()\n resolveIdleIfNeeded()\n\n return shutdownPromise\n },\n }\n\n return queue\n}\n\n/**\n * Create a queue with default unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.make()\n * const pending = queue.pending\n * // => 0\n * ```\n *\n * @category Constructors\n */\nexport const make = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/**\n * Create a queue with bounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.bounded(2)\n * const size = queue.size\n * // => 0\n * ```\n *\n * @category Constructors\n */\nexport const bounded = (maxSize: number, options?: QueueBoundedOptions): QueueType => createQueue(maxSize, options)\n\n/**\n * Create a queue with explicit unbounded capacity.\n *\n * @example\n * ```ts\n * import { Queue } from \"@nicolastoulemont/std\"\n *\n * const queue = Queue.unbounded()\n * const paused = queue.isPaused\n * // => false\n * ```\n *\n * @category Constructors\n */\nexport const unbounded = (options?: QueueOptions): QueueType => createQueue(Number.POSITIVE_INFINITY, options)\n\n/* oxlint-enable max-classes-per-file */\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"result-BEzV0DYC.mjs","names":["values"],"sources":["../src/result/result.ts"],"sourcesContent":["/**\n * Synchronous success/error primitives with typed channels (`Ok` / `Err`).\n *\n * **Mental model**\n * - `Result<A, E>` makes success and failure explicit.\n * - Use `flatMap` to sequence fallible operations without throwing.\n *\n * **Common tasks**\n * - Construct with `Result.ok`, `Result.err`, `Result.fromTry`.\n * - Transform with `Result.map`, `Result.mapErr`, `Result.flatMap`.\n * - Handle with `Result.match` or `Result.unwrapOr`.\n *\n * **Gotchas**\n * - `Result.err` short-circuits in `Fx.gen`.\n * - Keep domain errors in the `E` channel instead of throwing.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.fromTry(() => Number.parseInt(\"42\", 10))\n * const doubled = Result.map(parsed, (value) => value * 2)\n * ```\n *\n * @module\n */\nimport { FxTypeId } from \"../fx/fx.types\"\nimport { dual } from \"../shared/dual\"\nimport { isPromise } from \"../shared/is-promise\"\nimport { pipeMethod } from \"../shared/pipeable\"\nimport type {\n FromTryOptions,\n Result as ResultType,\n ResultAll,\n ResultFlatMap,\n ResultFromTry,\n ResultMap,\n ResultMapErr,\n ResultMatch,\n ResultTap,\n ResultOrElse,\n ResultFilter,\n ResultUnwrapOr,\n ResultUnwrapOrElse,\n} from \"./result.types\"\n\n/**\n * Re-exported `Result` type.\n *\n * @example\n * ```ts\n * import type { Result } from \"@nicolastoulemont/std\"\n *\n * type Example = Result.Result<unknown, unknown>\n * ```\n *\n * @category Re-exports\n */\nexport type Result<T, E> = ResultType<T, E>\n\n/* oxlint-disable no-unsafe-type-assertion -- Result constructors encode Fx phantom channels and iterator contracts via type-level markers. */\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a successful Result.\n *\n * @param value - The success value\n * @returns A Result with _tag: \"Ok\"\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Result.ok(42)\n * // => { _tag: \"Ok\", value: 42 }\n * ```\n *\n * @category Constructors\n */\nexport const ok = <T>(value: T): ResultType<T, never> => {\n const result: ResultType<T, never> = {\n _tag: \"Ok\",\n value,\n pipe: pipeMethod,\n [FxTypeId]: {\n _A: () => value,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<ResultType<T, never>, T, unknown> {\n return value\n },\n }\n return result\n}\n\n/**\n * Create an error Result.\n *\n * @param error - The error value\n * @returns A Result with _tag: \"Err\"\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Result.err(\"boom\")\n * // => { _tag: \"Err\", error: \"boom\" }\n * ```\n *\n * @category Constructors\n */\nexport const err = <E>(error: E): ResultType<never, E> => {\n const result: ResultType<never, E> = {\n _tag: \"Err\",\n error,\n pipe: pipeMethod,\n [FxTypeId]: {\n _A: () => undefined as never,\n _E: () => error,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<ResultType<never, E>, never, unknown> {\n yield result\n throw new Error(\"Unreachable: Fx.gen should short-circuit on error\")\n },\n }\n return result\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if a Result is successful.\n *\n * @param result - The Result to check\n * @returns true if the Result is Ok\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const isOk = Result.isOk(Result.ok(1))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isOk = <T, E>(result: ResultType<T, E>): result is Extract<ResultType<T, E>, { _tag: \"Ok\" }> =>\n result._tag === \"Ok\"\n\n/**\n * Check if a Result is an error.\n *\n * @param result - The Result to check\n * @returns true if the Result is an error\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const isErr = Result.isErr(Result.err(\"boom\"))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isErr = <T, E>(result: ResultType<T, E>): result is Extract<ResultType<T, E>, { _tag: \"Err\" }> =>\n result._tag === \"Err\"\n\n// ============================================================================\n// Transformations (curried for pipe)\n// ============================================================================\n\n/**\n * Transform the success value of a Result.\n * If the Result is an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `map(result, fn)`\n * - Data-last: `pipe(result, map(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<U, E>\n * - Async fn: returns Promise<Result<U, E>>\n *\n * @param fn - Function to transform the success value\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2)\n * const dataFirst = Result.map(input, (n) => n + 1)\n * // => { _tag: \"Ok\", value: 3 }\n * \n * const dataLast = Result.map((n: number) => n + 1)(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const map: ResultMap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (result._tag === \"Err\") return result as any\n const mapped = fn(result.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(ok) as any\n }\n return ok(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Transform the error value of a Result.\n * If the Result is successful, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `mapErr(result, fn)`\n * - Data-last: `pipe(result, mapErr(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T, F>\n * - Async fn: returns Promise<Result<T, F>>\n *\n * @param fn - Function to transform the error value\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\")\n * const dataFirst = Result.mapErr(input, (msg) => msg.toUpperCase())\n * // => { _tag: \"Err\", error: \"MISSING\" }\n *\n * const dataLast = Result.mapErr((msg: string) => msg.toUpperCase())(input)\n * // => { _tag: \"Err\", error: \"MISSING\" }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const mapErr: ResultMapErr = dual(2, (result: ResultType<unknown, unknown>, fn: (error: unknown) => unknown) => {\n if (result._tag === \"Ok\") return result as any\n const mapped = fn(result.error)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(err) as any\n }\n return err(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Chain operations that return Results.\n * If the Result is an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `flatMap(result, fn)`\n * - Data-last: `pipe(result, flatMap(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<U, E | E2>\n * - Async fn: returns Promise<Result<U, E | E2>>\n *\n * @param fn - Function that takes a value and returns a Result (or Promise<Result>)\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2)\n * const dataFirst = Result.flatMap(input, (n) => Result.ok(n + 1))\n * // => { _tag: \"Ok\", value: 3 }\n * \n * const dataLast = Result.flatMap((n: number) => Result.ok(n + 1))(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Sequencing\n */\n// oxlint-disable-next-line no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types\nexport const flatMap: ResultFlatMap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) =>\n result._tag === \"Ok\" ? fn(result.value) : result,\n)\n\n/**\n * Perform a side effect on the success value without modifying the Result.\n * Useful for debugging, logging, or other side effects in a pipeline.\n * If the Result is an error, the function is not called.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tap(result, fn)`\n * - Data-last: `pipe(result, tap(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T, E>\n * - Async fn: returns Promise<Result<T, E>>\n *\n * @param fn - Function to call with the success value (return value is ignored)\n * @returns A function that takes a Result and returns the same Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * let seen = 0\n * const input = Result.ok(2)\n * const dataFirst = Result.tap(input, (n) => {\n * seen = n\n * })\n * // => { _tag: \"Ok\", value: 2 }\n * \n * const dataLast = Result.tap((n: number) => {\n * seen = n\n * })(input)\n * // => { _tag: \"Ok\", value: 2 }\n * ```\n *\n * @category Sequencing\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tap: ResultTap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (result._tag === \"Err\") return result as any\n const sideEffect = fn(result.value)\n if (isPromise(sideEffect)) {\n return Promise.resolve(sideEffect).then(() => result) as any\n }\n return result as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Recover from an error by providing an alternative Result.\n * If the Result is successful, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `orElse(result, fn)`\n * - Data-last: `pipe(result, orElse(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T | U, E2>\n * - Async fn: returns Promise<Result<T | U, E2>>\n *\n * @param fn - Function that takes the error and returns an alternative Result\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.orElse(input, () => Result.ok(0))\n * // => { _tag: \"Ok\", value: 0 }\n * \n * const dataLast = Result.orElse(() => Result.ok(0))(input)\n * // => { _tag: \"Ok\", value: 0 }\n * ```\n *\n * @category Error Handling\n */\n// oxlint-disable-next-line no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types\nexport const orElse: ResultOrElse = dual(2, (result: ResultType<unknown, unknown>, fn: (error: unknown) => unknown) =>\n result._tag === \"Ok\" ? result : fn(result.error),\n)\n\n/**\n * Filter a successful Result based on a predicate.\n * If the predicate returns false, converts the success to an error.\n * If the Result is already an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `filter(result, predicate, onFail)`\n * - Data-last: `pipe(result, filter(predicate, onFail))`\n *\n * @param predicate - Function that returns true to keep the value\n * @param onFail - Function that creates the error when predicate fails\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(3)\n * const dataFirst = Result.filter(input, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Ok\", value: 3 }\n * \n * const dataLast = Result.filter((n: number) => n > 0, (n) => `${n} must be positive`)(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Filtering\n */\nexport const filter: ResultFilter = dual(\n 3,\n (\n result: ResultType<unknown, unknown>,\n predicate: (value: unknown) => boolean,\n onFail: (value: unknown) => unknown,\n ) => {\n if (result._tag === \"Err\") return result\n return predicate(result.value) ? result : err(onFail(result.value))\n },\n)\n\n// ============================================================================\n// Combinators\n// ============================================================================\n\n/**\n * Combine multiple Results into a single Result.\n * Supports both array and object inputs.\n *\n * - If all Results are ok, returns ok with all values\n * - If any Result is an error, returns the first error (short-circuits)\n *\n * For arrays of 1-6 elements, tuple types are inferred automatically.\n * For longer arrays, use `as const` to preserve tuple structure.\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const combined = Result.all([Result.ok(1), Result.ok(2)] as const)\n * // => { _tag: \"Ok\", value: [1, 2] }\n * ```\n *\n * @category Combining\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-type-assertion, no-unsafe-argument -- Required for handling union types in overloaded function */\nexport const all: ResultAll = (results: any): any => {\n if (Array.isArray(results)) {\n const values: unknown[] = []\n for (const result of results) {\n if (result._tag === \"Err\") return result\n values.push(result.value)\n }\n return ok(values)\n }\n\n const values: Record<string, unknown> = {}\n for (const [key, result] of Object.entries(results)) {\n const r = result as ResultType<unknown, unknown>\n if (r._tag === \"Err\") return result\n values[key] = r.value\n }\n return ok(values)\n}\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-type-assertion, no-unsafe-argument */\n\n// ============================================================================\n// Extraction\n// ============================================================================\n\n/**\n * Get the success value or a default value.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOr(result, defaultValue)`\n * - Data-last: `pipe(result, unwrapOr(defaultValue))`\n *\n * Uses NoInfer to prevent type inference from the default value.\n *\n * @param defaultValue - Value to return if the Result is an error\n * @returns A function that takes a Result and returns the value or default\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.unwrapOr(input, 0)\n * // => 0\n * \n * const dataLast = Result.unwrapOr(0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOr: ResultUnwrapOr = dual(\n 2,\n <T, E>(result: ResultType<T, E>, defaultValue: NoInfer<T>): T => (result._tag === \"Ok\" ? result.value : defaultValue),\n)\n\n/**\n * Get the success value or compute a value from the error.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOrElse(result, fn)`\n * - Data-last: `pipe(result, unwrapOrElse(fn))`\n *\n * @param fn - Function to compute a value from the error\n * @returns A function that takes a Result and returns the value or computed value\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.unwrapOrElse(input, () => 0)\n * // => 0\n *\n * const dataLast = Result.unwrapOrElse(() => 0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOrElse: ResultUnwrapOrElse = dual(\n 2,\n <T, E>(result: ResultType<T, E>, fn: (error: E) => T): T => (result._tag === \"Ok\" ? result.value : fn(result.error)),\n)\n\n/**\n * Pattern match on a Result, handling both success and error cases.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `match(result, { Ok: ..., Err: ... })`\n * - Data-last: `pipe(result, match({ Ok: ..., Err: ... }))`\n *\n * @param handlers - Object with `Ok` and `Err` handlers\n * @returns A function that takes a Result and returns the handler result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2) as Result.Result<number, string>\n * const dataFirst = Result.match(input, {\n * Ok: (value) => `ok:${value}` ,\n * Err: (error) => `err:${error}` ,\n * })\n * // => \"ok:2\"\n * \n * const dataLast = Result.match({\n * Ok: (value: number) => `ok:${value}` ,\n * Err: (error: string) => `err:${error}` ,\n * })(input)\n * // => \"ok:2\"\n * ```\n *\n * @category Pattern Matching\n */\nexport const match: ResultMatch = dual(\n 2,\n <T, E, U>(result: ResultType<T, E>, handlers: { Ok: (value: T) => U; Err: (error: E) => U }): U =>\n result._tag === \"Ok\" ? handlers.Ok(result.value) : handlers.Err(result.error),\n)\n\n// ============================================================================\n// Error Boundary\n// ============================================================================\n\n/**\n * Wrap a function that might throw into a Result.\n * Supports both sync and async functions with automatic type inference.\n *\n * Can be called with a simple callback or an object with `try` and `catch`:\n * - Simple: `fromTry(() => riskyOp())` — errors are wrapped as `Error`\n * - Object: `fromTry({ try: () => riskyOp(), catch: (e) => mapError(e) })` — custom error mapping\n *\n * @param fnOrOptions - Function that might throw, or object with `try` and `catch`\n * @returns A Result with the return value or the caught/mapped error\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.fromTry(() => Number.parseInt(\"42\", 10))\n * // => { _tag: \"Ok\", value: 42 }\n * ```\n *\n * @category Constructors\n */\n/* oxlint-disable no-explicit-any, no-unsafe-type-assertion -- Required for overloaded return type */\nexport const fromTry: ResultFromTry = (fnOrOptions: (() => unknown) | FromTryOptions<unknown, unknown>): any => {\n const fn = typeof fnOrOptions === \"function\" ? fnOrOptions : fnOrOptions.try\n const catchFn =\n typeof fnOrOptions === \"function\"\n ? (e: unknown) => (e instanceof Error ? e : new Error(String(e)))\n : fnOrOptions.catch\n const finallyFn = typeof fnOrOptions === \"function\" ? undefined : fnOrOptions.finally\n\n let isAsync = false\n try {\n const result = fn()\n if (isPromise(result)) {\n isAsync = true\n const promise = Promise.resolve(result)\n .then(ok)\n .catch((e: unknown) => err(catchFn(e)))\n return finallyFn ? promise.finally(finallyFn) : promise\n }\n return ok(result)\n } catch (e) {\n return err(catchFn(e))\n } finally {\n if (finallyFn && !isAsync) {\n finallyFn()\n }\n }\n}\n/* oxlint-enable no-explicit-any, no-unsafe-type-assertion */\n\nconst try_ = fromTry\n\nexport {\n /**\n * Alias of {@link fromTry}.\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.try(() => JSON.parse(\"{\\\"ok\\\":true}\"))\n * ```\n *\n * @category Constructors\n */\n try_ as try,\n}\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"result-BEzV0DYC.mjs","names":["values"],"sources":["../src/result/result.ts"],"sourcesContent":["/**\n * Synchronous success/error primitives with typed channels (`Ok` / `Err`).\n *\n * **Mental model**\n * - `Result<A, E>` makes success and failure explicit.\n * - Use `flatMap` to sequence fallible operations without throwing.\n *\n * **Common tasks**\n * - Construct with `Result.ok`, `Result.err`, `Result.fromTry`.\n * - Transform with `Result.map`, `Result.mapErr`, `Result.flatMap`.\n * - Handle with `Result.match` or `Result.unwrapOr`.\n *\n * **Gotchas**\n * - `Result.err` short-circuits in `Fx.gen`.\n * - Keep domain errors in the `E` channel instead of throwing.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.fromTry(() => Number.parseInt(\"42\", 10))\n * const doubled = Result.map(parsed, (value) => value * 2)\n * ```\n *\n * @module\n */\nimport { FxTypeId } from \"../fx/fx.types\"\nimport { dual } from \"../shared/dual\"\nimport { isPromise } from \"../shared/is-promise\"\nimport { pipeMethod } from \"../shared/pipeable\"\nimport type {\n FromTryOptions,\n Result as ResultType,\n ResultAll,\n ResultFlatMap,\n ResultFromTry,\n ResultMap,\n ResultMapErr,\n ResultMatch,\n ResultTap,\n ResultOrElse,\n ResultFilter,\n ResultUnwrapOr,\n ResultUnwrapOrElse,\n} from \"./result.types\"\n\n/**\n * Re-exported `Result` type.\n *\n * @example\n * ```ts\n * import type { Result } from \"@nicolastoulemont/std\"\n *\n * type Example = Result.Result<unknown, unknown>\n * ```\n *\n * @category Re-exports\n */\nexport type Result<T, E> = ResultType<T, E>\n\n/* oxlint-disable no-unsafe-type-assertion -- Result constructors encode Fx phantom channels and iterator contracts via type-level markers. */\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a successful Result.\n *\n * @param value - The success value\n * @returns A Result with _tag: \"Ok\"\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Result.ok(42)\n * // => { _tag: \"Ok\", value: 42 }\n * ```\n *\n * @category Constructors\n */\nexport const ok = <T>(value: T): ResultType<T, never> => {\n const result: ResultType<T, never> = {\n _tag: \"Ok\",\n value,\n pipe: pipeMethod,\n [FxTypeId]: {\n _A: () => value,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<ResultType<T, never>, T, unknown> {\n return value\n },\n }\n return result\n}\n\n/**\n * Create an error Result.\n *\n * @param error - The error value\n * @returns A Result with _tag: \"Err\"\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const value = Result.err(\"boom\")\n * // => { _tag: \"Err\", error: \"boom\" }\n * ```\n *\n * @category Constructors\n */\nexport const err = <E>(error: E): ResultType<never, E> => {\n const result: ResultType<never, E> = {\n _tag: \"Err\",\n error,\n pipe: pipeMethod,\n [FxTypeId]: {\n _A: () => undefined as never,\n _E: () => error,\n _R: () => undefined as never,\n },\n *[Symbol.iterator](): Generator<ResultType<never, E>, never, unknown> {\n yield result\n throw new Error(\"Unreachable: Fx.gen should short-circuit on error\")\n },\n }\n return result\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if a Result is successful.\n *\n * @param result - The Result to check\n * @returns true if the Result is Ok\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const isOk = Result.isOk(Result.ok(1))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isOk = <T, E>(result: ResultType<T, E>): result is Extract<ResultType<T, E>, { _tag: \"Ok\" }> =>\n result._tag === \"Ok\"\n\n/**\n * Check if a Result is an error.\n *\n * @param result - The Result to check\n * @returns true if the Result is an error\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const isErr = Result.isErr(Result.err(\"boom\"))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isErr = <T, E>(result: ResultType<T, E>): result is Extract<ResultType<T, E>, { _tag: \"Err\" }> =>\n result._tag === \"Err\"\n\n// ============================================================================\n// Transformations (curried for pipe)\n// ============================================================================\n\n/**\n * Transform the success value of a Result.\n * If the Result is an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `map(result, fn)`\n * - Data-last: `pipe(result, map(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<U, E>\n * - Async fn: returns Promise<Result<U, E>>\n *\n * @param fn - Function to transform the success value\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2)\n * const dataFirst = Result.map(input, (n) => n + 1)\n * // => { _tag: \"Ok\", value: 3 }\n *\n * const dataLast = Result.map((n: number) => n + 1)(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const map: ResultMap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (result._tag === \"Err\") return result as any\n const mapped = fn(result.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(ok) as any\n }\n return ok(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Transform the error value of a Result.\n * If the Result is successful, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `mapErr(result, fn)`\n * - Data-last: `pipe(result, mapErr(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T, F>\n * - Async fn: returns Promise<Result<T, F>>\n *\n * @param fn - Function to transform the error value\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\")\n * const dataFirst = Result.mapErr(input, (msg) => msg.toUpperCase())\n * // => { _tag: \"Err\", error: \"MISSING\" }\n *\n * const dataLast = Result.mapErr((msg: string) => msg.toUpperCase())(input)\n * // => { _tag: \"Err\", error: \"MISSING\" }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const mapErr: ResultMapErr = dual(2, (result: ResultType<unknown, unknown>, fn: (error: unknown) => unknown) => {\n if (result._tag === \"Ok\") return result as any\n const mapped = fn(result.error)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(err) as any\n }\n return err(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Chain operations that return Results.\n * If the Result is an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `flatMap(result, fn)`\n * - Data-last: `pipe(result, flatMap(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<U, E | E2>\n * - Async fn: returns Promise<Result<U, E | E2>>\n *\n * @param fn - Function that takes a value and returns a Result (or Promise<Result>)\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2)\n * const dataFirst = Result.flatMap(input, (n) => Result.ok(n + 1))\n * // => { _tag: \"Ok\", value: 3 }\n *\n * const dataLast = Result.flatMap((n: number) => Result.ok(n + 1))(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Sequencing\n */\n// oxlint-disable-next-line no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types\nexport const flatMap: ResultFlatMap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) =>\n result._tag === \"Ok\" ? fn(result.value) : result,\n)\n\n/**\n * Perform a side effect on the success value without modifying the Result.\n * Useful for debugging, logging, or other side effects in a pipeline.\n * If the Result is an error, the function is not called.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tap(result, fn)`\n * - Data-last: `pipe(result, tap(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T, E>\n * - Async fn: returns Promise<Result<T, E>>\n *\n * @param fn - Function to call with the success value (return value is ignored)\n * @returns A function that takes a Result and returns the same Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * let seen = 0\n * const input = Result.ok(2)\n * const dataFirst = Result.tap(input, (n) => {\n * seen = n\n * })\n * // => { _tag: \"Ok\", value: 2 }\n *\n * const dataLast = Result.tap((n: number) => {\n * seen = n\n * })(input)\n * // => { _tag: \"Ok\", value: 2 }\n * ```\n *\n * @category Sequencing\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tap: ResultTap = dual(2, (result: ResultType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (result._tag === \"Err\") return result as any\n const sideEffect = fn(result.value)\n if (isPromise(sideEffect)) {\n return Promise.resolve(sideEffect).then(() => result) as any\n }\n return result as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Recover from an error by providing an alternative Result.\n * If the Result is successful, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `orElse(result, fn)`\n * - Data-last: `pipe(result, orElse(fn))`\n *\n * Supports both sync and async functions:\n * - Sync fn: returns Result<T | U, E2>\n * - Async fn: returns Promise<Result<T | U, E2>>\n *\n * @param fn - Function that takes the error and returns an alternative Result\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.orElse(input, () => Result.ok(0))\n * // => { _tag: \"Ok\", value: 0 }\n *\n * const dataLast = Result.orElse(() => Result.ok(0))(input)\n * // => { _tag: \"Ok\", value: 0 }\n * ```\n *\n * @category Error Handling\n */\n// oxlint-disable-next-line no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types\nexport const orElse: ResultOrElse = dual(2, (result: ResultType<unknown, unknown>, fn: (error: unknown) => unknown) =>\n result._tag === \"Ok\" ? result : fn(result.error),\n)\n\n/**\n * Filter a successful Result based on a predicate.\n * If the predicate returns false, converts the success to an error.\n * If the Result is already an error, it passes through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `filter(result, predicate, onFail)`\n * - Data-last: `pipe(result, filter(predicate, onFail))`\n *\n * @param predicate - Function that returns true to keep the value\n * @param onFail - Function that creates the error when predicate fails\n * @returns A function that takes a Result and returns a new Result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(3)\n * const dataFirst = Result.filter(input, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Ok\", value: 3 }\n *\n * const dataLast = Result.filter((n: number) => n > 0, (n) => `${n} must be positive`)(input)\n * // => { _tag: \"Ok\", value: 3 }\n * ```\n *\n * @category Filtering\n */\nexport const filter: ResultFilter = dual(\n 3,\n (\n result: ResultType<unknown, unknown>,\n predicate: (value: unknown) => boolean,\n onFail: (value: unknown) => unknown,\n ) => {\n if (result._tag === \"Err\") return result\n return predicate(result.value) ? result : err(onFail(result.value))\n },\n)\n\n// ============================================================================\n// Combinators\n// ============================================================================\n\n/**\n * Combine multiple Results into a single Result.\n * Supports both array and object inputs.\n *\n * - If all Results are ok, returns ok with all values\n * - If any Result is an error, returns the first error (short-circuits)\n *\n * For arrays of 1-6 elements, tuple types are inferred automatically.\n * For longer arrays, use `as const` to preserve tuple structure.\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const combined = Result.all([Result.ok(1), Result.ok(2)] as const)\n * // => { _tag: \"Ok\", value: [1, 2] }\n * ```\n *\n * @category Combining\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-type-assertion, no-unsafe-argument -- Required for handling union types in overloaded function */\nexport const all: ResultAll = (results: any): any => {\n if (Array.isArray(results)) {\n const values: unknown[] = []\n for (const result of results) {\n if (result._tag === \"Err\") return result\n values.push(result.value)\n }\n return ok(values)\n }\n\n const values: Record<string, unknown> = {}\n for (const [key, result] of Object.entries(results)) {\n const r = result as ResultType<unknown, unknown>\n if (r._tag === \"Err\") return result\n values[key] = r.value\n }\n return ok(values)\n}\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-type-assertion, no-unsafe-argument */\n\n// ============================================================================\n// Extraction\n// ============================================================================\n\n/**\n * Get the success value or a default value.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOr(result, defaultValue)`\n * - Data-last: `pipe(result, unwrapOr(defaultValue))`\n *\n * Uses NoInfer to prevent type inference from the default value.\n *\n * @param defaultValue - Value to return if the Result is an error\n * @returns A function that takes a Result and returns the value or default\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.unwrapOr(input, 0)\n * // => 0\n *\n * const dataLast = Result.unwrapOr(0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOr: ResultUnwrapOr = dual(\n 2,\n <T, E>(result: ResultType<T, E>, defaultValue: NoInfer<T>): T => (result._tag === \"Ok\" ? result.value : defaultValue),\n)\n\n/**\n * Get the success value or compute a value from the error.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOrElse(result, fn)`\n * - Data-last: `pipe(result, unwrapOrElse(fn))`\n *\n * @param fn - Function to compute a value from the error\n * @returns A function that takes a Result and returns the value or computed value\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.err(\"missing\") as Result.Result<number, string>\n * const dataFirst = Result.unwrapOrElse(input, () => 0)\n * // => 0\n *\n * const dataLast = Result.unwrapOrElse(() => 0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOrElse: ResultUnwrapOrElse = dual(\n 2,\n <T, E>(result: ResultType<T, E>, fn: (error: E) => T): T => (result._tag === \"Ok\" ? result.value : fn(result.error)),\n)\n\n/**\n * Pattern match on a Result, handling both success and error cases.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `match(result, { Ok: ..., Err: ... })`\n * - Data-last: `pipe(result, match({ Ok: ..., Err: ... }))`\n *\n * @param handlers - Object with `Ok` and `Err` handlers\n * @returns A function that takes a Result and returns the handler result\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const input = Result.ok(2) as Result.Result<number, string>\n * const dataFirst = Result.match(input, {\n * Ok: (value) => `ok:${value}` ,\n * Err: (error) => `err:${error}` ,\n * })\n * // => \"ok:2\"\n *\n * const dataLast = Result.match({\n * Ok: (value: number) => `ok:${value}` ,\n * Err: (error: string) => `err:${error}` ,\n * })(input)\n * // => \"ok:2\"\n * ```\n *\n * @category Pattern Matching\n */\nexport const match: ResultMatch = dual(\n 2,\n <T, E, U>(result: ResultType<T, E>, handlers: { Ok: (value: T) => U; Err: (error: E) => U }): U =>\n result._tag === \"Ok\" ? handlers.Ok(result.value) : handlers.Err(result.error),\n)\n\n// ============================================================================\n// Error Boundary\n// ============================================================================\n\n/**\n * Wrap a function that might throw into a Result.\n * Supports both sync and async functions with automatic type inference.\n *\n * Can be called with a simple callback or an object with `try` and `catch`:\n * - Simple: `fromTry(() => riskyOp())` — errors are wrapped as `Error`\n * - Object: `fromTry({ try: () => riskyOp(), catch: (e) => mapError(e) })` — custom error mapping\n *\n * @param fnOrOptions - Function that might throw, or object with `try` and `catch`\n * @returns A Result with the return value or the caught/mapped error\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.fromTry(() => Number.parseInt(\"42\", 10))\n * // => { _tag: \"Ok\", value: 42 }\n * ```\n *\n * @category Constructors\n */\n/* oxlint-disable no-explicit-any, no-unsafe-type-assertion -- Required for overloaded return type */\nexport const fromTry: ResultFromTry = (fnOrOptions: (() => unknown) | FromTryOptions<unknown, unknown>): any => {\n const fn = typeof fnOrOptions === \"function\" ? fnOrOptions : fnOrOptions.try\n const catchFn =\n typeof fnOrOptions === \"function\"\n ? (e: unknown) => (e instanceof Error ? e : new Error(String(e)))\n : fnOrOptions.catch\n const finallyFn = typeof fnOrOptions === \"function\" ? undefined : fnOrOptions.finally\n\n let isAsync = false\n try {\n const result = fn()\n if (isPromise(result)) {\n isAsync = true\n const promise = Promise.resolve(result)\n .then(ok)\n .catch((e: unknown) => err(catchFn(e)))\n return finallyFn ? promise.finally(finallyFn) : promise\n }\n return ok(result)\n } catch (e) {\n return err(catchFn(e))\n } finally {\n if (finallyFn && !isAsync) {\n finallyFn()\n }\n }\n}\n/* oxlint-enable no-explicit-any, no-unsafe-type-assertion */\n\nconst try_ = fromTry\n\nexport {\n /**\n * Alias of {@link fromTry}.\n *\n * @example\n * ```ts\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const parsed = Result.try(() => JSON.parse(\"{\\\"ok\\\":true}\"))\n * ```\n *\n * @category Constructors\n */\n try_ as try,\n}\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"result.types-_xDAei3-.d.mts","names":[],"sources":["../src/shared/type-utils.types.ts","../src/result/result.types.ts"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"result.types-_xDAei3-.d.mts","names":[],"sources":["../src/shared/type-utils.types.ts","../src/result/result.types.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/scope/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"../scope-
|
|
1
|
+
import{n as e}from"../scope-D_kzd1nT.mjs";export{e as Scope};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./chunk-C934ptG5.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";import{n,t as r}from"./fx.runtime-
|
|
2
|
-
//# sourceMappingURL=scope-
|
|
1
|
+
import{t as e}from"./chunk-C934ptG5.mjs";import{t}from"./fx.types-Bg-Mmdm5.mjs";import{n,t as r}from"./fx.runtime-DclEDyjY.mjs";var i=e({make:()=>a});function a(){let e=[],i=!1,o=[];return{addFinalizer(n){return{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){i||e.push(n)}}},close(a){return e.some(e=>e()._tag===`AsyncFx`)?{_tag:`AsyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},async*[Symbol.asyncIterator](){if(i)return;i=!0;for(let e of[...o].toReversed()){let t=e.close(a);t._tag===`AsyncFx`?await r(t):n(t)}let t=[...e].toReversed();for(let e of t){let t=e();t._tag===`AsyncFx`?await r(t):n(t)}}}:{_tag:`SyncFx`,[t]:{_A:()=>void 0,_E:()=>void 0,_R:()=>void 0},*[Symbol.iterator](){if(i)return;i=!0;for(let e of[...o].toReversed())n(e.close(a));let t=[...e].toReversed();for(let e of t)n(e())}}},fork(){let e=a();return o.push(e),e}}}export{i as n,a as t};
|
|
2
|
+
//# sourceMappingURL=scope-D_kzd1nT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-D_kzd1nT.mjs","names":[],"sources":["../src/scope/scope.ts"],"sourcesContent":["/**\n * Scope lifecycle management for registering and running finalizers.\n *\n * **Mental model**\n * - A scope tracks cleanup actions and executes them in LIFO order.\n * - `Layer.scoped` and `Provide.layer` rely on scope semantics.\n *\n * **Common tasks**\n * - Create scopes with `Scope.make`.\n * - Register cleanup with `scope.addFinalizer`.\n * - Close scopes with `scope.close`.\n *\n * **Gotchas**\n * - Child scopes close before parent finalizers.\n * - Async finalizers force async scope close.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Scope } from \"@nicolastoulemont/std\"\n *\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const scope = Scope.make()\n * const closeFx = scope.close(Result.ok(undefined))\n * // => SyncFx<void> | AsyncFx<void>\n * ```\n *\n * @module\n */\nimport { runSync, runAsync } from \"../fx/fx.runtime\"\nimport { FxTypeId } from \"../fx/fx.types\"\nimport type { SyncFx, AsyncFx, FxYield } from \"../fx/fx.types\"\nimport type { Result } from \"../result/result.types\"\n\n/* oxlint-disable no-unsafe-type-assertion -- Scope encodes Fx phantom type slots and sync/async branch narrowing via assertions. */\n\n// ============================================================================\n// Scope Service\n// ============================================================================\n\n/**\n * Scope manages resource lifecycles with finalizers.\n * Finalizers run in LIFO (Last In, First Out) order when the scope closes.\n *\n * @example\n * ```ts\n * import { Scope } from \"@nicolastoulemont/std\"\n *\n * type Example = typeof Scope\n * ```\n *\n * @category Type-level\n */\nexport type ScopeService = {\n /**\n * Add a finalizer to be run when the scope closes.\n * Finalizers are run in LIFO order.\n *\n * @param finalizer - A function that returns an Fx to run on cleanup\n * @returns An Fx that completes when the finalizer is registered\n */\n addFinalizer(finalizer: () => SyncFx<void> | AsyncFx<void>): SyncFx<void>\n\n /**\n * Close the scope, running all finalizers in LIFO order.\n *\n * @param exit - The exit status of the computation\n * @returns An Fx that completes when all finalizers have run\n */\n close(exit: Result<unknown, unknown>): SyncFx<void> | AsyncFx<void>\n\n /**\n * Fork a child scope.\n * The child scope will be closed when the parent scope closes.\n *\n * @returns A new child scope\n */\n fork(): ScopeService\n}\n\n/**\n * Create a new Scope instance.\n * This is the concrete implementation of the ScopeService interface.\n *\n * @example\n * ```ts\n * import { Scope } from \"@nicolastoulemont/std\"\n *\n * import { Result } from \"@nicolastoulemont/std\"\n *\n * const scope = Scope.make()\n * const closeFx = scope.close(Result.ok(undefined))\n * // => SyncFx<void> | AsyncFx<void>\n * ```\n *\n * @category Constructors\n */\nexport function make(): ScopeService {\n type Finalizer = () => SyncFx<void> | AsyncFx<void>\n const finalizers: Finalizer[] = []\n let closed = false\n const children: ScopeService[] = []\n\n const scope: ScopeService = {\n addFinalizer(finalizer: Finalizer): SyncFx<void> {\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<never, never>, void, unknown> {\n if (!closed) {\n finalizers.push(finalizer)\n }\n },\n } as SyncFx<void>\n },\n\n close(exit: Result<unknown, unknown>): SyncFx<void> | AsyncFx<void> {\n // Check if any finalizer is async\n const hasAsyncFinalizer = finalizers.some((f) => {\n const fx = f()\n return fx._tag === \"AsyncFx\"\n })\n\n if (hasAsyncFinalizer) {\n return {\n _tag: \"AsyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n async *[Symbol.asyncIterator](): AsyncGenerator<FxYield<never, never>, void, unknown> {\n if (closed) return\n closed = true\n\n // Close children first\n for (const child of [...children].toReversed()) {\n const childClose = child.close(exit)\n if (childClose._tag === \"AsyncFx\") {\n // oxlint-disable-next-line no-await-in-loop\n await runAsync(childClose)\n } else {\n runSync(childClose)\n }\n }\n\n // Run finalizers in LIFO order\n const reversed = [...finalizers].toReversed()\n for (const finalizer of reversed) {\n const fx = finalizer()\n if (fx._tag === \"AsyncFx\") {\n // oxlint-disable-next-line no-await-in-loop\n await runAsync(fx)\n } else {\n runSync(fx)\n }\n }\n },\n } as AsyncFx<void>\n }\n\n // Sync version\n return {\n _tag: \"SyncFx\",\n [FxTypeId]: {\n _A: () => undefined as void,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<FxYield<never, never>, void, unknown> {\n if (closed) return\n closed = true\n\n // Close children first\n for (const child of [...children].toReversed()) {\n const childClose = child.close(exit)\n runSync(childClose as SyncFx<void>)\n }\n\n // Run finalizers in LIFO order\n const reversed = [...finalizers].toReversed()\n for (const finalizer of reversed) {\n const fx = finalizer()\n runSync(fx as SyncFx<void>)\n }\n },\n } as SyncFx<void>\n },\n\n fork(): ScopeService {\n const child = make()\n children.push(child)\n return child\n },\n }\n\n return scope\n}\n\n// ============================================================================\n// Helper Types\n// ============================================================================\n\n/**\n * Type utility to exclude Scope from requirements.\n * Used by Layer.scoped to auto-provide Scope.\n *\n * @example\n * ```ts\n * import { Scope } from \"@nicolastoulemont/std\"\n *\n * type Example = typeof Scope\n * ```\n *\n * @category Type-level\n */\nexport type ExcludeScope<R> = Exclude<R, ScopeService>\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"sJAmGA,SAAgB,GAAqB,CAEnC,IAAM,EAA0B,EAAE,CAC9B,EAAS,GACP,EAA2B,EAAE,CAsGnC,MApG4B,CAC1B,aAAa,EAAoC,CAC/C,MAAO,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CAED,EAAE,OAAO,WAA6D,CAC/D,GACH,EAAW,KAAK,EAAU,EAG/B,EAGH,MAAM,EAA8D,CA+ClE,OA7C0B,EAAW,KAAM,GAC9B,GAAG,CACJ,OAAS,UACnB,CAGO,CACL,KAAM,WACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CAED,OAAQ,OAAO,gBAAuE,CACpF,GAAI,EAAQ,OACZ,EAAS,GAGT,IAAK,IAAM,IAAS,CAAC,GAAG,EAAS,CAAC,YAAY,CAAE,CAC9C,IAAM,EAAa,EAAM,MAAM,EAAK,CAChC,EAAW,OAAS,UAEtB,MAAM,EAAS,EAAW,CAE1B,EAAQ,EAAW,CAKvB,IAAM,EAAW,CAAC,GAAG,EAAW,CAAC,YAAY,CAC7C,IAAK,IAAM,KAAa,EAAU,CAChC,IAAM,EAAK,GAAW,CAClB,EAAG,OAAS,UAEd,MAAM,EAAS,EAAG,CAElB,EAAQ,EAAG,GAIlB,CAII,CACL,KAAM,UACL,GAAW,CACV,OAAU,IAAA,GACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CAED,EAAE,OAAO,WAA6D,CACpE,GAAI,EAAQ,OACZ,EAAS,GAGT,IAAK,IAAM,IAAS,CAAC,GAAG,EAAS,CAAC,YAAY,CAE5C,EADmB,EAAM,MAAM,EAAK,CACD,CAIrC,IAAM,EAAW,CAAC,GAAG,EAAW,CAAC,YAAY,CAC7C,IAAK,IAAM,KAAa,EAEtB,EADW,GAAW,CACK,EAGhC,EAGH,MAAqB,CACnB,IAAM,EAAQ,GAAM,CAEpB,OADA,EAAS,KAAK,EAAM,CACb,GAEV"}
|
package/package.json
CHANGED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { c as FxTypeId } from "./fx.types-DeEWEltG.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/data/data.tagged-error.types.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A tagged error type with a discriminator and optional data.
|
|
7
|
-
* Uses `_tag` to match the existing pattern from `data/tagged`.
|
|
8
|
-
* Implements Fx protocol so it can be yielded in Fx.gen computations.
|
|
9
|
-
*
|
|
10
|
-
* @template Tag - The error tag (discriminator string)
|
|
11
|
-
* @template Data - Additional error data (optional)
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* type NotFoundError = TaggedError<"NotFoundError", { id: string }>
|
|
16
|
-
* type ValidationError = TaggedError<"ValidationError", { field: string; message: string }>
|
|
17
|
-
* type UnauthorizedError = TaggedError<"UnauthorizedError"> // No additional data
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
type TaggedError<Tag extends string, Data extends object = object> = {
|
|
21
|
-
readonly _tag: Tag;
|
|
22
|
-
readonly [FxTypeId]: {
|
|
23
|
-
readonly _A: () => never;
|
|
24
|
-
readonly _E: () => TaggedError<Tag, Data>;
|
|
25
|
-
readonly _R: () => never;
|
|
26
|
-
};
|
|
27
|
-
[Symbol.iterator](): Generator<TaggedError<Tag, Data>, never, unknown>;
|
|
28
|
-
} & Readonly<Data>;
|
|
29
|
-
/**
|
|
30
|
-
* Type for instances created by the TaggedError class factory.
|
|
31
|
-
* Extends Error and includes the tag, data, Fx protocol, and Yieldable protocol.
|
|
32
|
-
* When yielded, yields itself as an Fx type for proper inference.
|
|
33
|
-
*
|
|
34
|
-
* @template Tag - The error tag (discriminator string)
|
|
35
|
-
* @template Data - Additional error data (optional)
|
|
36
|
-
*/
|
|
37
|
-
type TaggedErrorInstance<Tag extends string, Data extends object = object> = TaggedError<Tag, Data> & Error;
|
|
38
|
-
/**
|
|
39
|
-
* Type for the class returned by TaggedError factory.
|
|
40
|
-
* Supports the Effect-style curried syntax: `TaggedError("Tag")<{ data }>` and `TaggedError("Tag")`
|
|
41
|
-
*
|
|
42
|
-
* @template Tag - The error tag (discriminator string)
|
|
43
|
-
*/
|
|
44
|
-
type TaggedErrorFactory<Tag extends string> = {
|
|
45
|
-
new <Data extends object = object>(...args: keyof Data extends never ? [] : [data: Data]): TaggedErrorInstance<Tag, Data>;
|
|
46
|
-
readonly _tag: Tag;
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
|
-
export { TaggedErrorFactory as t };
|
|
50
|
-
//# sourceMappingURL=data.tagged-error.types-CLlJJ3n5.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data.tagged-error.types-CLlJJ3n5.d.mts","names":[],"sources":["../src/data/data.tagged-error.types.ts"],"sourcesContent":[],"mappings":";;;;;;AAA8C;;;;;;;;;;;;;AAyBlC,KARP,WAkBA,CAAA,YAAmB,MAAA,EAAA,aAAA,MAAA,GAAA,MAAA,CAAA,GAAA;EAAiE,SAAA,IAAA,EAjBxE,GAiBwE;EAAK,UAhBlF,QAAA,CAgBkF,EAAA;IAAjB,SAAA,EAAA,EAAA,GAAA,GAAA,KAAA;IAAyB,SAAA,EAAA,EAAA,GAAA,GAd/E,WAc+E,CAdnE,GAcmE,EAd9D,IAc8D,CAAA;IAAK,SAAA,EAAA,EAAA,GAAA,GAAA,KAAA;EAQ/F,CAAA;EAEO,CAAA,MAAA,CAAA,QAAA,GAAA,EArBI,SAqBJ,CArBc,WAqBd,CArB0B,GAqB1B,EArB+B,IAqB/B,CAAA,EAAA,KAAA,EAAA,OAAA,CAAA;CAAiC,GApBhD,QAoBgD,CApBvC,IAoBuC,CAAA;;;;;;;;;KAV/C,wEAAwE,YAAY,KAAK,QAAQ;;;;;;;KAQ1F;oDAEO,iCAAiC,QAC/C,oBAAoB,KAAK;iBACb"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"either-6BwadiFj.mjs","names":["mapped","Result.ok","Result.err","Option.some","Option.none"],"sources":["../src/either/either.ts"],"sourcesContent":["/**\n * Biased disjoint union primitives for modeling two valid branches (`Left` / `Right`).\n *\n * **Mental model**\n * - `Either<L, R>` represents two meaningful outcomes.\n * - This module is right-biased for `map` / `flatMap`.\n *\n * **Common tasks**\n * - Construct with `Either.left` and `Either.right`.\n * - Transform with `Either.map`, `Either.mapLeft`, `Either.bimap`.\n * - Handle with `Either.match`, `Either.unwrapOr`, and conversions.\n *\n * **Gotchas**\n * - `Either.left` does not short-circuit in `Fx.gen`.\n * - Use `Result` when the left side should model failure semantics.\n *\n * **Quickstart**\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(2)\n * const next = Either.map(value, (n) => n + 1)\n * ```\n *\n * @module\n */\nimport { FxTypeId } from \"../fx/fx.types\"\nimport { Option } from \"../option\"\nimport type { Option as OptionType } from \"../option/option.types\"\nimport { Result } from \"../result\"\nimport type { Result as ResultType } from \"../result/result.types\"\nimport { dual } from \"../shared/dual\"\nimport { isPromise } from \"../shared/is-promise\"\nimport { pipeMethod } from \"../shared/pipeable\"\nimport type {\n Either as EitherType,\n EitherAll,\n EitherBimap,\n EitherFilter,\n EitherFlatMap,\n EitherMap,\n EitherMapLeft,\n EitherMatch,\n EitherOrElse,\n EitherTap,\n EitherTapLeft,\n EitherUnwrapOr,\n EitherUnwrapOrElse,\n} from \"./either.types\"\n\n/**\n * Re-exported `Either` type.\n *\n * @example\n * ```ts\n * import type { Either } from \"@nicolastoulemont/std\"\n *\n * type Example = Either.Either<unknown, unknown>\n * ```\n *\n * @category Re-exports\n */\nexport type Either<L, R> = EitherType<L, R>\n\n/* oxlint-disable no-unsafe-type-assertion -- Either constructors encode Fx marker channels and left/right union normalization through intentional assertions. */\n\n// ============================================================================\n// Constructors\n// ============================================================================\n\n/**\n * Create a right Either value (success/preferred path).\n *\n * By convention, right represents the correct/preferred outcome.\n * In Fx.gen(), this returns the value without short-circuiting.\n *\n * @param value - The right value\n * @returns An Either in the right state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.right(42)\n * // => { _tag: \"Right\", value: 42 }\n * ```\n *\n * @category Constructors\n */\nexport const right = <R, L = never>(value: R): EitherType<L, R> => ({\n _tag: \"Right\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeMethod,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, R, unknown> {\n return value\n },\n})\n\n/**\n * Create a left Either value (alternative path).\n *\n * By convention, left represents the alternative outcome.\n * Unlike Result's err(), left doesn't imply an error - it's a valid value.\n *\n * In Fx.gen(), left returns its value without short-circuiting.\n * This is the key difference from Result.err() which short-circuits.\n *\n * @param value - The left value\n * @returns An Either in the left state\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.left(\"missing\")\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n *\n * @category Constructors\n */\nexport const left = <L, R = never>(value: L): EitherType<L, R> => ({\n _tag: \"Left\",\n value,\n [FxTypeId]: {\n _A: () => value as L | R,\n _E: () => undefined as never,\n _R: () => undefined as never,\n },\n pipe: pipeMethod,\n // oxlint-disable-next-line require-yield\n *[Symbol.iterator](): Generator<never, L, unknown> {\n return value\n },\n})\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard to check if an Either is in the right state.\n *\n * @param either - The Either to check\n * @returns True if right, false if left (with type narrowing)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isRight = Either.isRight(Either.right(1))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isRight = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Right\" }> =>\n either._tag === \"Right\"\n\n/**\n * isLeft utility.\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const isLeft = Either.isLeft(Either.left(\"missing\"))\n * // => true\n * ```\n *\n * @category Guards\n */\nexport const isLeft = <L, R>(either: EitherType<L, R>): either is Extract<EitherType<L, R>, { _tag: \"Left\" }> =>\n either._tag === \"Left\"\n\n// ============================================================================\n// Right-biased Transformations\n// ============================================================================\n\n/**\n * Transform the right value of an Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `map(either, fn)`\n * - Data-last: `pipe(either, map(fn))`\n *\n * Supports async functions.\n *\n * @param fn - Transformation function for right values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.map(input, (n) => n + 1)\n * // => { _tag: \"Right\", value: 3 }\n * \n * const dataLast = Either.map((n: number) => n + 1)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const map: EitherMap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n\n/**\n * Transform the left value of an Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `mapLeft(either, fn)`\n * - Data-last: `pipe(either, mapLeft(fn))`\n *\n * Supports async functions.\n *\n * @param fn - Transformation function for left values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.mapLeft(input, (msg) => msg.toUpperCase())\n * // => { _tag: \"Left\", value: \"MISSING\" }\n *\n * const dataLast = Either.mapLeft((msg: string) => msg.toUpperCase())(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const mapLeft: EitherMapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const mapped = fn(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Transform both sides of an Either simultaneously.\n * Unique to Either - not available in Result/Option.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `bimap(either, fnLeft, fnRight)`\n * - Data-last: `pipe(either, bimap(fnLeft, fnRight))`\n *\n * Supports async functions.\n *\n * @param fnLeft - Transformation function for left values\n * @param fnRight - Transformation function for right values\n * @returns A curried function that transforms an Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.bimap(input, (left) => left.toUpperCase(), (right: number) => right + 1)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * \n * const dataLast = Either.bimap((left: string) => left.toUpperCase(), (right: number) => right + 1)(input)\n * // => { _tag: \"Left\", value: \"MISSING\" }\n * ```\n *\n * @category Mapping\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const bimap: EitherBimap = dual(\n 3,\n (either: EitherType<unknown, unknown>, fnLeft: (value: unknown) => unknown, fnRight: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") {\n const mapped = fnRight(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(right) as any\n }\n return right(mapped) as any\n }\n const mapped = fnLeft(either.value)\n if (isPromise(mapped)) {\n return Promise.resolve(mapped).then(left) as any\n }\n return left(mapped) as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Chain operations that return Either.\n * Left values short-circuit the chain.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `flatMap(either, fn)`\n * - Data-last: `pipe(either, flatMap(fn))`\n *\n * Supports async functions. Combines left error unions.\n *\n * @param fn - Function that returns an Either\n * @returns A curried function that chains Eithers\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2)\n * const dataFirst = Either.flatMap(input, (n) => Either.right(n + 1))\n * // => { _tag: \"Right\", value: 3 }\n * \n * const dataLast = Either.flatMap((n: number) => Either.right(n + 1))(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n *\n * @category Sequencing\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const flatMap: EitherFlatMap = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n return result as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on right values without modifying the Either.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tap(either, fn)`\n * - Data-last: `pipe(either, tap(fn))`\n *\n * Supports async functions.\n *\n * @param fn - Side effect function for right values\n * @returns A curried function that executes side effects\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = 0\n * const input = Either.right(2)\n * const dataFirst = Either.tap(input, (n) => {\n * seen = n\n * })\n * // => { _tag: \"Right\", value: 2 }\n * \n * const dataLast = Either.tap((n: number) => {\n * seen = n\n * })(input)\n * // => { _tag: \"Right\", value: 2 }\n * ```\n *\n * @category Sequencing\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tap: EitherTap = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Left\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Execute a side effect on left values without modifying the Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `tapLeft(either, fn)`\n * - Data-last: `pipe(either, tapLeft(fn))`\n *\n * Supports async functions.\n *\n * @param fn - Side effect function for left values\n * @returns A curried function that executes side effects\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * let seen = \"\"\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.tapLeft(input, (msg) => {\n * seen = msg\n * })\n * // => { _tag: \"Left\", value: \"missing\" }\n *\n * const dataLast = Either.tapLeft((msg: string) => {\n * seen = msg\n * })(input)\n * // => { _tag: \"Left\", value: \"missing\" }\n * ```\n *\n * @category Sequencing\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const tapLeft: EitherTapLeft = dual(\n 2,\n (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n if (isPromise(result)) {\n return Promise.resolve(result).then(() => either) as any\n }\n return either as any\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Recovery/Fallback\n// ============================================================================\n\n/**\n * Recover from a left value by providing an alternative Either.\n * Right values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `orElse(either, fn)`\n * - Data-last: `pipe(either, orElse(fn))`\n *\n * Supports async functions. Combines right value unions.\n *\n * @param fn - Function that returns an alternative Either\n * @returns A curried function that recovers from left\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\")\n * const dataFirst = Either.orElse(input, () => Either.right(0))\n * // => { _tag: \"Right\", value: 0 }\n * \n * const dataLast = Either.orElse(() => Either.right(0))(input)\n * // => { _tag: \"Right\", value: 0 }\n * ```\n *\n * @category Error Handling\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const orElse: EitherOrElse = dual(2, (either: EitherType<unknown, unknown>, fn: (value: unknown) => unknown) => {\n if (either._tag === \"Right\") return either as any\n const result = fn(either.value)\n return result as any\n})\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n/**\n * Swap left and right values.\n * Unique to Either - not available in Result/Option.\n *\n * Curried for use with pipe().\n *\n * @returns A curried function that swaps left and right\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const swap = Either.swap<string, number>()\n * const value = swap(Either.left(\"missing\"))\n * // => { _tag: \"Right\", value: \"missing\" }\n * ```\n *\n * @category Conversions\n */\nexport const swap =\n <L, R>() =>\n (either: EitherType<L, R>): EitherType<R, L> =>\n either._tag === \"Left\" ? right(either.value) : left(either.value)\n\n// ============================================================================\n// Filtering\n// ============================================================================\n\n/**\n * Filter right values based on a predicate.\n * Failed predicates convert to left with onFail callback.\n * Left values pass through unchanged.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `filter(either, predicate, onFail)`\n * - Data-last: `pipe(either, filter(predicate, onFail))`\n *\n * @param predicate - Function to test right values\n * @param onFail - Function to produce left value on failure\n * @returns A curried function that filters an Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(3)\n * const dataFirst = Either.filter(input, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n * \n * const dataLast = Either.filter((n: number) => n > 0, (n) => `${n} must be positive`)(input)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n *\n * @category Filtering\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion -- Required for overloaded return types in curried functions */\nexport const filter: EitherFilter = dual(\n 3,\n (\n either: EitherType<unknown, unknown>,\n predicate: (value: unknown) => boolean,\n onFail: (value: unknown) => unknown,\n ) => {\n if (either._tag === \"Left\") return either as any\n return predicate(either.value) ? (either as any) : left(onFail(either.value))\n },\n)\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-type-assertion */\n// ============================================================================\n// Combinators\n// ============================================================================\n\n/**\n * Combine multiple Eithers into a single Either.\n * Short-circuits on the first left value.\n *\n * Supports both array and object inputs with full type preservation.\n * For arrays of 1-6 elements, tuple types are inferred automatically.\n * For longer arrays, use `as const` to preserve tuple structure.\n *\n * @param eithers - Array or object of Eithers to combine\n * @returns Either with all right values or first left\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const combined = Either.all([Either.right(1), Either.right(2)] as const)\n * // => { _tag: \"Right\", value: [1, 2] }\n * ```\n *\n * @category Combining\n */\n/* oxlint-disable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment -- Required for handling union types in overloaded function */\nexport const all: EitherAll = (eithers: any): any => {\n // Array case\n if (Array.isArray(eithers)) {\n const values: unknown[] = []\n for (const either of eithers) {\n if (either._tag === \"Left\") return either\n values.push(either.value)\n }\n return right(values)\n }\n\n // Object case\n const result: Record<string, unknown> = {}\n for (const key in eithers) {\n const either = eithers[key]\n if (either._tag === \"Left\") return either\n result[key] = either.value\n }\n return right(result)\n}\n/* oxlint-enable no-explicit-any, no-unsafe-return, no-unsafe-member-access, strict-boolean-expressions, no-unsafe-assignment */\n// ============================================================================\n// Extraction\n// ============================================================================\n\n/**\n * Extract the right value or return a default.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOr(either, defaultValue)`\n * - Data-last: `pipe(either, unwrapOr(defaultValue))`\n *\n * Uses NoInfer to prevent type inference from the default value.\n *\n * @param defaultValue - Value to return if Either is left\n * @returns A curried function that extracts the value\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOr(input, 0)\n * // => 0\n * \n * const dataLast = Either.unwrapOr(0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOr: EitherUnwrapOr = dual(\n 2,\n <L, R>(either: EitherType<L, R>, defaultValue: NoInfer<R>): R =>\n either._tag === \"Right\" ? either.value : defaultValue,\n)\n\n/**\n * Extract the right value or compute one from the left value.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `unwrapOrElse(either, fn)`\n * - Data-last: `pipe(either, unwrapOrElse(fn))`\n *\n * @param fn - Function to compute default from left value\n * @returns A curried function that extracts the value\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.left(\"missing\") as Either.Either<string, number>\n * const dataFirst = Either.unwrapOrElse(input, () => 0)\n * // => 0\n *\n * const dataLast = Either.unwrapOrElse(() => 0)(input)\n * // => 0\n * ```\n *\n * @category Getters\n */\nexport const unwrapOrElse: EitherUnwrapOrElse = dual(\n 2,\n <L, R>(either: EitherType<L, R>, fn: (left: L) => R): R =>\n either._tag === \"Right\" ? either.value : fn(either.value),\n)\n\n/**\n * Pattern match on an Either with handlers for both cases.\n *\n * Supports both data-first and data-last calling styles:\n * - Data-first: `match(either, { Left: ..., Right: ... })`\n * - Data-last: `pipe(either, match({ Left: ..., Right: ... }))`\n *\n * @param handlers - Object with left and right handler functions\n * @returns A curried function that pattern matches\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const input = Either.right(2) as Either.Either<string, number>\n * const dataFirst = Either.match(input, {\n * Left: (left) => `error:${left}` ,\n * Right: (right) => `ok:${right}` ,\n * })\n * // => \"ok:2\"\n * \n * const dataLast = Either.match({\n * Left: (left: string) => `error:${left}` ,\n * Right: (right: number) => `ok:${right}` ,\n * })(input)\n * // => \"ok:2\"\n * ```\n *\n * @category Pattern Matching\n */\nexport const match: EitherMatch = dual(\n 2,\n <L, R, U>(either: EitherType<L, R>, handlers: { Left: (value: L) => U; Right: (value: R) => U }): U =>\n either._tag === \"Right\" ? handlers.Right(either.value) : handlers.Left(either.value),\n)\n\n// ============================================================================\n// Conversions\n// ============================================================================\n\n/**\n * Convert a Result to an Either.\n * Result's ok becomes right, err becomes left.\n *\n * @param result - The Result to convert\n * @returns An Either with the same semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Result } from \"@nicolastoulemont/std\"\n * \n * const value = Either.fromResult(Result.ok(1))\n * // => { _tag: \"Right\", value: 1 }\n * ```\n *\n * @category Conversions\n */\nexport const fromResult = <R, E>(result: ResultType<R, E>): EitherType<E, R> =>\n result._tag === \"Ok\" ? right(result.value) : left(result.error)\n\n/**\n * Convert an Either to a Result.\n * Either's right becomes ok, left becomes err.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns A Result with error semantics\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toResult(Either.left(\"missing\"))\n * // => { _tag: \"Err\", error: \"missing\" }\n * ```\n *\n * @category Conversions\n */\nexport const toResult = <L, R>(either: EitherType<L, R>): ResultType<R, L> =>\n either._tag === \"Right\" ? Result.ok(either.value) : Result.err(either.value)\n\n/**\n * Convert an Option to an Either.\n * Option's some becomes right, none becomes left with onNone callback.\n *\n * @param option - The Option to convert\n * @param onNone - Function to produce left value for none\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * import { Option } from \"@nicolastoulemont/std\"\n * \n * const value = Either.fromOption(Option.some(1), () => \"missing\")\n * // => { _tag: \"Right\", value: 1 }\n * ```\n *\n * @category Conversions\n */\nexport const fromOption = <R, L>(option: OptionType<R>, onNone: () => L): EitherType<L, R> =>\n option._tag === \"Some\" ? right(option.value) : left(onNone())\n\n/**\n * Convert an Either to an Option.\n * Either's right becomes some, left is discarded.\n *\n * Curried for use with pipe().\n *\n * @param either - The Either to convert\n * @returns An Option (left value is discarded)\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.toOption(Either.left(\"missing\"))\n * // => { _tag: \"None\" }\n * ```\n *\n * @category Conversions\n */\nexport const toOption = <L, R>(either: EitherType<L, R>): OptionType<R> =>\n either._tag === \"Right\" ? Option.some(either.value) : Option.none<R>()\n\n/**\n * Convert a nullable value to an Either.\n * null/undefined becomes left with onNull callback, otherwise right.\n *\n * @param value - The nullable value\n * @param onNull - Function to produce left value for null/undefined\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromNullable(\"Ada\", () => \"missing\")\n * // => { _tag: \"Right\", value: \"Ada\" }\n * ```\n *\n * @category Conversions\n */\nexport const fromNullable = <R, L>(value: R | null | undefined, onNull: () => L): EitherType<L, R> =>\n value === null || value === undefined ? left(onNull()) : right(value)\n\n/**\n * Create an Either from a predicate.\n * Predicate success becomes right, failure becomes left with onFail callback.\n *\n * @param value - The value to test\n * @param predicate - Function to test the value\n * @param onFail - Function to produce left value on failure\n * @returns An Either\n *\n * @example\n * ```ts\n * import { Either } from \"@nicolastoulemont/std\"\n *\n * const value = Either.fromPredicate(3, (n) => n > 0, (n) => `${n} must be positive`)\n * // => { _tag: \"Right\", value: 3 }\n * ```\n *\n * @category Constructors\n */\nexport const fromPredicate = <R, L>(\n value: R,\n predicate: (value: R) => boolean,\n onFail: (value: R) => L,\n): EitherType<L, R> => (predicate(value) ? right(value) : left(onFail(value)))\n\n/* oxlint-enable no-unsafe-type-assertion */\n"],"mappings":"ynBA2FA,MAAa,EAAuB,IAAgC,CAClE,KAAM,QACN,SACC,GAAW,CACV,OAAU,EACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,KAAM,EAEN,EAAE,OAAO,WAA0C,CACjD,OAAO,GAEV,EAwBY,EAAsB,IAAgC,CACjE,KAAM,OACN,SACC,GAAW,CACV,OAAU,EACV,OAAU,IAAA,GACV,OAAU,IAAA,GACX,CACD,KAAM,EAEN,EAAE,OAAO,WAA0C,CACjD,OAAO,GAEV,EAsBY,EAAiB,GAC5B,EAAO,OAAS,QAeL,EAAgB,GAC3B,EAAO,OAAS,OAkCL,EAAiB,EAAK,GAAI,EAAsC,IAAoC,CAC/G,GAAI,EAAO,OAAS,OAAQ,OAAO,EACnC,IAAM,EAAS,EAAG,EAAO,MAAM,CAI/B,OAHI,EAAU,EAAO,CACZ,QAAQ,QAAQ,EAAO,CAAC,KAAK,EAAM,CAErC,EAAM,EAAO,EACpB,CA+BW,EAAyB,EACpC,GACC,EAAsC,IAAoC,CACzE,GAAI,EAAO,OAAS,QAAS,OAAO,EACpC,IAAM,EAAS,EAAG,EAAO,MAAM,CAI/B,OAHI,EAAU,EAAO,CACZ,QAAQ,QAAQ,EAAO,CAAC,KAAK,EAAK,CAEpC,EAAK,EAAO,EAEtB,CA+BY,EAAqB,EAChC,GACC,EAAsC,EAAqC,IAAyC,CACnH,GAAI,EAAO,OAAS,QAAS,CAC3B,IAAMA,EAAS,EAAQ,EAAO,MAAM,CAIpC,OAHI,EAAUA,EAAO,CACZ,QAAQ,QAAQA,EAAO,CAAC,KAAK,EAAM,CAErC,EAAMA,EAAO,CAEtB,IAAM,EAAS,EAAO,EAAO,MAAM,CAInC,OAHI,EAAU,EAAO,CACZ,QAAQ,QAAQ,EAAO,CAAC,KAAK,EAAK,CAEpC,EAAK,EAAO,EAEtB,CA8BY,EAAyB,EACpC,GACC,EAAsC,IACjC,EAAO,OAAS,OAAe,EACpB,EAAG,EAAO,MAAM,CAGlC,CAmCY,EAAiB,EAAK,GAAI,EAAsC,IAAoC,CAC/G,GAAI,EAAO,OAAS,OAAQ,OAAO,EACnC,IAAM,EAAS,EAAG,EAAO,MAAM,CAI/B,OAHI,EAAU,EAAO,CACZ,QAAQ,QAAQ,EAAO,CAAC,SAAW,EAAO,CAE5C,GACP,CAmCW,EAAyB,EACpC,GACC,EAAsC,IAAoC,CACzE,GAAI,EAAO,OAAS,QAAS,OAAO,EACpC,IAAM,EAAS,EAAG,EAAO,MAAM,CAI/B,OAHI,EAAU,EAAO,CACZ,QAAQ,QAAQ,EAAO,CAAC,SAAW,EAAO,CAE5C,GAEV,CAkCY,EAAuB,EAAK,GAAI,EAAsC,IAC7E,EAAO,OAAS,QAAgB,EACrB,EAAG,EAAO,MAAM,CAE/B,CAqBW,MAEV,GACC,EAAO,OAAS,OAAS,EAAM,EAAO,MAAM,CAAG,EAAK,EAAO,MAAM,CAkCxD,EAAuB,EAClC,GAEE,EACA,EACA,IAEI,EAAO,OAAS,QACb,EAAU,EAAO,MAAM,CADK,EACgB,EAAK,EAAO,EAAO,MAAM,CAAC,CAEhF,CA4BY,EAAkB,GAAsB,CAEnD,GAAI,MAAM,QAAQ,EAAQ,CAAE,CAC1B,IAAM,EAAoB,EAAE,CAC5B,IAAK,IAAM,KAAU,EAAS,CAC5B,GAAI,EAAO,OAAS,OAAQ,OAAO,EACnC,EAAO,KAAK,EAAO,MAAM,CAE3B,OAAO,EAAM,EAAO,CAItB,IAAM,EAAkC,EAAE,CAC1C,IAAK,IAAM,KAAO,EAAS,CACzB,IAAM,EAAS,EAAQ,GACvB,GAAI,EAAO,OAAS,OAAQ,OAAO,EACnC,EAAO,GAAO,EAAO,MAEvB,OAAO,EAAM,EAAO,EAiCT,EAA2B,EACtC,GACO,EAA0B,IAC/B,EAAO,OAAS,QAAU,EAAO,MAAQ,EAC5C,CA0BY,EAAmC,EAC9C,GACO,EAA0B,IAC/B,EAAO,OAAS,QAAU,EAAO,MAAQ,EAAG,EAAO,MAAM,CAC5D,CAgCY,EAAqB,EAChC,GACU,EAA0B,IAClC,EAAO,OAAS,QAAU,EAAS,MAAM,EAAO,MAAM,CAAG,EAAS,KAAK,EAAO,MAAM,CACvF,CAyBY,EAAoB,GAC/B,EAAO,OAAS,KAAO,EAAM,EAAO,MAAM,CAAG,EAAK,EAAO,MAAM,CAqBpD,EAAkB,GAC7B,EAAO,OAAS,QAAUC,EAAU,EAAO,MAAM,CAAGC,EAAW,EAAO,MAAM,CAsBjE,GAAoB,EAAuB,IACtD,EAAO,OAAS,OAAS,EAAM,EAAO,MAAM,CAAG,EAAK,GAAQ,CAAC,CAqBlD,EAAkB,GAC7B,EAAO,OAAS,QAAUC,EAAY,EAAO,MAAM,CAAGC,GAAgB,CAoB3D,GAAsB,EAA6B,IAC9D,GAAU,KAA8B,EAAK,GAAQ,CAAC,CAAG,EAAM,EAAM,CAqB1D,GACX,EACA,EACA,IACsB,EAAU,EAAM,CAAG,EAAM,EAAM,CAAG,EAAK,EAAO,EAAM,CAAC"}
|