Skip to content

Commit 375778a

Browse files
committed
feat(46): add jsDoc namespace pattern
1 parent e4c23ea commit 375778a

File tree

33 files changed

+647
-1
lines changed

33 files changed

+647
-1
lines changed

docs/public/libs/v1/pattern/exhaustive.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
var unwrap = require('../common/unwrap.cjs');
44

5+
/**
6+
* {@include pattern/exhaustive/index.md}
7+
*/
58
function exhaustive(result) {
69
return unwrap.unwrap(result);
710
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,54 @@
11
import { type Unwrap } from "../common";
22
import { type PatternResult } from "./result";
3+
/**
4+
* Unwraps a pattern result when all cases are handled.
5+
*
6+
* Signature: `exhaustive(result)` → returns the unwrapped value
7+
*
8+
* Use this to signal that all patterns have been handled.
9+
*
10+
* ```ts
11+
* const input = <{
12+
* kind: "circle";
13+
* radius: number;
14+
* } | {
15+
* kind: "square";
16+
* size: number;
17+
* }>{
18+
* kind: "circle",
19+
* radius: 2,
20+
* };
21+
*
22+
* P.match(input)
23+
* .with(
24+
* { kind: "circle" },
25+
* (shape) => shape.radius * 2,
26+
* )
27+
* .with(
28+
* { kind: "square" },
29+
* (shape) => shape.size * 2,
30+
*
31+
* )
32+
* .exhaustive(); // 4
33+
*
34+
* pipe(
35+
* input,
36+
* P.match(
37+
* { kind: "circle" },
38+
* (shape) => shape.radius * 2,
39+
* ),
40+
* P.match(
41+
* { kind: "square" },
42+
* (shape) => shape.size * 2,
43+
* ),
44+
* P.exhaustive,
45+
* ); // 4
46+
* ```
47+
*
48+
* @see [`P.match`](https://utils.duplojs.dev/en/v1/api/pattern/match) For building match chains
49+
* @see https://utils.duplojs.dev/en/v1/api/pattern/exhaustive
50+
*
51+
* @namespace P
52+
*
53+
*/
354
export declare function exhaustive<const GenericValue extends unknown, GenericResult extends PatternResult<GenericValue>>(result: GenericResult): Unwrap<GenericResult>;

docs/public/libs/v1/pattern/exhaustive.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { unwrap } from '../common/unwrap.mjs';
22

3+
/**
4+
* {@include pattern/exhaustive/index.md}
5+
*/
36
function exhaustive(result) {
47
return unwrap(result);
58
}

docs/public/libs/v1/pattern/index.cjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ var when = require('./when.cjs');
1010
var builder = require('./match/builder.cjs');
1111
var pattern = require('./types/pattern.cjs');
1212

13-
13+
/**
14+
* {@include pattern/index.md}
15+
*/
1416

1517
exports.isResult = result.isResult;
1618
exports.result = result.result;

docs/public/libs/v1/pattern/index.d.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/**
2+
* Pattern matching utilities for building typed match pipelines. Functions preserve
3+
* inputs and return new values.
4+
*
5+
* **How to import:**
6+
* - From the main entry (namespace style)
7+
* - Via direct import for tree-shaking
8+
*
9+
* ```ts
10+
* import { DPattern, P } from "@duplojs/utils";
11+
* import * as DPattern from "@duplojs/utils/pattern";
12+
* import * as P from "@duplojs/utils/pattern";
13+
* ```
14+
*
15+
* What you will find in this namespace:
16+
* - matching flow (`P.match`, `P.when`, `P.otherwise`, `P.exhaustive`)
17+
* - predicates and patterns (`P.isMatch`, `P.union`)
18+
*
19+
* @see https://utils.duplojs.dev/en/v1/api/pattern
20+
* @see https://utils.duplojs.dev/fr/v1/api/pattern
21+
*
22+
* @namespace P
23+
*
24+
*/
125
export * from "./result";
226
export * from "./exhaustive";
327
export * from "./otherwise";

docs/public/libs/v1/pattern/index.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ export { union } from './union.mjs';
77
export { when } from './when.mjs';
88
export { InvalidExhaustivePatternError, matchBuilder } from './match/builder.mjs';
99
export { SymbolToolPatternFunctionLabel } from './types/pattern.mjs';
10+
11+
/**
12+
* {@include pattern/index.md}
13+
*/
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
import { type ForcePredicate, type AnyValue, type FixDeepFunctionInfer } from "../common";
22
import { type Pattern, type PatternValue } from "./types/pattern";
33
import { type ComplexMatchedValue } from "./types";
4+
/**
5+
* Checks whether a value matches a pattern.
6+
*
7+
* **Supported call styles:**
8+
* - Classic: `isMatch(input, pattern)` → returns a boolean
9+
* - Curried: `isMatch(pattern)` → returns a function waiting for the input
10+
* - Classic predicate: `isMatch(input, pattern)` → narrows the input type
11+
* - Curried predicate: `isMatch(pattern)` → narrows the input type
12+
*
13+
* The input is not mutated.
14+
*
15+
* ```ts
16+
* const input = <{
17+
* kind: "text";
18+
* content: string;
19+
* } | {
20+
* kind: "image";
21+
* url: string;
22+
* }>{
23+
* kind: "text",
24+
* content: "hello",
25+
* };
26+
*
27+
* if (P.isMatch(input, { kind: "text" })) {
28+
* // { kind: "text", content: "hello" }
29+
* }
30+
* ```
31+
*
32+
* @remarks
33+
* - Predicate overloads (type guards) narrow the output type
34+
*
35+
* @see https://utils.duplojs.dev/en/v1/api/pattern/isMatch
36+
*
37+
* @namespace P
38+
*
39+
*/
440
export declare function isMatch<GenericInput extends AnyValue, const GenericPattern extends Pattern<GenericInput>>(pattern: FixDeepFunctionInfer<Pattern<GenericInput>, GenericPattern>): (input: GenericInput) => input is ForcePredicate<GenericInput, ComplexMatchedValue<GenericInput, PatternValue<GenericPattern>>>;
541
export declare function isMatch<GenericInput extends AnyValue, const GenericPattern extends Pattern<GenericInput>>(input: GenericInput, pattern: FixDeepFunctionInfer<Pattern<GenericInput>, GenericPattern>): input is ForcePredicate<GenericInput, ComplexMatchedValue<GenericInput, PatternValue<GenericPattern>>>;

docs/public/libs/v1/pattern/match/index.d.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,64 @@ import { type PatternResult } from "../result";
44
import { type ComplexMatchedValue, type ComplexUnMatchedValue } from "../types";
55
import { type MatchBuilder } from "./builder";
66
export * from "./builder";
7+
/**
8+
* Creates a match builder or applies a single pattern.
9+
*
10+
* **Supported call styles:**
11+
* - Classic: `match(input)` → returns a match builder
12+
* - Classic: `match(input, pattern, handler)` → returns a result or the input
13+
* - Curried: `match(pattern, handler)` → returns a function waiting for the input
14+
*
15+
* If the input matches the pattern, the handler runs and the result is wrapped for chaining.
16+
* The input is not mutated.
17+
*
18+
* ```ts
19+
* const input = <{
20+
* type: "text";
21+
* value: string;
22+
* } | {
23+
* type: "count";
24+
* value: number;
25+
* }>{
26+
* type: "text",
27+
* value: "hello",
28+
* };
29+
*
30+
* P.match(input)
31+
* .with(
32+
* { type: "text" },
33+
* (item) => item.value.toUpperCase(),
34+
* )
35+
* .with(
36+
* { type: "count" },
37+
* (item) => `${item.value}:${item.type}`,
38+
* )
39+
* .otherwise(() => "unknown"); // "HELLO"
40+
*
41+
* pipe(
42+
* input,
43+
* P.match(
44+
* { type: "count" },
45+
* (item) => item.value * 2,
46+
* ),
47+
* P.otherwise(() => 0),
48+
* ); // 4
49+
*
50+
* P.match(input)
51+
* .when(
52+
* (item) => typeof item === "number",
53+
* () => "ok",
54+
* )
55+
* .otherwise(() => "no"); // "ok"
56+
* ```
57+
*
58+
* @see [`P.when`](https://utils.duplojs.dev/en/v1/api/pattern/when) For predicate branches
59+
* @see [`P.otherwise`](https://utils.duplojs.dev/en/v1/api/pattern/otherwise) For fallbacks
60+
* @see https://utils.duplojs.dev/en/v1/api/pattern/match
61+
*
62+
* @namespace P
63+
*
64+
*/
765
export declare function match<GenericInput extends unknown>(input: GenericInput): MatchBuilder<IsEqual<GenericInput, unknown> extends true ? AnyValue : GenericInput>;
866
export declare function match<GenericInput extends unknown, GenericInputValue extends Exclude<IsEqual<GenericInput, unknown> extends true ? AnyValue : GenericInput, PatternResult>, GenericInputPatternResult extends Extract<GenericInput, PatternResult>, const GenericPattern extends Pattern<GenericInputValue>, GenericPatternValue extends PatternValue<GenericPattern>, GenericOutput extends AnyValue | EscapeVoid, GenericMatchedValue extends Extract<ComplexMatchedValue<GenericInputValue, GenericPatternValue>, any>>(pattern: FixDeepFunctionInfer<Pattern<GenericInputValue>, GenericPattern>, theFunction: (value: Extract<ComplexMatchedValue<GenericInputValue, PatternValue<GenericPattern>>, any>) => GenericOutput): (input: GenericInput | GenericInputValue | GenericInputPatternResult) => BreakGenericLink<((IsEqual<GenericMatchedValue, never> extends true ? never : PatternResult<GenericOutput>) | GenericInputPatternResult | Extract<ComplexUnMatchedValue<GenericInputValue, GenericPatternValue>, any>)>;
967
export declare function match<GenericInput extends unknown, GenericInputValue extends Exclude<IsEqual<GenericInput, unknown> extends true ? AnyValue : GenericInput, PatternResult>, GenericInputPatternResult extends Extract<GenericInput, PatternResult>, const GenericPattern extends Pattern<GenericInputValue>, GenericPatternValue extends PatternValue<GenericPattern>, GenericOutput extends AnyValue | EscapeVoid, GenericMatchedValue extends Extract<ComplexMatchedValue<GenericInputValue, GenericPatternValue>, any>>(input: GenericInput | GenericInputValue | GenericInputPatternResult, pattern: FixDeepFunctionInfer<Pattern<GenericInputValue>, GenericPattern>, theFunction: (value: Extract<ComplexMatchedValue<GenericInputValue, PatternValue<GenericPattern>>, any>) => GenericOutput): BreakGenericLink<(IsEqual<GenericMatchedValue, never> extends true ? never : PatternResult<GenericOutput>) | GenericInputPatternResult | Extract<ComplexUnMatchedValue<GenericInputValue, GenericPatternValue>, any>>;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,60 @@
11
import { type AnyValue, type Unwrap } from "../common";
22
import { type PatternResult } from "./result";
3+
/**
4+
* Applies a fallback handler when no prior pattern matched.
5+
*
6+
* **Supported call styles:**
7+
* - Classic: `otherwise(input, handler)` → returns the unwrapped result or fallback
8+
* - Curried: `otherwise(handler)` → returns a function waiting for the input
9+
*
10+
* If the input is already a pattern result, it is unwrapped and returned.
11+
* The input is not mutated.
12+
*
13+
* ```ts
14+
* const input = <{
15+
* type: "text";
16+
* value: string;
17+
* } | {
18+
* type: "count";
19+
* value: number;
20+
* }>{
21+
* type: "text",
22+
* value: "hello",
23+
* };
24+
*
25+
* P.match(input)
26+
* .with(
27+
* { type: "text" },
28+
* (item) => item.value.toUpperCase(),
29+
* )
30+
* .with(
31+
* { type: "count" },
32+
* (item) => `${item.value}:${item.type}`,
33+
* )
34+
* .otherwise(() => "unknown"); // "HELLO"
35+
*
36+
* pipe(
37+
* input,
38+
* P.match(
39+
* { type: "count" },
40+
* (item) => item.value * 2,
41+
* ),
42+
* P.otherwise(() => 0),
43+
* ); // 4
44+
*
45+
* P.match(input)
46+
* .when(
47+
* (item) => typeof item === "number",
48+
* () => "ok",
49+
* )
50+
* .otherwise(() => "no"); // "ok"
51+
* ```
52+
*
53+
* @see [`P.match`](https://utils.duplojs.dev/en/v1/api/pattern/match) For building match chains
54+
* @see https://utils.duplojs.dev/en/v1/api/pattern/otherwise
55+
*
56+
* @namespace P
57+
*
58+
*/
359
export declare function otherwise<GenericInput extends AnyValue, GenericInputValue extends Exclude<GenericInput, PatternResult>, GenericInputPatternResult extends Extract<GenericInput, PatternResult>, GenericOutput extends AnyValue>(theFunction: (rest: GenericInputValue) => GenericOutput): (input: GenericInput | GenericInputPatternResult | GenericInputValue) => (GenericOutput | Unwrap<GenericInputPatternResult>);
460
export declare function otherwise<GenericInput extends AnyValue, GenericInputValue extends Exclude<GenericInput, PatternResult>, GenericInputPatternResult extends Extract<GenericInput, PatternResult>, GenericOutput extends AnyValue>(input: GenericInput | GenericInputPatternResult | GenericInputValue, theFunction: (rest: GenericInputValue) => GenericOutput): (GenericOutput | Unwrap<GenericInputPatternResult>);

docs/public/libs/v1/pattern/union.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ var isMatch = require('./isMatch.cjs');
44
var pattern = require('./types/pattern.cjs');
55

66
const SymbolToolPatternFunction = Symbol.for(pattern.SymbolToolPatternFunctionLabel);
7+
/**
8+
* {@include pattern/union/index.md}
9+
*/
710
function union(...patterns) {
811
return {
912
[SymbolToolPatternFunction]: (input) => {

0 commit comments

Comments
 (0)