diff --git a/.commands/test-lint.sh b/.commands/test-lint.sh
new file mode 100755
index 000000000..45a248e5d
--- /dev/null
+++ b/.commands/test-lint.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+
+ARGUMENTS="$@"
+
+# scripts
+eslint --quiet $ARGUMENTS scripts/
+# tests
+eslint --quiet $ARGUMENTS tests/
+eslint --quiet $ARGUMENTS integration/
+# documentation
+eslint --quiet $ARGUMENTS docs/
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 523b7c14c..70a596b8b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules
dist
coverage
-cache
\ No newline at end of file
+cache
+.temp
\ No newline at end of file
diff --git a/docs/en/v1/api/clean/index.md b/docs/en/v1/api/clean/index.md
index d5867a461..9c6120a7d 100644
--- a/docs/en/v1/api/clean/index.md
+++ b/docs/en/v1/api/clean/index.md
@@ -69,6 +69,12 @@ Declares an aggregate of linked business actions that must run in order.
### [equal](/en/v1/api/clean/primitives/operators/equal)
Compares two wrapped primitives (or a primitive and a raw value) with a type guard.
+### [matchWithString](/en/v1/api/clean/primitives/operators/matchWithString)
+Performs exhaustive matching with raw string keys and passes the narrowed original Clean primitive.
+
+### [matchWithNumber](/en/v1/api/clean/primitives/operators/matchWithNumber)
+Performs exhaustive matching with raw number keys and passes the narrowed original Clean primitive.
+
### [add](/en/v1/api/clean/primitives/operators/add)
Adds two `Number` (supports the curried version).
diff --git a/docs/en/v1/api/clean/primitives/index.md b/docs/en/v1/api/clean/primitives/index.md
index 31a5529c6..eda387d1e 100644
--- a/docs/en/v1/api/clean/primitives/index.md
+++ b/docs/en/v1/api/clean/primitives/index.md
@@ -96,6 +96,18 @@ function is(
### [equal](/en/v1/api/clean/primitives/operators/equal)
Compares two wrapped primitives (or a primitive and a raw value) with a type guard.
+### [matchWithString](/en/v1/api/clean/primitives/operators/matchWithString)
+Performs exhaustive matching with raw string keys and passes the narrowed original Clean primitive.
+
+### [matchWithStringOtherwise](/en/v1/api/clean/primitives/operators/matchWithStringOtherwise)
+Partially matches raw string keys and passes remaining wrapped values to a typed fallback.
+
+### [matchWithNumber](/en/v1/api/clean/primitives/operators/matchWithNumber)
+Performs exhaustive matching with raw number keys and passes the narrowed original Clean primitive.
+
+### [matchWithNumberOtherwise](/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise)
+Partially matches raw number keys and passes remaining wrapped values to a typed fallback.
+
### [add](/en/v1/api/clean/primitives/operators/add)
Adds two `Number` (supports the curried version).
diff --git a/docs/en/v1/api/clean/primitives/operators/add.md b/docs/en/v1/api/clean/primitives/operators/add.md
index 007a0b4c7..5cbd238d3 100644
--- a/docs/en/v1/api/clean/primitives/operators/add.md
+++ b/docs/en/v1/api/clean/primitives/operators/add.md
@@ -1,8 +1,8 @@
---
outline: [2, 3]
prev:
- text: "equal"
- link: "/en/v1/api/clean/primitives/operators/equal"
+ text: "matchWithNumberOtherwise"
+ link: "/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise"
next:
text: "subtract"
link: "/en/v1/api/clean/primitives/operators/subtract"
diff --git a/docs/en/v1/api/clean/primitives/operators/equal.md b/docs/en/v1/api/clean/primitives/operators/equal.md
index 3b89e3bef..e9266198e 100644
--- a/docs/en/v1/api/clean/primitives/operators/equal.md
+++ b/docs/en/v1/api/clean/primitives/operators/equal.md
@@ -1,8 +1,8 @@
---
outline: [2, 3]
next:
- text: "add"
- link: "/en/v1/api/clean/primitives/operators/add"
+ text: "matchWithString"
+ link: "/en/v1/api/clean/primitives/operators/matchWithString"
---
# equal
diff --git a/docs/en/v1/api/clean/primitives/operators/matchWithNumber.md b/docs/en/v1/api/clean/primitives/operators/matchWithNumber.md
new file mode 100644
index 000000000..7863d8218
--- /dev/null
+++ b/docs/en/v1/api/clean/primitives/operators/matchWithNumber.md
@@ -0,0 +1,59 @@
+---
+outline: [2, 3]
+description: "matchWithNumber() performs exhaustive pattern matching on a Clean number primitive value and passes the correctly narrowed original primitive to each branch."
+prev:
+ text: "matchWithStringOtherwise"
+ link: "/en/v1/api/clean/primitives/operators/matchWithStringOtherwise"
+next:
+ text: "matchWithNumberOtherwise"
+ link: "/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise"
+---
+
+# matchWithNumber
+
+`matchWithNumber()` performs exhaustive pattern matching on the value of a Clean number primitive. Every possible value must have a processing branch.
+
+A Clean primitive is a wrapped object, so it cannot be used directly as a matcher key. The keys are therefore raw `number` values. When a key matches, its callback receives the original Clean primitive narrowed to that value, preserving its `Primitive`, `ConstrainedType`, or `NewType` information.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithNumber , Matcher>(
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Curried signature
+
+```typescript
+function matchWithNumber , Matcher>(
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Parameters
+
+- `input`: a Clean primitive containing a `number`, including constrained values and new types.
+- `matcher`: an exhaustive object indexed by the possible raw `number` values. A broad `Primitive` requires an indexed `Record`.
+
+Every key must have exactly one handler. TypeScript rejects a missing key or a key outside the input union. The selected handler receives the original Clean object narrowed with `Primitive`.
+
+## Return value
+
+The selected handler result, typed as the union of every handler return type.
+
+## See also
+
+- [`matchWithString`](/en/v1/api/clean/primitives/operators/matchWithString) - String primitive equivalent.
+- [`equal`](/en/v1/api/clean/primitives/operators/equal) - Compares wrapped primitive values.
diff --git a/docs/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md b/docs/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md
new file mode 100644
index 000000000..a5cc03b31
--- /dev/null
+++ b/docs/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithNumberOtherwise() partially matches a Clean number primitive while preserving the narrowed original primitive in handlers and otherwise."
+prev:
+ text: "matchWithNumber"
+ link: "/en/v1/api/clean/primitives/operators/matchWithNumber"
+next:
+ text: "add"
+ link: "/en/v1/api/clean/primitives/operators/add"
+---
+
+# matchWithNumberOtherwise
+
+`matchWithNumberOtherwise()` handles selected values of a Clean number primitive. Raw number values form the matcher keys. Missing cases are sent to `otherwise`, which receives the original primitive narrowed to the remaining values.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithNumberOtherwise , Matcher, Output>(
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): MatcherResult | Output
+```
+
+### Curried signature
+
+```typescript
+function matchWithNumberOtherwise , Matcher, Output>(
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Parameters
+
+- `input`: a Clean number primitive with literal values.
+- `matcher`: a partial object indexed by raw values from the primitive. Unknown keys are rejected.
+- `otherwise`: receives the original `Primitive`, `ConstrainedType`, or `NewType`, narrowed to values without a handler.
+
+## Return value
+
+The selected handler result, or the `otherwise` result for an unhandled wrapped value.
+
+## See also
+
+- [`matchWithNumber`](/en/v1/api/clean/primitives/operators/matchWithNumber) - Exhaustive primitive matching.
+- [`matchWithStringOtherwise`](/en/v1/api/clean/primitives/operators/matchWithStringOtherwise) - String primitive equivalent.
diff --git a/docs/en/v1/api/clean/primitives/operators/matchWithString.md b/docs/en/v1/api/clean/primitives/operators/matchWithString.md
new file mode 100644
index 000000000..023b05bb4
--- /dev/null
+++ b/docs/en/v1/api/clean/primitives/operators/matchWithString.md
@@ -0,0 +1,59 @@
+---
+outline: [2, 3]
+description: "matchWithString() performs exhaustive pattern matching on a Clean string primitive value and passes the correctly narrowed original primitive to each branch."
+prev:
+ text: "equal"
+ link: "/en/v1/api/clean/primitives/operators/equal"
+next:
+ text: "matchWithStringOtherwise"
+ link: "/en/v1/api/clean/primitives/operators/matchWithStringOtherwise"
+---
+
+# matchWithString
+
+`matchWithString()` performs exhaustive pattern matching on the value of a Clean string primitive. Every possible value must have a processing branch.
+
+A Clean primitive is a wrapped object, so it cannot be used directly as a matcher key. The keys are therefore raw `string` values. When a key matches, its callback receives the original Clean primitive narrowed to that value, preserving its `Primitive`, `ConstrainedType`, or `NewType` information.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithString , Matcher>(
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Curried signature
+
+```typescript
+function matchWithString , Matcher>(
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Parameters
+
+- `input`: a Clean primitive containing a `string`, including constrained values and new types.
+- `matcher`: an exhaustive object indexed by the possible raw `string` values. A broad `Primitive` requires an indexed `Record`.
+
+Every key must have exactly one handler. TypeScript rejects a missing key or a key outside the input union. The selected handler receives the original Clean object narrowed with `Primitive`.
+
+## Return value
+
+The selected handler result, typed as the union of every handler return type.
+
+## See also
+
+- [`matchWithNumber`](/en/v1/api/clean/primitives/operators/matchWithNumber) - Numeric primitive equivalent.
+- [`equal`](/en/v1/api/clean/primitives/operators/equal) - Compares wrapped primitive values.
diff --git a/docs/en/v1/api/clean/primitives/operators/matchWithStringOtherwise.md b/docs/en/v1/api/clean/primitives/operators/matchWithStringOtherwise.md
new file mode 100644
index 000000000..1223953a4
--- /dev/null
+++ b/docs/en/v1/api/clean/primitives/operators/matchWithStringOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithStringOtherwise() partially matches a Clean string primitive while preserving the narrowed original primitive in handlers and otherwise."
+prev:
+ text: "matchWithString"
+ link: "/en/v1/api/clean/primitives/operators/matchWithString"
+next:
+ text: "matchWithNumber"
+ link: "/en/v1/api/clean/primitives/operators/matchWithNumber"
+---
+
+# matchWithStringOtherwise
+
+`matchWithStringOtherwise()` handles selected values of a Clean string primitive. Raw string values form the matcher keys. Missing cases are sent to `otherwise`, which receives the original primitive narrowed to the remaining values.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithStringOtherwise , Matcher, Output>(
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): MatcherResult | Output
+```
+
+### Curried signature
+
+```typescript
+function matchWithStringOtherwise , Matcher, Output>(
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Parameters
+
+- `input`: a Clean string primitive with literal values.
+- `matcher`: a partial object indexed by raw values from the primitive. Unknown keys are rejected.
+- `otherwise`: receives the original `Primitive`, `ConstrainedType`, or `NewType`, narrowed to values without a handler.
+
+## Return value
+
+The selected handler result, or the `otherwise` result for an unhandled wrapped value.
+
+## See also
+
+- [`matchWithString`](/en/v1/api/clean/primitives/operators/matchWithString) - Exhaustive primitive matching.
+- [`matchWithNumberOtherwise`](/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise) - Number primitive equivalent.
diff --git a/docs/en/v1/api/common/asyncInnerPipe.md b/docs/en/v1/api/common/asyncInnerPipe.md
index 5d39a600e..a7357a1ac 100644
--- a/docs/en/v1/api/common/asyncInnerPipe.md
+++ b/docs/en/v1/api/common/asyncInnerPipe.md
@@ -5,8 +5,8 @@ prev:
text: "asyncPipe"
link: "/en/v1/api/common/asyncPipe"
next:
- text: "forward"
- link: "/en/v1/api/common/forward"
+ text: "prepareAsyncPipe"
+ link: "/en/v1/api/common/prepareAsyncPipe"
---
# asyncInnerPipe
diff --git a/docs/en/v1/api/common/asyncPipe.md b/docs/en/v1/api/common/asyncPipe.md
index 0885a4d1a..d72592192 100644
--- a/docs/en/v1/api/common/asyncPipe.md
+++ b/docs/en/v1/api/common/asyncPipe.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "The asyncPipe() method chains asynchronous functions (promises or FutureEither) in series. Each step waits for the previous one to resolve and the last value is returned in a promise."
prev:
- text: "innerPipe"
- link: "/en/v1/api/common/innerPipe"
+ text: "preparePipe"
+ link: "/en/v1/api/common/preparePipe"
next:
text: "asyncInnerPipe"
link: "/en/v1/api/common/asyncInnerPipe"
diff --git a/docs/en/v1/api/common/forward.md b/docs/en/v1/api/common/forward.md
index db7b52610..03b9d5ba5 100644
--- a/docs/en/v1/api/common/forward.md
+++ b/docs/en/v1/api/common/forward.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "The forward() function returns the passed argument without modifying it. Useful to standardize an API that expects a function, or to improve readability in a pipeline."
prev:
- text: "asyncInnerPipe"
- link: "/en/v1/api/common/asyncInnerPipe"
+ text: "prepareAsyncPipe"
+ link: "/en/v1/api/common/prepareAsyncPipe"
next:
text: "forwardLog"
link: "/en/v1/api/common/forwardLog"
diff --git a/docs/en/v1/api/common/index.md b/docs/en/v1/api/common/index.md
index ab05a51f2..0c4a8ce04 100644
--- a/docs/en/v1/api/common/index.md
+++ b/docs/en/v1/api/common/index.md
@@ -32,12 +32,18 @@ Composes synchronous functions by chaining a single input.
### [innerPipe](/en/v1/api/common/innerPipe)
Prepares a reusable pipe that returns a function to apply later.
+### [preparePipe](/en/v1/api/common/preparePipe)
+Declares reusable synchronous steps with contextual input-to-output inference.
+
### [asyncPipe](/en/v1/api/common/asyncPipe)
Composes promises or `FutureEither` sequentially and returns a `Promise`.
### [asyncInnerPipe](/en/v1/api/common/asyncInnerPipe)
Curried version of `asyncPipe` that returns a function ready to accept a value (sync or async).
+### [prepareAsyncPipe](/en/v1/api/common/prepareAsyncPipe)
+Declares reusable maybe-promise steps with contextual input-to-output inference.
+
### [forward](/en/v1/api/common/forward)
Convenient identity function in a chain to pass the value through unchanged.
diff --git a/docs/en/v1/api/common/innerPipe.md b/docs/en/v1/api/common/innerPipe.md
index 1c9cf25b5..4aacee81e 100644
--- a/docs/en/v1/api/common/innerPipe.md
+++ b/docs/en/v1/api/common/innerPipe.md
@@ -5,8 +5,8 @@ prev:
text: "pipe"
link: "/en/v1/api/common/pipe"
next:
- text: "asyncPipe"
- link: "/en/v1/api/common/asyncPipe"
+ text: "preparePipe"
+ link: "/en/v1/api/common/preparePipe"
---
# innerPipe
diff --git a/docs/en/v1/api/common/prepareAsyncPipe.md b/docs/en/v1/api/common/prepareAsyncPipe.md
new file mode 100644
index 000000000..33dfefc6f
--- /dev/null
+++ b/docs/en/v1/api/common/prepareAsyncPipe.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "prepareAsyncPipe() declares maybe-promise pipeline steps once and returns a reusable asynchronous function with contextual input inference."
+prev:
+ text: "asyncInnerPipe"
+ link: "/en/v1/api/common/asyncInnerPipe"
+next:
+ text: "forward"
+ link: "/en/v1/api/common/forward"
+---
+
+# prepareAsyncPipe
+
+`prepareAsyncPipe()` is the asynchronous counterpart of `preparePipe()`. It declares up to fifteen transformations once, accepts synchronous or promise-returning steps, and returns a reusable asynchronous function.
+
+The prepared function accepts either a direct input or a promise. Its contextual input-to-output signature can drive the local input inference, including when the pipeline participates in a recursive asynchronous function.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Explicit input type
+
+```typescript
+const prepared = prepareAsyncPipe ()(
+ pipe1,
+ pipe2
+);
+```
+
+### Contextual input-to-output type
+
+```typescript
+const prepared: (input: Input) => Promise = prepareAsyncPipe()(
+ pipe1,
+ pipe2
+);
+```
+
+## Parameters
+
+- `Input`: optional upper constraint for the direct or promised input.
+- `pipe1, pipe2, ...`: one to fifteen transformations returning either a value or a promise.
+
+## Return value
+
+A reusable function accepting `Input | PromiseLike ` and returning a promise of the final output.
+
+## See also
+
+- [`preparePipe`](/en/v1/api/common/preparePipe) - Synchronous prepared variant.
+- [`asyncInnerPipe`](/en/v1/api/common/asyncInnerPipe) - Reusable asynchronous composition inferred directly from its steps.
diff --git a/docs/en/v1/api/common/preparePipe.md b/docs/en/v1/api/common/preparePipe.md
new file mode 100644
index 000000000..e3bd311cd
--- /dev/null
+++ b/docs/en/v1/api/common/preparePipe.md
@@ -0,0 +1,60 @@
+---
+outline: [2, 3]
+description: "preparePipe() declares synchronous pipeline steps once and returns a reusable function whose input can be inferred from its contextual input-to-output contract."
+prev:
+ text: "innerPipe"
+ link: "/en/v1/api/common/innerPipe"
+next:
+ text: "asyncPipe"
+ link: "/en/v1/api/common/asyncPipe"
+---
+
+# preparePipe
+
+`preparePipe()` declares up to fifteen synchronous transformations once and returns the function that executes them. Reusing that function avoids rebuilding the list of steps at every call.
+
+Unlike a directly inferred pipe, the returned function may provide its input through a contextual signature. This allows `preparePipe()` to infer the local input and all intermediate outputs without an explicit generic argument. The pattern is particularly useful for recursive functions, where the complete input-to-output contract is usually declared first.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Explicit input type
+
+```typescript
+const prepared = preparePipe ()(
+ pipe1,
+ pipe2
+);
+```
+
+### Contextual input-to-output type
+
+```typescript
+const prepared: (input: Input) => Output = preparePipe()(
+ pipe1,
+ pipe2
+);
+```
+
+## Parameters
+
+- `Input`: optional upper constraint for the input accepted by the prepared function.
+- `pipe1, pipe2, ...`: one to fifteen transformations. Each receives the previous output.
+
+The local input generic is inferred from the resulting function's contextual type and is used by the first step and by the returned function.
+
+## Return value
+
+A reusable function that accepts the inferred input and synchronously returns the final pipeline output.
+
+## See also
+
+- [`innerPipe`](/en/v1/api/common/innerPipe) - Builds a reusable pipe directly from its steps.
+- [`prepareAsyncPipe`](/en/v1/api/common/prepareAsyncPipe) - Maybe-promise asynchronous variant.
diff --git a/docs/en/v1/api/either/index.md b/docs/en/v1/api/either/index.md
index c4178845c..e8c3f7c4a 100644
--- a/docs/en/v1/api/either/index.md
+++ b/docs/en/v1/api/either/index.md
@@ -195,6 +195,9 @@ Type guard based on the literal information to precisely target a business case.
### [whenHasInformation](/en/v1/api/either/whenHasInformation)
Pattern matching that triggers a function when the information (or a list of infos) matches.
+### [whenIsSelected](/en/v1/api/either/whenIsSelected)
+Runs a callback for the informations selected with `true` in an exhaustive selector and forwards all other inputs unchanged.
+
### [matchInformation](/en/v1/api/either/matchInformation)
Exhaustive pattern matching by information where every Either case must be handled.
diff --git a/docs/en/v1/api/either/matchInformation.md b/docs/en/v1/api/either/matchInformation.md
index af46f0404..66532a766 100644
--- a/docs/en/v1/api/either/matchInformation.md
+++ b/docs/en/v1/api/either/matchInformation.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "Exhaustive pattern matching on Either information. Every information case must be handled."
prev:
- text: "whenHasInformation"
- link: "/en/v1/api/either/whenHasInformation"
+ text: "whenIsSelected"
+ link: "/en/v1/api/either/whenIsSelected"
next:
text: "matchInformationOtherwise"
link: "/en/v1/api/either/matchInformationOtherwise"
diff --git a/docs/en/v1/api/either/whenHasInformation.md b/docs/en/v1/api/either/whenHasInformation.md
index 1ea47b213..53c174639 100644
--- a/docs/en/v1/api/either/whenHasInformation.md
+++ b/docs/en/v1/api/either/whenHasInformation.md
@@ -5,8 +5,8 @@ prev:
text: "hasInformation"
link: "/en/v1/api/either/hasInformation"
next:
- text: "matchInformation"
- link: "/en/v1/api/either/matchInformation"
+ text: "whenIsSelected"
+ link: "/en/v1/api/either/whenIsSelected"
---
# whenHasInformation
diff --git a/docs/en/v1/api/either/whenIsSelected.md b/docs/en/v1/api/either/whenIsSelected.md
new file mode 100644
index 000000000..9fc1f2cd6
--- /dev/null
+++ b/docs/en/v1/api/either/whenIsSelected.md
@@ -0,0 +1,71 @@
+---
+outline: [2, 3]
+description: "Runs a callback on the unwrapped Either payloads selected by an exhaustive information selector and forwards all other inputs unchanged."
+prev:
+ text: "whenHasInformation"
+ link: "/en/v1/api/either/whenHasInformation"
+next:
+ text: "matchInformation"
+ link: "/en/v1/api/either/matchInformation"
+---
+
+# whenIsSelected
+
+Runs a callback on the unwrapped `Either` payloads selected by an exhaustive information selector and forwards all other inputs unchanged.
+
+The selector maps every possible information of the input union to `true` or `false`. A `true` entry executes the callback with the unwrapped payload; a `false` entry preserves the original `Either`.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function whenIsSelected<
+ GenericInput extends unknown,
+ GenericSelector extends Record,
+ GenericOutput,
+>(
+ input: GenericInput,
+ selector: GenericSelector,
+ theFunction: (value: UnwrappedSelectedInputs) => GenericOutput,
+): GenericOutput | UnselectedInputs
+```
+
+### Curried signature
+
+```typescript
+function whenIsSelected<
+ GenericInput extends unknown,
+ GenericSelector extends Record,
+ GenericOutput,
+>(
+ selector: GenericSelector,
+ theFunction: (value: UnwrappedSelectedInputs) => GenericOutput,
+): (input: GenericInput) => GenericOutput | UnselectedInputs
+```
+
+## Parameters
+
+- `selector`: Exhaustive object mapping every possible input information to `true` or `false`.
+- `theFunction`: Callback receiving the unwrapped payload of the selected informations.
+- `input`: Value to process immediately, or later through the curried form.
+
+## Return value
+
+Returns the callback result when the current information is selected with `true`. Otherwise, it returns the original input unchanged.
+
+When a selector entry is typed as `boolean`, the return type includes both the callback result and the original `Either` for that information.
+
+## See also
+
+- [`whenHasInformation`](/en/v1/api/either/whenHasInformation) - Selects one or several informations without an exhaustive selector.
+- [`unwrapSelection`](/en/v1/api/either/unwrapSelection) - Unwraps selected payloads without applying a callback.
+- [`matchInformation`](/en/v1/api/either/matchInformation) - Exhaustive callback-based matching by information.
diff --git a/docs/en/v1/api/pattern/index.md b/docs/en/v1/api/pattern/index.md
index aac156780..af934527c 100644
--- a/docs/en/v1/api/pattern/index.md
+++ b/docs/en/v1/api/pattern/index.md
@@ -28,6 +28,18 @@ import * as P from "@duplojs/utils/pattern";
### [match](/fr/v1/api/pattern/match)
Associates a pattern and a transformation function. Returns a `PatternResult` when the input matches the pattern exactly (primitive, tuple, object, union...).
+### [matchWithString](/en/v1/api/pattern/matchWithString)
+Exhaustively dispatches a string literal union to typed handlers.
+
+### [matchWithStringOtherwise](/en/v1/api/pattern/matchWithStringOtherwise)
+Handles selected string literals and sends remaining cases to a typed fallback.
+
+### [matchWithNumber](/en/v1/api/pattern/matchWithNumber)
+Exhaustively dispatches a number literal union to typed handlers.
+
+### [matchWithNumberOtherwise](/en/v1/api/pattern/matchWithNumberOtherwise)
+Handles selected number literals and sends remaining cases to a typed fallback.
+
### [when](/fr/v1/api/pattern/when)
Adds a guard (type predicate or boolean) in a pipeline. If the condition is true, the associated function is executed and its result is wrapped.
diff --git a/docs/en/v1/api/pattern/match.md b/docs/en/v1/api/pattern/match.md
index 5a372c9f4..c43ce70fe 100644
--- a/docs/en/v1/api/pattern/match.md
+++ b/docs/en/v1/api/pattern/match.md
@@ -5,8 +5,8 @@ prev:
text: "Pattern"
link: "/en/v1/api/pattern/"
next:
- text: "when"
- link: "/en/v1/api/pattern/when"
+ text: "matchWithString"
+ link: "/en/v1/api/pattern/matchWithString"
---
# match
diff --git a/docs/en/v1/api/pattern/matchWithNumber.md b/docs/en/v1/api/pattern/matchWithNumber.md
new file mode 100644
index 000000000..664cc58a6
--- /dev/null
+++ b/docs/en/v1/api/pattern/matchWithNumber.md
@@ -0,0 +1,55 @@
+---
+outline: [2, 3]
+description: "matchWithNumber() performs exhaustive pattern matching on a number literal union and guarantees processing for every possible value."
+prev:
+ text: "matchWithStringOtherwise"
+ link: "/en/v1/api/pattern/matchWithStringOtherwise"
+next:
+ text: "matchWithNumberOtherwise"
+ link: "/en/v1/api/pattern/matchWithNumberOtherwise"
+---
+
+# matchWithNumber
+
+`matchWithNumber()` performs exhaustive pattern matching on a number literal or a union of number literals. Every possible value must have exactly one handler, guaranteeing that no case is left unprocessed. The selected callback receives the literal value corresponding to its key, correctly narrowed by TypeScript.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithNumber (
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Curried signature
+
+```typescript
+function matchWithNumber (
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Parameters
+
+- `input`: a number literal or a union of number literals. Broad `number` values are rejected.
+- `matcher`: an exhaustive object whose keys are exactly the input literals. Each handler receives its corresponding narrowed literal.
+
+## Return value
+
+The selected handler result. Its static type is the union of all handler return types.
+
+## See also
+
+- [`matchWithString`](/en/v1/api/pattern/matchWithString) - String equivalent.
+- [`match`](/en/v1/api/pattern/match) - General-purpose pattern matching.
diff --git a/docs/en/v1/api/pattern/matchWithNumberOtherwise.md b/docs/en/v1/api/pattern/matchWithNumberOtherwise.md
new file mode 100644
index 000000000..d1e6c3c40
--- /dev/null
+++ b/docs/en/v1/api/pattern/matchWithNumberOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithNumberOtherwise() partially matches a number literal union and sends precisely the unhandled values to an otherwise callback."
+prev:
+ text: "matchWithNumber"
+ link: "/en/v1/api/pattern/matchWithNumber"
+next:
+ text: "when"
+ link: "/en/v1/api/pattern/when"
+---
+
+# matchWithNumberOtherwise
+
+`matchWithNumberOtherwise()` handles selected members of a number literal union. Matcher keys must belong to the input union, but may omit cases. The `otherwise` callback receives only the literals that have no handler.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithNumberOtherwise (
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): MatcherResult | Output
+```
+
+### Curried signature
+
+```typescript
+function matchWithNumberOtherwise (
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Parameters
+
+- `input`: a number literal or literal union; broad `number` values are rejected.
+- `matcher`: a partial object whose keys can only be members of `input`. A property may be `undefined` to route that case to `otherwise`.
+- `otherwise`: receives the exact union of cases without a handler.
+
+## Return value
+
+The selected handler result, or the `otherwise` result for an unhandled value.
+
+## See also
+
+- [`matchWithNumber`](/en/v1/api/pattern/matchWithNumber) - Exhaustive number matching.
+- [`matchWithStringOtherwise`](/en/v1/api/pattern/matchWithStringOtherwise) - String partial matching.
diff --git a/docs/en/v1/api/pattern/matchWithString.md b/docs/en/v1/api/pattern/matchWithString.md
new file mode 100644
index 000000000..04bb6f1d9
--- /dev/null
+++ b/docs/en/v1/api/pattern/matchWithString.md
@@ -0,0 +1,55 @@
+---
+outline: [2, 3]
+description: "matchWithString() performs exhaustive pattern matching on a string literal union and guarantees processing for every possible value."
+prev:
+ text: "match"
+ link: "/en/v1/api/pattern/match"
+next:
+ text: "matchWithStringOtherwise"
+ link: "/en/v1/api/pattern/matchWithStringOtherwise"
+---
+
+# matchWithString
+
+`matchWithString()` performs exhaustive pattern matching on a string literal or a union of string literals. Every possible value must have exactly one handler, guaranteeing that no case is left unprocessed. The selected callback receives the literal value corresponding to its key, correctly narrowed by TypeScript.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithString (
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Curried signature
+
+```typescript
+function matchWithString (
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Parameters
+
+- `input`: a string literal or a union of string literals. Broad `string` values are rejected.
+- `matcher`: an exhaustive object whose keys are exactly the input literals. Each handler receives its corresponding narrowed literal.
+
+## Return value
+
+The selected handler result. Its static type is the union of all handler return types.
+
+## See also
+
+- [`matchWithNumber`](/en/v1/api/pattern/matchWithNumber) - Numeric equivalent.
+- [`match`](/en/v1/api/pattern/match) - General-purpose pattern matching.
diff --git a/docs/en/v1/api/pattern/matchWithStringOtherwise.md b/docs/en/v1/api/pattern/matchWithStringOtherwise.md
new file mode 100644
index 000000000..c11fa1b75
--- /dev/null
+++ b/docs/en/v1/api/pattern/matchWithStringOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithStringOtherwise() partially matches a string literal union and sends precisely the unhandled values to an otherwise callback."
+prev:
+ text: "matchWithString"
+ link: "/en/v1/api/pattern/matchWithString"
+next:
+ text: "matchWithNumber"
+ link: "/en/v1/api/pattern/matchWithNumber"
+---
+
+# matchWithStringOtherwise
+
+`matchWithStringOtherwise()` handles selected members of a string literal union. Matcher keys must belong to the input union, but may omit cases. The `otherwise` callback receives only the literals that have no handler.
+
+## Interactive example
+
+
+
+## Syntax
+
+### Classic signature
+
+```typescript
+function matchWithStringOtherwise (
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): MatcherResult | Output
+```
+
+### Curried signature
+
+```typescript
+function matchWithStringOtherwise (
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Parameters
+
+- `input`: a string literal or literal union; broad `string` values are rejected.
+- `matcher`: a partial object whose keys can only be members of `input`. A property may be `undefined` to route that case to `otherwise`.
+- `otherwise`: receives the exact union of cases without a handler.
+
+## Return value
+
+The selected handler result, or the `otherwise` result for an unhandled value.
+
+## See also
+
+- [`matchWithString`](/en/v1/api/pattern/matchWithString) - Exhaustive string matching.
+- [`matchWithNumberOtherwise`](/en/v1/api/pattern/matchWithNumberOtherwise) - Numeric partial matching.
diff --git a/docs/en/v1/api/pattern/when.md b/docs/en/v1/api/pattern/when.md
index e6c23fcf8..3dc6d434b 100644
--- a/docs/en/v1/api/pattern/when.md
+++ b/docs/en/v1/api/pattern/when.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "when() adds a guard in the pattern matching pipeline. As soon as predicate returns true, the associated function is executed and its result is wrapped in a PatternResult. With a type guard, the branch is automatically typed with the predicated shape."
prev:
- text: "match"
- link: "/en/v1/api/pattern/match"
+ text: "matchWithNumberOtherwise"
+ link: "/en/v1/api/pattern/matchWithNumberOtherwise"
next:
text: "whenNot"
link: "/en/v1/api/pattern/whenNot"
diff --git a/docs/examples/v1/api/clean/primitives/operators/matchWithNumber/tryout.doc.ts b/docs/examples/v1/api/clean/primitives/operators/matchWithNumber/tryout.doc.ts
new file mode 100644
index 000000000..ec0ced5fc
--- /dev/null
+++ b/docs/examples/v1/api/clean/primitives/operators/matchWithNumber/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { DClean, pipe, type ExpectType } from "@duplojs/utils";
+
+const status = DClean.Number.createOrThrow(200 as 200 | 404);
+
+const result = pipe(
+ status,
+ DClean.matchWithNumber({
+ 200: (value) => {
+ type check = ExpectType<
+ typeof value,
+ DClean.Primitive<200 | 404> & DClean.Primitive<200>,
+ "strict"
+ >;
+
+ return "success" as const;
+ },
+ 404: () => "missing" as const,
+ }),
+);
+
+type check = ExpectType<
+ typeof result,
+ "success" | "missing",
+ "strict"
+>;
diff --git a/docs/examples/v1/api/clean/primitives/operators/matchWithNumberOtherwise/tryout.doc.ts b/docs/examples/v1/api/clean/primitives/operators/matchWithNumberOtherwise/tryout.doc.ts
new file mode 100644
index 000000000..70d9cee57
--- /dev/null
+++ b/docs/examples/v1/api/clean/primitives/operators/matchWithNumberOtherwise/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { DClean, type ExpectType, pipe, unwrap } from "@duplojs/utils";
+
+const status = DClean.Number.createOrThrow(
+ 404 as 200 | 404 | 500,
+);
+
+const result = pipe(
+ status,
+ DClean.matchWithNumberOtherwise(
+ {
+ 200: () => "success" as const,
+ },
+ (value) => {
+ type check = ExpectType<
+ typeof value,
+ DClean.Primitive<200 | 404 | 500>
+ & DClean.Primitive<404 | 500>,
+ "strict"
+ >;
+ return value;
+ },
+ ),
+);
+
+console.log(unwrap(result)); // 404
diff --git a/docs/examples/v1/api/clean/primitives/operators/matchWithString/tryout.doc.ts b/docs/examples/v1/api/clean/primitives/operators/matchWithString/tryout.doc.ts
new file mode 100644
index 000000000..db1428619
--- /dev/null
+++ b/docs/examples/v1/api/clean/primitives/operators/matchWithString/tryout.doc.ts
@@ -0,0 +1,24 @@
+import { DClean, pipe, type ExpectType } from "@duplojs/utils";
+
+const status = DClean.String.createOrThrow(
+ "success" as "success" | "failure",
+);
+
+const result = pipe(
+ status,
+ DClean.matchWithString({
+ success: (value) => {
+ type check = ExpectType<
+ typeof value,
+ DClean.Primitive<"success" | "failure">
+ & DClean.Primitive<"success">,
+ "strict"
+ >;
+
+ return 200 as const;
+ },
+ failure: () => 500 as const,
+ }),
+);
+
+type check = ExpectType;
diff --git a/docs/examples/v1/api/clean/primitives/operators/matchWithStringOtherwise/tryout.doc.ts b/docs/examples/v1/api/clean/primitives/operators/matchWithStringOtherwise/tryout.doc.ts
new file mode 100644
index 000000000..2e2cc374f
--- /dev/null
+++ b/docs/examples/v1/api/clean/primitives/operators/matchWithStringOtherwise/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { DClean, type ExpectType, pipe, unwrap } from "@duplojs/utils";
+
+const status = DClean.String.createOrThrow(
+ "failure" as "success" | "failure" | "pending",
+);
+
+const result = pipe(
+ status,
+ DClean.matchWithStringOtherwise(
+ {
+ success: () => 200 as const,
+ },
+ (value) => {
+ type check = ExpectType<
+ typeof value,
+ DClean.Primitive<"success" | "failure" | "pending">
+ & DClean.Primitive<"failure" | "pending">,
+ "strict"
+ >;
+ return value;
+ },
+ ),
+);
+
+console.log(unwrap(result)); // "failure"
diff --git a/docs/examples/v1/api/common/prepareAsyncPipe/tryout.doc.ts b/docs/examples/v1/api/common/prepareAsyncPipe/tryout.doc.ts
new file mode 100644
index 000000000..533d40731
--- /dev/null
+++ b/docs/examples/v1/api/common/prepareAsyncPipe/tryout.doc.ts
@@ -0,0 +1,36 @@
+import { type ExpectType, prepareAsyncPipe, DString } from "@duplojs/utils";
+
+const numberToString: (
+ input: number
+) => Promise = prepareAsyncPipe()(
+ async(value) => Promise.resolve(value),
+ DString.to,
+);
+
+const firstResult = await numberToString(10);
+const secondResult = await numberToString(
+ await Promise.resolve(42),
+);
+
+type firstCheck = ExpectType<
+ typeof firstResult,
+ string,
+ "strict"
+>;
+
+console.log(firstResult); // "10"
+console.log(secondResult); // "42"
+
+const explicitlyTypedPipe = prepareAsyncPipe()(
+ async(value) => Promise.resolve(value * 2),
+ DString.to,
+);
+const explicitResult = await explicitlyTypedPipe(21);
+
+type explicitCheck = ExpectType<
+ typeof explicitResult,
+ `${number}`,
+ "strict"
+>;
+
+console.log(explicitResult); // "42"
diff --git a/docs/examples/v1/api/common/preparePipe/tryout.doc.ts b/docs/examples/v1/api/common/preparePipe/tryout.doc.ts
new file mode 100644
index 000000000..bb5bf6651
--- /dev/null
+++ b/docs/examples/v1/api/common/preparePipe/tryout.doc.ts
@@ -0,0 +1,31 @@
+import { type ExpectType, preparePipe, DString } from "@duplojs/utils";
+
+const numberToString: (input: number) => string = preparePipe()(
+ DString.to,
+);
+
+const firstResult = numberToString(10);
+const secondResult = numberToString(42);
+
+type firstCheck = ExpectType<
+ typeof firstResult,
+ string,
+ "strict"
+>;
+
+console.log(firstResult); // "10"
+console.log(secondResult); // "42"
+
+const explicitlyTypedPipe = preparePipe()(
+ (value) => value * 2,
+ DString.to,
+);
+const explicitResult = explicitlyTypedPipe(21);
+
+type explicitCheck = ExpectType<
+ typeof explicitResult,
+ `${number}`,
+ "strict"
+>;
+
+console.log(explicitResult); // "42"
diff --git a/docs/examples/v1/api/either/whenIsSelected/tryout.doc.ts b/docs/examples/v1/api/either/whenIsSelected/tryout.doc.ts
new file mode 100644
index 000000000..926e0bff1
--- /dev/null
+++ b/docs/examples/v1/api/either/whenIsSelected/tryout.doc.ts
@@ -0,0 +1,37 @@
+import { E, pipe, type ExpectType } from "@duplojs/utils";
+
+const payment = true
+ ? E.right("payment.accepted", 120 as const)
+ : E.left("payment.rejected", "insufficient funds" as const);
+
+const formattedPayment = E.whenIsSelected(
+ payment,
+ {
+ "payment.accepted": true,
+ "payment.rejected": false,
+ },
+ (amount) => `paid:${amount}` as const,
+);
+
+type formattedPaymentCheck = ExpectType<
+ typeof formattedPayment,
+ "paid:120" | E.Left<"payment.rejected", "insufficient funds">,
+ "strict"
+>;
+
+const pipedPayment = pipe(
+ payment,
+ E.whenIsSelected(
+ {
+ "payment.accepted": true,
+ "payment.rejected": false,
+ },
+ (amount) => ({ amount }),
+ ),
+);
+
+type pipedPaymentCheck = ExpectType<
+ typeof pipedPayment,
+ { readonly amount: 120 } | E.Left<"payment.rejected", "insufficient funds">,
+ "strict"
+>;
diff --git a/docs/examples/v1/api/pattern/matchWithNumber/tryout.doc.ts b/docs/examples/v1/api/pattern/matchWithNumber/tryout.doc.ts
new file mode 100644
index 000000000..0ecf8a80b
--- /dev/null
+++ b/docs/examples/v1/api/pattern/matchWithNumber/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { DPattern, pipe, type ExpectType } from "@duplojs/utils";
+
+const status = 200 as 200 | 404;
+
+const result = pipe(
+ status,
+ DPattern.matchWithNumber({
+ 200: (value) => {
+ type check = ExpectType<
+ typeof value,
+ 200,
+ "strict"
+ >;
+
+ return "success" as const;
+ },
+ 404: () => "missing" as const,
+ }),
+);
+
+type check = ExpectType<
+ typeof result,
+ "success" | "missing",
+ "strict"
+>;
diff --git a/docs/examples/v1/api/pattern/matchWithNumberOtherwise/tryout.doc.ts b/docs/examples/v1/api/pattern/matchWithNumberOtherwise/tryout.doc.ts
new file mode 100644
index 000000000..c71274023
--- /dev/null
+++ b/docs/examples/v1/api/pattern/matchWithNumberOtherwise/tryout.doc.ts
@@ -0,0 +1,21 @@
+import { DPattern, type ExpectType, pipe } from "@duplojs/utils";
+
+const status = 404 as 200 | 404 | 500;
+
+const result = pipe(
+ status,
+ DPattern.matchWithNumberOtherwise(
+ {
+ 200: (value) => {
+ type check = ExpectType;
+ return "success" as const;
+ },
+ },
+ (value) => {
+ type check = ExpectType;
+ return `error: ${value}`;
+ },
+ ),
+);
+
+console.log(result); // "error: 404"
diff --git a/docs/examples/v1/api/pattern/matchWithString/tryout.doc.ts b/docs/examples/v1/api/pattern/matchWithString/tryout.doc.ts
new file mode 100644
index 000000000..a19c86378
--- /dev/null
+++ b/docs/examples/v1/api/pattern/matchWithString/tryout.doc.ts
@@ -0,0 +1,25 @@
+import { DPattern, pipe, type ExpectType } from "@duplojs/utils";
+
+const status = "success" as "success" | "failure";
+
+const result = pipe(
+ status,
+ DPattern.matchWithString({
+ success: (value) => {
+ type check = ExpectType<
+ typeof value,
+ "success",
+ "strict"
+ >;
+
+ return 200 as const;
+ },
+ failure: () => 500 as const,
+ }),
+);
+
+type check = ExpectType<
+ typeof result,
+ 200 | 500,
+ "strict"
+>;
diff --git a/docs/examples/v1/api/pattern/matchWithStringOtherwise/tryout.doc.ts b/docs/examples/v1/api/pattern/matchWithStringOtherwise/tryout.doc.ts
new file mode 100644
index 000000000..2c1cec5a0
--- /dev/null
+++ b/docs/examples/v1/api/pattern/matchWithStringOtherwise/tryout.doc.ts
@@ -0,0 +1,21 @@
+import { DPattern, type ExpectType, pipe } from "@duplojs/utils";
+
+const status = "failure" as "success" | "failure" | "pending";
+
+const result = pipe(
+ status,
+ DPattern.matchWithStringOtherwise(
+ {
+ success: (value) => {
+ type check = ExpectType;
+ return 200 as const;
+ },
+ },
+ (value) => {
+ type check = ExpectType;
+ return `unhandled: ${value}`;
+ },
+ ),
+);
+
+console.log(result); // "unhandled: failure"
diff --git a/docs/fr/v1/api/clean/index.md b/docs/fr/v1/api/clean/index.md
index fe141626c..cce9356bb 100644
--- a/docs/fr/v1/api/clean/index.md
+++ b/docs/fr/v1/api/clean/index.md
@@ -69,6 +69,12 @@ Déclare un agrégat d'actions métier liées qui doivent s'exécuter dans l'ord
### [equal](/fr/v1/api/clean/primitives/operators/equal)
Compare deux primitives wrappées (ou une primitive et une valeur brute) avec un type guard.
+### [matchWithString](/fr/v1/api/clean/primitives/operators/matchWithString)
+Effectue un matching exhaustif avec des clés string brutes et transmet la primitive Clean originale affinée.
+
+### [matchWithNumber](/fr/v1/api/clean/primitives/operators/matchWithNumber)
+Effectue un matching exhaustif avec des clés number brutes et transmet la primitive Clean originale affinée.
+
### [add](/fr/v1/api/clean/primitives/operators/add)
Additionne deux `Number` (supporte la version currifiée).
diff --git a/docs/fr/v1/api/clean/primitives/index.md b/docs/fr/v1/api/clean/primitives/index.md
index 6c6fba9fb..83a0fb9d3 100644
--- a/docs/fr/v1/api/clean/primitives/index.md
+++ b/docs/fr/v1/api/clean/primitives/index.md
@@ -96,6 +96,18 @@ function is(
### [equal](/fr/v1/api/clean/primitives/operators/equal)
Compare deux primitives wrappées (ou une primitive et une valeur brute) avec un type guard.
+### [matchWithString](/fr/v1/api/clean/primitives/operators/matchWithString)
+Effectue un matching exhaustif avec des clés string brutes et transmet la primitive Clean originale affinée.
+
+### [matchWithStringOtherwise](/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise)
+Effectue un matching partiel avec des clés string brutes et transmet les valeurs restantes à un fallback typé.
+
+### [matchWithNumber](/fr/v1/api/clean/primitives/operators/matchWithNumber)
+Effectue un matching exhaustif avec des clés number brutes et transmet la primitive Clean originale affinée.
+
+### [matchWithNumberOtherwise](/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise)
+Effectue un matching partiel avec des clés number brutes et transmet les valeurs restantes à un fallback typé.
+
### [add](/fr/v1/api/clean/primitives/operators/add)
Additionne deux `Number` (supporte la version currifiée).
diff --git a/docs/fr/v1/api/clean/primitives/operators/add.md b/docs/fr/v1/api/clean/primitives/operators/add.md
index 48819caa8..5aab403f3 100644
--- a/docs/fr/v1/api/clean/primitives/operators/add.md
+++ b/docs/fr/v1/api/clean/primitives/operators/add.md
@@ -1,8 +1,8 @@
---
outline: [2, 3]
prev:
- text: "equal"
- link: "/fr/v1/api/clean/primitives/operators/equal"
+ text: "matchWithNumberOtherwise"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise"
next:
text: "subtract"
link: "/fr/v1/api/clean/primitives/operators/subtract"
diff --git a/docs/fr/v1/api/clean/primitives/operators/equal.md b/docs/fr/v1/api/clean/primitives/operators/equal.md
index ac648fe93..e35b265b0 100644
--- a/docs/fr/v1/api/clean/primitives/operators/equal.md
+++ b/docs/fr/v1/api/clean/primitives/operators/equal.md
@@ -1,8 +1,8 @@
---
outline: [2, 3]
next:
- text: "add"
- link: "/fr/v1/api/clean/primitives/operators/operators/add"
+ text: "matchWithString"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithString"
---
# equal
diff --git a/docs/fr/v1/api/clean/primitives/operators/matchWithNumber.md b/docs/fr/v1/api/clean/primitives/operators/matchWithNumber.md
new file mode 100644
index 000000000..2462c1ced
--- /dev/null
+++ b/docs/fr/v1/api/clean/primitives/operators/matchWithNumber.md
@@ -0,0 +1,59 @@
+---
+outline: [2, 3]
+description: "matchWithNumber() effectue un pattern matching exhaustif sur la valeur d’une primitive Clean number et transmet à chaque branche la primitive originale correctement affinée."
+prev:
+ text: "matchWithStringOtherwise"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise"
+next:
+ text: "matchWithNumberOtherwise"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise"
+---
+
+# matchWithNumber
+
+`matchWithNumber()` effectue un pattern matching exhaustif sur la valeur d’une primitive Clean number. Chaque valeur possible doit avoir une branche de traitement.
+
+Une primitive Clean étant un objet wrappé, elle ne peut pas servir directement de clé au matcher. Les clés sont donc les valeurs `number` brutes. Lorsqu’une clé correspond, son callback reçoit la primitive Clean originale, affinée sur cette valeur. Ses informations `Primitive`, `ConstrainedType` ou `NewType` sont ainsi conservées.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithNumber , Matcher>(
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithNumber , Matcher>(
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Paramètres
+
+- `input` : une primitive Clean contenant une valeur `number`, y compris une valeur contrainte ou un new type.
+- `matcher` : un objet exhaustif indexé par les valeurs `number` brutes possibles. Une `Primitive` large nécessite un `Record` indexé.
+
+Chaque clé doit avoir exactement un handler. Une clé manquante ou étrangère à l’union est refusée par TypeScript. Le handler sélectionné reçoit l’objet Clean original affiné avec `Primitive`.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, typé comme l’union des retours de tous les handlers.
+
+## Voir aussi
+
+- [`matchWithString`](/fr/v1/api/clean/primitives/operators/matchWithString) - Équivalent pour les primitives string.
+- [`equal`](/fr/v1/api/clean/primitives/operators/equal) - Compare les valeurs de primitives wrappées.
diff --git a/docs/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md b/docs/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md
new file mode 100644
index 000000000..127df61fe
--- /dev/null
+++ b/docs/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithNumberOtherwise() traite partiellement une primitive Clean number tout en préservant la primitive originale affinée dans les handlers et otherwise."
+prev:
+ text: "matchWithNumber"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithNumber"
+next:
+ text: "add"
+ link: "/fr/v1/api/clean/primitives/operators/add"
+---
+
+# matchWithNumberOtherwise
+
+`matchWithNumberOtherwise()` traite certaines valeurs d’une primitive Clean number. Les valeurs number brutes forment les clés du matcher. Les cas manquants sont transmis à `otherwise`, qui reçoit la primitive originale affinée sur les valeurs restantes.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithNumberOtherwise , Matcher, Output>(
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): MatcherResult | Output
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithNumberOtherwise , Matcher, Output>(
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Paramètres
+
+- `input` : une primitive Clean number contenant des valeurs littérales.
+- `matcher` : un objet partiel indexé par les valeurs brutes de la primitive. Les clés inconnues sont refusées.
+- `otherwise` : reçoit la primitive `Primitive`, `ConstrainedType` ou `NewType` originale, affinée sur les valeurs sans handler.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, ou celui d’`otherwise` pour une valeur wrappée non traitée.
+
+## Voir aussi
+
+- [`matchWithNumber`](/fr/v1/api/clean/primitives/operators/matchWithNumber) - Matching exhaustif de primitive.
+- [`matchWithStringOtherwise`](/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise) - Équivalent pour une primitive string.
diff --git a/docs/fr/v1/api/clean/primitives/operators/matchWithString.md b/docs/fr/v1/api/clean/primitives/operators/matchWithString.md
new file mode 100644
index 000000000..7233fcb77
--- /dev/null
+++ b/docs/fr/v1/api/clean/primitives/operators/matchWithString.md
@@ -0,0 +1,59 @@
+---
+outline: [2, 3]
+description: "matchWithString() effectue un pattern matching exhaustif sur la valeur d’une primitive Clean string et transmet à chaque branche la primitive originale correctement affinée."
+prev:
+ text: "equal"
+ link: "/fr/v1/api/clean/primitives/operators/equal"
+next:
+ text: "matchWithStringOtherwise"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise"
+---
+
+# matchWithString
+
+`matchWithString()` effectue un pattern matching exhaustif sur la valeur d’une primitive Clean string. Chaque valeur possible doit avoir une branche de traitement.
+
+Une primitive Clean étant un objet wrappé, elle ne peut pas servir directement de clé au matcher. Les clés sont donc les valeurs `string` brutes. Lorsqu’une clé correspond, son callback reçoit la primitive Clean originale, affinée sur cette valeur. Ses informations `Primitive`, `ConstrainedType` ou `NewType` sont ainsi conservées.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithString , Matcher>(
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithString , Matcher>(
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Paramètres
+
+- `input` : une primitive Clean contenant une valeur `string`, y compris une valeur contrainte ou un new type.
+- `matcher` : un objet exhaustif indexé par les valeurs `string` brutes possibles. Une `Primitive` large nécessite un `Record` indexé.
+
+Chaque clé doit avoir exactement un handler. Une clé manquante ou étrangère à l’union est refusée par TypeScript. Le handler sélectionné reçoit l’objet Clean original affiné avec `Primitive`.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, typé comme l’union des retours de tous les handlers.
+
+## Voir aussi
+
+- [`matchWithNumber`](/fr/v1/api/clean/primitives/operators/matchWithNumber) - Équivalent pour les primitives numériques.
+- [`equal`](/fr/v1/api/clean/primitives/operators/equal) - Compare les valeurs de primitives wrappées.
diff --git a/docs/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise.md b/docs/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise.md
new file mode 100644
index 000000000..ca90e1d57
--- /dev/null
+++ b/docs/fr/v1/api/clean/primitives/operators/matchWithStringOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithStringOtherwise() traite partiellement une primitive Clean string tout en préservant la primitive originale affinée dans les handlers et otherwise."
+prev:
+ text: "matchWithString"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithString"
+next:
+ text: "matchWithNumber"
+ link: "/fr/v1/api/clean/primitives/operators/matchWithNumber"
+---
+
+# matchWithStringOtherwise
+
+`matchWithStringOtherwise()` traite certaines valeurs d’une primitive Clean string. Les valeurs string brutes forment les clés du matcher. Les cas manquants sont transmis à `otherwise`, qui reçoit la primitive originale affinée sur les valeurs restantes.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithStringOtherwise , Matcher, Output>(
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): MatcherResult | Output
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithStringOtherwise , Matcher, Output>(
+ matcher: Matcher,
+ otherwise: (value: UnhandledPrimitive) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Paramètres
+
+- `input` : une primitive Clean string contenant des valeurs littérales.
+- `matcher` : un objet partiel indexé par les valeurs brutes de la primitive. Les clés inconnues sont refusées.
+- `otherwise` : reçoit la primitive `Primitive`, `ConstrainedType` ou `NewType` originale, affinée sur les valeurs sans handler.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, ou celui d’`otherwise` pour une valeur wrappée non traitée.
+
+## Voir aussi
+
+- [`matchWithString`](/fr/v1/api/clean/primitives/operators/matchWithString) - Matching exhaustif de primitive.
+- [`matchWithNumberOtherwise`](/fr/v1/api/clean/primitives/operators/matchWithNumberOtherwise) - Équivalent pour une primitive number.
diff --git a/docs/fr/v1/api/common/asyncInnerPipe.md b/docs/fr/v1/api/common/asyncInnerPipe.md
index 99d4ca564..6d564b7ee 100644
--- a/docs/fr/v1/api/common/asyncInnerPipe.md
+++ b/docs/fr/v1/api/common/asyncInnerPipe.md
@@ -5,8 +5,8 @@ prev:
text: "asyncPipe"
link: "/fr/v1/api/common/asyncPipe"
next:
- text: "forward"
- link: "/fr/v1/api/common/forward"
+ text: "prepareAsyncPipe"
+ link: "/fr/v1/api/common/prepareAsyncPipe"
---
# asyncInnerPipe
diff --git a/docs/fr/v1/api/common/asyncPipe.md b/docs/fr/v1/api/common/asyncPipe.md
index f7c200f9e..b38b9ba91 100644
--- a/docs/fr/v1/api/common/asyncPipe.md
+++ b/docs/fr/v1/api/common/asyncPipe.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "La méthode asyncPipe() enchaîne des fonctions asynchrones (promesses ou FutureEither) en série. Chaque étape attend la résolution de la précédente et la dernière valeur est retournée dans une promesse."
prev:
- text: "innerPipe"
- link: "/fr/v1/api/common/innerPipe"
+ text: "preparePipe"
+ link: "/fr/v1/api/common/preparePipe"
next:
text: "asyncInnerPipe"
link: "/fr/v1/api/common/asyncInnerPipe"
diff --git a/docs/fr/v1/api/common/forward.md b/docs/fr/v1/api/common/forward.md
index 53b135c8d..b1610af41 100644
--- a/docs/fr/v1/api/common/forward.md
+++ b/docs/fr/v1/api/common/forward.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "La fonction forward() renvoie l'argument passé sans le modifier. Utile pour homogénéiser une API qui attend une fonction, ou pour améliorer la lisibilité dans un pipeline."
prev:
- text: "asyncInnerPipe"
- link: "/fr/v1/api/common/asyncInnerPipe"
+ text: "prepareAsyncPipe"
+ link: "/fr/v1/api/common/prepareAsyncPipe"
next:
text: "forwardLog"
link: "/fr/v1/api/common/forwardLog"
diff --git a/docs/fr/v1/api/common/index.md b/docs/fr/v1/api/common/index.md
index 8f2a5cce8..348d4ecd6 100644
--- a/docs/fr/v1/api/common/index.md
+++ b/docs/fr/v1/api/common/index.md
@@ -32,12 +32,18 @@ Compose des fonctions synchrones en chaînant un même input.
### [innerPipe](/fr/v1/api/common/innerPipe)
Prépare un pipe réutilisable qui retourne une fonction à appliquer plus tard.
+### [preparePipe](/fr/v1/api/common/preparePipe)
+Déclare des étapes synchrones réutilisables avec inférence contextuelle de l’entrée-sortie.
+
### [asyncPipe](/fr/v1/api/common/asyncPipe)
Compose des promesses ou des `FutureEither` de façon séquentielle en renvoyant un `Promise`.
### [asyncInnerPipe](/fr/v1/api/common/asyncInnerPipe)
Version curried d'`asyncPipe` qui renvoie une fonction prête à accepter une valeur (sync ou async).
+### [prepareAsyncPipe](/fr/v1/api/common/prepareAsyncPipe)
+Déclare des étapes synchrones ou asynchrones réutilisables avec inférence contextuelle de l’entrée-sortie.
+
### [forward](/fr/v1/api/common/forward)
Fonction identité pratique dans un chainage pour passer la valeur telle quelle.
diff --git a/docs/fr/v1/api/common/innerPipe.md b/docs/fr/v1/api/common/innerPipe.md
index cd162ee1a..7f5bb6cda 100644
--- a/docs/fr/v1/api/common/innerPipe.md
+++ b/docs/fr/v1/api/common/innerPipe.md
@@ -5,8 +5,8 @@ prev:
text: "pipe"
link: "/fr/v1/api/common/pipe"
next:
- text: "asyncPipe"
- link: "/fr/v1/api/common/asyncPipe"
+ text: "preparePipe"
+ link: "/fr/v1/api/common/preparePipe"
---
# innerPipe
diff --git a/docs/fr/v1/api/common/prepareAsyncPipe.md b/docs/fr/v1/api/common/prepareAsyncPipe.md
new file mode 100644
index 000000000..05f10fef0
--- /dev/null
+++ b/docs/fr/v1/api/common/prepareAsyncPipe.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "prepareAsyncPipe() déclare une seule fois les étapes synchrones ou asynchrones d’un pipeline et retourne une fonction réutilisable avec inférence contextuelle de l’entrée."
+prev:
+ text: "asyncInnerPipe"
+ link: "/fr/v1/api/common/asyncInnerPipe"
+next:
+ text: "forward"
+ link: "/fr/v1/api/common/forward"
+---
+
+# prepareAsyncPipe
+
+`prepareAsyncPipe()` est l’équivalent asynchrone de `preparePipe()`. Il déclare une seule fois jusqu’à quinze transformations, accepte des étapes synchrones ou retournant une promesse, puis produit une fonction asynchrone réutilisable.
+
+La fonction préparée accepte une entrée directe ou une promesse. Sa signature contextuelle d’entrée-sortie peut piloter l’inférence de l’entrée locale, notamment lorsque le pipeline participe à une fonction asynchrone récursive.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Type d’entrée explicite
+
+```typescript
+const prepared = prepareAsyncPipe ()(
+ pipe1,
+ pipe2
+);
+```
+
+### Type contextuel d’entrée-sortie
+
+```typescript
+const prepared: (input: Input) => Promise = prepareAsyncPipe()(
+ pipe1,
+ pipe2
+);
+```
+
+## Paramètres
+
+- `Input` : contrainte supérieure optionnelle de l’entrée directe ou promise.
+- `pipe1, pipe2, ...` : une à quinze transformations retournant une valeur ou une promesse.
+
+## Valeur de retour
+
+Une fonction réutilisable acceptant `Input | PromiseLike ` et retournant une promesse de la sortie finale.
+
+## Voir aussi
+
+- [`preparePipe`](/fr/v1/api/common/preparePipe) - Variante préparée synchrone.
+- [`asyncInnerPipe`](/fr/v1/api/common/asyncInnerPipe) - Composition asynchrone réutilisable inférée directement depuis ses étapes.
diff --git a/docs/fr/v1/api/common/preparePipe.md b/docs/fr/v1/api/common/preparePipe.md
new file mode 100644
index 000000000..f65d71ea7
--- /dev/null
+++ b/docs/fr/v1/api/common/preparePipe.md
@@ -0,0 +1,60 @@
+---
+outline: [2, 3]
+description: "preparePipe() déclare une seule fois les étapes d’un pipeline synchrone et retourne une fonction réutilisable dont l’entrée peut être inférée depuis son contrat contextuel."
+prev:
+ text: "innerPipe"
+ link: "/fr/v1/api/common/innerPipe"
+next:
+ text: "asyncPipe"
+ link: "/fr/v1/api/common/asyncPipe"
+---
+
+# preparePipe
+
+`preparePipe()` déclare une seule fois jusqu’à quinze transformations synchrones et retourne la fonction qui les exécute. Réutiliser cette fonction évite de reconstruire la liste des étapes à chaque appel.
+
+Contrairement à un pipe directement inféré, la fonction retournée peut fournir son entrée par une signature contextuelle. `preparePipe()` peut ainsi inférer l’entrée locale et toutes les sorties intermédiaires sans argument générique explicite. Ce pattern est particulièrement utile pour les fonctions récursives, dont le contrat complet entrée-sortie est généralement déclaré en premier.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Type d’entrée explicite
+
+```typescript
+const prepared = preparePipe ()(
+ pipe1,
+ pipe2
+);
+```
+
+### Type contextuel d’entrée-sortie
+
+```typescript
+const prepared: (input: Input) => Output = preparePipe()(
+ pipe1,
+ pipe2
+);
+```
+
+## Paramètres
+
+- `Input` : contrainte supérieure optionnelle de l’entrée acceptée par la fonction préparée.
+- `pipe1, pipe2, ...` : une à quinze transformations. Chacune reçoit la sortie précédente.
+
+Le générique local d’entrée est inféré depuis le type contextuel de la fonction résultante. Il est utilisé par la première étape et par la fonction retournée.
+
+## Valeur de retour
+
+Une fonction réutilisable qui accepte l’entrée inférée et retourne synchroniquement la sortie finale du pipeline.
+
+## Voir aussi
+
+- [`innerPipe`](/fr/v1/api/common/innerPipe) - Construit directement un pipe réutilisable depuis ses étapes.
+- [`prepareAsyncPipe`](/fr/v1/api/common/prepareAsyncPipe) - Variante asynchrone compatible avec les promesses.
diff --git a/docs/fr/v1/api/either/index.md b/docs/fr/v1/api/either/index.md
index 70112117b..121ec4da3 100644
--- a/docs/fr/v1/api/either/index.md
+++ b/docs/fr/v1/api/either/index.md
@@ -110,6 +110,9 @@ Type guard basé sur l'information littérale pour cibler précisément un cas m
### [whenHasInformation](/fr/v1/api/either/whenHasInformation)
Pattern matching qui déclenche une fonction quand l'information (ou une liste d'infos) correspond.
+### [whenIsSelected](/fr/v1/api/either/whenIsSelected)
+Exécute un callback pour les informations sélectionnées avec `true` dans un sélecteur exhaustif et relaie les autres entrées inchangées.
+
### [matchInformation](/fr/v1/api/either/matchInformation)
Pattern matching exhaustif par information où chaque cas Either doit être traité.
diff --git a/docs/fr/v1/api/either/matchInformation.md b/docs/fr/v1/api/either/matchInformation.md
index 64f199373..26f085bb7 100644
--- a/docs/fr/v1/api/either/matchInformation.md
+++ b/docs/fr/v1/api/either/matchInformation.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "Pattern matching exhaustif sur l'information d'un Either. Chaque information possible doit être traitée."
prev:
- text: "whenHasInformation"
- link: "/fr/v1/api/either/whenHasInformation"
+ text: "whenIsSelected"
+ link: "/fr/v1/api/either/whenIsSelected"
next:
text: "matchInformationOtherwise"
link: "/fr/v1/api/either/matchInformationOtherwise"
diff --git a/docs/fr/v1/api/either/whenHasInformation.md b/docs/fr/v1/api/either/whenHasInformation.md
index 5e1c8a195..65abc2e53 100644
--- a/docs/fr/v1/api/either/whenHasInformation.md
+++ b/docs/fr/v1/api/either/whenHasInformation.md
@@ -5,8 +5,8 @@ prev:
text: "hasInformation"
link: "/fr/v1/api/either/hasInformation"
next:
- text: "matchInformation"
- link: "/fr/v1/api/either/matchInformation"
+ text: "whenIsSelected"
+ link: "/fr/v1/api/either/whenIsSelected"
---
# whenHasInformation
diff --git a/docs/fr/v1/api/either/whenIsSelected.md b/docs/fr/v1/api/either/whenIsSelected.md
new file mode 100644
index 000000000..d5e0a6a87
--- /dev/null
+++ b/docs/fr/v1/api/either/whenIsSelected.md
@@ -0,0 +1,71 @@
+---
+outline: [2, 3]
+description: "Exécute un callback sur les payloads Either sélectionnés par un sélecteur exhaustif d'informations et relaie les autres entrées inchangées."
+prev:
+ text: "whenHasInformation"
+ link: "/fr/v1/api/either/whenHasInformation"
+next:
+ text: "matchInformation"
+ link: "/fr/v1/api/either/matchInformation"
+---
+
+# whenIsSelected
+
+Exécute un callback sur les payloads `Either` sélectionnés par un sélecteur exhaustif d'informations et relaie les autres entrées inchangées.
+
+Le sélecteur associe chaque information possible de l'union d'entrée à `true` ou `false`. Une entrée `true` exécute le callback avec le payload unwrap ; une entrée `false` conserve l'`Either` original.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function whenIsSelected<
+ GenericInput extends unknown,
+ GenericSelector extends Record,
+ GenericOutput,
+>(
+ input: GenericInput,
+ selector: GenericSelector,
+ theFunction: (value: UnwrappedSelectedInputs) => GenericOutput,
+): GenericOutput | UnselectedInputs
+```
+
+### Signature currifiée
+
+```typescript
+function whenIsSelected<
+ GenericInput extends unknown,
+ GenericSelector extends Record,
+ GenericOutput,
+>(
+ selector: GenericSelector,
+ theFunction: (value: UnwrappedSelectedInputs) => GenericOutput,
+): (input: GenericInput) => GenericOutput | UnselectedInputs
+```
+
+## Paramètres
+
+- `selector` : Objet exhaustif associant chaque information possible de l'entrée à `true` ou `false`.
+- `theFunction` : Callback recevant le payload unwrap des informations sélectionnées.
+- `input` : Valeur à traiter immédiatement, ou plus tard via la forme currifiée.
+
+## Valeur de retour
+
+Retourne le résultat du callback lorsque l'information courante est sélectionnée avec `true`. Sinon, renvoie l'entrée originale inchangée.
+
+Quand une entrée du sélecteur est typée `boolean`, le type de retour inclut à la fois le résultat du callback et l'`Either` original pour cette information.
+
+## Voir aussi
+
+- [`whenHasInformation`](/fr/v1/api/either/whenHasInformation) - Sélectionne une ou plusieurs informations sans sélecteur exhaustif.
+- [`unwrapSelection`](/fr/v1/api/either/unwrapSelection) - Unwrap les payloads sélectionnés sans appliquer de callback.
+- [`matchInformation`](/fr/v1/api/either/matchInformation) - Matching exhaustif par information avec callbacks.
diff --git a/docs/fr/v1/api/pattern/index.md b/docs/fr/v1/api/pattern/index.md
index 32119363f..aa006768a 100644
--- a/docs/fr/v1/api/pattern/index.md
+++ b/docs/fr/v1/api/pattern/index.md
@@ -28,6 +28,18 @@ import * as P from "@duplojs/utils/pattern";
### [match](/fr/v1/api/pattern/match)
Associe un motif et une fonction de transformation. Retourne un `PatternResult` quand l'entrée correspond exactement au motif (primitive, tuple, objet, union...).
+### [matchWithString](/fr/v1/api/pattern/matchWithString)
+Distribue exhaustivement une union de chaînes littérales vers des handlers typés.
+
+### [matchWithStringOtherwise](/fr/v1/api/pattern/matchWithStringOtherwise)
+Traite certaines chaînes littérales et transmet les cas restants à un fallback typé.
+
+### [matchWithNumber](/fr/v1/api/pattern/matchWithNumber)
+Distribue exhaustivement une union de nombres littéraux vers des handlers typés.
+
+### [matchWithNumberOtherwise](/fr/v1/api/pattern/matchWithNumberOtherwise)
+Traite certains nombres littéraux et transmet les cas restants à un fallback typé.
+
### [when](/fr/v1/api/pattern/when)
Ajoute une garde (type predicate ou boolean) dans un pipeline. Si la condition est vraie, la fonction associée est exécutée et son résultat est encapsulé.
diff --git a/docs/fr/v1/api/pattern/match.md b/docs/fr/v1/api/pattern/match.md
index ddde9f46c..f0e57bb0d 100644
--- a/docs/fr/v1/api/pattern/match.md
+++ b/docs/fr/v1/api/pattern/match.md
@@ -5,8 +5,8 @@ prev:
text: "Pattern"
link: "/fr/v1/api/pattern/"
next:
- text: "when"
- link: "/fr/v1/api/pattern/when"
+ text: "matchWithString"
+ link: "/fr/v1/api/pattern/matchWithString"
---
# match
diff --git a/docs/fr/v1/api/pattern/matchWithNumber.md b/docs/fr/v1/api/pattern/matchWithNumber.md
new file mode 100644
index 000000000..dd1317217
--- /dev/null
+++ b/docs/fr/v1/api/pattern/matchWithNumber.md
@@ -0,0 +1,55 @@
+---
+outline: [2, 3]
+description: "matchWithNumber() effectue un pattern matching exhaustif sur une union de nombres littéraux et garantit un traitement pour chaque valeur possible."
+prev:
+ text: "matchWithStringOtherwise"
+ link: "/fr/v1/api/pattern/matchWithStringOtherwise"
+next:
+ text: "matchWithNumberOtherwise"
+ link: "/fr/v1/api/pattern/matchWithNumberOtherwise"
+---
+
+# matchWithNumber
+
+`matchWithNumber()` effectue un pattern matching exhaustif sur un nombre littéral ou une union de nombres littéraux. Chaque valeur possible doit posséder exactement un handler, ce qui garantit qu’aucun cas ne reste sans traitement. Le callback sélectionné reçoit la valeur littérale correspondant à sa clé, correctement affinée par TypeScript.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithNumber (
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithNumber (
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Paramètres
+
+- `input` : un nombre littéral ou une union de nombres littéraux. Le type large `number` est refusé.
+- `matcher` : un objet exhaustif dont les clés correspondent exactement aux littéraux d’entrée. Chaque handler reçoit son littéral correctement affiné.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné. Son type statique est l’union des retours de tous les handlers.
+
+## Voir aussi
+
+- [`matchWithString`](/fr/v1/api/pattern/matchWithString) - Équivalent pour les chaînes.
+- [`match`](/fr/v1/api/pattern/match) - Pattern matching généraliste.
diff --git a/docs/fr/v1/api/pattern/matchWithNumberOtherwise.md b/docs/fr/v1/api/pattern/matchWithNumberOtherwise.md
new file mode 100644
index 000000000..73358e97c
--- /dev/null
+++ b/docs/fr/v1/api/pattern/matchWithNumberOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithNumberOtherwise() traite partiellement une union de nombres littéraux et transmet précisément les valeurs non traitées à un callback otherwise."
+prev:
+ text: "matchWithNumber"
+ link: "/fr/v1/api/pattern/matchWithNumber"
+next:
+ text: "when"
+ link: "/fr/v1/api/pattern/when"
+---
+
+# matchWithNumberOtherwise
+
+`matchWithNumberOtherwise()` traite certains membres d’une union de nombres littéraux. Les clés du matcher doivent appartenir à l’union d’entrée, mais certains cas peuvent être omis. Le callback `otherwise` reçoit uniquement les littéraux sans handler.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithNumberOtherwise (
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): MatcherResult | Output
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithNumberOtherwise (
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Paramètres
+
+- `input` : un nombre littéral ou une union de littéraux ; le type large `number` est refusé.
+- `matcher` : un objet partiel dont les clés doivent appartenir à `input`. Une propriété peut valoir `undefined` pour rediriger ce cas vers `otherwise`.
+- `otherwise` : reçoit l’union exacte des cas sans handler.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, ou celui d’`otherwise` pour une valeur non traitée.
+
+## Voir aussi
+
+- [`matchWithNumber`](/fr/v1/api/pattern/matchWithNumber) - Matching exhaustif de nombres.
+- [`matchWithStringOtherwise`](/fr/v1/api/pattern/matchWithStringOtherwise) - Matching partiel de chaînes.
diff --git a/docs/fr/v1/api/pattern/matchWithString.md b/docs/fr/v1/api/pattern/matchWithString.md
new file mode 100644
index 000000000..bf6ce6fa5
--- /dev/null
+++ b/docs/fr/v1/api/pattern/matchWithString.md
@@ -0,0 +1,55 @@
+---
+outline: [2, 3]
+description: "matchWithString() effectue un pattern matching exhaustif sur une union de chaînes littérales et garantit un traitement pour chaque valeur possible."
+prev:
+ text: "match"
+ link: "/fr/v1/api/pattern/match"
+next:
+ text: "matchWithStringOtherwise"
+ link: "/fr/v1/api/pattern/matchWithStringOtherwise"
+---
+
+# matchWithString
+
+`matchWithString()` effectue un pattern matching exhaustif sur une chaîne littérale ou une union de chaînes littérales. Chaque valeur possible doit posséder exactement un handler, ce qui garantit qu’aucun cas ne reste sans traitement. Le callback sélectionné reçoit la valeur littérale correspondant à sa clé, correctement affinée par TypeScript.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithString (
+ input: Input,
+ matcher: Matcher
+): ReturnType
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithString (
+ matcher: Matcher
+): (input: Input) => ReturnType
+```
+
+## Paramètres
+
+- `input` : une chaîne littérale ou une union de chaînes littérales. Le type large `string` est refusé.
+- `matcher` : un objet exhaustif dont les clés correspondent exactement aux littéraux d’entrée. Chaque handler reçoit son littéral correctement affiné.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné. Son type statique est l’union des retours de tous les handlers.
+
+## Voir aussi
+
+- [`matchWithNumber`](/fr/v1/api/pattern/matchWithNumber) - Équivalent numérique.
+- [`match`](/fr/v1/api/pattern/match) - Pattern matching généraliste.
diff --git a/docs/fr/v1/api/pattern/matchWithStringOtherwise.md b/docs/fr/v1/api/pattern/matchWithStringOtherwise.md
new file mode 100644
index 000000000..59ee7aa40
--- /dev/null
+++ b/docs/fr/v1/api/pattern/matchWithStringOtherwise.md
@@ -0,0 +1,58 @@
+---
+outline: [2, 3]
+description: "matchWithStringOtherwise() traite partiellement une union de chaînes littérales et transmet précisément les valeurs non traitées à un callback otherwise."
+prev:
+ text: "matchWithString"
+ link: "/fr/v1/api/pattern/matchWithString"
+next:
+ text: "matchWithNumber"
+ link: "/fr/v1/api/pattern/matchWithNumber"
+---
+
+# matchWithStringOtherwise
+
+`matchWithStringOtherwise()` traite certains membres d’une union de chaînes littérales. Les clés du matcher doivent appartenir à l’union d’entrée, mais certains cas peuvent être omis. Le callback `otherwise` reçoit uniquement les littéraux sans handler.
+
+## Exemple interactif
+
+
+
+## Syntaxe
+
+### Signature classique
+
+```typescript
+function matchWithStringOtherwise (
+ input: Input,
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): MatcherResult | Output
+```
+
+### Signature currifiée
+
+```typescript
+function matchWithStringOtherwise (
+ matcher: Matcher,
+ otherwise: (value: UnhandledValues) => Output
+): (input: Input) => MatcherResult | Output
+```
+
+## Paramètres
+
+- `input` : une chaîne littérale ou une union de littéraux ; le type large `string` est refusé.
+- `matcher` : un objet partiel dont les clés doivent appartenir à `input`. Une propriété peut valoir `undefined` pour rediriger ce cas vers `otherwise`.
+- `otherwise` : reçoit l’union exacte des cas sans handler.
+
+## Valeur de retour
+
+Le résultat du handler sélectionné, ou celui d’`otherwise` pour une valeur non traitée.
+
+## Voir aussi
+
+- [`matchWithString`](/fr/v1/api/pattern/matchWithString) - Matching exhaustif de chaînes.
+- [`matchWithNumberOtherwise`](/fr/v1/api/pattern/matchWithNumberOtherwise) - Matching partiel numérique.
diff --git a/docs/fr/v1/api/pattern/when.md b/docs/fr/v1/api/pattern/when.md
index 32775cc6e..405388224 100644
--- a/docs/fr/v1/api/pattern/when.md
+++ b/docs/fr/v1/api/pattern/when.md
@@ -2,8 +2,8 @@
outline: [2, 3]
description: "when() ajoute une garde dans le pipeline de pattern matching. Dès que predicate retourne true, la fonction associée est exécutée et son résultat est encapsulé dans un PatternResult. Avec un type guard, la branche est automatiquement typée avec la forme prédicatée."
prev:
- text: "match"
- link: "/fr/v1/api/pattern/match"
+ text: "matchWithNumberOtherwise"
+ link: "/fr/v1/api/pattern/matchWithNumberOtherwise"
next:
text: "whenNot"
link: "/fr/v1/api/pattern/whenNot"
diff --git a/docs/public/libs/v1/clean/evidence.cjs b/docs/public/libs/v1/clean/evidence.cjs
index 5e65e75a9..02baee8e4 100644
--- a/docs/public/libs/v1/clean/evidence.cjs
+++ b/docs/public/libs/v1/clean/evidence.cjs
@@ -1,8 +1,15 @@
'use strict';
var kind = require('./kind.cjs');
+var kindClass = require('../common/kindClass.cjs');
const evidenceKind = kind.createCleanKind("evidence");
+class ArrayWithEvidence extends kindClass.kindClass(evidenceKind, Array) {
+ constructor(array, evidence) {
+ super(evidence, ...array);
+ }
+ static [Symbol.species] = Array;
+}
function appendEvidence(...args) {
if (args.length === 1) {
const [evidenceName] = args;
@@ -13,6 +20,9 @@ function appendEvidence(...args) {
...(evidenceKind.has(input) && evidenceKind.getValue(input)),
[evidenceName]: null,
};
+ if (input instanceof Array) {
+ return new ArrayWithEvidence(input, evidence);
+ }
return evidenceKind.addTo(input, evidence);
}
function hasEvidence(...args) {
@@ -36,6 +46,7 @@ function hasEvidence(...args) {
return false;
}
+exports.ArrayWithEvidence = ArrayWithEvidence;
exports.appendEvidence = appendEvidence;
exports.evidenceKind = evidenceKind;
exports.hasEvidence = hasEvidence;
diff --git a/docs/public/libs/v1/clean/evidence.d.ts b/docs/public/libs/v1/clean/evidence.d.ts
index 79090d801..c497cf0ab 100644
--- a/docs/public/libs/v1/clean/evidence.d.ts
+++ b/docs/public/libs/v1/clean/evidence.d.ts
@@ -3,6 +3,11 @@ import type * as DEither from "../either";
export declare const evidenceKind: import("../common").KindHandler>>;
export interface Evidence extends Kind> {
}
+declare const ArrayWithEvidence_base: import("../common").KindClass>>, ArrayConstructor>;
+export declare class ArrayWithEvidence extends ArrayWithEvidence_base> {
+ constructor(array: readonly GenericElement[], evidence: Record);
+ static [Symbol.species]: ArrayConstructor;
+}
/**
* Appends an evidence trait on an object value to mark that a business step was completed.
*
@@ -110,3 +115,4 @@ export declare function appendEvidence>>, string>>(evidenceName: GenericEvidenceName | AnyTuple): (input: GenericInput) => input is Extract : never>;
export declare function hasEvidence>>, string>>(input: GenericInput, evidenceName: GenericEvidenceName | AnyTuple): input is Extract : never>;
export type GetEvidenceResult> extends infer InferredResult ? InferredResult extends Evidence ? InferredResult : InferredResult extends DEither.Right | DEither.Left ? Unwrap : InferredResult : never, Evidence>>>, string>> = Extract> extends infer InferredResult ? InferredResult extends Evidence ? InferredResult : InferredResult extends DEither.Right | DEither.Left ? Unwrap : InferredResult : never, EvidenceName extends any ? Evidence : never>;
+export {};
diff --git a/docs/public/libs/v1/clean/evidence.mjs b/docs/public/libs/v1/clean/evidence.mjs
index 166a4f2a1..cce7aa898 100644
--- a/docs/public/libs/v1/clean/evidence.mjs
+++ b/docs/public/libs/v1/clean/evidence.mjs
@@ -1,6 +1,13 @@
import { createCleanKind } from './kind.mjs';
+import { kindClass } from '../common/kindClass.mjs';
const evidenceKind = createCleanKind("evidence");
+class ArrayWithEvidence extends kindClass(evidenceKind, Array) {
+ constructor(array, evidence) {
+ super(evidence, ...array);
+ }
+ static [Symbol.species] = Array;
+}
function appendEvidence(...args) {
if (args.length === 1) {
const [evidenceName] = args;
@@ -11,6 +18,9 @@ function appendEvidence(...args) {
...(evidenceKind.has(input) && evidenceKind.getValue(input)),
[evidenceName]: null,
};
+ if (input instanceof Array) {
+ return new ArrayWithEvidence(input, evidence);
+ }
return evidenceKind.addTo(input, evidence);
}
function hasEvidence(...args) {
@@ -34,4 +44,4 @@ function hasEvidence(...args) {
return false;
}
-export { appendEvidence, evidenceKind, hasEvidence };
+export { ArrayWithEvidence, appendEvidence, evidenceKind, hasEvidence };
diff --git a/docs/public/libs/v1/clean/flag.d.ts b/docs/public/libs/v1/clean/flag.d.ts
index f54b71669..9176e598a 100644
--- a/docs/public/libs/v1/clean/flag.d.ts
+++ b/docs/public/libs/v1/clean/flag.d.ts
@@ -32,17 +32,26 @@ export interface FlagHandler>(entity: GenericInputEntity): GetKindValue[GenericName];
+ /**
+ * Checks whether the entity has this state and narrows its type to include the flag.
+ *
+ * ```ts
+ * User.MajorFlag.has(user); // false
+ * User.MajorFlag.has(flagged); // true
+ * ```
+ *
+ */
has(entity: GenericInputEntity): entity is Extract>;
}
export interface Flag extends Kind> {
}
/**
- * Creates a flag handler that can attach typed metadata to an entity.
+ * Creates a handler for assigning a typed business state to an entity.
*
* **Supported call styles:**
* - Classic: `createFlag(name)` -> returns a handler
*
- * Flags let you mark an entity after creation without changing its shape. The mark can optionally carry a value.
+ * Use flags to make an entity state part of a precise type contract. Functions can require an entity combined with one or more flags, while the same entity keeps its original business properties and can reuse its repositories, mappers, and other supporting code. A flag can optionally carry data associated with its state.
*
* ```ts
* namespace User {
@@ -97,10 +106,12 @@ export interface Flag matcher[unwrap.unwrap(input)](input);
+ }
+ const [input, matcher] = args;
+ return matcher[unwrap.unwrap(input)](input);
+}
+
+exports.matchWithNumber = matchWithNumber;
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.d.ts b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.d.ts
new file mode 100644
index 000000000..1774bbc0c
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.d.ts
@@ -0,0 +1,55 @@
+import { type ComputedTypeError, type FixDeepFunctionInfer, type IsEqual, type Unwrap } from "../../../common";
+import { type Primitive } from "../base";
+import { type OnlyLiteralPrimitiveNumber } from "../../../clean/types/onlyLiteral";
+type ComputeMatcher> = {
+ [Prop in Unwrap]: (value: GenericInput & Primitive) => unknown;
+};
+type ForbiddenMoreKey, GenericMatcher extends ComputeMatcher> = Exclude> extends infer InferredKey ? IsEqual extends true ? unknown : ComputedTypeError<`Key "${Extract}" is forbidden.`> : never;
+/**
+ * Performs exhaustive pattern matching on the value of a Clean number primitive.
+ *
+ * **Supported call styles:**
+ * - Classic: `matchWithNumber(input, matcher)` -> runs the handler matching the wrapped value
+ * - Curried: `matchWithNumber(matcher)` -> returns a function waiting for the primitive
+ *
+ * A Clean primitive cannot be used directly as an object key, so the matcher uses raw number values as keys. Every possible value must have a handler. The selected handler receives the original Clean primitive narrowed to the matching key, preserving its constraints and `NewType` metadata.
+ *
+ * ```ts
+ * const status = C.Number.createOrThrow(
+ * 200 as 200 | 404,
+ * );
+ *
+ * C.matchWithNumber(status, {
+ * 200: () => "success",
+ * 404: () => "missing",
+ * }); // "success" | "missing"
+ *
+ * pipe(
+ * status,
+ * C.matchWithNumber({
+ * 200: (value) => value,
+ * 404: () => status,
+ * }),
+ * ); // C.Primitive<200 | 404>
+ *
+ * const positiveStatus = C.Positive.createOrThrow(
+ * 200 as 200 | 404,
+ * );
+ *
+ * C.matchWithNumber(positiveStatus, {
+ * 200: (value) => value,
+ * 404: (value) => value,
+ * }); // C.ConstrainedType<"positive", 200 | 404>
+ * ```
+ *
+ * @remarks A broad `Primitive` is supported with a `Record` matcher. Literal unions reject missing and additional keys.
+ *
+ * @see https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithNumber
+ * @see [`C.matchWithString`](https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithString)
+ *
+ * @namespace C
+ *
+ */
+export declare function matchWithNumber, GenericMatcher extends ComputeMatcher>(matcher: FixDeepFunctionInfer>, GenericMatcher> & ForbiddenMoreKey, GenericMatcher>): (input: GenericInput & OnlyLiteralPrimitiveNumber) => ReturnType[keyof GenericMatcher]>;
+export declare function matchWithNumber, GenericMatcher extends ComputeMatcher>(input: GenericInput & OnlyLiteralPrimitiveNumber, matcher: FixDeepFunctionInfer, GenericMatcher> & ForbiddenMoreKey): ReturnType;
+export {};
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.mjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.mjs
new file mode 100644
index 000000000..0886b3ecf
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumber.mjs
@@ -0,0 +1,12 @@
+import { unwrap } from '../../../common/unwrap.mjs';
+
+function matchWithNumber(...args) {
+ if (args.length === 1) {
+ const [matcher] = args;
+ return (input) => matcher[unwrap(input)](input);
+ }
+ const [input, matcher] = args;
+ return matcher[unwrap(input)](input);
+}
+
+export { matchWithNumber };
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.cjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.cjs
new file mode 100644
index 000000000..9d9131cc9
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.cjs
@@ -0,0 +1,18 @@
+'use strict';
+
+var unwrap = require('../../../common/unwrap.cjs');
+
+function execute(input, matcher, otherwise) {
+ const callback = matcher[unwrap.unwrap(input)];
+ return callback === undefined ? otherwise(input) : callback(input);
+}
+function matchWithNumberOtherwise(...args) {
+ if (args.length === 2) {
+ const [matcher, otherwise] = args;
+ return (input) => execute(input, matcher, otherwise);
+ }
+ const [input, matcher, otherwise] = args;
+ return execute(input, matcher, otherwise);
+}
+
+exports.matchWithNumberOtherwise = matchWithNumberOtherwise;
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.d.ts b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.d.ts
new file mode 100644
index 000000000..fb230ff65
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.d.ts
@@ -0,0 +1,61 @@
+import { type AnyFunction, type ComputedTypeError, type FixDeepFunctionInfer, type IsEqual, type Unwrap } from "../../../common";
+import { type GetPropsWithValueExtends } from "../../../object";
+import { type OnlyLiteralPrimitiveNumber } from "../../../clean/types/onlyLiteral";
+import { type Primitive } from "../base";
+type ComputeMatcher> = {
+ [Prop in Unwrap]?: (value: GenericInput & Primitive) => unknown;
+};
+type ForbiddenMoreKey, GenericMatcher extends ComputeMatcher> = Exclude> extends infer InferredKey ? IsEqual extends true ? unknown : ComputedTypeError<`Key "${Extract}" is forbidden.`> : never;
+type HandledKeys = Extract, number>;
+type OtherwiseValue, GenericMatcher extends object> = Extract, HandledKeys>>, any>;
+/** Performs partial pattern matching on a Clean number primitive and delegates unhandled values to an `otherwise` callback.
+/**
+/** **Supported call styles:**
+/** - Classic: `matchWithNumberOtherwise(input, matcher, otherwise)` -> runs a matching handler or the fallback
+/** - Curried: `matchWithNumberOtherwise(matcher, otherwise)` -> returns a function waiting for the primitive
+/**
+/** Raw number values are used as matcher keys. Handlers receive the original primitive narrowed to their key, and `otherwise` receives the same original primitive narrowed to all remaining values.
+/**
+/** ```ts
+/** const status = C.Number.createOrThrow(
+/** 200 as 200 | 404 | 500,
+/** );
+/**
+/** C.matchWithNumberOtherwise(
+/** status,
+/** {
+/** 200: () => "success",
+/** },
+/** () => "error",
+/** ); // string
+/**
+/** pipe(
+/** status,
+/** C.matchWithNumberOtherwise(
+/** {
+/** 404: () => "missing",
+/** },
+/** (value) => value,
+/** ),
+/** ); // "missing" | C.Primitive<200 | 500>
+/**
+/** const result = C.matchWithNumberOtherwise(
+/** status,
+/** {
+/** 200: (value) => value,
+/** 404: undefined,
+/** },
+/** (value) => value,
+/** ); // C.Primitive<200 | 404 | 500>
+/** ```
+/**
+/** @remarks Constraints and `NewType` metadata remain attached to the primitive passed to every callback.
+/**
+/** @see https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithNumberOtherwise
+/** @see [`C.matchWithNumber`](https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithNumber)
+/**
+/** @namespace C
+/** */
+export declare function matchWithNumberOtherwise, GenericMatcher extends ComputeMatcher, GenericOutput>(matcher: FixDeepFunctionInfer>, GenericMatcher> & ForbiddenMoreKey, GenericMatcher>, otherwise: (value: OtherwiseValue) => GenericOutput): (input: GenericInput & OnlyLiteralPrimitiveNumber) => (ReturnType[keyof GenericMatcher], AnyFunction>> | GenericOutput);
+export declare function matchWithNumberOtherwise, GenericMatcher extends ComputeMatcher, GenericOutput>(input: GenericInput & OnlyLiteralPrimitiveNumber, matcher: FixDeepFunctionInfer, GenericMatcher> & ForbiddenMoreKey, otherwise: (value: OtherwiseValue) => GenericOutput): (ReturnType> | GenericOutput);
+export {};
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.mjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.mjs
new file mode 100644
index 000000000..d3ac2defc
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithNumberOtherwise.mjs
@@ -0,0 +1,16 @@
+import { unwrap } from '../../../common/unwrap.mjs';
+
+function execute(input, matcher, otherwise) {
+ const callback = matcher[unwrap(input)];
+ return callback === undefined ? otherwise(input) : callback(input);
+}
+function matchWithNumberOtherwise(...args) {
+ if (args.length === 2) {
+ const [matcher, otherwise] = args;
+ return (input) => execute(input, matcher, otherwise);
+ }
+ const [input, matcher, otherwise] = args;
+ return execute(input, matcher, otherwise);
+}
+
+export { matchWithNumberOtherwise };
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithString.cjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.cjs
new file mode 100644
index 000000000..2d70fa24d
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.cjs
@@ -0,0 +1,14 @@
+'use strict';
+
+var unwrap = require('../../../common/unwrap.cjs');
+
+function matchWithString(...args) {
+ if (args.length === 1) {
+ const [matcher] = args;
+ return (input) => matcher[unwrap.unwrap(input)](input);
+ }
+ const [input, matcher] = args;
+ return matcher[unwrap.unwrap(input)](input);
+}
+
+exports.matchWithString = matchWithString;
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithString.d.ts b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.d.ts
new file mode 100644
index 000000000..c72890efd
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.d.ts
@@ -0,0 +1,55 @@
+import { type ComputedTypeError, type FixDeepFunctionInfer, type IsEqual, type Unwrap } from "../../../common";
+import { type Primitive } from "../base";
+import { type OnlyLiteralPrimitiveString } from "../../../clean/types/onlyLiteral";
+type ComputeMatcher> = {
+ [Prop in Unwrap]: (value: GenericInput & Primitive) => unknown;
+};
+type ForbiddenMoreKey, GenericMatcher extends ComputeMatcher> = Exclude> extends infer InferredKey ? IsEqual extends true ? unknown : ComputedTypeError<`Key "${Extract}" is forbidden.`> : never;
+/**
+ * Performs exhaustive pattern matching on the value of a Clean string primitive.
+ *
+ * **Supported call styles:**
+ * - Classic: `matchWithString(input, matcher)` -> runs the handler matching the wrapped value
+ * - Curried: `matchWithString(matcher)` -> returns a function waiting for the primitive
+ *
+ * A Clean primitive cannot be used directly as an object key, so the matcher uses raw string values as keys. Every possible value must have a handler. The selected handler receives the original Clean primitive narrowed to the matching key, preserving its constraints and `NewType` metadata.
+ *
+ * ```ts
+ * const status = C.String.createOrThrow(
+ * "success" as "success" | "failure",
+ * );
+ *
+ * C.matchWithString(status, {
+ * success: () => 200,
+ * failure: () => 500,
+ * }); // 200 | 500
+ *
+ * pipe(
+ * status,
+ * C.matchWithString({
+ * success: (value) => value,
+ * failure: () => status,
+ * }),
+ * ); // C.Primitive<"success" | "failure">
+ *
+ * const noBlankStatus = C.NoBlank.createOrThrow(
+ * "success" as "success" | "failure",
+ * );
+ *
+ * C.matchWithString(noBlankStatus, {
+ * success: (value) => value,
+ * failure: (value) => value,
+ * }); // C.ConstrainedType<"no-blank", "success" | "failure">
+ * ```
+ *
+ * @remarks A broad `Primitive` is supported with a `Record` matcher. Literal unions reject missing and additional keys.
+ *
+ * @see https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithString
+ * @see [`C.matchWithNumber`](https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithNumber)
+ *
+ * @namespace C
+ *
+ */
+export declare function matchWithString, GenericMatcher extends ComputeMatcher>(matcher: FixDeepFunctionInfer>, GenericMatcher> & ForbiddenMoreKey, GenericMatcher>): (input: GenericInput & OnlyLiteralPrimitiveString) => ReturnType[keyof GenericMatcher]>;
+export declare function matchWithString, GenericMatcher extends ComputeMatcher>(input: GenericInput & OnlyLiteralPrimitiveString, matcher: FixDeepFunctionInfer, GenericMatcher> & ForbiddenMoreKey): ReturnType;
+export {};
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithString.mjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.mjs
new file mode 100644
index 000000000..5eaa0841b
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithString.mjs
@@ -0,0 +1,12 @@
+import { unwrap } from '../../../common/unwrap.mjs';
+
+function matchWithString(...args) {
+ if (args.length === 1) {
+ const [matcher] = args;
+ return (input) => matcher[unwrap(input)](input);
+ }
+ const [input, matcher] = args;
+ return matcher[unwrap(input)](input);
+}
+
+export { matchWithString };
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.cjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.cjs
new file mode 100644
index 000000000..615e6fd09
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.cjs
@@ -0,0 +1,18 @@
+'use strict';
+
+var unwrap = require('../../../common/unwrap.cjs');
+
+function execute(input, matcher, otherwise) {
+ const callback = matcher[unwrap.unwrap(input)];
+ return callback === undefined ? otherwise(input) : callback(input);
+}
+function matchWithStringOtherwise(...args) {
+ if (args.length === 2) {
+ const [matcher, otherwise] = args;
+ return (input) => execute(input, matcher, otherwise);
+ }
+ const [input, matcher, otherwise] = args;
+ return execute(input, matcher, otherwise);
+}
+
+exports.matchWithStringOtherwise = matchWithStringOtherwise;
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.d.ts b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.d.ts
new file mode 100644
index 000000000..355adaa11
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.d.ts
@@ -0,0 +1,61 @@
+import { type AnyFunction, type ComputedTypeError, type FixDeepFunctionInfer, type IsEqual, type Unwrap } from "../../../common";
+import { type GetPropsWithValueExtends } from "../../../object";
+import { type OnlyLiteralPrimitiveString } from "../../../clean/types/onlyLiteral";
+import { type Primitive } from "../base";
+type ComputeMatcher> = {
+ [Prop in Unwrap]?: (value: GenericInput & Primitive) => unknown;
+};
+type ForbiddenMoreKey, GenericMatcher extends ComputeMatcher> = Exclude> extends infer InferredKey ? IsEqual extends true ? unknown : ComputedTypeError<`Key "${Extract}" is forbidden.`> : never;
+type HandledKeys = Extract, string>;
+type OtherwiseValue, GenericMatcher extends object> = Extract, HandledKeys>>, any>;
+/** Performs partial pattern matching on a Clean string primitive and delegates unhandled values to an `otherwise` callback.
+/**
+/** **Supported call styles:**
+/** - Classic: `matchWithStringOtherwise(input, matcher, otherwise)` -> runs a matching handler or the fallback
+/** - Curried: `matchWithStringOtherwise(matcher, otherwise)` -> returns a function waiting for the primitive
+/**
+/** Raw string values are used as matcher keys. Handlers receive the original primitive narrowed to their key, and `otherwise` receives the same original primitive narrowed to all remaining values.
+/**
+/** ```ts
+/** const status = C.String.createOrThrow(
+/** "success" as "success" | "failure" | "pending",
+/** );
+/**
+/** C.matchWithStringOtherwise(
+/** status,
+/** {
+/** success: () => 200,
+/** },
+/** () => 500,
+/** ); // number
+/**
+/** pipe(
+/** status,
+/** C.matchWithStringOtherwise(
+/** {
+/** failure: () => "retry",
+/** },
+/** (value) => value,
+/** ),
+/** ); // "retry" | C.Primitive<"success" | "pending">
+/**
+/** const result = C.matchWithStringOtherwise(
+/** status,
+/** {
+/** success: (value) => value,
+/** failure: undefined,
+/** },
+/** (value) => value,
+/** ); // C.Primitive<"success" | "failure" | "pending">
+/** ```
+/**
+/** @remarks Constraints and `NewType` metadata remain attached to the primitive passed to every callback.
+/**
+/** @see https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithStringOtherwise
+/** @see [`C.matchWithString`](https://utils.duplojs.dev/en/v1/api/clean/primitives/operators/matchWithString)
+/**
+/** @namespace C
+/** */
+export declare function matchWithStringOtherwise, GenericMatcher extends ComputeMatcher, GenericOutput>(matcher: FixDeepFunctionInfer>, GenericMatcher> & ForbiddenMoreKey, GenericMatcher>, otherwise: (value: OtherwiseValue) => GenericOutput): (input: GenericInput & OnlyLiteralPrimitiveString) => (ReturnType[keyof GenericMatcher], AnyFunction>> | GenericOutput);
+export declare function matchWithStringOtherwise, GenericMatcher extends ComputeMatcher, GenericOutput>(input: GenericInput & OnlyLiteralPrimitiveString, matcher: FixDeepFunctionInfer, GenericMatcher> & ForbiddenMoreKey, otherwise: (value: OtherwiseValue) => GenericOutput): (ReturnType> | GenericOutput);
+export {};
diff --git a/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.mjs b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.mjs
new file mode 100644
index 000000000..e7fa46ba9
--- /dev/null
+++ b/docs/public/libs/v1/clean/primitive/matcher/matchWithStringOtherwise.mjs
@@ -0,0 +1,16 @@
+import { unwrap } from '../../../common/unwrap.mjs';
+
+function execute(input, matcher, otherwise) {
+ const callback = matcher[unwrap(input)];
+ return callback === undefined ? otherwise(input) : callback(input);
+}
+function matchWithStringOtherwise(...args) {
+ if (args.length === 2) {
+ const [matcher, otherwise] = args;
+ return (input) => execute(input, matcher, otherwise);
+ }
+ const [input, matcher, otherwise] = args;
+ return execute(input, matcher, otherwise);
+}
+
+export { matchWithStringOtherwise };
diff --git a/docs/public/libs/v1/clean/types/onlyLiteral.d.ts b/docs/public/libs/v1/clean/types/onlyLiteral.d.ts
new file mode 100644
index 000000000..691825e75
--- /dev/null
+++ b/docs/public/libs/v1/clean/types/onlyLiteral.d.ts
@@ -0,0 +1,7 @@
+import { type Unwrap, type ComputedTypeError } from "../../common";
+import { type Primitive } from "../primitive";
+export type OnlyLiteralPrimitiveString = string extends Unwrap ? ComputedTypeError<"Input primitive must be a literal string."> : GenericValue;
+export type OnlyLiteralPrimitiveNumber = number extends Unwrap ? ComputedTypeError<"Input primitive must be a literal number."> : GenericValue;
+export type OnlyLiteralPrimitiveBigInt = bigint extends Unwrap ? ComputedTypeError<"Input primitive must be a literal bigint."> : GenericValue;
+export type OnlyLiteralPrimitiveBoolean = boolean extends Unwrap ? ComputedTypeError<"Input primitive must be a literal boolean."> : GenericValue;
+export type OnlyLiteral = (OnlyLiteralPrimitiveString & OnlyLiteralPrimitiveNumber & OnlyLiteralPrimitiveBigInt & OnlyLiteralPrimitiveBoolean);
diff --git a/docs/public/libs/v1/common/index.cjs b/docs/public/libs/v1/common/index.cjs
index c93590b81..02080fb3b 100644
--- a/docs/public/libs/v1/common/index.cjs
+++ b/docs/public/libs/v1/common/index.cjs
@@ -62,6 +62,8 @@ var kindClass = require('./kindClass.cjs');
var promiseAll = require('./promiseAll.cjs');
var detachObjectMethod = require('./detachObjectMethod.cjs');
var bindPrototypeMethods = require('./bindPrototypeMethods.cjs');
+var preparePipe = require('./preparePipe.cjs');
+var prepareAsyncPipe = require('./prepareAsyncPipe.cjs');
/**
* {@include common/index.md}
@@ -154,3 +156,5 @@ exports.kindClass = kindClass.kindClass;
exports.promiseAll = promiseAll.promiseAll;
exports.detachObjectMethod = detachObjectMethod.detachObjectMethod;
exports.bindPrototypeMethods = bindPrototypeMethods.bindPrototypeMethods;
+exports.preparePipe = preparePipe.preparePipe;
+exports.prepareAsyncPipe = prepareAsyncPipe.prepareAsyncPipe;
diff --git a/docs/public/libs/v1/common/index.d.ts b/docs/public/libs/v1/common/index.d.ts
index c483a2e03..ac15d986a 100644
--- a/docs/public/libs/v1/common/index.d.ts
+++ b/docs/public/libs/v1/common/index.d.ts
@@ -86,3 +86,5 @@ export * from "./kindClass";
export * from "./promiseAll";
export * from "./detachObjectMethod";
export * from "./bindPrototypeMethods";
+export * from "./preparePipe";
+export * from "./prepareAsyncPipe";
diff --git a/docs/public/libs/v1/common/index.mjs b/docs/public/libs/v1/common/index.mjs
index f8f7f133f..917af8810 100644
--- a/docs/public/libs/v1/common/index.mjs
+++ b/docs/public/libs/v1/common/index.mjs
@@ -60,6 +60,8 @@ export { kindClass } from './kindClass.mjs';
export { promiseAll } from './promiseAll.mjs';
export { detachObjectMethod } from './detachObjectMethod.mjs';
export { bindPrototypeMethods } from './bindPrototypeMethods.mjs';
+export { preparePipe } from './preparePipe.mjs';
+export { prepareAsyncPipe } from './prepareAsyncPipe.mjs';
/**
* {@include common/index.md}
diff --git a/docs/public/libs/v1/common/prepareAsyncPipe.cjs b/docs/public/libs/v1/common/prepareAsyncPipe.cjs
new file mode 100644
index 000000000..fcdecbd71
--- /dev/null
+++ b/docs/public/libs/v1/common/prepareAsyncPipe.cjs
@@ -0,0 +1,14 @@
+'use strict';
+
+/** {@include common/prepareAsyncPipe/index.md} */
+function prepareAsyncPipe() {
+ return (...pipes) => async (input) => {
+ let acc = await input;
+ for (const pipe of pipes) {
+ acc = await pipe(acc);
+ }
+ return acc;
+ };
+}
+
+exports.prepareAsyncPipe = prepareAsyncPipe;
diff --git a/docs/public/libs/v1/common/prepareAsyncPipe.d.ts b/docs/public/libs/v1/common/prepareAsyncPipe.d.ts
new file mode 100644
index 000000000..f15c9fe6d
--- /dev/null
+++ b/docs/public/libs/v1/common/prepareAsyncPipe.d.ts
@@ -0,0 +1,60 @@
+import { type BreakGenericLink, type MaybePromise } from "./types";
+export interface PrepareAsyncPipe {
+ (pipe1: (input: BreakGenericLink) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise, pipe5: (input: GenericOutputPipe4) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise, pipe5: (input: GenericOutputPipe4) => MaybePromise, pipe6: (input: GenericOutputPipe5) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise, pipe5: (input: GenericOutputPipe4) => MaybePromise, pipe6: (input: GenericOutputPipe5) => MaybePromise, pipe7: (input: GenericOutputPipe6) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise, pipe5: (input: GenericOutputPipe4) => MaybePromise, pipe6: (input: GenericOutputPipe5) => MaybePromise, pipe7: (input: GenericOutputPipe6) => MaybePromise, pipe8: (input: GenericOutputPipe7) => MaybePromise): (input: MaybePromise) => Promise;
+ (pipe1: (input: BreakGenericLink) => MaybePromise, pipe2: (input: GenericOutputPipe1) => MaybePromise, pipe3: (input: GenericOutputPipe2) => MaybePromise, pipe4: (input: GenericOutputPipe3) => MaybePromise, pipe5: (input: GenericOutputPipe4) => MaybePromise, pipe6: (input: GenericOutputPipe5) => MaybePromise