@nlozgachev/pipelined 0.43.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/utils.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { N as NonEmptyArr } from './InternalTypes-DsCqxWZm.mjs';
2
- import { M as Maybe, R as Result, E as Equality, b as Ordering, T as Task } from './Validation-Do6uWLLZ.mjs';
3
- import './types.mjs';
1
+ import { a as NonEmptyArr, N as NonEmpty } from './InternalTypes-CLE7qlOc.mjs';
2
+ import { M as Maybe, R as Result, E as Equality, b as Ordering, T as Task } from './Validation-v38R0qH-.mjs';
3
+ import { Brand } from './types.mjs';
4
4
 
5
5
  declare namespace ArrMaybe {
6
6
  /**
@@ -11,7 +11,7 @@ declare namespace ArrMaybe {
11
11
  * ```ts
12
12
  * const parseNum = (s: string): Maybe<number> => {
13
13
  * const n = Number(s);
14
- * return isNaN(n) ? Maybe.none() : Maybe.some(n);
14
+ * return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
15
15
  * };
16
16
  *
17
17
  * pipe(["1", "2", "3"], Arr.Maybe.traverse(parseNum)); // Some([1, 2, 3])
@@ -25,8 +25,8 @@ declare namespace ArrMaybe {
25
25
  *
26
26
  * @example
27
27
  * ```ts
28
- * Arr.Maybe.sequence([Maybe.some(1), Maybe.some(2)]); // Some([1, 2])
29
- * Arr.Maybe.sequence([Maybe.some(1), Maybe.none()]); // None
28
+ * Arr.Maybe.sequence([Maybe.make.some(1), Maybe.make.some(2)]); // Some([1, 2])
29
+ * Arr.Maybe.sequence([Maybe.make.some(1), Maybe.make.none()]); // None
30
30
  * ```
31
31
  */
32
32
  const sequence: <A>(data: readonly Maybe<A>[]) => Maybe<readonly A[]>;
@@ -40,7 +40,7 @@ declare namespace ArrResult {
40
40
  * ```ts
41
41
  * pipe(
42
42
  * [1, 2, 3],
43
- * Arr.Result.traverse(n => n > 0 ? Result.ok(n) : Result.err("negative"))
43
+ * Arr.Result.traverse(n => n > 0 ? Result.make.ok(n) : Result.make.err("negative"))
44
44
  * ); // Ok([1, 2, 3])
45
45
  * ```
46
46
  */
@@ -53,7 +53,7 @@ declare namespace ArrResult {
53
53
  }
54
54
  declare namespace ArrTaskResult {
55
55
  /**
56
- * Maps each element to a TaskResult and runs them sequentially.
56
+ * Maps each element to a Task.Result and runs them sequentially.
57
57
  * Returns the first Err encountered, or Ok of all results if all succeed.
58
58
  *
59
59
  * @example
@@ -74,7 +74,7 @@ declare namespace ArrTaskResult {
74
74
  */
75
75
  const traverse: <E, A, B>(f: (a: A) => Task<Result<E, B>>) => (data: readonly A[]) => Task<Result<E, readonly B[]>>;
76
76
  /**
77
- * Collects an array of TaskResults into a TaskResult of array.
77
+ * Collects an array of Task.Results into a Task.Result of array.
78
78
  * Returns the first Err if any element is Err, runs sequentially.
79
79
  */
80
80
  const sequence: <E, A>(data: readonly Task<Result<E, A>>[]) => Task<Result<E, readonly A[]>>;
@@ -108,16 +108,18 @@ declare namespace ArrNonEmpty {
108
108
  * ```
109
109
  */
110
110
  const singleton: <A>(value: A) => NonEmptyArr<A>;
111
- /**
112
- * Returns Some if the array is non-empty, None otherwise.
113
- *
114
- * @example
115
- * ```ts
116
- * Arr.NonEmpty.fromArray([1, 2]); // Some([1, 2])
117
- * Arr.NonEmpty.fromArray([]); // None
118
- * ```
119
- */
120
- const fromArray: <A>(data: readonly A[]) => Maybe<NonEmptyArr<A>>;
111
+ namespace from {
112
+ /**
113
+ * Returns Some if the array is non-empty, None otherwise.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * Arr.NonEmpty.from.Array([1, 2]); // Some([1, 2])
118
+ * Arr.NonEmpty.from.Array([]); // None
119
+ * ```
120
+ */
121
+ const Array: <A>(data: readonly A[]) => Maybe<NonEmptyArr<A>>;
122
+ }
121
123
  /**
122
124
  * Returns the first element of a NonEmptyArr.
123
125
  *
@@ -154,6 +156,51 @@ declare namespace ArrNonEmpty {
154
156
  * ```
155
157
  */
156
158
  const reduce: <A>(f: (acc: A, a: A) => A) => (data: NonEmptyArr<A>) => A;
159
+ /**
160
+ * Transforms each element of a NonEmptyArr.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * pipe(Arr.NonEmpty.singleton(1), Arr.NonEmpty.map(n => n * 2)); // [2]
165
+ * ```
166
+ */
167
+ const map: <A, B>(f: (a: A) => B) => (data: NonEmptyArr<A>) => NonEmptyArr<B>;
168
+ /**
169
+ * Transforms each element of a NonEmptyArr, also receiving the index.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * pipe(Arr.NonEmpty.singleton("a"), Arr.NonEmpty.mapWithIndex((i, s) => `${i}:${s}`)); // ["0:a"]
174
+ * ```
175
+ */
176
+ const mapWithIndex: <A, B>(f: (i: number, a: A) => B) => (data: NonEmptyArr<A>) => NonEmptyArr<B>;
177
+ /**
178
+ * Inserts a separator between every element of a NonEmptyArr.
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * pipe([1, 2] as Arr.NonEmpty<number>, Arr.NonEmpty.intersperse(0)); // [1, 0, 2]
183
+ * ```
184
+ */
185
+ const intersperse: <A>(sep: A) => (data: NonEmptyArr<A>) => NonEmptyArr<A>;
186
+ /**
187
+ * Concatenates a NonEmptyArr with a standard array.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * pipe(Arr.NonEmpty.singleton(1), Arr.NonEmpty.concat([2, 3])); // [1, 2, 3]
192
+ * ```
193
+ */
194
+ const concat: <A>(other: readonly A[]) => (data: NonEmptyArr<A>) => NonEmptyArr<A>;
195
+ /**
196
+ * Reverses a NonEmptyArr.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * pipe(Arr.NonEmpty.singleton(1), Arr.NonEmpty.reverse); // [1]
201
+ * ```
202
+ */
203
+ const reverse: <A>(data: NonEmptyArr<A>) => NonEmptyArr<A>;
157
204
  }
158
205
  /**
159
206
  * Functional array utilities that compose well with pipe.
@@ -256,10 +303,7 @@ declare namespace Arr {
256
303
  * pipe([1, 2, 3], Arr.map(n => n * 2)); // [2, 4, 6]
257
304
  * ```
258
305
  */
259
- const map: <A, B>(f: (a: A) => B) => {
260
- (data: NonEmpty<A>): NonEmpty<B>;
261
- (data: readonly A[]): readonly B[];
262
- };
306
+ const map: <A, B>(f: (a: A) => B) => (data: readonly A[]) => readonly B[];
263
307
  /**
264
308
  * Transforms each element using both its value and its zero-based index.
265
309
  *
@@ -271,10 +315,7 @@ declare namespace Arr {
271
315
  * ); // [{ position: 1, value: "a" }, { position: 2, value: "b" }, { position: 3, value: "c" }]
272
316
  * ```
273
317
  */
274
- const mapWithIndex: <A, B>(f: (i: number, a: A) => B) => {
275
- (data: NonEmpty<A>): NonEmpty<B>;
276
- (data: readonly A[]): readonly B[];
277
- };
318
+ const mapWithIndex: <A, B>(f: (i: number, a: A) => B) => (data: readonly A[]) => readonly B[];
278
319
  /**
279
320
  * Filters elements that satisfy the predicate.
280
321
  *
@@ -292,7 +333,7 @@ declare namespace Arr {
292
333
  * ```ts
293
334
  * const parseNum = (s: string): Maybe<number> => {
294
335
  * const n = Number(s);
295
- * return isNaN(n) ? Maybe.none() : Maybe.some(n);
336
+ * return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
296
337
  * };
297
338
  *
298
339
  * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
@@ -316,7 +357,7 @@ declare namespace Arr {
316
357
  *
317
358
  * @example
318
359
  * ```ts
319
- * Arr.compact([Maybe.some(1), Maybe.none(), Maybe.some(3)]); // [1, 3]
360
+ * Arr.compact([Maybe.make.some(1), Maybe.make.none(), Maybe.make.some(3)]); // [1, 3]
320
361
  * ```
321
362
  */
322
363
  const compact: <A>(data: readonly Maybe<A>[]) => readonly A[];
@@ -326,7 +367,7 @@ declare namespace Arr {
326
367
  *
327
368
  * @example
328
369
  * ```ts
329
- * Arr.separate([Result.ok(1), Result.err("bad"), Result.ok(3)]); // [["bad"], [1, 3]]
370
+ * Arr.separate([Result.make.ok(1), Result.make.err("bad"), Result.make.ok(3)]); // [["bad"], [1, 3]]
330
371
  * ```
331
372
  */
332
373
  const separate: <E, A>(data: readonly Result<E, A>[]) => readonly [readonly E[], readonly A[]];
@@ -337,7 +378,7 @@ declare namespace Arr {
337
378
  * ```ts
338
379
  * pipe(
339
380
  * [1, 2, 3, 4],
340
- * Arr.partitionMap(n => n % 2 === 0 ? Result.ok(n) : Result.err(`odd: ${n}`))
381
+ * Arr.partitionMap(n => n % 2 === 0 ? Result.make.ok(n) : Result.make.err(`odd: ${n}`))
341
382
  * ); // [["odd: 1", "odd: 3"], [2, 4]]
342
383
  * ```
343
384
  */
@@ -441,23 +482,16 @@ declare namespace Arr {
441
482
  * pipe([1, 2, 3], Arr.intersperse(0)); // [1, 0, 2, 0, 3]
442
483
  * ```
443
484
  */
444
- const intersperse: <A>(sep: A) => {
445
- (data: NonEmpty<A>): NonEmpty<A>;
446
- (data: readonly A[]): readonly A[];
447
- };
485
+ const intersperse: <A>(sep: A) => (data: readonly A[]) => readonly A[];
448
486
  /**
449
- * Concatenates a standard array or NonEmptyArr with another array.
450
- * If the first array is a NonEmptyArr, the result is guaranteed to be a NonEmptyArr.
487
+ * Concatenates a standard array with another array.
451
488
  *
452
489
  * @example
453
490
  * ```ts
454
491
  * pipe([1, 2], Arr.concat([3, 4])); // [1, 2, 3, 4]
455
492
  * ```
456
493
  */
457
- const concat: <A>(other: readonly A[]) => {
458
- (data: NonEmpty<A>): NonEmpty<A>;
459
- (data: readonly A[]): readonly A[];
460
- };
494
+ const concat: <A>(other: readonly A[]) => (data: readonly A[]) => readonly A[];
461
495
  /**
462
496
  * Splits an array into chunks of the given size.
463
497
  *
@@ -497,10 +531,16 @@ declare namespace Arr {
497
531
  const Maybe: typeof ArrMaybe;
498
532
  const Result: typeof ArrResult;
499
533
  const Task: typeof ArrTask;
500
- /**
501
- * Returns true if the array is non-empty (type guard).
502
- */
503
- const isNonEmpty: <A>(data: readonly A[]) => data is NonEmpty<A>;
534
+ namespace is {
535
+ /**
536
+ * Returns true if the array is empty.
537
+ */
538
+ const empty: <A>(data: readonly A[]) => data is readonly [];
539
+ /**
540
+ * Returns true if the array is non-empty (type guard).
541
+ */
542
+ const nonEmpty: <A>(data: readonly A[]) => data is NonEmpty<A>;
543
+ }
504
544
  /**
505
545
  * Prepends a value to the beginning of an array, returning a NonEmptyArr.
506
546
  *
@@ -549,10 +589,7 @@ declare namespace Arr {
549
589
  * Arr.reverse([1, 2, 3]); // [3, 2, 1]
550
590
  * ```
551
591
  */
552
- const reverse: {
553
- <A>(data: NonEmpty<A>): NonEmpty<A>;
554
- <A>(data: readonly A[]): readonly A[];
555
- };
592
+ const reverse: <A>(data: readonly A[]) => readonly A[];
556
593
  /**
557
594
  * Returns a new array with `item` inserted before the element at `index`.
558
595
  * Negative indices are clamped to 0; indices beyond the array length append to the end.
@@ -638,6 +675,10 @@ declare namespace Arr {
638
675
  const NonEmpty: typeof ArrNonEmpty;
639
676
  }
640
677
 
678
+ /**
679
+ * A branded type representing a key-value dictionary with at least one entry.
680
+ */
681
+ type NonEmptyMap<K, V> = Brand<NonEmpty<"Dict">, ReadonlyMap<K, V>>;
641
682
  /**
642
683
  * Functional utilities for key-value dictionaries (`ReadonlyMap<K, V>`). All functions are pure
643
684
  * and data-last — they compose naturally with `pipe`.
@@ -651,50 +692,150 @@ declare namespace Arr {
651
692
  * import { pipe } from "@nlozgachev/pipelined/composition";
652
693
  *
653
694
  * const scores = pipe(
654
- * Dict.fromEntries([["alice", 10], ["bob", 8], ["carol", 10]] as const),
695
+ * Dict.from.entries([["alice", 10], ["bob", 8], ["carol", 10]] as const),
655
696
  * Dict.filter(n => n >= 10),
656
697
  * Dict.map(n => `${n} points`),
657
698
  * );
658
699
  * // ReadonlyMap { "alice" => "10 points", "carol" => "10 points" }
659
700
  * ```
660
701
  */
661
- declare namespace Dict {
702
+ declare namespace DictNonEmpty {
662
703
  /**
663
- * Creates an empty dictionary.
704
+ * Creates a NonEmptyMap containing a single key-value entry.
664
705
  *
665
706
  * @example
666
707
  * ```ts
667
- * Dict.empty<string, number>(); // ReadonlyMap {}
708
+ * Dict.NonEmpty.singleton("name", "Alice"); // ReadonlyMap { "name" => "Alice" }
668
709
  * ```
669
710
  */
670
- const empty: <K, V>() => ReadonlyMap<K, V>;
711
+ const singleton: <K, V>(key: K, value: V) => NonEmptyMap<K, V>;
712
+ namespace from {
713
+ /**
714
+ * Returns Some containing NonEmptyMap if the map is not empty, None otherwise.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * Dict.NonEmpty.from.Map(Dict.from.entries([["a", 1]])); // Some(ReadonlyMap { "a" => 1 })
719
+ * Dict.NonEmpty.from.Map(Dict.empty()); // None
720
+ * ```
721
+ */
722
+ const Map: <K, V>(m: ReadonlyMap<K, V>) => Maybe<NonEmptyMap<K, V>>;
723
+ }
671
724
  /**
672
- * Creates a dictionary with a single entry.
725
+ * Returns a non-empty array of keys, in insertion order.
673
726
  *
674
727
  * @example
675
728
  * ```ts
676
- * Dict.singleton("name", "Alice"); // ReadonlyMap { "name" => "Alice" }
729
+ * Dict.NonEmpty.keys(Dict.NonEmpty.singleton("a", 1)); // ["a"]
677
730
  * ```
678
731
  */
679
- const singleton: <K, V>(key: K, value: V) => ReadonlyMap<K, V>;
732
+ const keys: <K, V>(m: NonEmptyMap<K, V>) => NonEmptyArr<K>;
733
+ /**
734
+ * Returns a non-empty array of values, in insertion order.
735
+ *
736
+ * @example
737
+ * ```ts
738
+ * Dict.NonEmpty.values(Dict.NonEmpty.singleton("a", 1)); // [1]
739
+ * ```
740
+ */
741
+ const values: <K, V>(m: NonEmptyMap<K, V>) => NonEmptyArr<V>;
742
+ /**
743
+ * Returns a non-empty array of entry tuples, in insertion order.
744
+ *
745
+ * @example
746
+ * ```ts
747
+ * Dict.NonEmpty.entries(Dict.NonEmpty.singleton("a", 1)); // [["a", 1]]
748
+ * ```
749
+ */
750
+ const entries: <K, V>(m: NonEmptyMap<K, V>) => NonEmptyArr<readonly [K, V]>;
751
+ /**
752
+ * Reduces a NonEmptyMap's values from the left without an initial seed value.
753
+ *
754
+ * @example
755
+ * ```ts
756
+ * pipe(Dict.NonEmpty.singleton("a", 1), Dict.NonEmpty.reduce((a, b) => a + b)); // 1
757
+ * ```
758
+ */
759
+ const reduce: <V>(f: (acc: V, value: V) => V) => <K>(m: NonEmptyMap<K, V>) => V;
760
+ /**
761
+ * Transforms each value in the non-empty dictionary.
762
+ *
763
+ * @example
764
+ * ```ts
765
+ * pipe(Dict.NonEmpty.singleton("a", 1), Dict.NonEmpty.map(n => n * 2));
766
+ * // ReadonlyMap { "a" => 2 }
767
+ * ```
768
+ */
769
+ const map: <A, B>(f: (a: A) => B) => <K>(m: NonEmptyMap<K, A>) => NonEmptyMap<K, B>;
770
+ /**
771
+ * Transforms each value in the non-empty dictionary, also receiving the key.
772
+ *
773
+ * @example
774
+ * ```ts
775
+ * pipe(Dict.NonEmpty.singleton("a", 1), Dict.NonEmpty.mapWithKey((k, v) => `${k}:${v}`));
776
+ * // ReadonlyMap { "a" => "a:1" }
777
+ * ```
778
+ */
779
+ const mapWithKey: <K, A, B>(f: (key: K, a: A) => B) => (m: NonEmptyMap<K, A>) => NonEmptyMap<K, B>;
780
+ }
781
+ declare namespace Dict {
782
+ /**
783
+ * A branded type representing a key-value dictionary with at least one entry.
784
+ */
785
+ type NonEmpty<K, V> = NonEmptyMap<K, V>;
786
+ namespace is {
787
+ /**
788
+ * Returns `true` if the dictionary has no entries.
789
+ *
790
+ * @example
791
+ * ```ts
792
+ * Dict.is.empty(Dict.empty()); // true
793
+ * ```
794
+ */
795
+ const empty: <K, V>(m: ReadonlyMap<K, V>) => boolean;
796
+ /**
797
+ * Type guard to check if a dictionary is non-empty.
798
+ */
799
+ const nonEmpty: <K, V>(m: ReadonlyMap<K, V>) => m is NonEmpty<K, V>;
800
+ }
680
801
  /**
681
- * Creates a dictionary from an array of key-value pairs.
802
+ * Creates an empty dictionary.
682
803
  *
683
804
  * @example
684
805
  * ```ts
685
- * Dict.fromEntries([["a", 1], ["b", 2]]); // ReadonlyMap { "a" => 1, "b" => 2 }
806
+ * Dict.empty<string, number>(); // ReadonlyMap {}
686
807
  * ```
687
808
  */
688
- const fromEntries: <K, V>(entries: readonly (readonly [K, V])[]) => ReadonlyMap<K, V>;
809
+ const empty: <K, V>() => ReadonlyMap<K, V>;
689
810
  /**
690
- * Creates a dictionary from a plain object. Keys are always strings.
811
+ * Creates a dictionary with a single entry.
691
812
  *
692
813
  * @example
693
814
  * ```ts
694
- * Dict.fromRecord({ a: 1, b: 2 }); // ReadonlyMap { "a" => 1, "b" => 2 }
815
+ * Dict.singleton("name", "Alice"); // ReadonlyMap { "name" => "Alice" }
695
816
  * ```
696
817
  */
697
- const fromRecord: <V>(rec: Readonly<Record<string, V>>) => ReadonlyMap<string, V>;
818
+ const singleton: <K, V>(key: K, value: V) => ReadonlyMap<K, V>;
819
+ namespace from {
820
+ /**
821
+ * Creates a dictionary from an array of key-value pairs.
822
+ *
823
+ * @example
824
+ * ```ts
825
+ * Dict.from.entries([["a", 1], ["b", 2]]); // ReadonlyMap { "a" => 1, "b" => 2 }
826
+ * ```
827
+ */
828
+ const entries: <K, V>(entries: readonly (readonly [K, V])[]) => ReadonlyMap<K, V>;
829
+ /**
830
+ * Creates a dictionary from a plain object. Keys are always strings.
831
+ *
832
+ * @example
833
+ * ```ts
834
+ * Dict.from.Record({ a: 1, b: 2 }); // ReadonlyMap { "a" => 1, "b" => 2 }
835
+ * ```
836
+ */
837
+ const Record: <V>(rec: Readonly<Record<string, V>>) => ReadonlyMap<string, V>;
838
+ }
698
839
  /**
699
840
  * Groups elements of an array into a dictionary keyed by the result of `keyFn`. Each key maps
700
841
  * to the array of elements that produced it, in insertion order. Uses the native `Map.groupBy`
@@ -715,8 +856,8 @@ declare namespace Dict {
715
856
  *
716
857
  * @example
717
858
  * ```ts
718
- * pipe(Dict.fromEntries([["a", 1]]), Dict.has("a")); // true
719
- * pipe(Dict.fromEntries([["a", 1]]), Dict.has("b")); // false
859
+ * pipe(Dict.from.Entries([["a", 1]]), Dict.has("a")); // true
860
+ * pipe(Dict.from.Entries([["a", 1]]), Dict.has("b")); // false
720
861
  * ```
721
862
  */
722
863
  const has: <K>(key: K) => <V>(m: ReadonlyMap<K, V>) => boolean;
@@ -725,8 +866,8 @@ declare namespace Dict {
725
866
  *
726
867
  * @example
727
868
  * ```ts
728
- * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("a")); // Some(1)
729
- * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("b")); // None
869
+ * pipe(Dict.from.Entries([["a", 1]]), Dict.lookup("a")); // Some(1)
870
+ * pipe(Dict.from.Entries([["a", 1]]), Dict.lookup("b")); // None
730
871
  * ```
731
872
  */
732
873
  const lookup: <K>(key: K) => <V>(m: ReadonlyMap<K, V>) => Maybe<V>;
@@ -735,25 +876,16 @@ declare namespace Dict {
735
876
  *
736
877
  * @example
737
878
  * ```ts
738
- * Dict.size(Dict.fromEntries([["a", 1], ["b", 2]])); // 2
879
+ * Dict.size(Dict.from.Entries([["a", 1], ["b", 2]])); // 2
739
880
  * ```
740
881
  */
741
882
  const size: <K, V>(m: ReadonlyMap<K, V>) => number;
742
- /**
743
- * Returns `true` if the dictionary has no entries.
744
- *
745
- * @example
746
- * ```ts
747
- * Dict.isEmpty(Dict.empty()); // true
748
- * ```
749
- */
750
- const isEmpty: <K, V>(m: ReadonlyMap<K, V>) => boolean;
751
883
  /**
752
884
  * Returns all keys as a readonly array, in insertion order.
753
885
  *
754
886
  * @example
755
887
  * ```ts
756
- * Dict.keys(Dict.fromEntries([["a", 1], ["b", 2]])); // ["a", "b"]
888
+ * Dict.keys(Dict.from.Entries([["a", 1], ["b", 2]])); // ["a", "b"]
757
889
  * ```
758
890
  */
759
891
  const keys: <K, V>(m: ReadonlyMap<K, V>) => readonly K[];
@@ -762,7 +894,7 @@ declare namespace Dict {
762
894
  *
763
895
  * @example
764
896
  * ```ts
765
- * Dict.values(Dict.fromEntries([["a", 1], ["b", 2]])); // [1, 2]
897
+ * Dict.values(Dict.from.Entries([["a", 1], ["b", 2]])); // [1, 2]
766
898
  * ```
767
899
  */
768
900
  const values: <K, V>(m: ReadonlyMap<K, V>) => readonly V[];
@@ -771,7 +903,7 @@ declare namespace Dict {
771
903
  *
772
904
  * @example
773
905
  * ```ts
774
- * Dict.entries(Dict.fromEntries([["a", 1], ["b", 2]])); // [["a", 1], ["b", 2]]
906
+ * Dict.entries(Dict.from.Entries([["a", 1], ["b", 2]])); // [["a", 1], ["b", 2]]
775
907
  * ```
776
908
  */
777
909
  const entries: <K, V>(m: ReadonlyMap<K, V>) => readonly (readonly [K, V])[];
@@ -781,7 +913,7 @@ declare namespace Dict {
781
913
  *
782
914
  * @example
783
915
  * ```ts
784
- * pipe(Dict.fromEntries([["a", 1]]), Dict.insert("b", 2));
916
+ * pipe(Dict.from.Entries([["a", 1]]), Dict.insert("b", 2));
785
917
  * // ReadonlyMap { "a" => 1, "b" => 2 }
786
918
  * ```
787
919
  */
@@ -792,7 +924,7 @@ declare namespace Dict {
792
924
  *
793
925
  * @example
794
926
  * ```ts
795
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.remove("a"));
927
+ * pipe(Dict.from.Entries([["a", 1], ["b", 2]]), Dict.remove("a"));
796
928
  * // ReadonlyMap { "b" => 2 }
797
929
  * ```
798
930
  */
@@ -808,8 +940,8 @@ declare namespace Dict {
808
940
  * import { Maybe } from "@nlozgachev/pipelined/core";
809
941
  *
810
942
  * const increment = (opt: Maybe<number>) => Maybe.getOrElse(() => 0)(opt) + 1;
811
- * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("views", increment)); // { views: 6 }
812
- * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("likes", increment)); // { views: 5, likes: 1 }
943
+ * pipe(Dict.from.Entries([["views", 5]]), Dict.upsert("views", increment)); // { views: 6 }
944
+ * pipe(Dict.from.Entries([["views", 5]]), Dict.upsert("likes", increment)); // { views: 5, likes: 1 }
813
945
  * ```
814
946
  */
815
947
  const upsert: <K, V>(key: K, f: (existing: Maybe<V>) => V) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
@@ -818,7 +950,7 @@ declare namespace Dict {
818
950
  *
819
951
  * @example
820
952
  * ```ts
821
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.map(n => n * 2));
953
+ * pipe(Dict.from.Entries([["a", 1], ["b", 2]]), Dict.map(n => n * 2));
822
954
  * // ReadonlyMap { "a" => 2, "b" => 4 }
823
955
  * ```
824
956
  */
@@ -828,7 +960,7 @@ declare namespace Dict {
828
960
  *
829
961
  * @example
830
962
  * ```ts
831
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.mapWithKey((k, v) => `${k}:${v}`));
963
+ * pipe(Dict.from.Entries([["a", 1], ["b", 2]]), Dict.mapWithKey((k, v) => `${k}:${v}`));
832
964
  * // ReadonlyMap { "a" => "a:1", "b" => "b:2" }
833
965
  * ```
834
966
  */
@@ -838,7 +970,7 @@ declare namespace Dict {
838
970
  *
839
971
  * @example
840
972
  * ```ts
841
- * pipe(Dict.fromEntries([["a", 1], ["b", 3], ["c", 0]]), Dict.filter(n => n > 0));
973
+ * pipe(Dict.from.Entries([["a", 1], ["b", 3], ["c", 0]]), Dict.filter(n => n > 0));
842
974
  * // ReadonlyMap { "a" => 1, "b" => 3 }
843
975
  * ```
844
976
  */
@@ -849,7 +981,7 @@ declare namespace Dict {
849
981
  *
850
982
  * @example
851
983
  * ```ts
852
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.filterWithKey((k, v) => k !== "a" && v > 0));
984
+ * pipe(Dict.from.Entries([["a", 1], ["b", 2]]), Dict.filterWithKey((k, v) => k !== "a" && v > 0));
853
985
  * // ReadonlyMap { "b" => 2 }
854
986
  * ```
855
987
  */
@@ -862,10 +994,10 @@ declare namespace Dict {
862
994
  * ```ts
863
995
  * import { Maybe } from "@nlozgachev/pipelined/core";
864
996
  *
865
- * Dict.compact(Dict.fromEntries([
866
- * ["a", Maybe.some(1)],
867
- * ["b", Maybe.none()],
868
- * ["c", Maybe.some(3)],
997
+ * Dict.compact(Dict.from.Entries([
998
+ * ["a", Maybe.make.some(1)],
999
+ * ["b", Maybe.make.none()],
1000
+ * ["c", Maybe.make.some(3)],
869
1001
  * ]));
870
1002
  * // ReadonlyMap { "a" => 1, "c" => 3 }
871
1003
  * ```
@@ -879,9 +1011,9 @@ declare namespace Dict {
879
1011
  * ```ts
880
1012
  * const parse = (s: string): Maybe<number> => {
881
1013
  * const n = Number(s);
882
- * return isNaN(n) ? Maybe.none() : Maybe.some(n);
1014
+ * return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
883
1015
  * };
884
- * Dict.filterMap(parse)(Dict.fromRecord({ a: "1", b: "two", c: "3" }));
1016
+ * Dict.filterMap(parse)(Dict.from.Record({ a: "1", b: "two", c: "3" }));
885
1017
  * // ReadonlyMap { "a" => 1, "c" => 3 }
886
1018
  * ```
887
1019
  */
@@ -893,8 +1025,8 @@ declare namespace Dict {
893
1025
  * @example
894
1026
  * ```ts
895
1027
  * pipe(
896
- * Dict.fromEntries([["a", 1], ["b", 2]]),
897
- * Dict.union(Dict.fromEntries([["b", 3], ["c", 4]])),
1028
+ * Dict.from.Entries([["a", 1], ["b", 2]]),
1029
+ * Dict.union(Dict.from.Entries([["b", 3], ["c", 4]])),
898
1030
  * );
899
1031
  * // ReadonlyMap { "a" => 1, "b" => 3, "c" => 4 }
900
1032
  * ```
@@ -907,8 +1039,8 @@ declare namespace Dict {
907
1039
  * @example
908
1040
  * ```ts
909
1041
  * pipe(
910
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
911
- * Dict.intersection(Dict.fromEntries([["b", 99], ["c", 0]])),
1042
+ * Dict.from.Entries([["a", 1], ["b", 2], ["c", 3]]),
1043
+ * Dict.intersection(Dict.from.Entries([["b", 99], ["c", 0]])),
912
1044
  * );
913
1045
  * // ReadonlyMap { "b" => 2, "c" => 3 }
914
1046
  * ```
@@ -920,8 +1052,8 @@ declare namespace Dict {
920
1052
  * @example
921
1053
  * ```ts
922
1054
  * pipe(
923
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
924
- * Dict.difference(Dict.fromEntries([["b", 0]])),
1055
+ * Dict.from.Entries([["a", 1], ["b", 2], ["c", 3]]),
1056
+ * Dict.difference(Dict.from.Entries([["b", 0]])),
925
1057
  * );
926
1058
  * // ReadonlyMap { "a" => 1, "c" => 3 }
927
1059
  * ```
@@ -934,7 +1066,7 @@ declare namespace Dict {
934
1066
  * @example
935
1067
  * ```ts
936
1068
  * Dict.reduce(0, (acc, value) => acc + value)(
937
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]])
1069
+ * Dict.from.Entries([["a", 1], ["b", 2], ["c", 3]])
938
1070
  * ); // 6
939
1071
  * ```
940
1072
  */
@@ -946,20 +1078,23 @@ declare namespace Dict {
946
1078
  * @example
947
1079
  * ```ts
948
1080
  * Dict.reduceWithKey("", (acc, value, key) => acc + key + ":" + value + " ")(
949
- * Dict.fromEntries([["a", 1], ["b", 2]])
1081
+ * Dict.from.Entries([["a", 1], ["b", 2]])
950
1082
  * ); // "a:1 b:2 "
951
1083
  * ```
952
1084
  */
953
1085
  const reduceWithKey: <K, A, B>(init: B, f: (acc: B, value: A, key: K) => B) => (m: ReadonlyMap<K, A>) => B;
954
- /**
955
- * Converts a `ReadonlyMap<string, V>` to a plain object. Only meaningful when keys are strings.
956
- *
957
- * @example
958
- * ```ts
959
- * Dict.toRecord(Dict.fromEntries([["a", 1], ["b", 2]])); // { a: 1, b: 2 }
960
- * ```
961
- */
962
- const toRecord: <V>(m: ReadonlyMap<string, V>) => Readonly<Record<string, V>>;
1086
+ namespace to {
1087
+ /**
1088
+ * Converts a `ReadonlyMap<string, V>` to a plain object. Only meaningful when keys are strings.
1089
+ *
1090
+ * @example
1091
+ * ```ts
1092
+ * Dict.to.Record(Dict.from.Entries([["a", 1], ["b", 2]])); // { a: 1, b: 2 }
1093
+ * ```
1094
+ */
1095
+ const Record: <V>(m: ReadonlyMap<string, V>) => Readonly<Record<string, V>>;
1096
+ }
1097
+ const NonEmpty: typeof DictNonEmpty;
963
1098
  }
964
1099
 
965
1100
  /**
@@ -1185,13 +1320,10 @@ declare namespace Num {
1185
1320
  const max: (ns: readonly number[]) => Maybe<number>;
1186
1321
  }
1187
1322
 
1188
- declare const _nonEmptyRecord: unique symbol;
1189
1323
  /**
1190
1324
  * A branded type representing a record with at least one key-value pair.
1191
1325
  */
1192
- type NonEmptyRecord<A> = Readonly<Record<string, A>> & {
1193
- readonly [_nonEmptyRecord]: true;
1194
- };
1326
+ type NonEmptyRecord<A, K extends string = string> = Brand<NonEmpty<"Rec">, Readonly<Record<K, A>>>;
1195
1327
  declare namespace RecMaybe {
1196
1328
  /**
1197
1329
  * Map a function that returns a `Maybe` over each value of a record,
@@ -1200,7 +1332,7 @@ declare namespace RecMaybe {
1200
1332
  *
1201
1333
  * @example
1202
1334
  * ```ts
1203
- * const parseNum = (s: string) => s === "NaN" ? Maybe.none() : Maybe.some(Number(s));
1335
+ * const parseNum = (s: string) => s === "NaN" ? Maybe.make.none() : Maybe.make.some(Number(s));
1204
1336
  * pipe({ a: "1", b: "2" }, Rec.Maybe.traverse(parseNum)); // Some({ a: 1, b: 2 })
1205
1337
  * pipe({ a: "1", b: "NaN" }, Rec.Maybe.traverse(parseNum)); // None
1206
1338
  * ```
@@ -1212,8 +1344,8 @@ declare namespace RecMaybe {
1212
1344
  *
1213
1345
  * @example
1214
1346
  * ```ts
1215
- * Rec.Maybe.sequence({ a: Maybe.some(1), b: Maybe.some(2) }); // Some({ a: 1, b: 2 })
1216
- * Rec.Maybe.sequence({ a: Maybe.some(1), b: Maybe.none() }); // None
1347
+ * Rec.Maybe.sequence({ a: Maybe.make.some(1), b: Maybe.make.some(2) }); // Some({ a: 1, b: 2 })
1348
+ * Rec.Maybe.sequence({ a: Maybe.make.some(1), b: Maybe.make.none() }); // None
1217
1349
  * ```
1218
1350
  */
1219
1351
  const sequence: <A>(data: Readonly<Record<string, Maybe<A>>>) => Maybe<Readonly<Record<string, A>>>;
@@ -1226,7 +1358,7 @@ declare namespace RecResult {
1226
1358
  *
1227
1359
  * @example
1228
1360
  * ```ts
1229
- * const checkPositive = (n: number) => n < 0 ? Result.err("negative") : Result.ok(n);
1361
+ * const checkPositive = (n: number) => n < 0 ? Result.make.err("negative") : Result.make.ok(n);
1230
1362
  * pipe({ a: 1, b: 2 }, Rec.Result.traverse(checkPositive)); // Ok({ a: 1, b: 2 })
1231
1363
  * pipe({ a: 1, b: -2 }, Rec.Result.traverse(checkPositive)); // Err("negative")
1232
1364
  * ```
@@ -1238,8 +1370,8 @@ declare namespace RecResult {
1238
1370
  *
1239
1371
  * @example
1240
1372
  * ```ts
1241
- * Rec.Result.sequence({ a: Result.ok(1), b: Result.ok(2) }); // Ok({ a: 1, b: 2 })
1242
- * Rec.Result.sequence({ a: Result.ok(1), b: Result.err("oops") }); // Err("oops")
1373
+ * Rec.Result.sequence({ a: Result.make.ok(1), b: Result.make.ok(2) }); // Ok({ a: 1, b: 2 })
1374
+ * Rec.Result.sequence({ a: Result.make.ok(1), b: Result.make.err("oops") }); // Err("oops")
1243
1375
  * ```
1244
1376
  */
1245
1377
  const sequence: <E, A>(data: Readonly<Record<string, Result<E, A>>>) => Result<E, Readonly<Record<string, A>>>;
@@ -1253,17 +1385,19 @@ declare namespace RecNonEmpty {
1253
1385
  * Rec.NonEmpty.singleton("a", 1); // { a: 1 }
1254
1386
  * ```
1255
1387
  */
1256
- const singleton: <A>(key: string, value: A) => NonEmptyRecord<A>;
1257
- /**
1258
- * Creates a NonEmpty record from a standard record if it is not empty.
1259
- *
1260
- * @example
1261
- * ```ts
1262
- * Rec.NonEmpty.fromRecord({ a: 1 }); // Some({ a: 1 })
1263
- * Rec.NonEmpty.fromRecord({}); // None
1264
- * ```
1265
- */
1266
- const fromRecord: <A>(data: Readonly<Record<string, A>>) => Maybe<NonEmptyRecord<A>>;
1388
+ const singleton: <K extends string, A>(key: K, value: A) => NonEmptyRecord<A, K>;
1389
+ namespace from {
1390
+ /**
1391
+ * Creates a NonEmpty record from a standard record if it is not empty.
1392
+ *
1393
+ * @example
1394
+ * ```ts
1395
+ * Rec.NonEmpty.from.Record({ a: 1 }); // Some({ a: 1 })
1396
+ * Rec.NonEmpty.from.Record({}); // None
1397
+ * ```
1398
+ */
1399
+ const Record: <K extends string, A>(data: Readonly<Record<K, A>>) => Maybe<NonEmptyRecord<A, K>>;
1400
+ }
1267
1401
  /**
1268
1402
  * Returns a non-empty array of keys for a NonEmpty record.
1269
1403
  *
@@ -1272,7 +1406,7 @@ declare namespace RecNonEmpty {
1272
1406
  * Rec.NonEmpty.keys(Rec.NonEmpty.singleton("a", 1)); // ["a"]
1273
1407
  * ```
1274
1408
  */
1275
- const keys: <A>(data: NonEmptyRecord<A>) => NonEmptyArr<string>;
1409
+ const keys: <K extends string, A>(data: NonEmptyRecord<A, K>) => NonEmptyArr<K>;
1276
1410
  /**
1277
1411
  * Returns a non-empty array of values for a NonEmpty record.
1278
1412
  *
@@ -1281,7 +1415,7 @@ declare namespace RecNonEmpty {
1281
1415
  * Rec.NonEmpty.values(Rec.NonEmpty.singleton("a", 1)); // [1]
1282
1416
  * ```
1283
1417
  */
1284
- const values: <A>(data: NonEmptyRecord<A>) => NonEmptyArr<A>;
1418
+ const values: <K extends string, A>(data: NonEmptyRecord<A, K>) => NonEmptyArr<A>;
1285
1419
  /**
1286
1420
  * Returns a non-empty array of entry tuples for a NonEmpty record.
1287
1421
  *
@@ -1290,7 +1424,7 @@ declare namespace RecNonEmpty {
1290
1424
  * Rec.NonEmpty.entries(Rec.NonEmpty.singleton("a", 1)); // [["a", 1]]
1291
1425
  * ```
1292
1426
  */
1293
- const entries: <A>(data: NonEmptyRecord<A>) => NonEmptyArr<readonly [string, A]>;
1427
+ const entries: <K extends string, A>(data: NonEmptyRecord<A, K>) => NonEmptyArr<readonly [K, A]>;
1294
1428
  /**
1295
1429
  * Reduces a NonEmpty record's values from the left without an initial value.
1296
1430
  *
@@ -1299,7 +1433,25 @@ declare namespace RecNonEmpty {
1299
1433
  * pipe(Rec.NonEmpty.singleton("a", 1), Rec.NonEmpty.reduce((a, b) => a + b)); // 1
1300
1434
  * ```
1301
1435
  */
1302
- const reduce: <A>(f: (acc: A, a: A) => A) => (data: NonEmptyRecord<A>) => A;
1436
+ const reduce: <A>(f: (acc: A, a: A) => A) => <K extends string>(data: NonEmptyRecord<A, K>) => A;
1437
+ /**
1438
+ * Transforms each value of a NonEmpty record.
1439
+ *
1440
+ * @example
1441
+ * ```ts
1442
+ * pipe(Rec.NonEmpty.singleton("a", 1), Rec.NonEmpty.map(n => n * 2)); // { a: 2 }
1443
+ * ```
1444
+ */
1445
+ const map: <A, B>(f: (a: A) => B) => <K extends string>(data: NonEmptyRecord<A, K>) => NonEmptyRecord<B, K>;
1446
+ /**
1447
+ * Transforms each value of a NonEmpty record, also receiving the key.
1448
+ *
1449
+ * @example
1450
+ * ```ts
1451
+ * pipe(Rec.NonEmpty.singleton("a", 1), Rec.NonEmpty.mapWithKey((k, v) => `${k}:${v}`)); // { a: "a:1" }
1452
+ * ```
1453
+ */
1454
+ const mapWithKey: <A, B>(f: (key: string, a: A) => B) => <K extends string>(data: NonEmptyRecord<A, K>) => NonEmptyRecord<B, K>;
1303
1455
  }
1304
1456
  /**
1305
1457
  * Functional record/object utilities that compose well with pipe.
@@ -1318,11 +1470,17 @@ declare namespace Rec {
1318
1470
  /**
1319
1471
  * A branded type representing a record with at least one key-value pair.
1320
1472
  */
1321
- type NonEmpty<A> = NonEmptyRecord<A>;
1322
- /**
1323
- * Type guard to check if a record is non-empty.
1324
- */
1325
- const isNonEmpty: <A>(data: Readonly<Record<string, A>>) => data is NonEmptyRecord<A>;
1473
+ type NonEmpty<A, K extends string = string> = NonEmptyRecord<A, K>;
1474
+ namespace is {
1475
+ /**
1476
+ * Returns true if the record has no keys.
1477
+ */
1478
+ const empty: <A>(data: Readonly<Record<string, A>>) => boolean;
1479
+ /**
1480
+ * Type guard to check if a record is non-empty.
1481
+ */
1482
+ const nonEmpty: <A, K extends string>(data: Readonly<Record<K, A>>) => data is NonEmptyRecord<A, K>;
1483
+ }
1326
1484
  /**
1327
1485
  * Transforms each value in a record.
1328
1486
  *
@@ -1331,10 +1489,7 @@ declare namespace Rec {
1331
1489
  * pipe({ a: 1, b: 2 }, Rec.map(n => n * 2)); // { a: 2, b: 4 }
1332
1490
  * ```
1333
1491
  */
1334
- const map: <A, B>(f: (a: A) => B) => {
1335
- (data: NonEmpty<A>): NonEmpty<B>;
1336
- (data: Readonly<Record<string, A>>): Readonly<Record<string, B>>;
1337
- };
1492
+ const map: <A, B>(f: (a: A) => B) => <K extends string>(data: Readonly<Record<K, A>>) => Readonly<Record<K, B>>;
1338
1493
  const filterMap: <A, B>(f: (a: A) => Maybe<B>) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, B>>;
1339
1494
  /**
1340
1495
  * Transforms each value in a record, also receiving the key.
@@ -1345,10 +1500,7 @@ declare namespace Rec {
1345
1500
  * // { a: "a:1", b: "b:2" }
1346
1501
  * ```
1347
1502
  */
1348
- const mapWithKey: <A, B>(f: (key: string, a: A) => B) => {
1349
- (data: NonEmpty<A>): NonEmpty<B>;
1350
- (data: Readonly<Record<string, A>>): Readonly<Record<string, B>>;
1351
- };
1503
+ const mapWithKey: <A, B>(f: (key: string, a: A) => B) => <K extends string>(data: Readonly<Record<K, A>>) => Readonly<Record<K, B>>;
1352
1504
  /**
1353
1505
  * Filters values in a record by a predicate.
1354
1506
  *
@@ -1390,15 +1542,17 @@ declare namespace Rec {
1390
1542
  * Returns all key-value pairs of a record.
1391
1543
  */
1392
1544
  const entries: <T extends Record<string, unknown>>(data: T) => readonly (readonly [keyof T, T[keyof T]])[];
1393
- /**
1394
- * Creates a record from key-value pairs.
1395
- *
1396
- * @example
1397
- * ```ts
1398
- * Rec.fromEntries([["a", 1], ["b", 2]]); // { a: 1, b: 2 }
1399
- * ```
1400
- */
1401
- const fromEntries: <A>(data: readonly (readonly [string, A])[]) => Readonly<Record<string, A>>;
1545
+ namespace from {
1546
+ /**
1547
+ * Creates a record from key-value pairs.
1548
+ *
1549
+ * @example
1550
+ * ```ts
1551
+ * Rec.from.entries([["a", 1], ["b", 2]]); // { a: 1, b: 2 }
1552
+ * ```
1553
+ */
1554
+ const entries: <A>(data: readonly (readonly [string, A])[]) => Readonly<Record<string, A>>;
1555
+ }
1402
1556
  /**
1403
1557
  * Groups elements of an array into a record keyed by the result of `keyFn`. Each key maps to
1404
1558
  * the array of elements that produced it, in insertion order.
@@ -1442,10 +1596,6 @@ declare namespace Rec {
1442
1596
  * ```
1443
1597
  */
1444
1598
  const merge: <A>(other: Readonly<Record<string, A>>) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, A>>;
1445
- /**
1446
- * Returns true if the record has no keys.
1447
- */
1448
- const isEmpty: <A>(data: Readonly<Record<string, A>>) => boolean;
1449
1599
  /**
1450
1600
  * Returns the number of keys in a record.
1451
1601
  */
@@ -1467,7 +1617,7 @@ declare namespace Rec {
1467
1617
  *
1468
1618
  * @example
1469
1619
  * ```ts
1470
- * Rec.compact({ a: Maybe.some(1), b: Maybe.none(), c: Maybe.some(3) });
1620
+ * Rec.compact({ a: Maybe.make.some(1), b: Maybe.make.none(), c: Maybe.make.some(3) });
1471
1621
  * // { a: 1, c: 3 }
1472
1622
  * ```
1473
1623
  */
@@ -1477,6 +1627,10 @@ declare namespace Rec {
1477
1627
  const NonEmpty: typeof RecNonEmpty;
1478
1628
  }
1479
1629
 
1630
+ /**
1631
+ * A branded type representing a string with at least one character.
1632
+ */
1633
+ type NonEmptyString = Brand<NonEmpty<"Str">, string>;
1480
1634
  /**
1481
1635
  * String utilities. All transformation functions are data-last and curried so they
1482
1636
  * compose naturally with `pipe`. Safe parsers return `Maybe` instead of `NaN`.
@@ -1489,7 +1643,41 @@ declare namespace Rec {
1489
1643
  * pipe(" Hello, World! ", Str.trim, Str.toLowerCase); // "hello, world!"
1490
1644
  * ```
1491
1645
  */
1646
+ declare namespace StrNonEmpty {
1647
+ namespace from {
1648
+ /**
1649
+ * Returns Some containing NonEmptyString if the string is not empty, None otherwise.
1650
+ *
1651
+ * @example
1652
+ * ```ts
1653
+ * Str.NonEmpty.from.String("hello"); // Some("hello")
1654
+ * Str.NonEmpty.from.String(""); // None
1655
+ * ```
1656
+ */
1657
+ const String: (s: string) => Maybe<NonEmptyString>;
1658
+ }
1659
+ }
1492
1660
  declare namespace Str {
1661
+ /**
1662
+ * A branded type representing a string with at least one character.
1663
+ */
1664
+ type NonEmpty = NonEmptyString;
1665
+ namespace is {
1666
+ /**
1667
+ * Returns `true` when the string is empty.
1668
+ *
1669
+ * @example
1670
+ * ```ts
1671
+ * pipe("", Str.is.empty); // true
1672
+ * pipe("hi", Str.is.empty); // false
1673
+ * ```
1674
+ */
1675
+ const empty: (s: string) => boolean;
1676
+ /**
1677
+ * Type guard to check if a string is non-empty.
1678
+ */
1679
+ const nonEmpty: (s: string) => s is NonEmpty;
1680
+ }
1493
1681
  /**
1494
1682
  * Splits a string by a separator. Data-last: use in `pipe`.
1495
1683
  *
@@ -1604,16 +1792,6 @@ declare namespace Str {
1604
1792
  * ```
1605
1793
  */
1606
1794
  const words: (s: string) => readonly string[];
1607
- /**
1608
- * Returns `true` when the string is empty.
1609
- *
1610
- * @example
1611
- * ```ts
1612
- * pipe("", Str.isEmpty); // true
1613
- * pipe("hi", Str.isEmpty); // false
1614
- * ```
1615
- */
1616
- const isEmpty: (s: string) => boolean;
1617
1795
  /**
1618
1796
  * Returns `true` when the string is empty or contains only whitespace.
1619
1797
  *
@@ -1701,8 +1879,13 @@ declare namespace Str {
1701
1879
  * ```
1702
1880
  */
1703
1881
  const parseJson: (s: string) => Result<SyntaxError, unknown>;
1882
+ const NonEmpty: typeof StrNonEmpty;
1704
1883
  }
1705
1884
 
1885
+ /**
1886
+ * A branded type representing a unique collection with at least one element.
1887
+ */
1888
+ type NonEmptySet<A> = Brand<NonEmpty<"Uniq">, ReadonlySet<A>>;
1706
1889
  /**
1707
1890
  * Functional utilities for unique-value collections (`ReadonlySet<A>`). All functions are pure
1708
1891
  * and data-last — they compose naturally with `pipe`.
@@ -1715,78 +1898,142 @@ declare namespace Str {
1715
1898
  * import { pipe } from "@nlozgachev/pipelined/composition";
1716
1899
  *
1717
1900
  * const active = pipe(
1718
- * Uniq.fromArray(["alice", "bob", "alice", "carol"]),
1901
+ * Uniq.from.Array(["alice", "bob", "alice", "carol"]),
1719
1902
  * Uniq.remove("bob"),
1720
1903
  * Uniq.map(name => name.toUpperCase()),
1721
1904
  * );
1722
1905
  * // ReadonlySet { "ALICE", "CAROL" }
1723
1906
  * ```
1724
1907
  */
1725
- declare namespace Uniq {
1908
+ declare namespace UniqNonEmpty {
1726
1909
  /**
1727
- * Creates an empty unique collection.
1910
+ * Creates a single-element unique collection.
1728
1911
  *
1729
1912
  * @example
1730
1913
  * ```ts
1731
- * Uniq.empty<number>(); // ReadonlySet {}
1914
+ * Uniq.NonEmpty.singleton(42); // ReadonlySet { 42 }
1732
1915
  * ```
1733
1916
  */
1734
- const empty: <A>() => ReadonlySet<A>;
1917
+ const singleton: <A>(item: A) => NonEmptySet<A>;
1918
+ namespace from {
1919
+ /**
1920
+ * Returns Some containing NonEmptySet if the set is not empty, None otherwise.
1921
+ *
1922
+ * @example
1923
+ * ```ts
1924
+ * Uniq.NonEmpty.from.Set(Uniq.from.Array([1, 2])); // Some(ReadonlySet { 1, 2 })
1925
+ * Uniq.NonEmpty.from.Set(Uniq.empty()); // None
1926
+ * ```
1927
+ */
1928
+ const Set: <A>(s: ReadonlySet<A>) => Maybe<NonEmptySet<A>>;
1929
+ }
1735
1930
  /**
1736
- * Creates a unique collection containing a single item.
1931
+ * Folds the collection into a single value without an initial seed value.
1737
1932
  *
1738
1933
  * @example
1739
1934
  * ```ts
1740
- * Uniq.singleton(42); // ReadonlySet { 42 }
1935
+ * pipe(Uniq.NonEmpty.singleton(42), Uniq.NonEmpty.reduce((a, b) => a + b)); // 42
1741
1936
  * ```
1742
1937
  */
1743
- const singleton: <A>(item: A) => ReadonlySet<A>;
1938
+ const reduce: <A>(f: (acc: A, a: A) => A) => (s: NonEmptySet<A>) => A;
1744
1939
  /**
1745
- * Creates a unique collection from an array, automatically discarding duplicates.
1940
+ * Transforms each item in the non-empty unique collection.
1746
1941
  *
1747
1942
  * @example
1748
1943
  * ```ts
1749
- * Uniq.fromArray([1, 2, 2, 3, 3, 3]); // ReadonlySet { 1, 2, 3 }
1750
- * Uniq.fromArray([]); // ReadonlySet {}
1944
+ * pipe(Uniq.NonEmpty.singleton(1), Uniq.NonEmpty.map(n => n * 2)); // ReadonlySet { 2 }
1751
1945
  * ```
1752
1946
  */
1753
- const fromArray: <A>(arr: readonly A[]) => ReadonlySet<A>;
1947
+ const map: <A, B>(f: (a: A) => B) => (s: NonEmptySet<A>) => NonEmptySet<B>;
1948
+ namespace to {
1949
+ /**
1950
+ * Converts the collection to a non-empty readonly array in insertion order.
1951
+ *
1952
+ * @example
1953
+ * ```ts
1954
+ * Uniq.NonEmpty.to.Array(Uniq.NonEmpty.singleton(42)); // [42]
1955
+ * ```
1956
+ */
1957
+ const Array: <A>(s: NonEmptySet<A>) => NonEmptyArr<A>;
1958
+ }
1959
+ }
1960
+ declare namespace Uniq {
1961
+ /**
1962
+ * A branded type representing a unique collection with at least one element.
1963
+ */
1964
+ type NonEmpty<A> = NonEmptySet<A>;
1965
+ namespace is {
1966
+ /**
1967
+ * Returns `true` if the collection has no items.
1968
+ *
1969
+ * @example
1970
+ * ```ts
1971
+ * Uniq.is.empty(Uniq.empty()); // true
1972
+ * ```
1973
+ */
1974
+ const empty: <A>(s: ReadonlySet<A>) => boolean;
1975
+ /**
1976
+ * Type guard to check if a unique collection is non-empty.
1977
+ */
1978
+ const nonEmpty: <A>(s: ReadonlySet<A>) => s is NonEmpty<A>;
1979
+ }
1754
1980
  /**
1755
- * Returns `true` if the collection contains the given item.
1981
+ * Creates an empty unique collection.
1756
1982
  *
1757
1983
  * @example
1758
1984
  * ```ts
1759
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(2)); // true
1760
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(4)); // false
1985
+ * Uniq.empty<number>(); // ReadonlySet {}
1761
1986
  * ```
1762
1987
  */
1763
- const has: <A>(item: A) => (s: ReadonlySet<A>) => boolean;
1988
+ const empty: <A>() => ReadonlySet<A>;
1764
1989
  /**
1765
- * Returns the number of items in the collection.
1990
+ * Creates a unique collection containing a single item.
1766
1991
  *
1767
1992
  * @example
1768
1993
  * ```ts
1769
- * Uniq.size(Uniq.fromArray([1, 2, 3])); // 3
1994
+ * Uniq.singleton(42); // ReadonlySet { 42 }
1770
1995
  * ```
1771
1996
  */
1772
- const size: <A>(s: ReadonlySet<A>) => number;
1997
+ const singleton: <A>(item: A) => ReadonlySet<A>;
1998
+ namespace from {
1999
+ /**
2000
+ * Creates a unique collection from an array, automatically discarding duplicates.
2001
+ *
2002
+ * @example
2003
+ * ```ts
2004
+ * Uniq.from.Array([1, 2, 2, 3, 3, 3]); // ReadonlySet { 1, 2, 3 }
2005
+ * Uniq.from.Array([]); // ReadonlySet {}
2006
+ * ```
2007
+ */
2008
+ const Array: <A>(arr: readonly A[]) => ReadonlySet<A>;
2009
+ }
2010
+ /**
2011
+ * Returns `true` if the collection contains the given item.
2012
+ *
2013
+ * @example
2014
+ * ```ts
2015
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.has(2)); // true
2016
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.has(4)); // false
2017
+ * ```
2018
+ */
2019
+ const has: <A>(item: A) => (s: ReadonlySet<A>) => boolean;
1773
2020
  /**
1774
- * Returns `true` if the collection has no items.
2021
+ * Returns the number of items in the collection.
1775
2022
  *
1776
2023
  * @example
1777
2024
  * ```ts
1778
- * Uniq.isEmpty(Uniq.empty()); // true
2025
+ * Uniq.size(Uniq.from.Array([1, 2, 3])); // 3
1779
2026
  * ```
1780
2027
  */
1781
- const isEmpty: <A>(s: ReadonlySet<A>) => boolean;
2028
+ const size: <A>(s: ReadonlySet<A>) => number;
1782
2029
  /**
1783
2030
  * Returns `true` if every item in `set` also exists in `other`.
1784
2031
  *
1785
2032
  * @example
1786
2033
  * ```ts
1787
- * pipe(Uniq.fromArray([1, 2]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
1788
- * pipe(Uniq.fromArray([1, 4]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // false
1789
- * pipe(Uniq.empty<number>(), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
2034
+ * pipe(Uniq.from.Array([1, 2]), Uniq.isSubsetOf(Uniq.from.Array([1, 2, 3]))); // true
2035
+ * pipe(Uniq.from.Array([1, 4]), Uniq.isSubsetOf(Uniq.from.Array([1, 2, 3]))); // false
2036
+ * pipe(Uniq.empty<number>(), Uniq.isSubsetOf(Uniq.from.Array([1, 2, 3]))); // true
1790
2037
  * ```
1791
2038
  */
1792
2039
  const isSubsetOf: <A>(other: ReadonlySet<A>) => (s: ReadonlySet<A>) => boolean;
@@ -1796,8 +2043,8 @@ declare namespace Uniq {
1796
2043
  *
1797
2044
  * @example
1798
2045
  * ```ts
1799
- * pipe(Uniq.fromArray([1, 2]), Uniq.insert(3)); // ReadonlySet { 1, 2, 3 }
1800
- * pipe(Uniq.fromArray([1, 2]), Uniq.insert(2)); // ReadonlySet { 1, 2 } — unchanged
2046
+ * pipe(Uniq.from.Array([1, 2]), Uniq.insert(3)); // ReadonlySet { 1, 2, 3 }
2047
+ * pipe(Uniq.from.Array([1, 2]), Uniq.insert(2)); // ReadonlySet { 1, 2 } — unchanged
1801
2048
  * ```
1802
2049
  */
1803
2050
  const insert: <A>(item: A) => (s: ReadonlySet<A>) => ReadonlySet<A>;
@@ -1807,8 +2054,8 @@ declare namespace Uniq {
1807
2054
  *
1808
2055
  * @example
1809
2056
  * ```ts
1810
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(2)); // ReadonlySet { 1, 3 }
1811
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(4)); // ReadonlySet { 1, 2, 3 } — unchanged
2057
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.remove(2)); // ReadonlySet { 1, 3 }
2058
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.remove(4)); // ReadonlySet { 1, 2, 3 } — unchanged
1812
2059
  * ```
1813
2060
  */
1814
2061
  const remove: <A>(item: A) => (s: ReadonlySet<A>) => ReadonlySet<A>;
@@ -1818,7 +2065,7 @@ declare namespace Uniq {
1818
2065
  *
1819
2066
  * @example
1820
2067
  * ```ts
1821
- * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.map(n => n % 3)); // ReadonlySet { 1, 2, 0 }
2068
+ * pipe(Uniq.from.Array([1, 2, 3, 4]), Uniq.map(n => n % 3)); // ReadonlySet { 1, 2, 0 }
1822
2069
  * ```
1823
2070
  */
1824
2071
  const map: <A, B>(f: (a: A) => B) => (s: ReadonlySet<A>) => ReadonlySet<B>;
@@ -1827,7 +2074,7 @@ declare namespace Uniq {
1827
2074
  *
1828
2075
  * @example
1829
2076
  * ```ts
1830
- * pipe(Uniq.fromArray([1, 2, 3, 4, 5]), Uniq.filter(n => n % 2 === 0));
2077
+ * pipe(Uniq.from.Array([1, 2, 3, 4, 5]), Uniq.filter(n => n % 2 === 0));
1831
2078
  * // ReadonlySet { 2, 4 }
1832
2079
  * ```
1833
2080
  */
@@ -1837,7 +2084,7 @@ declare namespace Uniq {
1837
2084
  *
1838
2085
  * @example
1839
2086
  * ```ts
1840
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.union(Uniq.fromArray([2, 3, 4])));
2087
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.union(Uniq.from.Array([2, 3, 4])));
1841
2088
  * // ReadonlySet { 1, 2, 3, 4 }
1842
2089
  * ```
1843
2090
  */
@@ -1847,7 +2094,7 @@ declare namespace Uniq {
1847
2094
  *
1848
2095
  * @example
1849
2096
  * ```ts
1850
- * pipe(Uniq.fromArray([1, 2, 3]), Uniq.intersection(Uniq.fromArray([2, 3, 4])));
2097
+ * pipe(Uniq.from.Array([1, 2, 3]), Uniq.intersection(Uniq.from.Array([2, 3, 4])));
1851
2098
  * // ReadonlySet { 2, 3 }
1852
2099
  * ```
1853
2100
  */
@@ -1857,7 +2104,7 @@ declare namespace Uniq {
1857
2104
  *
1858
2105
  * @example
1859
2106
  * ```ts
1860
- * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.difference(Uniq.fromArray([2, 4])));
2107
+ * pipe(Uniq.from.Array([1, 2, 3, 4]), Uniq.difference(Uniq.from.Array([2, 4])));
1861
2108
  * // ReadonlySet { 1, 3 }
1862
2109
  * ```
1863
2110
  */
@@ -1867,19 +2114,22 @@ declare namespace Uniq {
1867
2114
  *
1868
2115
  * @example
1869
2116
  * ```ts
1870
- * Uniq.reduce(0, (acc, n) => acc + n)(Uniq.fromArray([1, 2, 3])); // 6
2117
+ * Uniq.reduce(0, (acc, n) => acc + n)(Uniq.from.Array([1, 2, 3])); // 6
1871
2118
  * ```
1872
2119
  */
1873
2120
  const reduce: <A, B>(init: B, f: (acc: B, a: A) => B) => (s: ReadonlySet<A>) => B;
1874
- /**
1875
- * Converts the collection to a readonly array in insertion order.
1876
- *
1877
- * @example
1878
- * ```ts
1879
- * Uniq.toArray(Uniq.fromArray([3, 1, 2])); // [3, 1, 2]
1880
- * ```
1881
- */
1882
- const toArray: <A>(s: ReadonlySet<A>) => readonly A[];
2121
+ namespace to {
2122
+ /**
2123
+ * Converts the collection to a readonly array in insertion order.
2124
+ *
2125
+ * @example
2126
+ * ```ts
2127
+ * Uniq.to.Array(Uniq.from.Array([3, 1, 2])); // [3, 1, 2]
2128
+ * ```
2129
+ */
2130
+ const Array: <A>(s: ReadonlySet<A>) => readonly A[];
2131
+ }
2132
+ const NonEmpty: typeof UniqNonEmpty;
1883
2133
  }
1884
2134
 
1885
- export { Arr, Dict, type NonEmptyRecord, Num, Rec, Str, Uniq };
2135
+ export { Arr, Dict, type NonEmptyMap, type NonEmptyRecord, type NonEmptySet, type NonEmptyString, Num, Rec, Str, Uniq };