@nunofyobiz/effect-extras 0.0.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/LICENSE +21 -0
- package/README.md +140 -0
- package/dist/index.d.ts +3703 -0
- package/dist/index.js +1006 -0
- package/dist/index.js.map +1 -0
- package/package.json +103 -0
- package/src/ArrayX/ArrayX.ts +818 -0
- package/src/ArrayX/index.ts +1 -0
- package/src/BigIntX/BigIntX.ts +35 -0
- package/src/BigIntX/index.ts +1 -0
- package/src/BooleanX/BooleanX.ts +24 -0
- package/src/BooleanX/index.ts +1 -0
- package/src/DurationX/DurationX.ts +178 -0
- package/src/DurationX/index.ts +1 -0
- package/src/EffectX/EffectX.ts +183 -0
- package/src/EffectX/index.ts +1 -0
- package/src/FormDataX/FormDataX.ts +57 -0
- package/src/FormDataX/index.ts +1 -0
- package/src/MapX/MapX.ts +54 -0
- package/src/MapX/index.ts +1 -0
- package/src/NonNullableX/NonNullableX.ts +290 -0
- package/src/NonNullableX/index.ts +2 -0
- package/src/NumberX/NumberX.ts +282 -0
- package/src/NumberX/index.ts +1 -0
- package/src/OptionX/OptionX.ts +234 -0
- package/src/OptionX/index.ts +1 -0
- package/src/OrderX/OrderX.ts +35 -0
- package/src/OrderX/index.ts +1 -0
- package/src/PredicateX/PredicateX.ts +98 -0
- package/src/PredicateX/index.ts +1 -0
- package/src/PromiseX/PromiseX.ts +32 -0
- package/src/PromiseX/index.ts +1 -0
- package/src/RecordX/RecordX.ts +478 -0
- package/src/RecordX/index.ts +1 -0
- package/src/ResultX/ResultX.ts +53 -0
- package/src/ResultX/index.ts +1 -0
- package/src/SchemaX/SchemaX.ts +324 -0
- package/src/SchemaX/index.ts +1 -0
- package/src/SetX/SetX.ts +160 -0
- package/src/SetX/index.ts +1 -0
- package/src/StringX/StringX.ts +97 -0
- package/src/StringX/index.ts +1 -0
- package/src/StructX/StructX.ts +310 -0
- package/src/StructX/index.ts +1 -0
- package/src/These/These.ts +1173 -0
- package/src/These/index.ts +1 -0
- package/src/index.ts +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ArrayX/ArrayX.ts","../src/RecordX/RecordX.ts","../src/These/These.ts","../src/ResultX/ResultX.ts","../src/BigIntX/BigIntX.ts","../src/BooleanX/BooleanX.ts","../src/DurationX/DurationX.ts","../src/EffectX/EffectX.ts","../src/FormDataX/FormDataX.ts","../src/MapX/MapX.ts","../src/NonNullableX/NonNullableX.ts","../src/NumberX/NumberX.ts","../src/OptionX/OptionX.ts","../src/OrderX/OrderX.ts","../src/PredicateX/PredicateX.ts","../src/PromiseX/PromiseX.ts","../src/SchemaX/SchemaX.ts","../src/SetX/SetX.ts","../src/StringX/StringX.ts","../src/StructX/StructX.ts"],"names":["takeFirstWhere","takeLastWhere","key","upsert","Predicate","Option","orElse","pipe","RightOnly","LeftOnly","mapLeft","mapRight","dual","Array","identity","categorize","Record","BigInt","map","Duration","Effect","match","Match","EffectNumber","a","b","ifSome","String","Schema","Struct"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Generic, framework-agnostic extensions to Effect's `Array` module.\n *\n * @since 0.0.0\n */\nimport {\n Array,\n Equivalence,\n Option,\n Order,\n Predicate,\n Record,\n pipe,\n} from \"effect\";\nimport { dual, identity } from \"effect/Function\";\nimport { RecordX } from \"../RecordX\";\nimport { These } from \"../These\";\nimport { ResultX } from \"../ResultX\";\n\n/**\n * Returns a shallow copy of `array` between `start` (inclusive) and `end`\n * (exclusive), as a pipeable, dual-form alias for `Array.prototype.slice`.\n *\n * `Array.prototype.slice` is already non-mutating (it returns a shallow copy),\n * but it isn't pipeable. This helper makes it composable inside `pipe(...)`\n * chains alongside the rest of the codebase's Effect-style utilities.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(ArrayX.slice([1, 2, 3, 4], 1, 3), [2, 3])\n *\n * // data-last (pipeable)\n * assert.deepStrictEqual(pipe([1, 2, 3, 4], ArrayX.slice(1, 3)), [2, 3])\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const slice = dual<\n <A>(start: number, end: number) => (array: readonly A[]) => A[],\n <A>(array: readonly A[], start: number, end: number) => A[]\n>(3, <A>(array: readonly A[], start: number, end: number): A[] =>\n array.slice(start, end),\n);\n\n/**\n * Zips two arrays into one, calling `f` with a `These` for each index so that\n * length mismatches are handled explicitly rather than truncated.\n *\n * Unlike `Array.zipWith` (which stops at the shorter array), this walks to the\n * length of the *longer* array. At each index `f` receives a `These.These<A, B>`:\n * `LeftAndRight` when both arrays have an element, `LeftOnly` when only the\n * first does, and `RightOnly` when only the second does. Use it when the\n * \"extra\" tail of either array still carries meaning.\n *\n * @example\n * ```ts\n * import { ArrayX, These } from \"@nunofyobiz/effect-extras\"\n *\n * const describe = These.match({\n * LeftOnly: ({ left }) => `left ${left}`,\n * RightOnly: ({ right }) => `right ${right}`,\n * LeftAndRight: ({ left, right }) => `both ${left}/${right}`,\n * })\n *\n * assert.deepStrictEqual(ArrayX.zipWithThese([1, 2, 3], [10, 20], describe), [\n * \"both 1/10\",\n * \"both 2/20\",\n * \"left 3\",\n * ])\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const zipWithThese = dual<\n <A, B, C>(\n f: (ab: These.These<A, B>) => C,\n ) => (array1: readonly A[], array2: readonly B[]) => C[],\n <A, B, C>(\n array1: readonly A[],\n array2: readonly B[],\n f: (ab: These.These<A, B>) => C,\n ) => C[]\n>(\n 3,\n <A, B, C>(\n array1: readonly A[],\n array2: readonly B[],\n f: (ab: These.These<A, B>) => C,\n ): C[] => {\n const newLength = Math.max(array1.length, array2.length);\n\n if (newLength === 0) {\n return [];\n }\n\n return Array.makeBy(newLength, (index) => {\n if (index < array1.length && index < array2.length) {\n return f(\n These.LeftAndRight({\n left: array1[index],\n right: array2[index],\n }),\n );\n }\n\n if (index < array1.length) {\n return f(\n These.LeftOnly({\n left: array1[index],\n }),\n );\n }\n\n if (index < array2.length) {\n return f(\n These.RightOnly({\n right: array2[index],\n }),\n );\n }\n\n throw new Error(`Index ${index} is out of bounds for array1 and array2`);\n });\n },\n);\n\n/**\n * Moves a unique item within an array to a new position, using a custom identification function.\n *\n * **Assumption**: Items should be unique in the array based on the identification function.\n *\n * **Happy case**: If the source item is found exactly once and the destination reference item is found (or null, to move to the end):\n * The source item is moved from its current position to the new position\n *\n * **Source item not found**: The array is returned unchanged, regardless of whether the destination reference item exists.\n *\n * **Source item found but duplicated**:\n * - If destination reference item is found: All copies of the source item are removed, then a single copy is inserted before the destination reference item\n * - If destination reference item is not found: The array is returned completely unchanged (no items are moved or removed)\n *\n * Used internally by {@link insertUniq}; not exported as the codebase has no\n * direct callers.\n */\nconst moveUniqWith = dual<\n <A, I extends string | number>(config: {\n identify: (item: A) => I;\n sourceId: I;\n moveToBeLeftOfId: I | null;\n }) => (array: readonly A[] | A[]) => A[],\n <A, I extends string | number>(\n array: readonly A[] | A[],\n config: {\n identify: (item: A) => I;\n sourceId: I;\n moveToBeLeftOfId: I | null;\n },\n ) => A[]\n>(\n 2,\n <A, I extends string | number>(\n inputArray: readonly A[] | A[],\n {\n identify,\n sourceId,\n moveToBeLeftOfId,\n }: {\n identify: (item: A) => I;\n sourceId: I;\n moveToBeLeftOfId: I | null;\n },\n ): A[] => {\n const array: A[] = [...inputArray];\n\n // Find the source item and its index\n const sourceIndex = array.findIndex((item) => identify(item) === sourceId);\n if (sourceIndex < 0) {\n return array;\n }\n\n const sourceItem = array[sourceIndex];\n\n // Remove ALL occurrences of the source item from the array\n const arrayWithoutSource = array.filter(\n (item) => identify(item) !== sourceId,\n );\n\n // If moveToBeLeftOfId is null, move to end\n if (moveToBeLeftOfId === null) {\n return [...arrayWithoutSource, sourceItem];\n }\n\n // Find the destination index in the array without the source item\n const destinationIndex = arrayWithoutSource.findIndex(\n (item) => identify(item) === moveToBeLeftOfId,\n );\n if (destinationIndex < 0) {\n // If destination not found, leave array completely unchanged\n return array;\n }\n\n // Insert the source item before the destination index\n return [\n ...slice(arrayWithoutSource, 0, destinationIndex),\n sourceItem,\n ...slice(arrayWithoutSource, destinationIndex, arrayWithoutSource.length),\n ];\n },\n);\n\n/**\n * Inserts or moves a unique item in an array at a specified position.\n *\n * **Assumption**: Items should be unique in the array based on standard equality.\n *\n * **Happy case**: If the item doesn't exist in the array and the destination reference item is found:\n * The new item is inserted before the destination reference item\n *\n * **Item not found in array**:\n * - If destination reference item is found: The new item is inserted before the destination reference item\n * - If destination reference item is not found: The new item is inserted at the end of the array\n *\n * **Item found but duplicated**:\n * - If destination reference item is found: All existing copies are removed, then a single copy is inserted before the destination reference item\n * - If destination reference item is not found: All existing copies are removed, then a single copy is inserted at the end of the array\n *\n * @param array - The input array to modify\n * @param config - Configuration object containing:\n * - `item`: The item to insert or update (must be a string or number)\n * - `insertToBeLeftOf`: The item to position the new/updated item before,\n * or null to insert at the end\n *\n * @returns A new array with the item inserted or moved to the specified position\n *\n * @example\n * ```ts\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Move an existing item to sit just before \"c\"\n * assert.deepStrictEqual(\n * ArrayX.insertUniq([\"a\", \"b\", \"c\", \"d\"], { item: \"a\", insertToBeLeftOf: \"c\" }),\n * [\"b\", \"a\", \"c\", \"d\"],\n * )\n *\n * // Insert a brand-new item; unknown destination falls through to the end\n * assert.deepStrictEqual(\n * ArrayX.insertUniq([\"a\", \"b\"], { item: \"new\", insertToBeLeftOf: null }),\n * [\"a\", \"b\", \"new\"],\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const insertUniq = dual<\n <A extends string | number>(config: {\n item: A;\n insertToBeLeftOf: A | null;\n }) => (array: readonly A[] | A[]) => A[],\n <A extends string | number>(\n array: readonly A[] | A[],\n config: {\n item: A;\n insertToBeLeftOf: A | null;\n },\n ) => A[]\n>(\n 2,\n <A extends string | number>(\n array: readonly A[] | A[],\n { item, insertToBeLeftOf }: { item: A; insertToBeLeftOf: A | null },\n ): A[] => {\n // Always deduplicate and append the item to the end for insertUniq\n // This ensures we always have exactly one copy of the item, regardless of destination\n const arrayWithNewItem = pipe(\n array,\n Array.filter((existingItem) => existingItem !== item),\n Array.append(item),\n );\n\n // Now move that new item to the desired position\n return moveUniqWith(arrayWithNewItem, {\n identify: identity,\n sourceId: item,\n moveToBeLeftOfId: insertToBeLeftOf,\n });\n },\n);\n\n/**\n * Maps over `array` while threading an accumulator, iterating from right to\n * left instead of left to right.\n *\n * Identical to `Array.mapAccum`, except the traversal order is reversed: `f` is\n * called on the last element first, and the resulting array is returned in the\n * original (left-to-right) order. Use it when each element's mapped value\n * depends on state accumulated from the elements that follow it.\n *\n * @example\n * ```ts\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Running suffix-sum: each slot holds the sum of itself and everything after it\n * assert.deepStrictEqual(\n * ArrayX.mapRightAccum([1, 2, 3], 0, (total, n) => [total + n, total + n]),\n * [6, [6, 5, 3]],\n * )\n * ```\n *\n * @category folding\n * @since 0.0.0\n */\nexport const mapRightAccum = dual<\n <A, B, C>(\n initialAccumulator: C,\n f: (accumulator: C, a: A, index: number) => [C, B],\n ) => (array: A[]) => [C, B[]],\n <A, B, C>(\n array: A[],\n initialAccumulator: C,\n f: (accumulator: C, a: A, index: number) => [C, B],\n ) => [C, B[]]\n>(\n 3,\n <A, B, C>(\n array: A[],\n initialAccumulator: C,\n f: (accumulator: C, a: A, index: number) => [C, B],\n ): [C, B[]] => {\n const [accumulator, result] = pipe(\n array,\n Array.reverse,\n Array.mapAccum(initialAccumulator, f),\n );\n return [accumulator, Array.reverse(result)];\n },\n);\n\n/**\n * Returns the maximum element of `array` according to `order`, wrapped in an\n * `Option` so that empty arrays are handled safely.\n *\n * Effect's `Array.max` throws on an empty array; this returns `Option.none()`\n * instead, and `Option.some(max)` otherwise. Reach for it whenever the input\n * array might be empty.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * pipe([3, 7, 2], ArrayX.maxOption(Order.Number)),\n * Option.some(7),\n * )\n * assert.deepStrictEqual(\n * pipe([], ArrayX.maxOption(Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const maxOption = dual<\n <A>(order: Order.Order<A>) => (array: A[]) => Option.Option<A>,\n <A>(array: A[], order: Order.Order<A>) => Option.Option<A>\n>(\n 2,\n <A>(array: A[], order: Order.Order<A>): Option.Option<A> =>\n pipe(\n // If the array is empty, there is no max\n array,\n Option.liftPredicate(Array.isArrayNonEmpty),\n\n // If it is non-empty, get the max\n Option.map(Array.max(order)),\n ),\n);\n\nconst takeFirstOrLastWhere = dual<\n <A, B extends A>(\n predicate: Predicate.Refinement<A, B>,\n takeOne: (array: Array.NonEmptyReadonlyArray<B>) => B,\n ) => (array: A[]) => Option.Option<B>,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n takeOne: (array: Array.NonEmptyReadonlyArray<B>) => B,\n ) => Option.Option<B>\n>(\n 3,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n takeOne: (array: Array.NonEmptyReadonlyArray<B>) => B,\n ): Option.Option<B> =>\n pipe(\n // Keep only the items that match\n array,\n Array.filter(predicate),\n\n // If there is anything left, take one\n Option.liftPredicate(Array.isArrayNonEmpty),\n Option.map(takeOne),\n ),\n);\n\n/**\n * Returns the smallest element of `array` (per `order`) that matches\n * `predicate`, narrowed to the refined type `B`, or `Option.none()` if none\n * match.\n *\n * Combines a refinement filter with `Array.min`: only elements satisfying\n * `predicate` are considered, and the minimum of those (by `order`) is\n * returned. The refinement narrows the element type, so the resulting `Option`\n * carries the more specific `B`.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * const isEven = (n: number): n is number => n % 2 === 0\n *\n * assert.deepStrictEqual(\n * pipe([3, 4, 1, 2, 5], ArrayX.takeFirstWhere(isEven, Order.Number)),\n * Option.some(2),\n * )\n * assert.deepStrictEqual(\n * pipe([1, 3, 5], ArrayX.takeFirstWhere(isEven, Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const takeFirstWhere = dual<\n <A, B extends A>(\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => (array: A[]) => Option.Option<B>,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => Option.Option<B>\n>(\n 3,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ): Option.Option<B> =>\n takeFirstOrLastWhere(array, predicate, Array.min(order)),\n);\n\n/**\n * Returns the largest element of `array` (per `order`) that matches\n * `predicate`, narrowed to the refined type `B`, or `Option.none()` if none\n * match.\n *\n * The mirror of {@link takeFirstWhere}: only elements satisfying `predicate`\n * are considered, and the maximum of those (by `order`) is returned. The\n * refinement narrows the element type, so the resulting `Option` carries the\n * more specific `B`.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * const isEven = (n: number): n is number => n % 2 === 0\n *\n * assert.deepStrictEqual(\n * pipe([3, 4, 1, 2, 5], ArrayX.takeLastWhere(isEven, Order.Number)),\n * Option.some(4),\n * )\n * assert.deepStrictEqual(\n * pipe([1, 3, 5], ArrayX.takeLastWhere(isEven, Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const takeLastWhere = dual<\n <A, B extends A>(\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => (array: A[]) => Option.Option<B>,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => Option.Option<B>\n>(\n 3,\n <A, B extends A>(\n array: A[],\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ): Option.Option<B> =>\n takeFirstOrLastWhere(array, predicate, Array.max(order)),\n);\n\n/**\n * Groups `items` into a partial record keyed by the category each item maps to\n * via `categorize`.\n *\n * Each item is appended to the array under its category, preserving input\n * order. The result is `Partial<Record<C, A[]>>` because not every possible\n * category `C` is guaranteed to appear — only categories that received at least\n * one item are present.\n *\n * @example\n * ```ts\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * const parity = (n: number) => (n % 2 === 0 ? \"even\" : \"odd\")\n *\n * assert.deepStrictEqual(ArrayX.categorize([1, 2, 3, 4], parity), {\n * odd: [1, 3],\n * even: [2, 4],\n * })\n * ```\n *\n * @category folding\n * @since 0.0.0\n */\nexport const categorize = <A, C extends string>(\n items: Iterable<A>,\n categorize: (a: A) => C,\n): Partial<Record<C, A[]>> =>\n Array.reduce(\n items,\n\n // Start with an empty record of categorized items. `Record.empty()`\n // returns a `NonLiteralKey<C>`-keyed record, which is structurally\n // equivalent to `Partial<Record<C, A[]>>`; the cast tells TypeScript\n // we'll be writing typed keys back via the reducer below.\n Record.empty<C, A[]>() as Record<C, A[]>,\n\n // For each item, add it to the appropriate category\n (categorizedItems, item: A) =>\n RecordX.upsert(\n categorizedItems,\n categorize(item), // This is the next item's category\n Option.match({\n // This is the first item in this category, so create a new array\n onNone: () => Array.of(item),\n\n // Append the item to the existing array\n onSome: Array.append(item),\n }),\n ),\n );\n\n/**\n * Removes all `null` and `undefined` elements from `array`, narrowing the\n * element type to `NonNullable<A>`.\n *\n * Falsy-but-present values such as `0` and `\"\"` are kept — only nullish values\n * are dropped. Use it to clean up an array of optionals into a dense array of\n * known-present values.\n *\n * @example\n * ```ts\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * ArrayX.compactNullable([1, null, 2, undefined, 0, \"\"]),\n * [1, 2, 0, \"\"],\n * )\n * ```\n *\n * @category filtering\n * @since 0.0.0\n */\nexport const compactNullable = <A>(array: A[]): NonNullable<A>[] =>\n Array.filter(array, Predicate.isNotNullish);\n\n/**\n * Drops the leading elements of `array` until `predicate` first holds, keeping\n * everything from the first match onward.\n *\n * The first matching element and all subsequent elements are retained\n * regardless of whether they match — only the prefix *before* the first match\n * is trimmed. If nothing matches, returns an empty array.\n *\n * @example\n * ```ts\n * import { Predicate } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Trims the leading strings, then keeps everything (including the trailing \"b\")\n * assert.deepStrictEqual(\n * ArrayX.filterHead([\"a\", 1, 2, \"b\"], Predicate.isNumber),\n * [1, 2, \"b\"],\n * )\n * ```\n *\n * @category filtering\n * @since 0.0.0\n */\nexport const filterHead = dual<\n <A>(predicate: Predicate.Predicate<A>) => (array: A[]) => A[],\n <A>(array: A[], predicate: Predicate.Predicate<A>) => A[]\n>(2, <A>(array: A[], predicate: Predicate.Predicate<A>): A[] => {\n const firstMatchingIndex = Array.findFirstIndex(array, predicate);\n return Option.match(firstMatchingIndex, {\n onSome: (index) => slice(array, index, array.length),\n onNone: () => [],\n });\n});\n\n/**\n * Drops the trailing elements of `array` after `predicate` last holds, keeping\n * everything up to and including the last match.\n *\n * The mirror of {@link filterHead}: the last matching element and all preceding\n * elements are retained regardless of whether they match — only the suffix\n * *after* the last match is trimmed. If nothing matches, returns an empty\n * array.\n *\n * @example\n * ```ts\n * import { Predicate } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Keeps the leading \"a\" and trims the trailing strings after the last number\n * assert.deepStrictEqual(\n * ArrayX.filterTail([\"a\", 1, 2, \"b\"], Predicate.isNumber),\n * [\"a\", 1, 2],\n * )\n * ```\n *\n * @category filtering\n * @since 0.0.0\n */\nexport const filterTail = dual<\n <A>(predicate: Predicate.Predicate<A>) => (array: A[]) => A[],\n <A>(array: A[], predicate: Predicate.Predicate<A>) => A[]\n>(2, <A>(array: A[], predicate: Predicate.Predicate<A>): A[] => {\n const lastMatchingIndex = Array.findLastIndex(array, predicate);\n return Option.match(lastMatchingIndex, {\n onSome: (index) => slice(array, 0, index + 1),\n onNone: () => [],\n });\n});\n\n/**\n * Maps `f` over `array` and drops every result that is `null` or `undefined`,\n * narrowing the element type to `NonNullable<B>`.\n *\n * A nullable-friendly `Array.filterMap`: where `filterMap` expects `f` to\n * return an `Option`, this accepts a function returning `B | null` (or\n * `undefined`) and treats nullish results as \"skip this element\". Falsy-but-\n * present values such as `0` and `\"\"` are kept.\n *\n * @example\n * ```ts\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Keep only the even numbers, mapped to their halves\n * assert.deepStrictEqual(\n * ArrayX.filterMapNullable([1, 2, 3, 4], (n) => (n % 2 === 0 ? n / 2 : null)),\n * [1, 2],\n * )\n * ```\n *\n * @category filtering\n * @since 0.0.0\n */\nexport const filterMapNullable = dual<\n <A, B>(f: (a: A) => B | null) => (array: A[]) => NonNullable<B>[],\n <A, B>(array: A[], f: (a: A) => B | null) => NonNullable<B>[]\n>(2, <A, B>(array: A[], f: (a: A) => B | null): NonNullable<B>[] =>\n pipe(\n array,\n Array.filterMap((value) =>\n pipe(f(value), Option.fromNullishOr, ResultX.fromOption),\n ),\n ),\n);\n\n/**\n * Finds the first element of a 2-dimensional array (row-major order) matching\n * `predicate`, returning it alongside its row and column indices.\n *\n * Scans rows top-to-bottom and, within each row, left-to-right. On a match\n * returns `Option.some([value, rowIndex, columnIndex])`; if no element matches\n * (or the grid is empty), returns `Option.none()`.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * const grid = [\n * [\"A\", \"B\", \"C\"],\n * [\"D\", \"E\", \"F\"],\n * ]\n *\n * assert.deepStrictEqual(\n * ArrayX.findFirstWithIndex2d(grid, (cell) => cell === \"E\"),\n * Option.some([\"E\", 1, 1]),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const findFirstWithIndex2d = dual<\n <A>(\n predicate: Predicate.Predicate<A>,\n ) => (array: A[][]) => Option.Option<[A, number, number]>,\n <A>(\n array: A[][],\n predicate: Predicate.Predicate<A>,\n ) => Option.Option<[A, number, number]>\n>(\n 2,\n <A>(\n array: A[][],\n predicate: Predicate.Predicate<A>,\n ): Option.Option<[A, number, number]> =>\n Array.findFirstWithIndex(array, (row) =>\n Array.findFirstWithIndex(row, predicate),\n ).pipe(\n Option.map(([[value, secondIndex], firstIndex]) => [\n value,\n firstIndex,\n secondIndex,\n ]),\n ),\n);\n\n/**\n * Splits `array` into runs of consecutive elements that share the same group\n * value, where the group is derived by `chunk` and compared with the provided\n * `Equivalence`.\n *\n * Only *adjacent* elements are grouped: a new run starts every time the group\n * value changes from the previous element. Each entry in the result carries the\n * `group` value and the non-empty array of `values` that produced it, preserving\n * input order. An empty input yields an empty array. Use it for run-length-style\n * segmentation; reach for `Array.groupBy` instead when you want all elements\n * with the same key collapsed regardless of position.\n *\n * @example\n * ```ts\n * import { Equivalence } from \"effect\"\n * import { ArrayX } from \"@nunofyobiz/effect-extras\"\n *\n * // Group adjacent numbers by parity\n * assert.deepStrictEqual(\n * ArrayX.chunkBy([2, 4, 1, 3, 6], (n) => n % 2 === 0, Equivalence.Boolean),\n * [\n * { group: true, values: [2, 4] },\n * { group: false, values: [1, 3] },\n * { group: true, values: [6] },\n * ],\n * )\n * ```\n *\n * @category folding\n * @since 0.0.0\n */\nexport const chunkBy = dual<\n <A, B>(\n chunk: (a: A) => B,\n GroupEquivalence: Equivalence.Equivalence<B>,\n ) => (array: A[]) => { group: B; values: Array.NonEmptyArray<A> }[],\n <A, B>(\n array: A[],\n chunk: (a: A) => B,\n GroupEquivalence: Equivalence.Equivalence<B>,\n ) => { group: B; values: Array.NonEmptyArray<A> }[]\n>(\n 3,\n <A, B>(\n array: A[],\n chunk: (a: A) => B,\n chunkEquals: Equivalence.Equivalence<B>,\n ): { group: B; values: Array.NonEmptyArray<A> }[] => {\n if (array.length === 0) {\n return [];\n }\n\n const result: { group: B; values: Array.NonEmptyArray<A> }[] = [];\n\n for (const item of array) {\n const groupValue = chunk(item);\n\n if (result.length > 0) {\n const lastGroup = result.at(-1);\n if (lastGroup && chunkEquals(lastGroup.group, groupValue)) {\n // Add to current group\n lastGroup.values.push(item);\n continue;\n }\n }\n\n // Start a new group\n result.push({ group: groupValue, values: Array.of(item) });\n }\n\n return result;\n },\n);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Record` module.\n *\n * @since 0.0.0\n */\nimport { Array, Option, Order, Predicate, Record, pipe } from \"effect\";\nimport { dual } from \"effect/Function\";\nimport { ArrayX } from \"../ArrayX\";\n\n/**\n * Returns `true` when `record` has at least one entry, narrowing it to a\n * known-non-empty `Record`.\n *\n * The negation of `Record.isEmptyRecord`, packaged as a type guard so it reads\n * naturally at call sites that want to branch on \"this record has something in\n * it\" without a manual `!Record.isEmptyRecord(...)`.\n *\n * @example\n * ```ts\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(RecordX.isNonEmptyRecord({ a: 1 }), true)\n * assert.deepStrictEqual(RecordX.isNonEmptyRecord({}), false)\n * ```\n *\n * @category guards\n * @since 0.0.0\n */\nexport const isNonEmptyRecord = <K extends PropertyKey, V>(\n record: Record<K, V>,\n): record is Record<K, V> => pipe(record, Predicate.not(Record.isEmptyRecord));\n\n/**\n * Modifies the value at `key` in `self` with `f`, leaving the record unchanged\n * if the key doesn't exist.\n *\n * v4's `Record.modify` returns `Option<Record>` — `None` when the key is\n * absent. This helper picks the \"do nothing if absent\" semantics that v3's\n * `Record.modify` had implicitly, and that most call sites assume. The modifier\n * is never invoked when the key is missing.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(\n * RecordX.modifyIfExists({ a: 1, b: 2 }, \"b\", (n) => n * 10),\n * { a: 1, b: 20 },\n * )\n *\n * // a missing key leaves the record untouched\n * const counts: Record<string, number> = { a: 1, b: 2 }\n * assert.deepStrictEqual(\n * RecordX.modifyIfExists(counts, \"missing\", (n) => n + 1),\n * { a: 1, b: 2 },\n * )\n *\n * // data-last (pipeable)\n * assert.deepStrictEqual(\n * pipe({ a: 1, b: 2 }, RecordX.modifyIfExists(\"a\", (n) => n * 10)),\n * { a: 10, b: 2 },\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const modifyIfExists: {\n <K extends string, A>(\n key: NoInfer<K>,\n f: (a: A) => A,\n ): (self: Record<K, A>) => Record<K, A>;\n <K extends string, A>(\n self: Record<K, A>,\n key: NoInfer<K>,\n f: (a: A) => A,\n ): Record<K, A>;\n} = dual(\n 3,\n <K extends string, A>(\n self: Record<K, A>,\n key: K,\n f: (a: A) => A,\n ): Record<K, A> =>\n pipe(\n Record.modify(self, key, f),\n Option.getOrElse(() => self),\n ),\n);\n\n/**\n * Returns the smallest value of `record` (per `order`) that matches\n * `predicate`, narrowed to the refined type `B`, or `Option.none()` if none\n * match.\n *\n * The `Record` counterpart of `ArrayX.takeFirstWhere`: it considers only the\n * record's values, keeps those satisfying `predicate`, and returns the minimum\n * of them by `order`. Keys are ignored entirely.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const isEven = (n: number): n is number => n % 2 === 0\n *\n * // data-first\n * assert.deepStrictEqual(\n * RecordX.takeFirstWhere({ a: 3, b: 4, c: 2 }, isEven, Order.Number),\n * Option.some(2),\n * )\n *\n * // data-last (pipeable); no even values yields None\n * assert.deepStrictEqual(\n * pipe({ a: 1, b: 3 }, RecordX.takeFirstWhere(isEven, Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const takeFirstWhere = dual<\n <K extends PropertyKey, A, B extends A>(\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => (record: Record<K, A>) => Option.Option<B>,\n <K extends PropertyKey, A, B extends A>(\n record: Record<K, A>,\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => Option.Option<B>\n>(\n 3,\n <K extends PropertyKey, A, B extends A>(\n record: Record<K, A>,\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ): Option.Option<B> =>\n ArrayX.takeFirstWhere(Record.values(record), predicate, order),\n);\n\n/**\n * Returns the largest value of `record` (per `order`) that matches `predicate`,\n * narrowed to the refined type `B`, or `Option.none()` if none match.\n *\n * The mirror of {@link takeFirstWhere}: it considers only the record's values,\n * keeps those satisfying `predicate`, and returns the maximum of them by\n * `order`. Keys are ignored entirely.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const isEven = (n: number): n is number => n % 2 === 0\n *\n * // data-first\n * assert.deepStrictEqual(\n * RecordX.takeLastWhere({ a: 3, b: 4, c: 2 }, isEven, Order.Number),\n * Option.some(4),\n * )\n *\n * // data-last (pipeable); no even values yields None\n * assert.deepStrictEqual(\n * pipe({ a: 1, b: 3 }, RecordX.takeLastWhere(isEven, Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const takeLastWhere = dual<\n <K extends PropertyKey, A, B extends A>(\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => (record: Record<K, A>) => Option.Option<B>,\n <K extends PropertyKey, A, B extends A>(\n record: Record<K, A>,\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ) => Option.Option<B>\n>(\n 3,\n <K extends PropertyKey, A, B extends A>(\n record: Record<K, A>,\n predicate: Predicate.Refinement<A, B>,\n order: Order.Order<B>,\n ): Option.Option<B> =>\n ArrayX.takeLastWhere(Record.values(record), predicate, order),\n);\n\n/**\n * Returns the largest value of `record` according to `order`, wrapped in an\n * `Option` so empty records are handled safely.\n *\n * Sorts the record's values by `order` and takes the last one, yielding\n * `Option.none()` when the record is empty and `Option.some(max)` otherwise.\n * Keys are ignored — only values participate in the ordering.\n *\n * @example\n * ```ts\n * import { Option, Order, pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(\n * RecordX.takeLast({ a: 3, b: 5, c: 1 }, Order.Number),\n * Option.some(5),\n * )\n *\n * // data-last (pipeable); empty record yields None\n * assert.deepStrictEqual(\n * pipe({}, RecordX.takeLast(Order.Number)),\n * Option.none(),\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const takeLast = dual<\n <K extends PropertyKey, A>(\n order: Order.Order<A>,\n ) => (record: Record<K, A>) => Option.Option<A>,\n <K extends PropertyKey, A>(\n record: Record<K, A>,\n order: Order.Order<A>,\n ) => Option.Option<A>\n>(\n 2,\n <K extends PropertyKey, A>(\n record: Record<K, A>,\n order: Order.Order<A>,\n ): Option.Option<A> =>\n pipe(Record.values(record), Array.sort(order), Array.last),\n);\n\n/**\n * Re-types the keys of a `Record` to a different key type `K2` without touching\n * the runtime value.\n *\n * A purely type-level reinterpretation: the record is returned as-is, but the\n * compiler now treats its keys as `K2` instead of the inferred `K1`. Use it at a\n * boundary where you know the keys conform to a narrower branded or literal key\n * type that TypeScript can't infer from the value alone. It performs no\n * validation — the caller is responsible for the keys actually matching `K2`.\n *\n * @example\n * ```ts\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * type UserId = string & { readonly _brand: \"UserId\" }\n *\n * const byId: Record<string, number> = { u1: 10, u2: 20 }\n * const branded = RecordX.keysAs<UserId>()(byId)\n *\n * // Same runtime value, keys now seen as `UserId`\n * assert.deepStrictEqual(branded, { u1: 10, u2: 20 })\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const keysAs =\n <K2 extends PropertyKey>() =>\n <K1 extends PropertyKey, V>(record: Record<K1, V>): Record<K2, V> =>\n record as unknown as Record<K2, V>;\n\n/**\n * Returns the value at `key` in `record`, throwing an `Error` if the key is\n * absent.\n *\n * The unsafe, get-or-explode counterpart to `Record.get` (which returns an\n * `Option`). The thrown error names the missing key and lists the record's\n * existing keys to aid debugging. Reach for {@link getOrThrowWith} when you need\n * a custom error; prefer `Record.get` whenever absence is a real possibility.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const record: Record<string, number> = { a: 1, b: 2 }\n *\n * // data-first\n * assert.deepStrictEqual(RecordX.getOrThrow(record, \"a\"), 1)\n *\n * // data-last (pipeable)\n * assert.deepStrictEqual(pipe(record, RecordX.getOrThrow(\"b\")), 2)\n *\n * // missing key throws\n * assert.throws(() => RecordX.getOrThrow(record, \"missing\"))\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const getOrThrow = dual<\n <K extends string | symbol>(key: K) => <V>(record: Record<K, V>) => V,\n <K extends string | symbol, V>(record: Record<K, V>, key: K) => V\n>(\n 2,\n <K extends string | symbol, V>(record: Record<K, V>, key: K): V =>\n getOrThrowWith(\n record,\n key,\n (key) =>\n new Error(\n `Key ${String(key)} not found in record\\nExisting keys=${String(Record.keys(record))}`,\n ),\n ),\n);\n\n/**\n * Returns the value at `key` in `record`, throwing the result of `onNone(key)`\n * if the key is absent.\n *\n * Like {@link getOrThrow}, but lets the caller supply the thrown value (an\n * `Error`, a string, or any custom failure) computed from the missing key. Use\n * it when the default \"key not found\" message isn't descriptive enough for the\n * call site.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const record: Record<string, number> = { a: 1 }\n * const onNone = (key: string) => new Error(`no ${key}`)\n *\n * // data-first\n * assert.deepStrictEqual(RecordX.getOrThrowWith(record, \"a\", onNone), 1)\n *\n * // data-last (pipeable)\n * assert.deepStrictEqual(pipe(record, RecordX.getOrThrowWith(\"a\", onNone)), 1)\n *\n * // missing key throws the custom error\n * assert.throws(() => RecordX.getOrThrowWith(record, \"missing\", onNone))\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const getOrThrowWith = dual<\n <K extends string | symbol>(\n key: K,\n onNone: (key: K) => unknown,\n ) => <V>(record: Record<K, V>) => V,\n <K extends string | symbol, V>(\n record: Record<K, V>,\n key: K,\n onNone: (key: K) => unknown,\n ) => V\n>(\n 3,\n <K extends string | symbol, V>(\n record: Record<K, V>,\n key: K,\n onNone: (key: K) => unknown,\n ): V =>\n Record.get(record, key).pipe(Option.getOrThrowWith(() => onNone(key))),\n);\n\n/**\n * Inserts or updates the value at `key`, deriving the new value from the current\n * one via `upsert`.\n *\n * The `upsert` function receives an `Option` of the existing value —\n * `Option.some(value)` when the key is present, `Option.none()` when it's\n * absent — and returns the value to store. This unifies \"insert if missing\" and\n * \"update if present\" into a single pass, with `Option.match` as the natural way\n * to handle both cases.\n *\n * @example\n * ```ts\n * import { Option, pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const bump = Option.match({\n * onNone: () => 1,\n * onSome: (n: number) => n + 1,\n * })\n *\n * // data-first: updates an existing entry\n * assert.deepStrictEqual(RecordX.upsert({ a: 1 }, \"a\", bump), { a: 2 })\n *\n * // data-last (pipeable): inserts a missing entry\n * const counts: Record<string, number> = { a: 1 }\n * assert.deepStrictEqual(pipe(counts, RecordX.upsert(\"b\", bump)), {\n * a: 1,\n * b: 1,\n * })\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const upsert = dual<\n <K extends string | symbol, V>(\n key: K,\n upsert: (existingValue: Option.Option<V>) => V,\n ) => (record: Record<K, V>) => Record<K, V>,\n <K extends string | symbol, V>(\n record: Record<K, V>,\n key: K,\n upsert: (existingValue: Option.Option<V>) => V,\n ) => Record<K, V>\n>(\n 3,\n <K extends string | symbol, V>(\n record: Record<K, V>,\n key: K,\n upsert: (existingValue: Option.Option<V>) => V,\n ): Record<K, V> => {\n const existingValue = Record.get(record, key);\n const updatedValue = upsert(existingValue);\n return Record.set(record, key, updatedValue);\n },\n);\n\n/**\n * Indexes an iterable of values into a `Record`, keying each value by the result\n * of `identify`.\n *\n * Builds a lookup table from a collection: every value is stored under the key\n * `identify(value)`. When two values produce the same key the later one wins, so\n * the result holds the last value seen per key. Useful for turning a list of\n * records into a by-id map.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { RecordX } from \"@nunofyobiz/effect-extras\"\n *\n * const items = [\n * { id: \"a\", n: 1 },\n * { id: \"b\", n: 2 },\n * { id: \"a\", n: 3 }, // wins over the earlier \"a\"\n * ]\n *\n * // data-first\n * assert.deepStrictEqual(\n * RecordX.collectBy(items, (item) => item.id),\n * { a: { id: \"a\", n: 3 }, b: { id: \"b\", n: 2 } },\n * )\n *\n * // data-last (pipeable)\n * assert.deepStrictEqual(\n * pipe(items, RecordX.collectBy((item) => item.id)),\n * { a: { id: \"a\", n: 3 }, b: { id: \"b\", n: 2 } },\n * )\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const collectBy = dual<\n <K extends string | symbol, V>(\n identify: (v: V) => K,\n ) => (values: Iterable<V>) => Record<K, V>,\n <K extends string | symbol, V>(\n values: Iterable<V>,\n identify: (v: V) => K,\n ) => Record<K, V>\n>(\n 2,\n <K extends string | symbol, V>(\n values: Iterable<V>,\n identify: (v: V) => K,\n ): Record<K, V> =>\n Array.reduce(values, {} as Record<K, V>, (accumulator, value) =>\n Record.set<K, V, K, V>(accumulator, identify(value), value),\n ),\n);\n","/**\n * The `These` data type — an inclusive-or carrying a `left`, a `right`, or both at once.\n *\n * @since 0.0.0\n */\nimport { Data, Effect, Option, Predicate, Struct, pipe } from \"effect\";\nimport { constUndefined, identity } from \"effect/Function\";\n\n/**\n * A value carrying a left `L`, a right `R`, or both at once — the data type for\n * an \"inclusive or\".\n *\n * Where `Result<R, L>` models an exclusive choice (success _or_ failure),\n * `These` adds the third case where both sides are present. It is a tagged enum\n * with three constructors: `LeftOnly` (only `left`), `RightOnly` (only `right`),\n * and `LeftAndRight` (both). Reach for it when an operation can produce partial\n * results — e.g. a parse that yields a value _and_ a list of warnings.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const both: These.These<number, string> = These.LeftAndRight({\n * left: 1,\n * right: \"a\"\n * })\n *\n * assert.deepStrictEqual(both._tag, \"LeftAndRight\")\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type These<L, R> = Data.TaggedEnum<{\n LeftOnly: {\n readonly left: L;\n };\n\n RightOnly: {\n readonly right: R;\n };\n\n LeftAndRight: {\n readonly left: L;\n readonly right: R;\n };\n}>;\n\n/**\n * The `LeftOnly` member of `These` — a value that carries only a `left` and no\n * `right`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value: These.LeftOnly<number> = These.LeftOnly({ left: 1 })\n *\n * assert.deepStrictEqual(value.left, 1)\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type LeftOnly<L> = These<L, never> & {\n _tag: \"LeftOnly\";\n};\n\n/**\n * The `RightOnly` member of `These` — a value that carries only a `right` and no\n * `left`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value: These.RightOnly<string> = These.RightOnly({ right: \"a\" })\n *\n * assert.deepStrictEqual(value.right, \"a\")\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type RightOnly<R> = These<never, R> & {\n _tag: \"RightOnly\";\n};\n\n/**\n * The `LeftAndRight` member of `These` — a value that carries both a `left` and a\n * `right`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value: These.LeftAndRight<number, string> = These.LeftAndRight({\n * left: 1,\n * right: \"a\"\n * })\n *\n * assert.deepStrictEqual(value, { _tag: \"LeftAndRight\", left: 1, right: \"a\" })\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type LeftAndRight<L, R> = These<L, R> & {\n _tag: \"LeftAndRight\";\n};\n\n/**\n * Any `These` that is guaranteed to carry a `left` — either `LeftOnly` or\n * `LeftAndRight`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value: These.WithLeft<number, string> = These.LeftOnly({ left: 1 })\n *\n * assert.deepStrictEqual(value.left, 1)\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type WithLeft<L, R> = LeftOnly<L> | LeftAndRight<L, R>;\n\n/**\n * Any `These` that is guaranteed to carry a `right` — either `RightOnly` or\n * `LeftAndRight`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value: These.WithRight<number, string> = These.RightOnly({ right: \"a\" })\n *\n * assert.deepStrictEqual(value.right, \"a\")\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type WithRight<L, R> = RightOnly<R> | LeftAndRight<L, R>;\n\ninterface TheseDefinition extends Data.TaggedEnum.WithGenerics<2> {\n readonly taggedEnum: These<this[\"A\"], this[\"B\"]>;\n}\n\nconst taggedEnum = Data.taggedEnum<TheseDefinition>();\n\n/**\n * Constructs a `LeftOnly` — a `These` that carries only a `left`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value = These.LeftOnly({ left: 1 })\n *\n * assert.deepStrictEqual(value._tag, \"LeftOnly\")\n * assert.deepStrictEqual(value.left, 1)\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const LeftOnly = taggedEnum.LeftOnly;\n\n/**\n * Constructs a `RightOnly` — a `These` that carries only a `right`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value = These.RightOnly({ right: \"a\" })\n *\n * assert.deepStrictEqual(value._tag, \"RightOnly\")\n * assert.deepStrictEqual(value.right, \"a\")\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const RightOnly = taggedEnum.RightOnly;\n\n/**\n * Constructs a `LeftAndRight` — a `These` that carries both a `left` and a\n * `right`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const value = These.LeftAndRight({ left: 1, right: \"a\" })\n *\n * assert.deepStrictEqual(value._tag, \"LeftAndRight\")\n * assert.deepStrictEqual(value.left, 1)\n * assert.deepStrictEqual(value.right, \"a\")\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const LeftAndRight = taggedEnum.LeftAndRight;\n\n/**\n * Builds per-tag refinements for `These`. `is(\"LeftOnly\")` is a type guard that\n * narrows a `These` to its `LeftOnly` member, and likewise for `\"RightOnly\"` and\n * `\"LeftAndRight\"`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(These.is(\"LeftOnly\")(These.LeftOnly({ left: 1 })), true)\n * assert.deepStrictEqual(\n * These.is(\"LeftOnly\")(These.RightOnly({ right: \"a\" })),\n * false\n * )\n * ```\n *\n * @category guards\n * @since 0.0.0\n */\nexport const is = taggedEnum.$is;\n\n/**\n * Folds a `These` over its three tags. Provide a handler for `LeftOnly`,\n * `RightOnly`, and `LeftAndRight` and `match` returns a function from a `These`\n * to the handlers' common result type.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const describe = These.match({\n * LeftOnly: ({ left }) => `left ${left}`,\n * RightOnly: ({ right }) => `right ${right}`,\n * LeftAndRight: ({ left, right }) => `both ${left}/${right}`\n * })\n *\n * assert.deepStrictEqual(\n * describe(These.LeftAndRight({ left: 1, right: \"a\" })),\n * \"both 1/a\"\n * )\n * ```\n *\n * @category pattern matching\n * @since 0.0.0\n */\nexport const match = taggedEnum.$match;\n\n/**\n * Builds a `These` known to carry a `left`, choosing `LeftAndRight` when `right`\n * is present and `LeftOnly` otherwise.\n *\n * Use it when the `left` is mandatory and the `right` is an optional companion:\n * pass an absent (`null`/`undefined`) `right` to get a `LeftOnly`, or a present\n * one to get a `LeftAndRight`. The return type `WithLeft<L, R>` reflects that a\n * `left` is always present.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * These.WithLeft({ left: 1, right: \"a\" }),\n * These.LeftAndRight({ left: 1, right: \"a\" })\n * )\n *\n * assert.deepStrictEqual(\n * These.WithLeft({ left: 1 }),\n * These.LeftOnly({ left: 1 })\n * )\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const WithLeft = <L, R>({\n left,\n right,\n}: {\n left: L;\n right?: R | undefined;\n}): WithLeft<L, R> =>\n Predicate.isNotNullish(right)\n ? LeftAndRight({ left, right })\n : LeftOnly({ left });\n\n/**\n * Builds a `These` known to carry a `right`, choosing `LeftAndRight` when `left`\n * is present and `RightOnly` otherwise.\n *\n * The mirror of `WithLeft`: the `right` is mandatory and the `left` is an\n * optional companion. Pass an absent (`null`/`undefined`) `left` to get a\n * `RightOnly`, or a present one to get a `LeftAndRight`. The return type\n * `WithRight<L, R>` reflects that a `right` is always present.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * These.WithRight({ left: 1, right: \"a\" }),\n * These.LeftAndRight({ left: 1, right: \"a\" })\n * )\n *\n * assert.deepStrictEqual(\n * These.WithRight({ right: \"a\" }),\n * These.RightOnly({ right: \"a\" })\n * )\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const WithRight = <L, R>({\n left,\n right,\n}: {\n left?: L | undefined;\n right: R;\n}): WithRight<L, R> =>\n Predicate.isNotNullish(left)\n ? LeftAndRight({ left, right })\n : RightOnly({ right });\n\n/**\n * Builds a `These` from a pair of possibly-nullish inputs, wrapping the result in\n * an `Option` so the all-absent case is expressible.\n *\n * Returns `Option.some(LeftAndRight)` when both are present, `Option.some(LeftOnly)`\n * or `Option.some(RightOnly)` when exactly one is present, and `Option.none()`\n * when both are nullish. Use it as the total entry point for turning two optional\n * values into a `These`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Option } from \"effect\"\n *\n * assert.deepStrictEqual(\n * These.optionFromNullables({ left: 1, right: \"a\" }),\n * Option.some(These.LeftAndRight({ left: 1, right: \"a\" }))\n * )\n *\n * assert.deepStrictEqual(\n * These.optionFromNullables({ left: 1, right: null }),\n * Option.some(These.LeftOnly({ left: 1 }))\n * )\n *\n * assert.deepStrictEqual(\n * These.optionFromNullables({ left: null, right: undefined }),\n * Option.none()\n * )\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const optionFromNullables = <L, R>({\n left,\n right,\n}: {\n left?: L | null | undefined;\n right?: R | null | undefined;\n}): Option.Option<These<L, R>> => {\n if (Predicate.isNotNullish(left) && Predicate.isNotNullish(right)) {\n return Option.some(LeftAndRight({ left, right }));\n }\n if (Predicate.isNotNullish(left)) {\n return Option.some(LeftOnly({ left }));\n }\n if (Predicate.isNotNullish(right)) {\n return Option.some(RightOnly({ right }));\n }\n return Option.none();\n};\n\n/**\n * Builds a `These` from a pair of possibly-nullish inputs, falling back to the\n * `orElse` thunk when both are absent.\n *\n * The non-optional companion to `optionFromNullables`: it unwraps the same logic\n * but resolves the all-absent case with `orElse` instead of an `Option`. The\n * default `orElse` throws, so omit it only when at least one side is guaranteed\n * present.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * These.fromNullables({ left: 1, right: \"a\" }),\n * These.LeftAndRight({ left: 1, right: \"a\" })\n * )\n *\n * // Both absent — fall back via orElse instead of throwing\n * assert.deepStrictEqual(\n * These.fromNullables({\n * left: null,\n * right: null,\n * orElse: () => These.LeftOnly({ left: 0 })\n * }),\n * These.LeftOnly({ left: 0 })\n * )\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const fromNullables = <L, R>({\n left,\n right,\n orElse = () => {\n throw new Error(\"Both left and right are nullable\");\n },\n}: {\n left?: L | null | undefined;\n right?: R | null | undefined;\n orElse?: () => These<L, R>;\n}): These<L, R> =>\n pipe(optionFromNullables({ left, right }), Option.getOrElse(orElse));\n\n/**\n * Folds a `These` from the left's perspective, collapsing the three tags into two\n * handlers.\n *\n * Both `LeftOnly` and `LeftAndRight` carry a `left`, so they route to the `Left`\n * handler; only `RightOnly` lacks a `left` and routes to `RightOnly`. Use it when\n * you care about the `left` value and treat the right-only case as the exception.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const onLeft = These.matchLeft({\n * Left: (left: number) => `left ${left}`,\n * RightOnly: (right: string) => `right ${right}`\n * })\n *\n * assert.deepStrictEqual(onLeft(These.LeftOnly({ left: 1 })), \"left 1\")\n * assert.deepStrictEqual(\n * onLeft(These.LeftAndRight({ left: 1, right: \"a\" })),\n * \"left 1\"\n * )\n * assert.deepStrictEqual(onLeft(These.RightOnly({ right: \"a\" })), \"right a\")\n * ```\n *\n * @category pattern matching\n * @since 0.0.0\n */\nexport const matchLeft =\n <L, R, A>({\n Left,\n RightOnly,\n }: {\n Left: (left: L) => A;\n RightOnly: (right: R) => A;\n }) =>\n (these: These<L, R>): A =>\n pipe(\n these,\n\n match({\n LeftOnly: ({ left }) => Left(left),\n RightOnly: ({ right }) => RightOnly(right),\n LeftAndRight: ({ left }) => Left(left),\n }),\n\n // Make Typescript happy\n (a) => a as A,\n );\n\n/**\n * Folds a `These` from the right's perspective, collapsing the three tags into two\n * handlers.\n *\n * The mirror of `matchLeft`: both `RightOnly` and `LeftAndRight` carry a `right`,\n * so they route to the `Right` handler; only `LeftOnly` lacks a `right` and routes\n * to `LeftOnly`. Use it when you care about the `right` value and treat the\n * left-only case as the exception.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const onRight = These.matchRight({\n * LeftOnly: (left: number) => `left ${left}`,\n * Right: (right: string) => `right ${right}`\n * })\n *\n * assert.deepStrictEqual(onRight(These.RightOnly({ right: \"a\" })), \"right a\")\n * assert.deepStrictEqual(\n * onRight(These.LeftAndRight({ left: 1, right: \"a\" })),\n * \"right a\"\n * )\n * assert.deepStrictEqual(onRight(These.LeftOnly({ left: 1 })), \"left 1\")\n * ```\n *\n * @category pattern matching\n * @since 0.0.0\n */\nexport const matchRight =\n <L, R, A>({\n LeftOnly,\n Right,\n }: {\n LeftOnly: (left: L) => A;\n Right: (right: R) => A;\n }) =>\n (these: These<L, R>): A =>\n pipe(\n these,\n\n match({\n LeftOnly: ({ left }) => LeftOnly(left),\n RightOnly: ({ right }) => Right(right),\n LeftAndRight: ({ right }) => Right(right),\n }),\n\n // Make Typescript happy\n (a) => a as A,\n );\n\n/**\n * Completes a `These` into a guaranteed `LeftAndRight` by filling whichever side\n * is missing from the matching `orElse` thunk.\n *\n * A `LeftAndRight` passes through unchanged; a `LeftOnly` gains a `right` from\n * `orElseRight`; a `RightOnly` gains a `left` from `orElseLeft`. Use it to\n * normalise a partial `These` into the both-present shape before reading both\n * sides.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const fill = These.orElse({\n * orElseLeft: () => 0,\n * orElseRight: () => \"default\"\n * })\n *\n * assert.deepStrictEqual(\n * fill(These.LeftOnly({ left: 1 })),\n * These.LeftAndRight({ left: 1, right: \"default\" })\n * )\n * assert.deepStrictEqual(\n * fill(These.RightOnly({ right: \"a\" })),\n * These.LeftAndRight({ left: 0, right: \"a\" })\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const orElse = <L2, R2>({\n orElseLeft,\n orElseRight,\n}: {\n orElseLeft: () => L2;\n orElseRight: () => R2;\n}): (<L, R>(these: These<L, R>) => LeftAndRight<L | L2, R | R2>) =>\n match({\n LeftOnly: ({ left }) => LeftAndRight({ left, right: orElseRight() }),\n RightOnly: ({ right }) => LeftAndRight({ left: orElseLeft(), right }),\n LeftAndRight: ({ left, right }) => LeftAndRight({ left, right }),\n });\n\n/**\n * Completes a `These` into a `LeftAndRight` whose missing side is filled with\n * `undefined`.\n *\n * A specialisation of `orElse` that supplies `undefined` for whichever side is\n * absent, so the result always exposes both `left` and `right` keys (each\n * possibly `undefined`). Use it when you want to destructure both sides without\n * branching on the tag.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * These.orUndefined(These.LeftOnly({ left: 1 })),\n * These.LeftAndRight({ left: 1, right: undefined })\n * )\n * assert.deepStrictEqual(\n * These.orUndefined(These.RightOnly({ right: \"a\" })),\n * These.LeftAndRight({ left: undefined, right: \"a\" })\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const orUndefined = orElse({\n orElseLeft: () => undefined,\n orElseRight: () => undefined,\n});\n\n/**\n * Extracts the `left` of a `These`, falling back to `orElseReturn` when no `left`\n * is present.\n *\n * `LeftOnly` and `LeftAndRight` return their `left`; `RightOnly` returns the\n * result of `orElseReturn`. Use it to read the left side with a default in one\n * step.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const leftOrZero = These.leftOrElse(() => 0)\n *\n * assert.deepStrictEqual(leftOrZero(These.LeftOnly({ left: 1 })), 1)\n * assert.deepStrictEqual(\n * leftOrZero(These.LeftAndRight({ left: 1, right: \"a\" })),\n * 1\n * )\n * assert.deepStrictEqual(leftOrZero(These.RightOnly({ right: \"a\" })), 0)\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const leftOrElse =\n <A>(orElseReturn: () => A) =>\n <L, R>(these: These<L, R>): L | A =>\n pipe(\n these,\n orElse({\n orElseLeft: orElseReturn,\n orElseRight: constUndefined,\n }),\n Struct.get(\"left\"),\n );\n\n/**\n * Extracts the `left` of a `These`, returning `undefined` when no `left` is\n * present.\n *\n * A specialisation of `leftOrElse` whose fallback is `undefined`: `LeftOnly` and\n * `LeftAndRight` yield their `left`, while `RightOnly` yields `undefined`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(These.leftOrUndefined(These.LeftOnly({ left: 1 })), 1)\n * assert.deepStrictEqual(\n * These.leftOrUndefined(These.RightOnly({ right: \"a\" })),\n * undefined\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const leftOrUndefined = leftOrElse(() => undefined);\n\n/**\n * Extracts the `right` of a `These`, falling back to `orElseReturn` when no\n * `right` is present.\n *\n * The mirror of `leftOrElse`: `RightOnly` and `LeftAndRight` return their\n * `right`; `LeftOnly` returns the result of `orElseReturn`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const rightOrDefault = These.rightOrElse(() => \"default\")\n *\n * assert.deepStrictEqual(\n * rightOrDefault(These.RightOnly({ right: \"a\" })),\n * \"a\"\n * )\n * assert.deepStrictEqual(\n * rightOrDefault(These.LeftOnly({ left: 1 })),\n * \"default\"\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const rightOrElse =\n <A>(orElseReturn: () => A) =>\n <L, R>(these: These<L, R>): R | A =>\n pipe(\n these,\n orElse({\n orElseLeft: constUndefined,\n orElseRight: orElseReturn,\n }),\n Struct.get(\"right\"),\n );\n\n/**\n * Extracts the `right` of a `These`, returning `undefined` when no `right` is\n * present.\n *\n * A specialisation of `rightOrElse` whose fallback is `undefined`: `RightOnly` and\n * `LeftAndRight` yield their `right`, while `LeftOnly` yields `undefined`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * These.rightOrUndefined(These.RightOnly({ right: \"a\" })),\n * \"a\"\n * )\n * assert.deepStrictEqual(\n * These.rightOrUndefined(These.LeftOnly({ left: 1 })),\n * undefined\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const rightOrUndefined = rightOrElse(() => undefined);\n\n/**\n * Extracts the `right` of a `These` as an `Option`.\n *\n * `RightOnly` and `LeftAndRight` yield `Option.some(right)`; `LeftOnly` yields\n * `Option.none()`. Use it when you want to chain the right side through `Option`\n * combinators rather than fall back to a default eagerly.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Option } from \"effect\"\n *\n * assert.deepStrictEqual(\n * These.rightOption(These.RightOnly({ right: \"a\" })),\n * Option.some(\"a\")\n * )\n * assert.deepStrictEqual(\n * These.rightOption(These.LeftOnly({ left: 1 })),\n * Option.none()\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const rightOption = <L, R>(these: These<L, R>): Option.Option<R> =>\n pipe(\n these,\n matchRight({\n LeftOnly: () => Option.none(),\n Right: Option.some,\n }),\n );\n\n/**\n * Extracts the `left` of a `These` as an `Option`.\n *\n * The mirror of `rightOption`: `LeftOnly` and `LeftAndRight` yield\n * `Option.some(left)`, while `RightOnly` yields `Option.none()`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Option } from \"effect\"\n *\n * assert.deepStrictEqual(\n * These.leftOption(These.LeftOnly({ left: 1 })),\n * Option.some(1)\n * )\n * assert.deepStrictEqual(\n * These.leftOption(These.RightOnly({ right: \"a\" })),\n * Option.none()\n * )\n * ```\n *\n * @category getters\n * @since 0.0.0\n */\nexport const leftOption = <L, R>(these: These<L, R>): Option.Option<L> =>\n pipe(\n these,\n matchLeft({\n Left: Option.some,\n RightOnly: () => Option.none(),\n }),\n );\n\n/**\n * Transforms both sides of a `These`, applying `mapLeft` to any `left` and\n * `mapRight` to any `right`.\n *\n * Each constructor is rebuilt with its mapped contents, so `LeftOnly` maps only\n * the left, `RightOnly` only the right, and `LeftAndRight` both. The tag is\n * preserved. Use it as the bifunctor map over `These`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const both = These.mapBoth({\n * mapLeft: (left: number) => left + 1,\n * mapRight: (right: string) => right.toUpperCase()\n * })\n *\n * assert.deepStrictEqual(\n * both(These.LeftAndRight({ left: 1, right: \"a\" })),\n * These.LeftAndRight({ left: 2, right: \"A\" })\n * )\n * assert.deepStrictEqual(\n * both(These.LeftOnly({ left: 1 })),\n * These.LeftOnly({ left: 2 })\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const mapBoth = <L1, R1, L2, R2>({\n mapLeft,\n mapRight,\n}: {\n mapLeft: (left: L1) => L2;\n mapRight: (right: R1) => R2;\n}): ((these: These<L1, R1>) => These<L2, R2>) =>\n match({\n LeftOnly: ({ left }) => LeftOnly({ left: mapLeft(left) }),\n RightOnly: ({ right }) => RightOnly({ right: mapRight(right) }),\n LeftAndRight: ({ left, right }) =>\n LeftAndRight({ left: mapLeft(left), right: mapRight(right) }),\n });\n\n/**\n * Effectful `mapBoth`: transforms each present side through an `Effect`,\n * reassembling the results into a `These` inside an `Effect`.\n *\n * For `LeftAndRight` both effects run via `Effect.all` and their results are\n * combined; `LeftOnly`/`RightOnly` run only the relevant effect. Errors and\n * requirements from both mappers are unioned into the result type. Use it when\n * mapping a `These`'s sides requires effects (validation, IO).\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Effect } from \"effect\"\n *\n * const both = These.mapBothEffect({\n * mapLeft: (left: number) => Effect.succeed(left + 1),\n * mapRight: (right: string) => Effect.succeed(right.toUpperCase())\n * })\n *\n * assert.deepStrictEqual(\n * Effect.runSync(both(These.LeftAndRight({ left: 1, right: \"a\" }))),\n * These.LeftAndRight({ left: 2, right: \"A\" })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const mapBothEffect = <L1, R1, L2, R2, EL, ER, RL, RR>({\n mapLeft,\n mapRight,\n}: {\n mapLeft: (left: L1) => Effect.Effect<L2, EL, RL>;\n mapRight: (right: R1) => Effect.Effect<R2, ER, RR>;\n}): ((\n these: These<L1, R1>,\n) => Effect.Effect<These<L2, R2>, EL | ER, RL | RR>) =>\n match({\n LeftOnly: ({ left }) =>\n pipe(\n mapLeft(left),\n Effect.map((left2) => LeftOnly({ left: left2 })),\n ),\n\n RightOnly: ({ right }) =>\n pipe(\n mapRight(right),\n Effect.map((right2) => RightOnly({ right: right2 })),\n ),\n\n LeftAndRight: ({ left, right }) =>\n pipe(\n Effect.all({ left: mapLeft(left), right: mapRight(right) }),\n Effect.map(({ left: left2, right: right2 }) =>\n LeftAndRight({ left: left2, right: right2 }),\n ),\n ),\n });\n\n/**\n * Transforms the `left` of a `These`, leaving any `right` untouched.\n *\n * A specialisation of `mapBoth` with the right mapper set to `identity`:\n * `LeftOnly` and `LeftAndRight` have their `left` mapped, while `RightOnly` passes\n * through unchanged.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const inc = These.mapLeft((left: number) => left + 1)\n *\n * assert.deepStrictEqual(\n * inc(These.LeftAndRight({ left: 1, right: \"a\" })),\n * These.LeftAndRight({ left: 2, right: \"a\" })\n * )\n * assert.deepStrictEqual(\n * inc(These.RightOnly({ right: \"a\" })),\n * These.RightOnly({ right: \"a\" })\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const mapLeft = <L1, L2>(\n mapLeft: (left: L1) => L2,\n): (<R>(these: These<L1, R>) => These<L2, R>) =>\n mapBoth({ mapLeft, mapRight: identity });\n\n/**\n * Chains the `left` of a `These` into a new `These`, flattening the result.\n *\n * Whenever a `left` is present (`LeftOnly` or `LeftAndRight`) it is passed to\n * `mapLeft`, whose returned `These` replaces the original; `RightOnly` passes\n * through unchanged. Use it to sequence left-driven computations that themselves\n * produce a `These`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const chain = These.flatMapLeft((left: number) =>\n * left > 0\n * ? These.LeftOnly({ left: left * 10 })\n * : These.RightOnly({ right: \"non-positive\" })\n * )\n *\n * assert.deepStrictEqual(\n * chain(These.LeftOnly({ left: 2 })),\n * These.LeftOnly({ left: 20 })\n * )\n * assert.deepStrictEqual(\n * chain(These.RightOnly({ right: \"a\" })),\n * These.RightOnly({ right: \"a\" })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const flatMapLeft = <L1, L2, R2>(\n mapLeft: (left: L1) => These<L2, R2>,\n): (<R1>(these: These<L1, R1>) => These<L2, R1 | R2>) =>\n match({\n LeftOnly: ({ left }) => mapLeft(left),\n RightOnly: ({ right }) => RightOnly({ right }),\n LeftAndRight: ({ left }) => mapLeft(left),\n });\n\n/**\n * Effectful `mapLeft`: transforms the `left` of a `These` through an `Effect`,\n * leaving any `right` untouched.\n *\n * A specialisation of `mapBothEffect` with the right mapper set to\n * `Effect.succeed`: the `left` (when present) is mapped effectfully and the\n * `right` is carried through unchanged.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Effect } from \"effect\"\n *\n * const inc = These.mapLeftEffect((left: number) => Effect.succeed(left + 1))\n *\n * assert.deepStrictEqual(\n * Effect.runSync(inc(These.LeftAndRight({ left: 1, right: \"a\" }))),\n * These.LeftAndRight({ left: 2, right: \"a\" })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const mapLeftEffect = <L1, L2, EL, RL>(\n mapLeft: (left: L1) => Effect.Effect<L2, EL, RL>,\n): (<R>(these: These<L1, R>) => Effect.Effect<These<L2, R>, EL, RL>) =>\n mapBothEffect({ mapLeft, mapRight: Effect.succeed });\n\n/**\n * Effectful `flatMapLeft`: chains the `left` of a `These` into an `Effect` that\n * yields a new `These`, flattening the result.\n *\n * When a `left` is present it is passed to `mapLeft`, whose effectful `These`\n * replaces the original; `RightOnly` is lifted unchanged via `Effect.succeed`. Use\n * it to sequence left-driven effectful computations that produce a `These`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Effect } from \"effect\"\n *\n * const chain = These.flatMapLeftEffect((left: number) =>\n * Effect.succeed(These.LeftOnly({ left: left * 10 }))\n * )\n *\n * assert.deepStrictEqual(\n * Effect.runSync(chain(These.LeftOnly({ left: 2 }))),\n * These.LeftOnly({ left: 20 })\n * )\n * assert.deepStrictEqual(\n * Effect.runSync(chain(These.RightOnly({ right: \"a\" }))),\n * These.RightOnly({ right: \"a\" })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const flatMapLeftEffect = <L1, L2, R2, EL, RL>(\n mapLeft: (left: L1) => Effect.Effect<These<L2, R2>, EL, RL>,\n): (<R1>(these: These<L1, R1>) => Effect.Effect<These<L2, R1 | R2>, EL, RL>) =>\n match({\n LeftOnly: ({ left }) => mapLeft(left),\n RightOnly: ({ right }) => Effect.succeed(RightOnly({ right })),\n LeftAndRight: ({ left }) => mapLeft(left),\n });\n\n/**\n * Transforms the `right` of a `These`, leaving any `left` untouched.\n *\n * The mirror of `mapLeft`: `RightOnly` and `LeftAndRight` have their `right`\n * mapped, while `LeftOnly` passes through unchanged.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const upper = These.mapRight((right: string) => right.toUpperCase())\n *\n * assert.deepStrictEqual(\n * upper(These.LeftAndRight({ left: 1, right: \"a\" })),\n * These.LeftAndRight({ left: 1, right: \"A\" })\n * )\n * assert.deepStrictEqual(\n * upper(These.LeftOnly({ left: 1 })),\n * These.LeftOnly({ left: 1 })\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const mapRight = <R1, R2>(\n mapRight: (right: R1) => R2,\n): (<L>(these: These<L, R1>) => These<L, R2>) =>\n mapBoth({ mapLeft: identity, mapRight });\n\n/**\n * Chains the `right` of a `These` into a new `These`, flattening the result.\n *\n * The mirror of `flatMapLeft`: whenever a `right` is present (`RightOnly` or\n * `LeftAndRight`) it is passed to `mapRight`, whose returned `These` replaces the\n * original; `LeftOnly` passes through unchanged.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n *\n * const chain = These.flatMapRight((right: string) =>\n * These.RightOnly({ right: right.toUpperCase() })\n * )\n *\n * assert.deepStrictEqual(\n * chain(These.RightOnly({ right: \"a\" })),\n * These.RightOnly({ right: \"A\" })\n * )\n * assert.deepStrictEqual(\n * chain(These.LeftOnly({ left: 1 })),\n * These.LeftOnly({ left: 1 })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const flatMapRight = <L2, R1, R2>(\n mapRight: (right: R1) => These<L2, R2>,\n): (<L1>(these: These<L1, R1>) => These<L1 | L2, R2>) =>\n match({\n LeftOnly: ({ left }) => LeftOnly({ left }),\n RightOnly: ({ right }) => mapRight(right),\n LeftAndRight: ({ right }) => mapRight(right),\n });\n\n/**\n * Effectful `mapRight`: transforms the `right` of a `These` through an `Effect`,\n * leaving any `left` untouched.\n *\n * The mirror of `mapLeftEffect`: the `right` (when present) is mapped effectfully\n * and the `left` is carried through unchanged via `Effect.succeed`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Effect } from \"effect\"\n *\n * const upper = These.mapRightEffect((right: string) =>\n * Effect.succeed(right.toUpperCase())\n * )\n *\n * assert.deepStrictEqual(\n * Effect.runSync(upper(These.LeftAndRight({ left: 1, right: \"a\" }))),\n * These.LeftAndRight({ left: 1, right: \"A\" })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const mapRightEffect = <R1, R2, ER, RR>(\n mapRight: (right: R1) => Effect.Effect<R2, ER, RR>,\n): (<L>(these: These<L, R1>) => Effect.Effect<These<L, R2>, ER, RR>) =>\n mapBothEffect({ mapLeft: Effect.succeed, mapRight });\n\n/**\n * Effectful `flatMapRight`: chains the `right` of a `These` into an `Effect` that\n * yields a new `These`, flattening the result.\n *\n * The mirror of `flatMapLeftEffect`: when a `right` is present it is passed to\n * `mapRight`, whose effectful `These` replaces the original; `LeftOnly` is lifted\n * unchanged via `Effect.succeed`.\n *\n * @example\n * ```ts\n * import { These } from \"@nunofyobiz/effect-extras\"\n * import { Effect } from \"effect\"\n *\n * const chain = These.flatMapRightEffect((right: string) =>\n * Effect.succeed(These.RightOnly({ right: right.toUpperCase() }))\n * )\n *\n * assert.deepStrictEqual(\n * Effect.runSync(chain(These.RightOnly({ right: \"a\" }))),\n * These.RightOnly({ right: \"A\" })\n * )\n * assert.deepStrictEqual(\n * Effect.runSync(chain(These.LeftOnly({ left: 1 }))),\n * These.LeftOnly({ left: 1 })\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const flatMapRightEffect = <L2, R1, R2, ER, RR>(\n mapRight: (right: R1) => Effect.Effect<These<L2, R2>, ER, RR>,\n): (<L1>(these: These<L1, R1>) => Effect.Effect<These<L1 | L2, R2>, ER, RR>) =>\n match({\n LeftOnly: ({ left }) => Effect.succeed(LeftOnly({ left })),\n RightOnly: ({ right }) => mapRight(right),\n LeftAndRight: ({ right }) => mapRight(right),\n });\n","/**\n * Generic, framework-agnostic extensions to Effect's `Result` module.\n *\n * @since 0.0.0\n */\nimport { Option, Result } from \"effect\";\n\n/**\n * Lifts an `Option` into a `Result` with a `void` failure: `Some(value)` becomes\n * `Result.succeed(value)` and `None` becomes `Result.failVoid`.\n *\n * Useful in v4 where `Array.filterMap` and `Record.filterMap` expect\n * `Result`-returning predicates (a `Success` keeps the value, a `Failure` drops\n * it); in v3 those APIs accepted `Option`-returning predicates directly:\n *\n * ```ts\n * import { Array } from \"effect\"\n * import { ResultX } from \"@nunofyobiz/effect-extras\"\n *\n * declare const items: ReadonlyArray<number>\n * declare const maybeTransform: (item: number) => import(\"effect\").Option.Option<string>\n *\n * // v3: Array.filterMap(items, (item) => maybeTransform(item))\n * // v4:\n * Array.filterMap(items, (item) => ResultX.fromOption(maybeTransform(item)))\n * ```\n *\n * Effect ships `Result.fromOption(option, onNone)` which requires a non-`void`\n * failure value; this helper specializes to the common \"drop the item, no error\n * needed\" case used by `filterMap`.\n *\n * @example\n * ```ts\n * import { Option, Result } from \"effect\"\n * import { ResultX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(\n * ResultX.fromOption(Option.some(1)),\n * Result.succeed(1),\n * )\n * assert.deepStrictEqual(\n * ResultX.fromOption(Option.none<number>()),\n * Result.failVoid,\n * )\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const fromOption = <A>(\n option: Option.Option<A>,\n): Result.Result<A, void> =>\n Option.isSome(option) ? Result.succeed(option.value) : Result.failVoid;\n","/**\n * Generic, framework-agnostic extensions to Effect's `BigInt` module.\n *\n * @since 0.0.0\n */\nimport { BigInt, Option } from \"effect\";\n\n/**\n * Converts a `bigint` to a `number`, throwing when the value cannot be\n * represented exactly.\n *\n * Delegates to Effect's `BigInt.toNumber`, which returns `None` once the\n * `bigint` falls outside the safe integer range (`Number.MAX_SAFE_INTEGER`).\n * This unwraps that `Option`, throwing instead of silently losing precision —\n * use it only when the value is known to fit.\n *\n * @example\n * ```ts\n * import { BigIntX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(BigIntX.toNumberOrThrow(42n), 42)\n *\n * // throws when outside the safe integer range\n * assert.throws(() => BigIntX.toNumberOrThrow(9007199254740993n))\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const toNumberOrThrow = (value: bigint): number =>\n BigInt.toNumber(value).pipe(\n Option.getOrThrowWith(\n () => new Error(`Value ${value} is outside safe integer range`),\n ),\n );\n","/**\n * Generic, framework-agnostic extensions to Effect's `Boolean` module.\n *\n * @since 0.0.0\n */\n/**\n * Converts a `boolean` to its binary digit: `1` for `true`, `0` for `false`.\n *\n * Useful when a numeric flag is required — summing booleans to count how many\n * predicates hold, or feeding a bit into bitwise math or an external API that\n * expects `0`/`1` rather than `false`/`true`.\n *\n * @example\n * ```ts\n * import { BooleanX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(BooleanX.toBinary(true), 1)\n * assert.deepStrictEqual(BooleanX.toBinary(false), 0)\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const toBinary = (value: boolean): 0 | 1 => (value ? 1 : 0);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Duration` module.\n *\n * @since 0.0.0\n */\nimport { DateTime, Duration, Match, Option } from \"effect\";\nimport { dual, pipe } from \"effect/Function\";\nimport { BigIntX } from \"../BigIntX\";\n\n// Some private constants for conversion\nconst MICROS_PER_MILLI = 1000;\n\n/**\n * Computes the elapsed `Duration` from `that` to `self`, clamped at zero.\n *\n * Represents the time that has passed since the reference instant `that`. When\n * `that` lies in the future relative to `self`, the elapsed time is `zero`\n * rather than a negative duration.\n *\n * @example\n * ```ts\n * import { DateTime, Duration, pipe } from \"effect\"\n * import { DurationX } from \"@nunofyobiz/effect-extras\"\n *\n * const earlier = DateTime.makeUnsafe(1000)\n * const later = DateTime.makeUnsafe(4000)\n *\n * // data-first\n * assert.deepStrictEqual(DurationX.diff(later, earlier), Duration.seconds(3))\n *\n * // future reference clamps to zero\n * assert.deepStrictEqual(DurationX.diff(earlier, later), Duration.zero)\n *\n * // data-last (piped)\n * assert.deepStrictEqual(\n * pipe(later, DurationX.diff(earlier)),\n * Duration.seconds(3),\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const diff = dual<\n // Data-last typing\n (that: DateTime.DateTime) => (self: DateTime.DateTime) => Duration.Duration,\n // Data-first typing\n (self: DateTime.DateTime, that: DateTime.DateTime) => Duration.Duration\n>(\n 2,\n (self: DateTime.DateTime, that: DateTime.DateTime): Duration.Duration =>\n Duration.millis(\n // Clamp at 0 — \"diff\" represents elapsed time since `that`; if `that`\n // is in the future relative to `self`, the elapsed time is zero\n // (not negative).\n Math.max(0, DateTime.toEpochMillis(self) - DateTime.toEpochMillis(that)),\n ),\n);\n\n// Internal — used by mapAsUnit.\nconst toUnit = dual<\n // Data-last typing\n (unit: Duration.Unit) => (duration: Duration.Duration) => number,\n // Data-first typing\n (duration: Duration.Duration, unit: Duration.Unit) => number\n>(2, (duration: Duration.Duration, unit: Duration.Unit): number =>\n Match.value(unit).pipe(\n Match.whenOr(\"week\", \"weeks\", () => Duration.toWeeks(duration)),\n Match.whenOr(\"day\", \"days\", () => Duration.toDays(duration)),\n Match.whenOr(\"hour\", \"hours\", () => Duration.toHours(duration)),\n Match.whenOr(\"minute\", \"minutes\", () => Duration.toMinutes(duration)),\n Match.whenOr(\"second\", \"seconds\", () => Duration.toSeconds(duration)),\n Match.whenOr(\"milli\", \"millis\", () => Duration.toMillis(duration)),\n Match.whenOr(\n \"micro\",\n \"micros\",\n () => Duration.toMillis(duration) * MICROS_PER_MILLI,\n ),\n Match.whenOr(\"nano\", \"nanos\", () =>\n pipe(\n Duration.toNanos(duration),\n Option.getOrThrowWith(\n () => new Error(\"Duration.toNanos returned None\"),\n ),\n BigIntX.toNumberOrThrow,\n ),\n ),\n Match.exhaustive,\n ),\n);\n\n// Internal — used by mapAsUnit.\nconst fromUnit = dual<\n // Data-last typing\n (unit: Duration.Unit) => (value: number) => Duration.Duration,\n // Data-first typing\n (value: number, unit: Duration.Unit) => Duration.Duration\n>(\n 2,\n (value: number, unit: Duration.Unit): Duration.Duration =>\n Match.value(unit).pipe(\n Match.whenOr(\"week\", \"weeks\", () => Duration.weeks(value)),\n Match.whenOr(\"day\", \"days\", () => Duration.days(value)),\n Match.whenOr(\"hour\", \"hours\", () => Duration.hours(value)),\n Match.whenOr(\"minute\", \"minutes\", () => Duration.minutes(value)),\n Match.whenOr(\"second\", \"seconds\", () => Duration.seconds(value)),\n Match.whenOr(\"milli\", \"millis\", () => Duration.millis(value)),\n Match.whenOr(\"micro\", \"micros\", () => Duration.micros(BigInt(value))),\n Match.whenOr(\"nano\", \"nanos\", () => Duration.nanos(BigInt(value))),\n Match.exhaustive,\n ),\n);\n\n/**\n * Transforms a `Duration` by converting it to a numeric `unit`, applying `map`,\n * then converting back.\n *\n * Lets you operate on a duration in whatever unit is convenient — round it to\n * whole minutes, halve its seconds, floor its days — without juggling\n * conversions by hand. The `map` callback receives the duration expressed as a\n * `number` of `unit`s and returns the new count.\n *\n * @example\n * ```ts\n * import { Duration, Number, pipe } from \"effect\"\n * import { DurationX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first: halve a 4-second duration\n * assert.deepStrictEqual(\n * DurationX.mapAsUnit(Duration.seconds(4), \"second\", Number.divideUnsafe(2)),\n * Duration.seconds(2),\n * )\n *\n * // data-last (piped)\n * assert.deepStrictEqual(\n * pipe(\n * Duration.minutes(10),\n * DurationX.mapAsUnit(\"minute\", (minutes) => minutes + 5),\n * ),\n * Duration.minutes(15),\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const mapAsUnit = dual<\n // Data-last typing\n (\n unit: Duration.Unit,\n map: (numberOfUnits: number) => number,\n ) => (duration: Duration.Duration) => Duration.Duration,\n // Data-first typing\n (\n duration: Duration.Duration,\n unit: Duration.Unit,\n map: (numberOfUnits: number) => number,\n ) => Duration.Duration\n>(\n 3,\n (\n duration: Duration.Duration,\n unit: Duration.Unit,\n map: (numberOfUnits: number) => number,\n ): Duration.Duration =>\n pipe(\n duration,\n\n // Convert to that unit\n toUnit(unit),\n\n // Truncate to the requested number of digits\n map,\n\n // Convert back to a duration\n fromUnit(unit),\n ),\n);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Effect` module.\n *\n * @since 0.0.0\n */\nimport { Cause, Duration, Effect, Option, Predicate, pipe } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * The duration of time a user registers something as \"instant\" — used as the\n * default poll interval for {@link tryUntil}. 200ms is the generally agreed\n * value. See https://psychology.stackexchange.com/a/1680\n */\nconst USER_INSTANT_DURATION = Duration.millis(200);\n\n/**\n * Flattens an `Effect` that succeeds with an `Option` into an `Effect` that\n * fails with `onNone()` when the `Option` is `None`.\n *\n * When the wrapped `Option` is `Some(value)` the effect succeeds with `value`;\n * when it is `None` the effect fails with the error produced by the `onNone`\n * thunk. An existing failure of the source effect is preserved untouched, so the\n * result's error channel is the union of the original error and the `None`\n * error.\n *\n * @example\n * ```ts\n * import { Effect, Option, Result } from \"effect\"\n * import { EffectX } from \"@nunofyobiz/effect-extras\"\n *\n * const some = EffectX.flattenOption(\n * Effect.succeed(Option.some(1)),\n * () => \"missing\",\n * )\n * assert.deepStrictEqual(Effect.runSync(Effect.result(some)), Result.succeed(1))\n *\n * const none = EffectX.flattenOption(\n * Effect.succeed(Option.none<number>()),\n * () => \"missing\",\n * )\n * assert.deepStrictEqual(\n * Effect.runSync(Effect.result(none)),\n * Result.fail(\"missing\"),\n * )\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const flattenOption = dual<\n <A, E1, E2, R>(\n onNone: () => E2,\n ) => (\n effect: Effect.Effect<Option.Option<A>, E1, R>,\n ) => Effect.Effect<A, E1 | E2, R>,\n <A, E1, E2, R>(\n effect: Effect.Effect<Option.Option<A>, E1, R>,\n onNone: () => E2,\n ) => Effect.Effect<A, E1 | E2, R>\n>(\n 2,\n <A, E1, E2, R>(\n effect: Effect.Effect<Option.Option<A>, E1, R>,\n onNone: () => E2,\n ): Effect.Effect<A, E1 | E2, R> =>\n Effect.flatMap(effect, (option) =>\n pipe(Effect.fromOption(option), Effect.mapError(onNone)),\n ),\n);\n\n/**\n * Converts an `Option` to an `Effect`, mapping the `None` case to a caller-chosen\n * error via the `onNone` thunk.\n *\n * Equivalent to `Effect.mapError(Effect.fromOption(option), onNone)`: it bridges\n * the `NoSuchElementError` that `Effect.fromOption` produces to the caller's own\n * error type, so callers never have to handle `NoSuchElementError`. This fills\n * the v4 gap where `Effect.mapError` no longer accepts an `Option` directly —\n * instead of\n * `pipe(option, Effect.fromOption, Effect.mapError(() => new MyError()))`, write\n * `pipe(option, EffectX.fromOptionOrElse(() => new MyError()))`. The `onNone`\n * thunk runs only when the `Option` is `None`.\n *\n * @example\n * ```ts\n * import { Effect, Option, Result, pipe } from \"effect\"\n * import { EffectX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * const some = EffectX.fromOptionOrElse(Option.some(42), () => \"missing\")\n * assert.deepStrictEqual(Effect.runSync(Effect.result(some)), Result.succeed(42))\n *\n * // data-last (piped) — None maps to the chosen error\n * const none = pipe(\n * Option.none<number>(),\n * EffectX.fromOptionOrElse(() => \"missing\"),\n * )\n * assert.deepStrictEqual(\n * Effect.runSync(Effect.result(none)),\n * Result.fail(\"missing\"),\n * )\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const fromOptionOrElse: {\n <E>(onNone: () => E): <A>(option: Option.Option<A>) => Effect.Effect<A, E>;\n <A, E>(option: Option.Option<A>, onNone: () => E): Effect.Effect<A, E>;\n} = dual(\n 2,\n <A, E>(option: Option.Option<A>, onNone: () => E): Effect.Effect<A, E> =>\n pipe(Effect.fromOption(option), Effect.mapError(onNone)),\n);\n\n/**\n * Repeatedly calls a synchronous `try` thunk until its result satisfies the\n * `until` refinement, sleeping `sleepDuration` between attempts and failing with\n * a `TimeoutError` once `maxDuration` elapses.\n *\n * The thunk is evaluated immediately; if its first result already passes the\n * refinement the effect succeeds without any delay. Otherwise it polls on the\n * `sleepDuration` interval (defaulting to 200ms — the threshold below which a\n * delay reads as \"instant\" to a user) until either the predicate holds (the\n * effect succeeds with the narrowed `B` value) or `maxDuration` is exceeded (the\n * effect fails with a `Cause.TimeoutError`). Use it to await an external,\n * non-effectful condition such as a flag flipped by a callback.\n *\n * @example\n * ```ts\n * import { Duration, Effect } from \"effect\"\n * import { EffectX } from \"@nunofyobiz/effect-extras\"\n *\n * // First attempt already matches, so it resolves immediately.\n * const effect = EffectX.tryUntil({\n * try: () => 1,\n * until: (value: number): value is number => value === 1,\n * sleepDuration: Duration.millis(100),\n * maxDuration: Duration.seconds(1),\n * })\n *\n * assert.deepStrictEqual(Effect.runSync(effect), 1)\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const tryUntil = <A, B extends A>({\n try: doTry,\n until: isDone,\n sleepDuration = USER_INSTANT_DURATION,\n maxDuration,\n}: {\n try: () => A;\n until: Predicate.Refinement<A, B>;\n sleepDuration?: Duration.Duration;\n maxDuration: Duration.Duration;\n}): Effect.Effect<B, Cause.TimeoutError, never> => {\n const immediateValue = doTry();\n if (isDone(immediateValue)) {\n return Effect.succeed(immediateValue);\n }\n\n // Continually call it again on a schedule with a delay\n return Effect.sync(doTry).pipe(\n // Sleep in between each attempt\n Effect.delay(sleepDuration),\n\n // Keep doing this until the predicate passes\n Effect.repeat({ until: isDone }),\n\n // Until a timeout occurs. In v4, `Effect.timeout` raises `TimeoutError`\n // on its own — no separate `timeoutFail` overload is needed.\n Effect.timeout(maxDuration),\n Effect.catchTag(\"TimeoutError\", () =>\n Effect.fail(\n new Cause.TimeoutError(\n `Timed out after ${Duration.format(maxDuration)} waiting for value to pass predicate`,\n ),\n ),\n ),\n );\n};\n","/**\n * Helpers for decoding `FormData` with Effect `Schema`.\n *\n * @since 0.0.0\n */\nimport { Function, Schema } from \"effect\";\n\n/**\n * Decodes a `FormData` into a typed value using a `Schema`, throwing on\n * validation failure.\n *\n * Built on v4's native `Schema.fromFormData`, which first parses the `FormData`\n * entries into a nested tree record (bracket-path notation is supported) and then\n * decodes that tree with the provided inner schema. For schemas with non-string\n * fields (for example `Schema.Int`), wrap the inner schema in\n * `Schema.toCodecStringTree(schema, { keepDeclarations: true })` so the\n * string → number/boolean coercion happens. Usable only with schemas that have\n * no decoding services — this is enforced at the type level via\n * `S[\"DecodingServices\"] = never` — and it throws synchronously when the input\n * fails validation.\n *\n * @example\n * ```ts\n * import { Schema } from \"effect\"\n * import { FormDataX } from \"@nunofyobiz/effect-extras\"\n *\n * const formData = new FormData()\n * formData.append(\"name\", \"John\")\n * formData.append(\"age\", \"30\")\n *\n * const result = FormDataX.decodeSync(\n * formData,\n * Schema.Struct({ name: Schema.String, age: Schema.NumberFromString }),\n * )\n *\n * assert.deepStrictEqual(result, { name: \"John\", age: 30 })\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const decodeSync: {\n <S extends Schema.Top & { readonly DecodingServices: never }>(\n formData: FormData,\n schema: S,\n ): S[\"Type\"];\n <S extends Schema.Top & { readonly DecodingServices: never }>(\n schema: S,\n ): (formData: FormData) => S[\"Type\"];\n} = Function.dual(\n 2,\n <S extends Schema.Top & { readonly DecodingServices: never }>(\n formData: FormData,\n schema: S,\n ): S[\"Type\"] =>\n Schema.decodeUnknownSync(Schema.fromFormData(schema))(formData),\n);\n","/**\n * Generic, framework-agnostic extensions for working with `Map`.\n *\n * @since 0.0.0\n */\nimport { Predicate } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * Like `Map.prototype.get`, but when the key is absent it stores the computed\n * fallback at that key and returns it. Mutates the input map in place.\n *\n * Use it for memoization-style caches where a miss should both populate the map\n * and yield the value in one step. Throws if the resolved value is nullish (only\n * possible when `fallbackIfNotFound` returns `null`/`undefined` for a value type\n * that admits them — treated as a programmer error). Supports both data-first and\n * data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { MapX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Miss: stores the fallback and returns it (data-first)\n * const map = new Map<string, number>()\n * assert.deepStrictEqual(MapX.getOrElseSetGet(map, \"a\", () => 1), 1)\n * assert.deepStrictEqual(map.get(\"a\"), 1)\n *\n * // Hit: returns the existing value, fallback is ignored (data-last)\n * assert.deepStrictEqual(\n * pipe(map, MapX.getOrElseSetGet(\"a\", () => 99)),\n * 1\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const getOrElseSetGet = dual<\n <K, V>(key: K, fallbackIfNotFound: () => V) => (map: Map<K, V>) => V,\n <K, V>(map: Map<K, V>, key: K, fallbackIfNotFound: () => V) => V\n>(3, <K, V>(map: Map<K, V>, key: K, fallbackIfNotFound: () => V): V => {\n if (!map.has(key)) {\n map.set(key, fallbackIfNotFound());\n return fallbackIfNotFound();\n }\n\n const existingValue = map.get(key);\n if (Predicate.isNullish(existingValue)) {\n throw new Error(`Value is nullable: ${String(key)}`);\n }\n\n return existingValue;\n});\n","/**\n * Helpers for working with non-nullable values.\n *\n * @since 0.0.0\n */\nimport {\n Number as EffectNumber,\n Match,\n Order,\n Ordering,\n Predicate,\n} from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * Returns `value` narrowed to `NonNullable<A>`, throwing an `Error` if it is\n * `null` or `undefined`.\n *\n * Use it at trusted boundaries where a value is known to be present but typed as\n * nullable, turning a silent `undefined` into a loud failure. An optional\n * `variableName` is woven into the thrown message to aid debugging. This is the\n * function re-exported as `nn` from the module barrel, a terse shorthand handy\n * inside string interpolations.\n *\n * @example\n * ```ts\n * import { NonNullableX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(NonNullableX.fromNullableOrThrow(\"value\"), \"value\")\n *\n * assert.throws(\n * () => NonNullableX.fromNullableOrThrow(null, \"varName\"),\n * /Value is nullable: null \\(variable name: varName\\)/\n * )\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const fromNullableOrThrow = <A>(\n value: A,\n variableName?: string,\n): NonNullable<A> => {\n if (Predicate.isNotNullish(value)) {\n return value;\n }\n throw new Error(\n `Value is nullable: ${String(value)}${Predicate.isNotNullish(variableName) ? ` (variable name: ${variableName})` : \"\"}`,\n );\n};\n\n/**\n * Branches on whether `value` is nullish, passing the value narrowed to\n * `NonNullable<A>` to the `whenNotNullable` handler.\n *\n * A nullable-aware sibling of `Match.value`: it folds a present-or-absent value\n * into a single `B` without an `if`/`else` or a manual `!= null` check. Note that\n * falsy-but-present values (`\"\"`, `0`, `false`) take the `whenNotNullable`\n * branch — only `null` and `undefined` are treated as absent. Supports both\n * data-first and data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { NonNullableX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Data-first — present value flows through narrowed\n * assert.deepStrictEqual(\n * NonNullableX.match(\"value\", {\n * whenNullable: () => \"nullable\",\n * whenNotNullable: (value) => value\n * }),\n * \"value\"\n * )\n *\n * // Data-last — null takes the whenNullable branch\n * assert.deepStrictEqual(\n * pipe(\n * null,\n * NonNullableX.match({\n * whenNullable: () => \"nullable\",\n * whenNotNullable: (value) => value\n * })\n * ),\n * \"nullable\"\n * )\n * ```\n *\n * @category pattern matching\n * @since 0.0.0\n */\nexport const match = dual<\n <A, B>(handlers: {\n whenNullable: () => B;\n whenNotNullable: (value: NonNullable<A>) => B;\n }) => (value: A) => B,\n <A, B>(\n value: A,\n handlers: {\n whenNullable: () => B;\n whenNotNullable: (value: NonNullable<A>) => B;\n },\n ) => B\n>(\n 2,\n <A, B>(\n value: A,\n {\n whenNullable,\n whenNotNullable,\n }: { whenNullable: () => B; whenNotNullable: (value: NonNullable<A>) => B },\n ): B =>\n Predicate.isNotNullish(value) ? whenNotNullable(value) : whenNullable(),\n);\n\n/**\n * Applies `map` to `a` only when it is non-nullish, passing nullish inputs\n * through unchanged.\n *\n * This is the nullable-preserving map: a present value is transformed to `B`,\n * while `null` stays `null` and `undefined` stays `undefined`, so nullability is\n * carried through the transformation. Supports both data-first and data-last\n * (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { NonNullableX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Data-first — present value is transformed\n * assert.deepStrictEqual(NonNullableX.map(1, (v: number) => v + 1), 2)\n *\n * // Data-last — nullish passes through unchanged\n * const value: number | null = null\n * assert.deepStrictEqual(\n * pipe(\n * value,\n * NonNullableX.map<number | null, number>((v) => v + 1)\n * ),\n * null\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const map = dual<\n <A, B>(\n map: (a: NonNullable<A>) => B,\n ) => (a: A) => B | (null & A) | (undefined & A),\n <A, B>(\n a: A,\n map: (a: NonNullable<A>) => B,\n ) => B | (null & A) | (undefined & A)\n>(\n 2,\n <A, B>(\n a: A,\n map: (a: NonNullable<A>) => B,\n ): B | (null & A) | (undefined & A) => {\n if (Predicate.isNotNullish(a)) {\n return map(a);\n }\n\n if (Predicate.isNullish(a)) {\n return a;\n }\n\n throw new Error(`Value is neither nullable nor non-nullable: ${String(a)}`);\n },\n);\n\n/**\n * Lifts a total function `(a: A) => B` into one that tolerates nullish input,\n * applying it to present values and passing `null`/`undefined` through unchanged.\n *\n * Where `map` operates on a value, `lift` transforms the function itself,\n * yielding a reusable `(a: A | null | undefined) => B | null | undefined` you can\n * drop into a `pipe`. Use it to adapt a plain transform to a nullable pipeline\n * without wrapping each call site.\n *\n * @example\n * ```ts\n * import { NonNullableX } from \"@nunofyobiz/effect-extras\"\n * import { Number, pipe } from \"effect\"\n *\n * const addOne = NonNullableX.lift(Number.sum(1))\n *\n * assert.deepStrictEqual(pipe(1, addOne), 2)\n * assert.deepStrictEqual(pipe(null, addOne), null)\n * assert.deepStrictEqual(pipe(undefined, addOne), undefined)\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const lift =\n <A, B>(map: (a: A) => B) =>\n (a: A | null | undefined): B | null | undefined => {\n if (Predicate.isNullish(a)) {\n return a;\n }\n\n return map(a);\n };\n\n/**\n * Extends an `Order.Order<A>` to an `Order.Order<A | null>`, deciding where\n * `null` sorts relative to present values via the `behavior` argument.\n *\n * Pass `\"value-null\"` to push `null`s to the end and `\"null-value\"` to pull them\n * to the front; two present values fall back to the wrapped order. Use it to sort\n * collections that mix real values with gaps without a bespoke comparator.\n * Supports both data-first and data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { NonNullableX } from \"@nunofyobiz/effect-extras\"\n * import { Array, Order, pipe } from \"effect\"\n *\n * // \"value-null\" — nulls sorted last\n * assert.deepStrictEqual(\n * pipe(\n * [null, 1, 3, null, 2],\n * Array.sort(NonNullableX.nullableOrder(Order.Number, \"value-null\"))\n * ),\n * [1, 2, 3, null, null]\n * )\n *\n * // \"null-value\" — nulls sorted first (data-last)\n * assert.deepStrictEqual(\n * pipe(\n * [null, 1, 3, null, 2],\n * Array.sort(pipe(Order.Number, NonNullableX.nullableOrder(\"null-value\")))\n * ),\n * [null, null, 1, 2, 3]\n * )\n * ```\n *\n * @category ordering\n * @since 0.0.0\n */\nexport const nullableOrder = dual<\n (\n behavior: \"value-null\" | \"null-value\",\n ) => <A>(order: Order.Order<A>) => Order.Order<A | null>,\n <A>(\n order: Order.Order<A>,\n behavior: \"value-null\" | \"null-value\",\n ) => Order.Order<A | null>\n>(\n 2,\n <A>(\n order: Order.Order<A>,\n behavior: \"value-null\" | \"null-value\",\n ): Order.Order<A | null> => {\n // Prepare to sort them based on their nullability\n const { nullableSortCategory, valueSortCategory } = Match.value(\n behavior,\n ).pipe(\n Match.when(\"value-null\", () => ({\n nullableSortCategory: 1,\n valueSortCategory: 0,\n })),\n Match.when(\"null-value\", () => ({\n nullableSortCategory: 0,\n valueSortCategory: 1,\n })),\n Match.exhaustive,\n );\n\n return (a: A | null, b: A | null): Ordering.Ordering => {\n // Right off the bat, if they are both defined just return the regular ordering\n if (Predicate.isNotNullish(a) && Predicate.isNotNullish(b)) {\n return order(a, b);\n }\n\n // Otherwise figure out which category each value is\n const aCategory = Predicate.isNotNullish(a)\n ? valueSortCategory\n : nullableSortCategory;\n\n const bCategory = Predicate.isNotNullish(b)\n ? valueSortCategory\n : nullableSortCategory;\n\n return EffectNumber.sign(aCategory - bCategory);\n };\n },\n);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Number` module.\n *\n * @since 0.0.0\n */\nimport { Number as EffectNumber, Option, pipe } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n// Internal — used by unsafeLogBase.\nconst logBase = dual<\n // Data-last typing\n (base: number) => (number: number) => Option.Option<number>,\n // Data-first typing\n (number: number, base: number) => Option.Option<number>\n>(2, (number: number, base: number): Option.Option<number> => {\n if (number <= 0) {\n return Option.none();\n }\n\n if (base <= 0 || base === 1) {\n return Option.none();\n }\n\n if (base < 1 && number >= 1) {\n return Option.none();\n }\n\n if (base >= 1 && number < 1) {\n return Option.none();\n }\n\n return Option.some(Math.log(number) / Math.log(base));\n});\n\n/**\n * Computes the logarithm of `number` in the given `base`, throwing when the\n * inputs fall outside the domain of `log`.\n *\n * Throws when `number <= 0`, when `base` is `<= 0` or `1`, or when `number` and\n * `base` sit on opposite sides of `1` (a fractional base with `number >= 1`, or\n * a base `>= 1` with `number < 1`) — cases where the real logarithm is\n * undefined or non-finite. Reach for it only when the inputs are already known\n * to be valid.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(NumberX.unsafeLogBase(8, 2), 3)\n * assert.deepStrictEqual(NumberX.unsafeLogBase(100, 10), 2)\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(8, NumberX.unsafeLogBase(2)), 3)\n *\n * // throws outside the domain of log\n * assert.throws(() => NumberX.unsafeLogBase(0, 2))\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const unsafeLogBase = dual<\n (base: number) => (number: number) => number,\n (number: number, base: number) => number\n>(2, (number: number, base: number): number =>\n Option.getOrThrowWith(\n logBase(number, base),\n () => new Error(`Error calculating log base ${base} of ${number}`),\n ),\n);\n\n/**\n * Converts a number to a percentage of some total.\n *\n * Internal — used by unsafeToPercentOf.\n */\nconst toPercentOf = dual<\n // Data-last typing\n (total: number) => (numerator: number) => Option.Option<number>,\n // Data-first typing\n (numerator: number, total: number) => Option.Option<number>\n>(\n 2,\n (numerator: number, total: number): Option.Option<number> =>\n pipe(\n EffectNumber.divide(numerator, total),\n Option.map((ratio) => ratio * 100),\n ),\n);\n\n/**\n * Expresses `numerator` as a percentage of `total`, throwing on division by\n * zero.\n *\n * Returns `(numerator / total) * 100`. When `total` is `0` the percentage is\n * undefined, so this throws rather than returning `Infinity` or `NaN` — use it\n * only when `total` is known to be non-zero.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(NumberX.unsafeToPercentOf(1, 2), 50)\n * assert.deepStrictEqual(NumberX.unsafeToPercentOf(2, 1), 200)\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(1, NumberX.unsafeToPercentOf(2)), 50)\n *\n * // throws on division by zero\n * assert.throws(() => NumberX.unsafeToPercentOf(1, 0))\n * ```\n *\n * @category unsafe\n * @since 0.0.0\n */\nexport const unsafeToPercentOf = dual<\n // Data-last typing\n (total: number) => (numerator: number) => number,\n // Data-first typing\n (numerator: number, total: number) => number\n>(2, (numerator: number, total: number): number =>\n Option.getOrThrowWith(\n toPercentOf(numerator, total),\n () => new Error(`Division by zero when dividing ${numerator} by ${total}`),\n ),\n);\n\n/**\n * Formats `number` with a fixed number of decimal places, returning a `string`.\n *\n * A pipeable wrapper around `Number.prototype.toFixed` — the result is rounded\n * (not truncated) to `numberDigits` decimals and always carries exactly that\n * many digits after the point.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(NumberX.toFixed(3.236242, 2), \"3.24\")\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(3.236242, NumberX.toFixed(0)), \"3\")\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const toFixed = dual<\n (numberDigits: number) => (number: number) => string,\n (number: number, numberDigits: number) => string\n>(2, (number: number, numberDigits: number): string =>\n number.toFixed(numberDigits),\n);\n\n/**\n * Rounds `number` to a fixed number of decimal places, returning a `number`.\n *\n * Unlike {@link toFixed}, the result stays a `number` (no trailing zeroes) — it\n * formats via `toFixed` then parses back, which sidesteps the usual\n * floating-point rounding artifacts. See\n * https://stackoverflow.com/a/29494612/22875620.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(NumberX.roundToDigits(3.236242, 2), 3.24)\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(3.736242, NumberX.roundToDigits(0)), 4)\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const roundToDigits = dual<\n // Data-last typing\n (numberDigits: number) => (number: number) => number,\n // Data-first typing\n (number: number, numberDigits: number) => number\n>(2, (number: number, numberDigits: number): number =>\n Number(number.toFixed(numberDigits)),\n);\n\n/**\n * Renders `number` as a `string`, left-padded with zeroes to at least\n * `numberDigits` characters.\n *\n * If the number's string representation is already as long as (or longer than)\n * `numberDigits`, it is returned unchanged.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(NumberX.padLeftZeroes(1, 3), \"001\")\n *\n * // longer than the target width is returned unchanged\n * assert.deepStrictEqual(NumberX.padLeftZeroes(1000, 3), \"1000\")\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(10, NumberX.padLeftZeroes(3)), \"010\")\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const padLeftZeroes = dual<\n (numberDigits: number) => (number: number) => string,\n (number: number, numberDigits: number) => string\n>(2, (number: number, numberDigits: number): string =>\n number.toString().padStart(numberDigits, \"0\"),\n);\n\n/**\n * Converts a `0`-indexed value to its `1`-indexed rank by adding `1`.\n *\n * Handy for presentation where humans count from one (e.g. the element at\n * index `0` is shown as \"item 1\").\n *\n * @example\n * ```ts\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(NumberX.indexToRank(0), 1)\n * assert.deepStrictEqual(NumberX.indexToRank(4), 5)\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const indexToRank = (index: number): number => index + 1;\n\nconst EXCEL_COLUMNS_BASE_CHARS = [...\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"];\n\n/**\n * Converts a `0`-indexed column number into its bijective base-26 spreadsheet\n * label (`A`, `B`, …, `Z`, `AA`, `AB`, …).\n *\n * Returns `None` for a negative `index`; every non-negative index maps to a\n * `Some` label. Indexing is `0`-based here, so `0` is `\"A\"` and `25` is `\"Z\"`,\n * unlike the `1`-based numbering shown in most spreadsheet references.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { NumberX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(NumberX.indexToExcel(0), Option.some(\"A\"))\n * assert.deepStrictEqual(NumberX.indexToExcel(26), Option.some(\"AA\"))\n * assert.deepStrictEqual(NumberX.indexToExcel(-1), Option.none())\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const indexToExcel = (index: number): Option.Option<string> => {\n if (index < 0) {\n return Option.none();\n }\n\n const baseChars = EXCEL_COLUMNS_BASE_CHARS;\n\n let excel = \"\";\n const base = baseChars.length;\n do {\n excel = baseChars[index % base] + excel;\n index = Math.floor(index / base) - 1;\n } while (index >= 0);\n\n return Option.some(excel);\n};\n","/**\n * Generic, framework-agnostic extensions to Effect's `Option` module.\n *\n * @since 0.0.0\n */\nimport { Option, Predicate, pipe } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * Combines two `Option`s into an `Option` of a tuple, succeeding only when both\n * are `Some`.\n *\n * Returns `Some([a, b])` when both inputs are `Some`, and `None` if either is\n * `None`. Useful when an operation needs two optional values present at once.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * // Both Some — succeeds with the pair\n * assert.deepStrictEqual(\n * OptionX.tupleOf(Option.some(1), Option.some(\"a\")),\n * Option.some([1, \"a\"]),\n * )\n *\n * // Either None collapses to None\n * assert.deepStrictEqual(\n * OptionX.tupleOf(Option.some(1), Option.none()),\n * Option.none(),\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const tupleOf = dual<\n <A>(a: Option.Option<A>) => <B>(b: Option.Option<B>) => Option.Option<[A, B]>,\n <A, B>(a: Option.Option<A>, b: Option.Option<B>) => Option.Option<[A, B]>\n>(\n 2,\n <A, B>(a: Option.Option<A>, b: Option.Option<B>): Option.Option<[A, B]> =>\n Option.flatMap(a, (a) => Option.map(b, (b) => [a, b])),\n);\n\n/**\n * Runs a side effect with the value of an `Option` when it is `Some`, doing\n * nothing when it is `None`.\n *\n * A shorthand for the \"if Some, do something\" branch of `Option.match` where the\n * `None` case is a no-op. The callback's return value is ignored — `ifSome`\n * always returns `void`.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * const log: Array<number> = []\n * OptionX.ifSome(Option.some(1), (value) => log.push(value))\n * OptionX.ifSome(Option.none<number>(), (value) => log.push(value))\n *\n * assert.deepStrictEqual(log, [1])\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const ifSome = dual<\n <A>(ifSome: (value: A) => void) => (self: Option.Option<A>) => void,\n <A>(self: Option.Option<A>, ifSome: (value: A) => void) => void\n>(2, <A>(self: Option.Option<A>, ifSome: (value: A) => void): void => {\n Option.match(self, {\n onSome: (value) => {\n ifSome(value);\n // Don't return anything\n },\n onNone: () => {\n // Do nothing\n },\n });\n});\n\n/**\n * Runs a side effect with the value of an `Option` when it is `Some`, then\n * returns the `Option` unchanged.\n *\n * The pass-through counterpart of {@link ifSome}: it taps into a `Some` value\n * (for logging, metrics, debugging) without breaking a `pipe` chain, since it\n * returns the original `Option`. For `None` it is a no-op.\n *\n * @example\n * ```ts\n * import { Option, pipe } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * const log: Array<number> = []\n * const result = pipe(\n * Option.some(1),\n * OptionX.inspectSome((value) => log.push(value)),\n * Option.map((value) => value + 1),\n * )\n *\n * assert.deepStrictEqual(result, Option.some(2))\n * assert.deepStrictEqual(log, [1])\n * ```\n *\n * @category sequencing\n * @since 0.0.0\n */\nexport const inspectSome = dual<\n <A>(\n function_: (value: A) => void,\n ) => (self: Option.Option<A>) => Option.Option<A>,\n <A>(self: Option.Option<A>, function_: (value: A) => void) => Option.Option<A>\n>(\n 2,\n <A>(\n self: Option.Option<A>,\n function_: (value: A) => void,\n ): Option.Option<A> => {\n ifSome(self, function_);\n return self;\n },\n);\n\n/**\n * Normalizes a possibly-nullish `Option` into a plain `Option`, mapping `null`\n * and `undefined` to `None`.\n *\n * Handy at boundaries where an `Option` value might itself arrive as `null` or\n * `undefined` (for example an optional field that holds an `Option`): the result\n * is always a well-formed `Option`, never `null`/`undefined`.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(OptionX.fromNullableOption(Option.some(1)), Option.some(1))\n * assert.deepStrictEqual(OptionX.fromNullableOption(null), Option.none())\n * assert.deepStrictEqual(OptionX.fromNullableOption(undefined), Option.none())\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const fromNullableOption = <A>(\n nullableOption: Option.Option<A> | null | undefined,\n): Option.Option<A> =>\n Predicate.isNotNullish(nullableOption) ? nullableOption : Option.none();\n\n/**\n * Maps the value of an `Option` when it is `Some`, returning `null` when it is\n * `None`.\n *\n * A shorthand for `pipe(self, Option.map(map), Option.getOrNull)`. The `null`\n * fallback makes it especially convenient in JSX/React, where rendering `null`\n * skips output — `mapSomeOrNull(value, (v) => render(v))` replaces a more verbose\n * `Option.match` with `onNone: () => null`.\n *\n * @example\n * ```ts\n * import { Option, pipe } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(OptionX.mapSomeOrNull(Option.some(1), (v) => v + 1), 2)\n *\n * // None maps to null\n * assert.deepStrictEqual(\n * OptionX.mapSomeOrNull(Option.none<number>(), (v) => v + 1),\n * null,\n * )\n *\n * // data-last (piped)\n * assert.deepStrictEqual(\n * pipe(Option.some(1), OptionX.mapSomeOrNull((v) => v + 1)),\n * 2,\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const mapSomeOrNull = dual<\n <A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | null,\n <A, B>(self: Option.Option<A>, map: (a: A) => B) => B | null\n>(2, <A, B>(self: Option.Option<A>, map: (a: A) => B): B | null =>\n pipe(self, Option.map(map), Option.getOrNull),\n);\n\n/**\n * Maps the value of an `Option` when it is `Some`, returning `undefined` when it\n * is `None`.\n *\n * The `undefined`-returning counterpart of {@link mapSomeOrNull}: a shorthand for\n * `pipe(self, Option.map(map), Option.getOrUndefined)`. Reach for it when the\n * consuming API expects `undefined` rather than `null` for \"absent\" (for example\n * an optional prop or a value spread into an object).\n *\n * @example\n * ```ts\n * import { Option, pipe } from \"effect\"\n * import { OptionX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(\n * OptionX.mapSomeOrUndefined(Option.some(1), (v) => v + 1),\n * 2,\n * )\n *\n * // None maps to undefined\n * assert.deepStrictEqual(\n * OptionX.mapSomeOrUndefined(Option.none<number>(), (v) => v + 1),\n * undefined,\n * )\n *\n * // data-last (piped)\n * assert.deepStrictEqual(\n * pipe(Option.some(1), OptionX.mapSomeOrUndefined((v) => v + 1)),\n * 2,\n * )\n * ```\n *\n * @category mapping\n * @since 0.0.0\n */\nexport const mapSomeOrUndefined = dual<\n <A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | undefined,\n <A, B>(self: Option.Option<A>, map: (a: A) => B) => B | undefined\n>(2, <A, B>(self: Option.Option<A>, map: (a: A) => B): B | undefined =>\n pipe(self, Option.map(map), Option.getOrUndefined),\n);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Order` module.\n *\n * @since 0.0.0\n */\nimport { Number as EffectNumber, Order } from \"effect\";\n\n/**\n * Builds an `Order.Order` for an enum-like set of values from an explicit rank\n * table, sorting each value by its assigned numeric rank.\n *\n * Use it when a union of string (or other `PropertyKey`) literals has a natural\n * priority that isn't its alphabetical order — pass a record mapping every\n * member to a rank and the resulting order sorts ascending by that rank.\n *\n * @example\n * ```ts\n * import { OrderX } from \"@nunofyobiz/effect-extras\"\n * import { Array } from \"effect\"\n *\n * const byAge = OrderX.rankedEnum({ child: 0, parent: 1, grandparent: 2 })\n *\n * assert.deepStrictEqual(\n * Array.sort([\"parent\", \"grandparent\", \"child\"], byAge),\n * [\"child\", \"parent\", \"grandparent\"]\n * )\n * ```\n *\n * @category ordering\n * @since 0.0.0\n */\nexport const rankedEnum =\n <const A extends PropertyKey>(ranks: Record<A, number>): Order.Order<A> =>\n (self, that) =>\n EffectNumber.sign(ranks[self] - ranks[that]);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Predicate` module.\n *\n * @since 0.0.0\n */\nimport { Predicate, String } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * Runs a refinement against `value` and branches on the result, passing the\n * narrowed value to the `whenTrue` handler.\n *\n * It pairs a `Predicate.Refinement<A, B>` with two continuations so the success\n * branch receives `value` already narrowed to `B`, replacing an `if`/`else` that\n * would otherwise re-check or cast. Supports both data-first and data-last\n * (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { PredicateX } from \"@nunofyobiz/effect-extras\"\n * import { Predicate, pipe } from \"effect\"\n *\n * // Data-first\n * assert.deepStrictEqual(\n * PredicateX.matchRefine(\"hello\", Predicate.isString, {\n * whenTrue: (value) => `String: ${value}`,\n * whenFalse: () => \"Not a string\"\n * }),\n * \"String: hello\"\n * )\n *\n * // Data-last (pipeable)\n * assert.deepStrictEqual(\n * pipe(\n * 42,\n * PredicateX.matchRefine(Predicate.isString, {\n * whenTrue: (value) => `String: ${value}`,\n * whenFalse: () => \"Not a string\"\n * })\n * ),\n * \"Not a string\"\n * )\n * ```\n *\n * @category pattern matching\n * @since 0.0.0\n */\nexport const matchRefine = dual<\n <A, B extends A, C>(\n predicate: Predicate.Refinement<A, B>,\n handlers: {\n whenFalse: () => C;\n whenTrue: (value: B) => C;\n },\n ) => (value: A) => C,\n <A, B extends A, C>(\n value: A,\n predicate: Predicate.Refinement<A, B>,\n handlers: { whenFalse: () => C; whenTrue: (value: B) => C },\n ) => C\n>(\n 3,\n <A, B extends A, C>(\n value: A,\n predicate: Predicate.Refinement<A, B>,\n handlers: { whenFalse: () => C; whenTrue: (value: B) => C },\n ): C => (predicate(value) ? handlers.whenTrue(value) : handlers.whenFalse()),\n);\n\n/**\n * Refines an `unknown` value to a non-empty `string`, returning `true` only when\n * the value is present, is a `string`, and has at least one character.\n *\n * This is the compound guard the repo's conventions call for: it folds\n * `Predicate.isNotNullish`, `Predicate.isString`, and `String.isNonEmpty` into a\n * single reusable refinement so call sites get `value is string` narrowing\n * without restating the three checks.\n *\n * @example\n * ```ts\n * import { PredicateX } from \"@nunofyobiz/effect-extras\"\n *\n * assert.deepStrictEqual(PredicateX.isNonEmptyString(\"hello\"), true)\n * assert.deepStrictEqual(PredicateX.isNonEmptyString(\"\"), false)\n * assert.deepStrictEqual(PredicateX.isNonEmptyString(null), false)\n * assert.deepStrictEqual(PredicateX.isNonEmptyString(123), false)\n * ```\n *\n * @category refinements\n * @since 0.0.0\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return (\n Predicate.isNotNullish(value) &&\n Predicate.isString(value) &&\n String.isNonEmpty(value)\n );\n}\n","/**\n * Helpers for working with native `Promise`s.\n *\n * @since 0.0.0\n */\n/**\n * Discards the resolved value of a `Promise`, returning a `Promise<void>` that\n * resolves once the original settles.\n *\n * Useful when you await a promise only for its side effect and want the result\n * type to reflect that nothing meaningful is produced — for example when an API\n * expects a `Promise<void>` or when narrowing a value-bearing promise to keep\n * call sites from accidentally depending on the resolved value. A rejection of\n * the original promise still propagates.\n *\n * @example\n * ```ts\n * import { PromiseX } from \"@nunofyobiz/effect-extras\"\n *\n * const run = async (): Promise<void> => {\n * const result = await PromiseX.asVoid(Promise.resolve(42))\n * assert.deepStrictEqual(result, undefined)\n * }\n *\n * void run()\n * ```\n *\n * @category conversions\n * @since 0.0.0\n */\nexport const asVoid = <T>(promise: Promise<T>): Promise<void> =>\n promise.then(() => undefined);\n","/**\n * Generic, framework-agnostic extensions to Effect's `Schema` module.\n *\n * @since 0.0.0\n */\nimport { BigInt, Schema, SchemaGetter, Struct } from \"effect\";\n\n/**\n * A `Schema` for a non-empty string that is trimmed on both decode and encode.\n *\n * Leading and trailing whitespace is stripped, and the resulting value must be\n * non-empty — so a whitespace-only input (e.g. `\" \"`) fails the\n * `NonEmptyString` refinement after trimming. Use it wherever user-supplied text\n * should be normalized and guaranteed to carry content.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const decoded = Effect.runSync(\n * Schema.decodeEffect(SchemaX.TrimmedNonEmptyString)(\" hello \"),\n * )\n * assert.deepStrictEqual(decoded, \"hello\")\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const TrimmedNonEmptyString = Schema.NonEmptyString.pipe(\n Schema.decode({\n decode: SchemaGetter.transform((s) => s.trim()),\n encode: SchemaGetter.transform((s) => s.trim()),\n }),\n);\n\n/**\n * A `Schema` for a URL-safe file path built on top of {@link\n * TrimmedNonEmptyString}.\n *\n * On decode the path is `decodeURIComponent`-ed (percent-escapes are expanded);\n * on encode it is `encodeURIComponent`-ed back into its URL-safe form. The\n * underlying value is also trimmed and required to be non-empty. Use it at the\n * boundary between stored/transmitted encoded paths and the decoded paths your\n * code works with.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * // Decoding expands percent-escapes\n * const decoded = Effect.runSync(\n * Schema.decodeEffect(SchemaX.URLSafeFilePath)(\"a%2Fb.txt\"),\n * )\n * assert.deepStrictEqual(decoded, \"a/b.txt\")\n *\n * // Encoding produces the URL-safe form\n * const encoded = Effect.runSync(\n * Schema.encodeEffect(SchemaX.URLSafeFilePath)(\"a/b.txt\"),\n * )\n * assert.deepStrictEqual(encoded, \"a%2Fb.txt\")\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const URLSafeFilePath = TrimmedNonEmptyString.pipe(\n Schema.decode({\n decode: SchemaGetter.transform((path) => decodeURIComponent(path)),\n encode: SchemaGetter.transform((path) => encodeURIComponent(path)),\n }),\n);\n\n// Internal — only used to construct nonNegativeBigInt below.\nconst clampMinBigInt =\n (min: bigint) =>\n <S extends Schema.Schema<bigint>>(schema: S) =>\n schema.pipe(\n Schema.decode({\n decode: SchemaGetter.transform((value) => BigInt.max(value, min)),\n encode: SchemaGetter.transform((value) => BigInt.max(value, min)),\n }),\n );\n\n/**\n * Transforms a `bigint` `Schema` so its value is clamped to be non-negative,\n * mapping any value below `0n` up to `0n` on both decode and encode.\n *\n * Unlike a refinement that *rejects* negative input, this *coerces* it: a\n * negative `bigint` decodes to `0n` rather than failing. Apply it to a `bigint`\n * schema whenever negative magnitudes are meaningless and should be floored at\n * zero rather than treated as errors.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const NonNegative = SchemaX.nonNegativeBigInt(Schema.BigInt)\n *\n * // Negative values are clamped up to 0n\n * assert.deepStrictEqual(\n * Effect.runSync(Schema.decodeEffect(NonNegative)(-5n)),\n * 0n,\n * )\n *\n * // Non-negative values pass through unchanged\n * assert.deepStrictEqual(\n * Effect.runSync(Schema.decodeEffect(NonNegative)(7n)),\n * 7n,\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const nonNegativeBigInt = clampMinBigInt(0n);\n\n/**\n * Extracts the \"constructor input\" type of a `Schema` — what `.make({...})`\n * accepts.\n *\n * Differs from `S[\"Type\"]` (the decoded type) in that fields carrying\n * constructor defaults (e.g. an `Overrideable` timestamp) are *optional* in\n * `MakeIn` but *required* in `Type`. Use it in signatures that accept a value to\n * construct, so callers can pass a plain object literal without supplying the\n * defaulted, override-branded fields.\n *\n * @example\n * ```ts\n * import { Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const Person = Schema.Struct({ name: Schema.String, age: Schema.Number })\n *\n * const input: SchemaX.MakeIn<typeof Person> = { name: \"Ada\", age: 36 }\n *\n * assert.deepStrictEqual(input, { name: \"Ada\", age: 36 })\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type MakeIn<S extends { readonly \"~type.make.in\": unknown }> =\n S[\"~type.make.in\"];\n\n// ---------------------------------------------------------------------------\n// Schema.Struct utilities — v4 removed the `.pick(...)`, `.omit(...)`, and\n// `Schema.partial(...)` methods that v3 had on `Schema.Struct` instances. These\n// helpers restore the same ergonomics on top of v4's `mapFields` primitive.\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a new `Schema.Struct` containing only the named `keys` of `schema`.\n *\n * Restores the v3 ergonomics of `mySchema.pick(\"a\", \"b\")` — v4 removed the\n * `.pick(...)` method from `Schema.Struct` instances, so this rebuilds it on top\n * of v4's `mapFields` primitive. Each picked field keeps its original schema,\n * including any refinements.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const Source = Schema.Struct({\n * a: Schema.Number,\n * b: Schema.String,\n * c: Schema.Boolean,\n * })\n *\n * const Picked = SchemaX.pick(Source, \"a\", \"b\")\n *\n * const decoded = Effect.runSync(\n * Schema.decodeEffect(Picked)({ a: 1, b: \"hi\" }),\n * )\n * assert.deepStrictEqual(decoded, { a: 1, b: \"hi\" })\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const pick = <\n const Fields extends Schema.Struct.Fields,\n const Keys extends readonly (keyof Fields & string)[],\n>(\n schema: Schema.Struct<Fields>,\n ...keys: Keys\n): Schema.Struct<Pick<Fields, Keys[number]>> =>\n schema.mapFields(\n (fields) =>\n Struct.pick(fields, keys as readonly (keyof Fields)[]) as Pick<\n Fields,\n Keys[number]\n >,\n );\n\n/**\n * Returns a new `Schema.Struct` with the named `keys` of `schema` removed.\n *\n * The complement of {@link pick}, restoring the v3 ergonomics of\n * `mySchema.omit(\"a\")` that v4 dropped from `Schema.Struct` instances. Every\n * surviving field keeps its original schema, including any refinements.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const Source = Schema.Struct({\n * a: Schema.Number,\n * b: Schema.String,\n * c: Schema.Boolean,\n * })\n *\n * const Omitted = SchemaX.omit(Source, \"c\")\n *\n * const decoded = Effect.runSync(\n * Schema.decodeEffect(Omitted)({ a: 1, b: \"hi\" }),\n * )\n * assert.deepStrictEqual(decoded, { a: 1, b: \"hi\" })\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const omit = <\n const Fields extends Schema.Struct.Fields,\n const Keys extends readonly (keyof Fields & string)[],\n>(\n schema: Schema.Struct<Fields>,\n ...keys: Keys\n): Schema.Struct<Omit<Fields, Keys[number]>> =>\n schema.mapFields(\n (fields) =>\n Struct.omit(fields, keys as readonly (keyof Fields)[]) as Omit<\n Fields,\n Keys[number]\n >,\n );\n\n/**\n * Returns a new `Schema.Struct` in which every field of `schema` is made\n * optional.\n *\n * Restores the v3 `Schema.partial(mySchema)` behaviour that v4 removed, by\n * wrapping each field in `Schema.optional`. A decoded value may therefore omit\n * any field; fields that *are* present still have to satisfy their original\n * schema, refinements included.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const Source = Schema.Struct({ a: Schema.Number, b: Schema.String })\n * const Partial = SchemaX.partial(Source)\n *\n * // All fields may be absent\n * assert.deepStrictEqual(Effect.runSync(Schema.decodeEffect(Partial)({})), {})\n *\n * // A present subset still decodes\n * assert.deepStrictEqual(\n * Effect.runSync(Schema.decodeEffect(Partial)({ a: 1 })),\n * { a: 1 },\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const partial = <Fields extends Schema.Struct.Fields>(\n schema: Schema.Struct<Fields>,\n): Schema.Struct<{ [K in keyof Fields]: Schema.optional<Fields[K]> }> =>\n schema.mapFields((fields) => {\n const result: { [K in keyof Fields]?: Schema.optional<Fields[K]> } = {};\n for (const key of Object.keys(fields) as (keyof Fields)[]) {\n result[key] = Schema.optional(fields[key]);\n }\n return result as { [K in keyof Fields]: Schema.optional<Fields[K]> };\n });\n\n/**\n * Returns a new `Schema.Struct` containing only the named `keys` of `schema`,\n * with every picked field made optional.\n *\n * Equivalent to `partial(pick(schema, ...keys))`, but reads more directly for\n * the common \"partial update over a subset of fields\" pattern: select the\n * mutable fields of an entity, then allow any of them to be omitted in the\n * update payload. Composes {@link pick} and {@link partial} in one call.\n *\n * @example\n * ```ts\n * import { Effect, Schema } from \"effect\"\n * import { SchemaX } from \"@nunofyobiz/effect-extras\"\n *\n * const Source = Schema.Struct({\n * a: Schema.Number,\n * b: Schema.String,\n * c: Schema.Boolean,\n * })\n *\n * const Update = SchemaX.pickPartial(Source, \"a\", \"b\")\n *\n * // Only picked fields are known, and each may be omitted\n * assert.deepStrictEqual(Effect.runSync(Schema.decodeEffect(Update)({})), {})\n * assert.deepStrictEqual(\n * Effect.runSync(Schema.decodeEffect(Update)({ a: 1 })),\n * { a: 1 },\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const pickPartial = <\n const Fields extends Schema.Struct.Fields,\n const Keys extends readonly (keyof Fields & string)[],\n>(\n schema: Schema.Struct<Fields>,\n ...keys: Keys\n): Schema.Struct<{ [K in Keys[number]]: Schema.optional<Fields[K]> }> =>\n partial(pick(schema, ...keys));\n","/**\n * Generic, framework-agnostic extensions for working with `Set`.\n *\n * @since 0.0.0\n */\nimport { dual } from \"effect/Function\";\n\n/**\n * Runs a mutating function against a copy of `set`, leaving the original\n * untouched, and returns the mutated copy.\n *\n * Use it to reuse imperative `Set` mutation code (`.add`, `.delete`) without\n * sacrificing immutability: the callback may freely mutate the set it receives\n * because it operates on a fresh clone. Supports both data-first and data-last\n * (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { SetX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * const original = new Set([\"a\", \"b\"])\n *\n * const result = pipe(\n * original,\n * SetX.safelyMutate((set) => {\n * set.delete(\"a\")\n * return set.add(\"c\")\n * })\n * )\n *\n * assert.deepStrictEqual(result, new Set([\"b\", \"c\"]))\n * // The original is left intact\n * assert.deepStrictEqual(original, new Set([\"a\", \"b\"]))\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const safelyMutate = dual<\n <A>(mutate: (set: Set<A>) => Set<A>) => (set: Set<A>) => Set<A>,\n <A>(set: Set<A>, mutate: (set: Set<A>) => Set<A>) => Set<A>\n>(2, <A>(set: Set<A>, mutate: (set: Set<A>) => Set<A>): Set<A> => {\n const copy = new Set(set);\n return mutate(copy);\n});\n\n/**\n * Returns a new `Set` with `value` added, leaving the input set unchanged.\n *\n * When `value` is already present the input set is returned as-is (no copy),\n * making repeated adds of existing members allocation-free. Supports both\n * data-first and data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { SetX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Data-first — adds a new element into a fresh set\n * assert.deepStrictEqual(\n * SetX.add(new Set([\"a\", \"b\"]), \"c\"),\n * new Set([\"a\", \"b\", \"c\"])\n * )\n *\n * // Data-last — existing element leaves the set unchanged\n * assert.deepStrictEqual(\n * pipe(new Set([\"a\", \"b\"]), SetX.add(\"b\")),\n * new Set([\"a\", \"b\"])\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const add = dual<\n <A>(value: A) => (set: Set<A>) => Set<A>,\n <A>(set: Set<A>, value: A) => Set<A>\n>(\n 2,\n <A>(set: Set<A>, value: A): Set<A> =>\n set.has(value) ? set : new Set(set).add(value),\n);\n\n/**\n * Returns a new `Set` with `value` removed, leaving the input set unchanged.\n *\n * When `value` is absent the input set is returned as-is (no copy). Supports both\n * data-first and data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { SetX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Data-first — removes an existing element into a fresh set\n * assert.deepStrictEqual(\n * SetX.remove(new Set([\"a\", \"b\", \"c\"]), \"c\"),\n * new Set([\"a\", \"b\"])\n * )\n *\n * // Data-last — absent element leaves the set unchanged\n * assert.deepStrictEqual(\n * pipe(new Set([\"a\", \"b\"]), SetX.remove(\"z\")),\n * new Set([\"a\", \"b\"])\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const remove = dual<\n <A>(value: A) => (set: Set<A>) => Set<A>,\n <A>(set: Set<A>, value: A) => Set<A>\n>(2, <A>(set: Set<A>, value: A): Set<A> => {\n if (set.has(value)) {\n const newSet = new Set(set);\n newSet.delete(value);\n return newSet;\n }\n return set;\n});\n\n/**\n * Returns a new `Set` with `value` added if it was absent or removed if it was\n * present, leaving the input set unchanged.\n *\n * Use it for membership toggles (selection state, feature flags by key) where a\n * value's presence should flip on each call. Supports both data-first and\n * data-last (pipeable) call styles.\n *\n * @example\n * ```ts\n * import { SetX } from \"@nunofyobiz/effect-extras\"\n * import { pipe } from \"effect\"\n *\n * // Data-first — absent value gets added\n * assert.deepStrictEqual(\n * SetX.toggle(new Set([\"a\", \"b\"]), \"c\"),\n * new Set([\"a\", \"b\", \"c\"])\n * )\n *\n * // Data-last — present value gets removed\n * assert.deepStrictEqual(\n * pipe(new Set([\"a\", \"b\", \"c\"]), SetX.toggle(\"b\")),\n * new Set([\"a\", \"c\"])\n * )\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const toggle = dual<\n <A>(value: A) => (set: Set<A>) => Set<A>,\n <A>(set: Set<A>, value: A) => Set<A>\n>(\n 2,\n <A>(set: Set<A>, value: A): Set<A> =>\n set.has(value) ? remove(set, value) : add(set, value),\n);\n","/**\n * Generic, framework-agnostic extensions to Effect's `String` module.\n *\n * @since 0.0.0\n */\nimport { dual } from \"effect/Function\";\n\n/**\n * Prepends `start` to `string_`.\n *\n * v4's `String` module has no native `prepend` (only `concat`), so this fills\n * the gap as a pipeable helper.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { StringX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(StringX.prepend(\"world\", \"hello \"), \"hello world\")\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(\"world\", StringX.prepend(\"hello \")), \"hello world\")\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const prepend = dual<\n (start: string) => (string_: string) => string,\n (string_: string, start: string) => string\n>(2, (string_: string, start: string): string => `${start}${string_}`);\n\n/**\n * Wraps `string_` between `start` and `end`.\n *\n * No v4 native equivalent — handy for quoting, bracketing, or fencing a value.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { StringX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(StringX.surround(\"value\", \"[\", \"]\"), \"[value]\")\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(\"value\", StringX.surround(\"(\", \")\")), \"(value)\")\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const surround = dual<\n (start: string, end: string) => (string_: string) => string,\n (string_: string, start: string, end: string) => string\n>(\n 3,\n (string_: string, start: string, end: string): string =>\n `${start}${string_}${end}`,\n);\n\n/**\n * Prepends `start` to `string_` unless `string_` already starts with it.\n *\n * Idempotent: applying it to an already-prefixed string is a no-op, so\n * `ensurePrepend(\"foofoo\", \"foo\")` stays `\"foofoo\"` rather than gaining a\n * second `\"foo\"`.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { StringX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first — adds the prefix when missing\n * assert.deepStrictEqual(StringX.ensurePrepend(\"bar\", \"foo\"), \"foobar\")\n *\n * // idempotent — already prefixed, returned unchanged\n * assert.deepStrictEqual(StringX.ensurePrepend(\"foobar\", \"foo\"), \"foobar\")\n *\n * // data-last (piped)\n * assert.deepStrictEqual(pipe(\"bar\", StringX.ensurePrepend(\"foo\")), \"foobar\")\n * ```\n *\n * @category combinators\n * @since 0.0.0\n */\nexport const ensurePrepend = dual<\n (start: string) => (string_: string) => string,\n (string_: string, start: string) => string\n>(2, (string_: string, start: string): string => {\n if (string_.startsWith(start)) {\n return string_;\n }\n\n return `${start}${string_}`;\n});\n","/**\n * Generic, framework-agnostic extensions to Effect's `Struct` module.\n *\n * @since 0.0.0\n */\nimport { Option, Predicate, Record, pipe } from \"effect\";\nimport { dual } from \"effect/Function\";\n\n/**\n * Describes the shape of a per-field transformation over an object `O`: a record\n * `T` whose values are functions taking the corresponding field of `O`.\n *\n * Used to type the \"evolve\" pattern, where each provided key maps to a function\n * that receives that field's current value. Copied from Effect's internal\n * `Struct.evolve()` type, which is not exported — it would be better to use\n * theirs directly if it ever becomes public.\n *\n * @example\n * ```ts\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * type Transform = StructX.PartialTransform<\n * { a: number; b: string },\n * { a: (n: number) => boolean }\n * >\n *\n * const evolve: Transform = { a: (n) => n > 0 }\n *\n * assert.deepStrictEqual(evolve.a(1), true)\n * ```\n *\n * @category models\n * @since 0.0.0\n */\nexport type PartialTransform<O, T> = {\n [K in keyof T]: T[K] extends (a: O[K & keyof O]) => unknown\n ? T[K]\n : (a: O[K & keyof O]) => unknown;\n};\n\n/**\n * Builds a singleton record `{ [name]: value }` when `value` is defined, or an\n * empty object `{}` when it is `undefined` — meant to be spread into an object\n * literal.\n *\n * This is the canonical fix for `exactOptionalPropertyTypes: true` (which this\n * repo enables for Effect Schema). Under that flag, spreading\n * `{ key: maybeUndefined }` into an object whose key is `key?: T` is a type\n * error: the property must be *absent*, not present-but-`undefined`. Spreading\n * `...defined(\"key\", maybeUndefined)` instead conditionally omits the property\n * altogether. Note that `null` and other falsy-but-defined values (`0`, `\"\"`,\n * `false`) are kept — only `undefined` is dropped.\n *\n * @example\n * ```ts\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * // Defined value → singleton record\n * assert.deepStrictEqual(StructX.defined(\"name\", \"Ada\"), { name: \"Ada\" })\n *\n * // undefined → property omitted entirely\n * assert.deepStrictEqual(StructX.defined(\"name\", undefined), {})\n *\n * // Falsy-but-defined values are kept\n * assert.deepStrictEqual(StructX.defined(\"name\", 0), { name: 0 })\n *\n * // Typical use: spread to conditionally include an optional field\n * const maybeAge: number | undefined = undefined\n * assert.deepStrictEqual({ id: 1, ...StructX.defined(\"age\", maybeAge) }, {\n * id: 1,\n * })\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const defined = <const K extends string, V>(\n name: K,\n value: V | undefined,\n): Partial<Record<K, Exclude<V, undefined>>> =>\n Predicate.isUndefined(value)\n ? {}\n : Record.singleton(name, value as Exclude<V, undefined>);\n\n/**\n * Removes every property whose value is `undefined` from `record`, narrowing\n * each remaining property type to exclude `undefined`.\n *\n * The bulk counterpart of {@link defined}: instead of building one optional\n * field, it filters a whole object. Very useful for update/patch actions where\n * `undefined` means \"leave this field unchanged\" while every other value —\n * including `null`, `0`, `\"\"`, `false`, and `Option.none()` — means \"set the\n * field to exactly this\".\n *\n * @example\n * ```ts\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * // Drops `b` (undefined) but keeps every other value, including null/0/false\n * assert.deepStrictEqual(\n * StructX.filterDefined({ a: \"x\", b: undefined, c: 0, d: null, e: false }),\n * { a: \"x\", c: 0, d: null, e: false },\n * )\n * ```\n *\n * @category filtering\n * @since 0.0.0\n */\nexport const filterDefined = <R extends Record<string, unknown>>(\n record: R,\n): Partial<{ [P in keyof R]: Exclude<R[P], undefined> }> =>\n Object.entries(record).reduce(\n (accumulator, [key, value]) => ({ ...accumulator, ...defined(key, value) }),\n {} as Partial<{ [P in keyof R]: Exclude<R[P], undefined> }>,\n );\n\n/**\n * Builds a singleton record `{ [name]: value }` when `value` is `Some`, or an\n * empty object `{}` when it is `None` — meant to be spread into an object\n * literal.\n *\n * The `Option`-valued sibling of {@link defined}: where `defined` keys off\n * `undefined`, this keys off `Option` presence. Spread `...some(\"key\", opt)` to\n * conditionally include a field only when the `Option` carries a value, which\n * stays correct under `exactOptionalPropertyTypes: true`.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * // Some → singleton record\n * assert.deepStrictEqual(StructX.some(\"name\", Option.some(\"Ada\")), {\n * name: \"Ada\",\n * })\n *\n * // None → property omitted entirely\n * assert.deepStrictEqual(StructX.some(\"name\", Option.none()), {})\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const some = <const K extends string, V>(\n name: K,\n value: Option.Option<V>,\n): Partial<Record<K, V>> =>\n Option.match(value, {\n onSome: (someValue) => Record.singleton(name, someValue),\n onNone: () => ({}),\n });\n\n/**\n * Like {@link some}, but with swapped argument order for piping. Returns a\n * singleton record `{ [name]: value }` when the Option is `Some`, or an\n * empty object `{}` when `None`.\n *\n * Internal-only — exists to support {@link pickSome} in data-last form.\n * Not exported because the codebase has no direct callers.\n */\nconst someSingleton: {\n <const K extends string>(\n name: K,\n ): <V>(value: Option.Option<V>) => Partial<Record<K, V>>;\n <V, const K extends string>(\n value: Option.Option<V>,\n name: K,\n ): Partial<Record<K, V>>;\n} = dual(\n 2,\n <V, const K extends string>(\n value: Option.Option<V>,\n name: K,\n ): Partial<Record<K, V>> => some(name, value),\n);\n\n/**\n * Looks up `key` in a record of `Option` values and returns a singleton record\n * when the value is `Some`, or `{}` when the key is absent or its value is\n * `None`.\n *\n * Combines `Record.get` + `Option.flatten` + a singleton builder in one call —\n * ideal for spreading an optional field out of a lookup table into an object\n * literal under `exactOptionalPropertyTypes: true`. By default the output key\n * matches the lookup key; pass `renameKeyTo` to emit the value under a different\n * name.\n *\n * @example\n * ```ts\n * import { Option } from \"effect\"\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * const lookup = {\n * a: Option.some(100),\n * b: Option.none<number>(),\n * }\n *\n * // Some → singleton record under the same key\n * assert.deepStrictEqual(StructX.pickSome(lookup, \"a\"), { a: 100 })\n *\n * // None → property omitted entirely\n * assert.deepStrictEqual(StructX.pickSome(lookup, \"b\"), {})\n *\n * // Rename the output key\n * assert.deepStrictEqual(StructX.pickSome(lookup, \"a\", \"count\"), { count: 100 })\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport function pickSome<const K extends string, V>(\n record: Record<K, Option.Option<V>>,\n key: K,\n): Partial<Record<K, V>>;\nexport function pickSome<const K1 extends string, V, const K2 extends string>(\n record: Record<K1, Option.Option<V>>,\n key: K1,\n renameKeyTo: K2,\n): Partial<Record<K2, V>>;\nexport function pickSome<const K1 extends string, V, const K2 extends string>(\n record: Record<K1, Option.Option<V>>,\n key: K1,\n renameKeyTo?: K2,\n): Partial<Record<K1 | K2, V>> {\n return pipe(\n Record.get(record, key),\n Option.flatten,\n someSingleton(renameKeyTo ?? key),\n );\n}\n\n/**\n * Builds a singleton record `{ [name]: value }` when `value` is truthy, or an\n * empty object `{}` otherwise — meant to be spread into an object literal.\n *\n * Stricter than {@link defined}: it drops not just `undefined` but every falsy\n * value (`null`, `false`, `0`, `\"\"`, `NaN`), and narrows the value type\n * accordingly. Use it to spread a field only when it carries a meaningful,\n * non-falsy value.\n *\n * @example\n * ```ts\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * // Truthy value → singleton record\n * assert.deepStrictEqual(StructX.truthy(\"name\", \"Ada\"), { name: \"Ada\" })\n *\n * // Falsy values → property omitted entirely\n * assert.deepStrictEqual(StructX.truthy(\"name\", \"\"), {})\n * assert.deepStrictEqual(StructX.truthy(\"name\", 0), {})\n * assert.deepStrictEqual(StructX.truthy(\"name\", false), {})\n * ```\n *\n * @category constructors\n * @since 0.0.0\n */\nexport const truthy = <const K extends string, V>(\n name: K,\n value: V,\n): Partial<Record<K, Exclude<NonNullable<V>, false | 0 | \"\">>> =>\n Predicate.isTruthy(value)\n ? Record.singleton(name, value as Exclude<NonNullable<V>, false | 0 | \"\">)\n : {};\n\n/**\n * Returns `true` when `object` has `key` set to a non-nullish value, narrowing\n * that property to `NonNullable` on the type level.\n *\n * A type guard combining `hasProperty` with a nullish check: after a successful\n * test, TypeScript treats `object[key]` as present and free of `null` /\n * `undefined`. Handy as a predicate passed to `Array.filter` to keep only the\n * elements whose `key` is populated.\n *\n * @example\n * ```ts\n * import { pipe } from \"effect\"\n * import { StructX } from \"@nunofyobiz/effect-extras\"\n *\n * // data-first\n * assert.deepStrictEqual(\n * StructX.hasNotNullableProperty({ id: \"1\" }, \"id\"),\n * true,\n * )\n *\n * // data-last (pipeable); a null value fails the guard\n * assert.deepStrictEqual(\n * pipe({ id: null }, StructX.hasNotNullableProperty(\"id\")),\n * false,\n * )\n * ```\n *\n * @category refinements\n * @since 0.0.0\n */\nexport const hasNotNullableProperty = dual<\n <T, K extends keyof T>(\n key: K,\n ) => (object: T) => object is T & Record<K, NonNullable<T[K]>>,\n <T, K extends keyof T>(\n object: T,\n key: K,\n ) => object is T & Record<K, NonNullable<T[K]>>\n>(\n 2,\n <T, K extends keyof T>(\n object: T,\n key: K,\n ): object is T & Record<K, NonNullable<T[K]>> =>\n Predicate.hasProperty(object, key) && Predicate.isNotNullish(object[key]),\n);\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nunofyobiz/effect-extras",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Generic, framework-agnostic extensions of the Effect standard library (ArrayX, OptionX, RecordX, StructX, …).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"effect",
|
|
7
|
+
"effect-ts",
|
|
8
|
+
"functional",
|
|
9
|
+
"typescript",
|
|
10
|
+
"utilities"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/nunofyobiz/effect-extras#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/nunofyobiz/effect-extras/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/nunofyobiz/effect-extras.git"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "bigpopakap",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"src",
|
|
33
|
+
"!src/**/*.test.ts"
|
|
34
|
+
],
|
|
35
|
+
"lint-staged": {
|
|
36
|
+
"*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}": [
|
|
37
|
+
"eslint --fix --max-warnings=0 --no-warn-ignored"
|
|
38
|
+
],
|
|
39
|
+
"*.{md,mdx,yml,yaml,json5,css}": [
|
|
40
|
+
"prettier --write"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@changesets/changelog-github": "0.5.1",
|
|
45
|
+
"@changesets/cli": "2.29.7",
|
|
46
|
+
"@commitlint/config-conventional": "20.5.3",
|
|
47
|
+
"@commitlint/types": "20.5.0",
|
|
48
|
+
"@effect/docgen": "0.5.2",
|
|
49
|
+
"@effect/language-service": "0.86.2",
|
|
50
|
+
"@effect/vitest": "4.0.0-beta.74",
|
|
51
|
+
"@eslint-community/eslint-plugin-eslint-comments": "4.7.2",
|
|
52
|
+
"@eslint/compat": "2.0.5",
|
|
53
|
+
"@eslint/js": "10.0.1",
|
|
54
|
+
"@types/node": "24.12.2",
|
|
55
|
+
"@typescript-eslint/parser": "8.60.0",
|
|
56
|
+
"@vitest/coverage-v8": "4.1.7",
|
|
57
|
+
"@vitest/eslint-plugin": "1.6.18",
|
|
58
|
+
"commitlint": "20.5.3",
|
|
59
|
+
"effect": "4.0.0-beta.74",
|
|
60
|
+
"eslint": "10.2.1",
|
|
61
|
+
"eslint-config-prettier": "10.1.8",
|
|
62
|
+
"eslint-import-resolver-typescript": "4.4.4",
|
|
63
|
+
"eslint-plugin-import-x": "4.16.1",
|
|
64
|
+
"eslint-plugin-package-json": "0.91.2",
|
|
65
|
+
"eslint-plugin-prettier": "5.5.6",
|
|
66
|
+
"eslint-plugin-unicorn": "64.0.0",
|
|
67
|
+
"husky": "9.1.7",
|
|
68
|
+
"knip": "6.4.1",
|
|
69
|
+
"lint-staged": "17.0.7",
|
|
70
|
+
"prettier": "3.8.3",
|
|
71
|
+
"tsup": "8.5.0",
|
|
72
|
+
"tsx": "4.22.4",
|
|
73
|
+
"typescript": "6.0.3",
|
|
74
|
+
"typescript-eslint": "8.60.0",
|
|
75
|
+
"vitest": "4.1.7"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"effect": "4.0.0-beta.74"
|
|
79
|
+
},
|
|
80
|
+
"engines": {
|
|
81
|
+
"node": ">=22"
|
|
82
|
+
},
|
|
83
|
+
"publishConfig": {
|
|
84
|
+
"access": "public",
|
|
85
|
+
"provenance": true
|
|
86
|
+
},
|
|
87
|
+
"scripts": {
|
|
88
|
+
"build": "tsup",
|
|
89
|
+
"changeset": "changeset",
|
|
90
|
+
"check-all": "pnpm tc && pnpm lint && pnpm test && pnpm build && pnpm knip && pnpm docgen",
|
|
91
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
92
|
+
"docgen": "docgen",
|
|
93
|
+
"format": "prettier --write \"**/*.{md,mdx,yml,yaml,json5,css}\"",
|
|
94
|
+
"knip": "knip",
|
|
95
|
+
"lint": "eslint .",
|
|
96
|
+
"lint:fix": "eslint . --fix",
|
|
97
|
+
"release": "pnpm build && changeset publish",
|
|
98
|
+
"tc": "tsc --noEmit -p tsconfig.json",
|
|
99
|
+
"test": "vitest run",
|
|
100
|
+
"testw": "vitest",
|
|
101
|
+
"version-packages": "changeset version"
|
|
102
|
+
}
|
|
103
|
+
}
|