@budsbox/lib-es 2.3.0 → 3.0.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.
@@ -0,0 +1,256 @@
1
+ import type { Predicate, TypePredicate } from '@budsbox/lib-types';
2
+ /**
3
+ * Extracts the narrowed types from a list of predicates into a corresponding tuple.
4
+ *
5
+ * This helper type recursively processes a tuple of predicates and extracts the second type parameter
6
+ * (the narrowed type) from each predicate. The result is a new tuple where each element represents
7
+ * what the input type would be narrowed to if that predicate's type guard succeeds.
8
+ *
9
+ * When used with {@link TypePredicate} types, this is particularly useful for functions like
10
+ * {@link everyPredicate} that need to intersect all narrowed types, or {@link somePredicate}
11
+ * that need to union them.
12
+ *
13
+ * @typeParam TPredicates - A readonly tuple of {@link Predicate} types to extract narrow types from.
14
+ * @example
15
+ * ```typescript
16
+ * type Guard1 = (v: unknown) => v is string;
17
+ * type Guard2 = (v: unknown) => v is { name: string };
18
+ * type Narrowed = PredicatesListNarrowType<[Guard1, Guard2]>;
19
+ * // Narrowed = [string, { name: string }]
20
+ * ```
21
+ * @example
22
+ * ```typescript
23
+ * // Used in practice with everyPredicate
24
+ * const isString = (v: unknown): v is string => typeof v === 'string';
25
+ * const hasLength = (v: unknown): v is { length: number } => 'length' in (v as any);
26
+ * const predicate = everyPredicate(isString, hasLength);
27
+ * // The type system narrows to: string & { length: number }
28
+ * ```
29
+ */
30
+ export type PredicatesListNarrowed<TPredicates extends readonly Predicate[]> = TPredicates extends [infer TLeft, ...infer TRight] ? [
31
+ TLeft extends Predicate<infer _, infer TNarrow> ? TNarrow : never,
32
+ ...PredicatesListNarrowed<TRight extends readonly Predicate[] ? TRight : never>
33
+ ] : TPredicates extends readonly [infer TLeft, ...infer TRight] ? [
34
+ TLeft extends Predicate<infer _, infer TNarrow> ? TNarrow : never,
35
+ ...PredicatesListNarrowed<TRight extends readonly Predicate[] ? TRight : never>
36
+ ] : TPredicates extends readonly [] ? [] : TPredicates extends ReadonlyArray<Predicate<infer _, infer TNarrow>> ? TNarrow[] : never;
37
+ /**
38
+ * Extracts the input argument types from a list of predicates into a corresponding tuple.
39
+ *
40
+ * This helper type recursively processes a tuple of predicates and extracts the first type parameter
41
+ * (the input type) from each predicate. The result is a new tuple where each element represents
42
+ * the type that the predicate expects as input.
43
+ *
44
+ * @typeParam TPredicates - A readonly tuple of {@link Predicate} types to extract argument types from.
45
+ * @example
46
+ * ```typescript
47
+ * type Guard1 = (v: string) => boolean;
48
+ * type Guard2 = (v: string) => boolean;
49
+ * type Args = PredicatesListArg<[Guard1, Guard2]>;
50
+ * // Args = [string, string]
51
+ * ```
52
+ * @example
53
+ * ```typescript
54
+ * // Used in practice with everyPredicate
55
+ * const isLongerThan5 = (v: string) => v.length > 5;
56
+ * const isUpperCase = (v: string) => v === v.toUpperCase();
57
+ * const predicate = everyPredicate(isLongerThan5, isUpperCase);
58
+ * // Both predicates require string input, so the value must be a string
59
+ * ```
60
+ */
61
+ export type PredicatesListArg<TPredicates extends readonly Predicate[]> = TPredicates extends [infer TLeft, ...infer TRight] ? [
62
+ TLeft extends Predicate<infer TArg, infer _> ? TArg : never,
63
+ ...PredicatesListArg<TRight extends readonly Predicate[] ? TRight : never>
64
+ ] : TPredicates extends readonly [] ? [] : TPredicates extends ReadonlyArray<Predicate<infer TArg>> ? TArg[] : never;
65
+ /**
66
+ * Transforms a list of predicates' narrowed types into a tuple where each element is optional.
67
+ *
68
+ * This type extracts the narrowed types from each predicate using {@link PredicatesListNarrowed},
69
+ * then makes each type in the resulting tuple optional by unioning it with undefined.
70
+ * Useful for cases where partial satisfaction of predicates is acceptable.
71
+ *
72
+ * @typeParam TPredicates - A readonly tuple of {@link Predicate} types to normalize.
73
+ * @example
74
+ * ```typescript
75
+ * type Guard1 = (v: unknown) => v is string;
76
+ * type Guard2 = (v: unknown) => v is number;
77
+ * type Normalized = NormalizedOptionalRest<[Guard1, Guard2]>;
78
+ * // Normalized = [string | undefined, number | undefined]
79
+ * ```
80
+ * @example
81
+ * ```typescript
82
+ * // Applied to type predicates with different narrowed types
83
+ * type Predicates = [
84
+ * (v: unknown) => v is boolean,
85
+ * (v: unknown) => v is { id: string }
86
+ * ];
87
+ * type Result = NormalizedOptionalRest<Predicates>;
88
+ * // Result = [boolean | undefined, { id: string } | undefined]
89
+ * ```
90
+ */
91
+ export type NormalizedOptionalRest<TPredicates extends readonly Predicate[]> = OptionalsTuple<PredicatesListNarrowed<TPredicates>>;
92
+ type OptionalsTuple<TTuple extends readonly unknown[]> = TTuple extends readonly [] ? [] : TTuple extends readonly [infer THead, ...infer TRest] ? [
93
+ THead | undefined,
94
+ ...OptionalsTuple<TRest>
95
+ ] : never;
96
+ /**
97
+ * Asserts that a given condition is true. Throws an error if the condition is false.
98
+ * The error message can be a string or a lazily evaluated function that returns a string.
99
+ *
100
+ * @param condition - A boolean expression that is expected to evaluate to true.
101
+ * @param message - An optional error message or a function that generates the error message
102
+ * if the condition evaluates to false. Defaults to 'Expected condition to be true'.
103
+ * @throws {@link !TypeError} in the following cases:
104
+ * - if the condition evaluates to false
105
+ * - if the condition is not a boolean
106
+ * - if the message is not a string or a function that returns a string
107
+ * @inline
108
+ * @category Assertions
109
+ */
110
+ export type InvariantFn = (condition: boolean, message?: string | (() => string)) => asserts condition is true;
111
+ /**
112
+ * Asserts that the given value satisfies the specified predicate function. If the value
113
+ * does not satisfy the predicate, an error will be thrown. If the predicate is a type guard,
114
+ * the value will be narrowed accordingly.
115
+ *
116
+ * @internal
117
+ * @param predicate - A predicate function used to validate the value. Optionally, the predicate
118
+ * may act as a type guard and narrow the type of the value.
119
+ * @param value - The value to be verified against the predicate.
120
+ * @param valueName - The name of the value for the error message. Defaults to 'value'.
121
+ * @throws {@link !TypeError} - if the value does not meet the requirements defined by the predicate.
122
+ * @typeParam TValue - The type of the value being checked.
123
+ * @typeParam TGuardInput - The type of the input to the predicate.
124
+ * @typeParam TNarrowed - The narrowed type of the value if the predicate is a type guard.
125
+ * @category Assertions
126
+ */
127
+ export interface InvariantPredicateFn {
128
+ <TNarrowed>(predicate: TypePredicate<unknown, TNarrowed>, value: unknown, valueName?: string): asserts value is TNarrowed;
129
+ <TValue extends TGuardInput, TGuardInput, TNarrowed extends TGuardInput>(predicate: TypePredicate<TGuardInput, TNarrowed>, value: TValue, valueName?: string): asserts value is TValue extends TNarrowed ? TValue : TValue & TNarrowed;
130
+ <TValue>(predicate: Predicate<TValue>, value: TValue, valueName?: string): void;
131
+ (predicate: Predicate, value: unknown, valueName?: string): void;
132
+ }
133
+ /**
134
+ * Represents a descriptor for a predicate.
135
+ *
136
+ * @category Describing
137
+ */
138
+ export type PredicateDescriptor = {
139
+ and: readonly Predicate[];
140
+ } | {
141
+ condition: string;
142
+ } | {
143
+ or: readonly Predicate[];
144
+ } | {
145
+ type: string;
146
+ };
147
+ /**
148
+ * Adds a human-readable description to a given type guard function, enhancing its metadata.
149
+ * This metadata can later be used for debugging, logging, or explanatory purposes.
150
+ *
151
+ * @internal
152
+ * @param predicate - A predicate responsible for evaluating whether a value satisfies
153
+ * a specific type.
154
+ * @param typeDescription - A string description of the type that the `predicate` validates.
155
+ * @returns The original predicate, with the description attached.
156
+ * @throws {@link !TypeError} If `typeGuard` is not a function or `typeDescription` is not a string.
157
+ * @category Describing
158
+ */
159
+ export type DescribeTypePredicateFn = <TPredicate extends Predicate>(predicate: TPredicate, typeDescription: string) => TPredicate;
160
+ /**
161
+ * Adds a human-readable description to a given predicate function, enhancing its metadata.
162
+ * This metadata can later be used for debugging, logging, or explanatory purposes.
163
+ *
164
+ * @param predicate - The predicate function to associate with a description. Must be a valid function.
165
+ * @param conditionDescription - A description explaining the condition represented by the predicate. Must be a string.
166
+ * @returns The original predicate function, with the description attached.
167
+ * @throws {@link !TypeError} If `predicate` is not a function or `conditionDescription` is not a string.
168
+ * @category Describing
169
+ */
170
+ export type DescribePredicateFn = <TPredicate extends Predicate>(predicate: TPredicate, conditionDescription: string) => TPredicate;
171
+ /**
172
+ * Retrieves the descriptor associated with a given predicate function, if available.
173
+ *
174
+ * @internal
175
+ * @param predicate - A predicate function to retrieve the descriptor from.
176
+ * @returns The `PredicateDescriptor` associated with the predicate, or `undefined` if not present.
177
+ * @throws {@link !TypeError} If the provided `predicate` is not a function.
178
+ * @category Describing
179
+ */
180
+ export type GetPredicateDescriptorFn = (predicate: Predicate) => PredicateDescriptor | undefined;
181
+ /**
182
+ * Formats an error message indicating the expected condition for a predicate function.
183
+ *
184
+ * @param predicate - The predicate function to generate an error message for.
185
+ * @param value - The value that failed to satisfy the predicate.
186
+ * @param valueName - The name of the value for the error message. Defaults to 'value'.
187
+ * @returns A formatted error message describing what was expected.
188
+ * @throws {@link !TypeError} If `predicate` is not a function or `valueName` is not a string.
189
+ * @category Formatting
190
+ */
191
+ export type FormatPredicateExpectedMessageFn = (predicate: Predicate, value: unknown, valueName?: string) => string;
192
+ /**
193
+ * Formats an {@link Error} object into a concise debug string.
194
+ *
195
+ * Includes the error's name, message, optional `code` and `cause` properties,
196
+ * and a truncated stack trace. Nested values are formatted using {@link formatDebugValue}.
197
+ *
198
+ * @param error - The error to format.
199
+ * @param options - Optional formatting configuration via {@link FormatOptions}.
200
+ * @returns A formatted string representation of the error.
201
+ * @throws {@link !TypeError} If `error` is not an instance of {@link Error}.
202
+ * @category Formatting
203
+ */
204
+ export type FormatErrorFn = (error: Error, options?: FormatOptions) => string;
205
+ /**
206
+ * Formats a value into a human-readable debug string representation.
207
+ *
208
+ * Handles primitives, arrays, objects, functions, dates, errors, maps, sets,
209
+ * and objects with custom `toString` methods. Circular references are detected
210
+ * and marked as `[Circular]` for arrays or `{Circular}` for objects.
211
+ *
212
+ * @param value - The value to format for debugging purposes.
213
+ * @param options - Optional formatting configuration via {@link FormatOptions}.
214
+ * @returns A string representation suitable for debug output.
215
+ * @throws {@link !TypeError} in the following cases:
216
+ * - `options` is not an object or `undefined`.
217
+ * - `options` has a `maxDepth` property that is not a positive integer.
218
+ * - `options` has a `maxArrayLength` property that is not a positive integer.
219
+ * - `options` has a `maxStringLength` property that is not a positive integer.
220
+ * @category Formatting
221
+ */
222
+ export type FormatDebugValueFn = (value: unknown, options?: FormatOptions) => string;
223
+ /**
224
+ * Configuration options for debug formatting functions.
225
+ *
226
+ * @category Formatting
227
+ */
228
+ export interface FormatOptions {
229
+ /**
230
+ * Maximum recursion depth for nested structures.
231
+ *
232
+ * @defaultValue `2`
233
+ */
234
+ readonly maxDepth?: number;
235
+ /**
236
+ * Maximum number of items to display in arrays.
237
+ *
238
+ * @defaultValue `5`
239
+ */
240
+ readonly maxItems?: number;
241
+ /**
242
+ * Maximum string length before truncation.
243
+ *
244
+ * @defaultValue `15`
245
+ */
246
+ readonly maxLength?: number;
247
+ /**
248
+ * Set of already-seen objects for circular reference detection.
249
+ *
250
+ * @internal
251
+ * @defaultValue `new WeakSet()`
252
+ */
253
+ readonly seen?: WeakSet<object>;
254
+ }
255
+ export {};
256
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
package/dist/logical.d.ts CHANGED
@@ -1,53 +1,61 @@
1
- import type { FValueFalse, FValueTrue, TestFn } from './types.js';
1
+ /**
2
+ * This module provides functional logical operations and utilities.
3
+ *
4
+ * @module
5
+ * @importTarget ./logical
6
+ */
7
+ import type { Predicate } from '@budsbox/lib-types';
8
+ import type { FValueFalse, FValueTrue } from './types.js';
2
9
  import { isNotNil, isTrue } from '#guards';
10
+ export type { FValueFalse, FValueTrue };
3
11
  /**
4
12
  * Functional If
5
13
  *
6
14
  * Evaluates a value with a given test and returns a value (or executes a function and returns its result) based on the result.
7
15
  *
8
- * @typeParam TValue - The type of the value to be tested.
9
- * @typeParam TTestFn - The type of the test function that takes the value as a parameter and returns a boolean.
10
- * @typeParam TTrue - The type of the value or the return type of the function if the test's result is true.
11
- * @typeParam TFalse - The type of the value or the return type of the function if the test's result is true.
12
16
  * @param value - The value to test against the provided test function.
13
17
  * @param test - A function to evaluate the provided value.
14
18
  * @param onTrue - A function or value to execute or return if the test evaluates to true.
15
19
  * @param onFalse - A function or value to execute or return if the test evaluates to false.
16
20
  * @returns The value or the result of the function based on the test result
21
+ * @typeParam TValue - The type of the value to be tested.
22
+ * @typeParam TTestFn - The type of the test function that takes the value as a parameter and returns a boolean.
23
+ * @typeParam TTrue - The type of the value or the return type of the function if the test's result is true.
24
+ * @typeParam TFalse - The type of the value or the return type of the function if the test's result is true.
17
25
  * @example
18
26
  * ```ts
19
27
  * const result1 = fif(10, (n) => n > 5, 'Greater', 'Smaller');
20
28
  * // result1 is 'Greater'
21
29
  *
22
- * const result2 = fif(3, (n) => n > 5, (n) => `Above ${n}`, (n) => `Below ${n}`);
23
- * // result2 is 'Below 3'
30
+ * const result2 = fif(3, (n) => n > 5, (n) => `${n} greater than 5`, (n) => `${n} below 5`);
31
+ * // result2 is '3 below 5'
24
32
  * ```
25
33
  */
26
- export declare function fif<TValue, TTestFn extends TestFn<TValue>, TTrue, TFalse = undefined>(value: TValue, test: TTestFn, onTrue: FValueTrue<TValue, TTestFn, TTrue>, onFalse?: FValueFalse<TValue, TTestFn, TFalse>): TTrue | TFalse;
34
+ export declare function fif<TValue, TTestFn extends Predicate<TValue>, TTrue, TFalse = undefined>(value: TValue, test: TTestFn, onTrue: FValueTrue<TValue, TTestFn, TTrue>, onFalse?: FValueFalse<TValue, TTestFn, TFalse>): TFalse | TTrue;
27
35
  /**
28
36
  * Functional If (Static)
29
37
  *
30
38
  * Evaluates a condition and returns a value or executes a function based on the result.
31
39
  *
32
- * @typeParam TTrue - The type of the value or the return type of the function if the condition is true.
33
- * @typeParam TFalse - The type of the value or the return type of the function if condition is true.
34
40
  * @param condition - The condition to evaluate.
35
41
  * @param onTrue - The value or function to return/execute if the condition is true. If it's a function, it receives `true` as an argument.
36
42
  * @param onFalse - The value or function to return/execute if the condition is false. If it's a function, it receives `false` as an argument.
37
43
  * @returns The value or the result of the function based on the evaluated condition.
44
+ * @typeParam TTrue - The type of the value or the return type of the function if the condition is true.
45
+ * @typeParam TFalse - The type of the value or the return type of the function if condition is true.
38
46
  */
39
- export declare function fifs<TTrue, TFalse = undefined>(condition: boolean, onTrue: FValueTrue<boolean, typeof isTrue, TTrue>, onFalse?: FValueFalse<boolean, typeof isTrue, TFalse>): TTrue | TFalse;
47
+ export declare function fifs<TTrue, TFalse = undefined>(condition: boolean, onTrue: FValueTrue<boolean, typeof isTrue, TTrue>, onFalse?: FValueFalse<boolean, typeof isTrue, TFalse>): TFalse | TTrue;
40
48
  /**
41
49
  * Ensures that the provided value is not null or undefined
42
50
  * and returns a value (or executes a function and returns it's result) based on the result.
43
51
  *
44
- * @typeParam TValue - The type of the value to be checked.
45
- * @typeParam TTrue - The type of the value or the return type of the function if the value is not null or undefined.
46
- * @typeParam TFalse - The type of the value or the return type of the function if the value is null or undefined.
47
52
  * @param value - The value to be checked.
48
53
  * @param onTrue - Callback function to be executed if the value is not null or undefined.
49
54
  * @param onFalse - (Optional) Callback function to be executed if the value is null or undefined.
50
55
  * @returns The result of the appropriate callback function based on the evaluation of the value.
56
+ * @typeParam TValue - The type of the value to be checked.
57
+ * @typeParam TTrue - The type of the value or the return type of the function if the value is not null or undefined.
58
+ * @typeParam TFalse - The type of the value or the return type of the function if the value is null or undefined.
51
59
  */
52
- export declare function sure<TValue, TTrue, TFalse = undefined>(value: TValue, onTrue: FValueTrue<TValue, typeof isNotNil, TTrue>, onFalse?: FValueFalse<TValue, typeof isNotNil, TFalse>): TTrue | TFalse;
60
+ export declare function sure<TValue, TTrue, TFalse = undefined>(value: TValue, onTrue: FValueTrue<TValue, typeof isNotNil, TTrue>, onFalse?: FValueFalse<TValue, typeof isNotNil, TFalse>): TFalse | TTrue;
53
61
  //# sourceMappingURL=logical.d.ts.map
package/dist/logical.js CHANGED
@@ -1,49 +1,28 @@
1
- import { isFunction, isNotNil, isTrue } from '#guards';
2
1
  /**
3
- * Functional If
2
+ * This module provides functional logical operations and utilities.
4
3
  *
5
- * Evaluates a value with a given test and returns a value (or executes a function and returns its result) based on the result.
6
- *
7
- * @typeParam TValue - The type of the value to be tested.
8
- * @typeParam TTestFn - The type of the test function that takes the value as a parameter and returns a boolean.
9
- * @typeParam TTrue - The type of the value or the return type of the function if the test's result is true.
10
- * @typeParam TFalse - The type of the value or the return type of the function if the test's result is true.
11
- * @param value - The value to test against the provided test function.
12
- * @param test - A function to evaluate the provided value.
13
- * @param onTrue - A function or value to execute or return if the test evaluates to true.
14
- * @param onFalse - A function or value to execute or return if the test evaluates to false.
15
- * @returns The value or the result of the function based on the test result
16
- * @example
17
- * ```ts
18
- * const result1 = fif(10, (n) => n > 5, 'Greater', 'Smaller');
19
- * // result1 is 'Greater'
20
- *
21
- * const result2 = fif(3, (n) => n > 5, (n) => `Above ${n}`, (n) => `Below ${n}`);
22
- * // result2 is 'Below 3'
23
- * ```
4
+ * @module
5
+ * @importTarget ./logical
24
6
  */
7
+ import { callPredicate, isFunction, isNotNil, isTrue } from '#guards';
25
8
  export function fif(value, test, onTrue, onFalse) {
26
- if (test(value)) {
27
- return isFunction(onTrue) ?
28
- onTrue(value)
29
- : onTrue;
30
- }
31
- if (isFunction(onFalse)) {
32
- return onFalse(value);
33
- }
34
- return onFalse;
9
+ return (callPredicate(test, value, 'test') ?
10
+ isFunction(onTrue) ? onTrue(value)
11
+ : onTrue
12
+ : isFunction(onFalse) ? onFalse(value)
13
+ : onFalse);
35
14
  }
36
15
  /**
37
16
  * Functional If (Static)
38
17
  *
39
18
  * Evaluates a condition and returns a value or executes a function based on the result.
40
19
  *
41
- * @typeParam TTrue - The type of the value or the return type of the function if the condition is true.
42
- * @typeParam TFalse - The type of the value or the return type of the function if condition is true.
43
20
  * @param condition - The condition to evaluate.
44
21
  * @param onTrue - The value or function to return/execute if the condition is true. If it's a function, it receives `true` as an argument.
45
22
  * @param onFalse - The value or function to return/execute if the condition is false. If it's a function, it receives `false` as an argument.
46
23
  * @returns The value or the result of the function based on the evaluated condition.
24
+ * @typeParam TTrue - The type of the value or the return type of the function if the condition is true.
25
+ * @typeParam TFalse - The type of the value or the return type of the function if condition is true.
47
26
  */
48
27
  export function fifs(condition, onTrue, onFalse) {
49
28
  return fif(condition, isTrue, onTrue, onFalse);
@@ -52,13 +31,13 @@ export function fifs(condition, onTrue, onFalse) {
52
31
  * Ensures that the provided value is not null or undefined
53
32
  * and returns a value (or executes a function and returns it's result) based on the result.
54
33
  *
55
- * @typeParam TValue - The type of the value to be checked.
56
- * @typeParam TTrue - The type of the value or the return type of the function if the value is not null or undefined.
57
- * @typeParam TFalse - The type of the value or the return type of the function if the value is null or undefined.
58
34
  * @param value - The value to be checked.
59
35
  * @param onTrue - Callback function to be executed if the value is not null or undefined.
60
36
  * @param onFalse - (Optional) Callback function to be executed if the value is null or undefined.
61
37
  * @returns The result of the appropriate callback function based on the evaluation of the value.
38
+ * @typeParam TValue - The type of the value to be checked.
39
+ * @typeParam TTrue - The type of the value or the return type of the function if the value is not null or undefined.
40
+ * @typeParam TFalse - The type of the value or the return type of the function if the value is null or undefined.
62
41
  */
63
42
  export function sure(value, onTrue, onFalse) {
64
43
  return fif(value, isNotNil, onTrue, onFalse);
package/dist/map.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * This module provides Map-related utilities, including a read-only Map implementation.
3
+ *
4
+ * @module
5
+ * @importTarget ./map
6
+ */
7
+ import type { Nil } from '@budsbox/lib-types';
8
+ /**
9
+ * A read-only Map implementation that conforms to the `ReadonlyMap` interface.
10
+ * This class provides a wrapper around `Map` to enforce immutability.
11
+ *
12
+ * @typeParam K - The type of keys maintained by this map.
13
+ * @typeParam V - The type of mapped values.
14
+ */
15
+ export declare class ROMap<K, V> extends Map<K, V> implements ReadonlyMap<K, V> {
16
+ /**
17
+ * Constructs a new instance of the class with an optional collection of entries.
18
+ *
19
+ * @param entries - An optional iterable object containing key-value pairs (tuples) to initialize the map.
20
+ * If not provided or set to `Nil`, the map will be empty.
21
+ * @typeParam K - The type of the keys in the map.
22
+ * @typeParam V - The type of the values in the map.
23
+ */
24
+ constructor(entries?: Iterable<readonly [K, V]> | Nil);
25
+ /**
26
+ * Throws a `TypeError` exception because the map is read-only.
27
+ *
28
+ * @param args - The arguments to be passed to the `Map.set` method.
29
+ * @returns This method does not return a value.
30
+ * @throws {@link !TypeError} Indeed: map is read-only.
31
+ * @privateRemarks It works as original `Map#set` when invoked from the constructor.
32
+ */
33
+ set(...args: readonly [key: K, value: V]): never;
34
+ /**
35
+ * Throws a `TypeError` exception because the map is read-only.
36
+ *
37
+ * @param key - The key of the element to remove from the map.
38
+ * @throws {@link !TypeError} Indeed: map is read-only.
39
+ */
40
+ delete(key: K): never;
41
+ /**
42
+ * Throws a `TypeError` exception because the map is read-only.
43
+ *
44
+ * @throws {@link !TypeError} Indeed: map is read-only.
45
+ */
46
+ clear(): never;
47
+ }
48
+ //# sourceMappingURL=map.d.ts.map
package/dist/map.js ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * This module provides Map-related utilities, including a read-only Map implementation.
3
+ *
4
+ * @module
5
+ * @importTarget ./map
6
+ */
7
+ /**
8
+ * A read-only Map implementation that conforms to the `ReadonlyMap` interface.
9
+ * This class provides a wrapper around `Map` to enforce immutability.
10
+ *
11
+ * @typeParam K - The type of keys maintained by this map.
12
+ * @typeParam V - The type of mapped values.
13
+ */
14
+ export class ROMap extends Map {
15
+ /**
16
+ * Constructs a new instance of the class with an optional collection of entries.
17
+ *
18
+ * @param entries - An optional iterable object containing key-value pairs (tuples) to initialize the map.
19
+ * If not provided or set to `Nil`, the map will be empty.
20
+ * @typeParam K - The type of the keys in the map.
21
+ * @typeParam V - The type of the values in the map.
22
+ */
23
+ constructor(entries) {
24
+ super(entries);
25
+ createdMaps.add(this);
26
+ }
27
+ /**
28
+ * Throws a `TypeError` exception because the map is read-only.
29
+ *
30
+ * @param args - The arguments to be passed to the `Map.set` method.
31
+ * @returns This method does not return a value.
32
+ * @throws {@link !TypeError} Indeed: map is read-only.
33
+ * @privateRemarks It works as original `Map#set` when invoked from the constructor.
34
+ */
35
+ set(...args) {
36
+ if (createdMaps.has(this)) {
37
+ throw new TypeError(`Cannot set key ${String(args[0])}: map is read-only`);
38
+ }
39
+ // reachable from constructor only
40
+ return super.set(...args);
41
+ }
42
+ /**
43
+ * Throws a `TypeError` exception because the map is read-only.
44
+ *
45
+ * @param key - The key of the element to remove from the map.
46
+ * @throws {@link !TypeError} Indeed: map is read-only.
47
+ */
48
+ delete(key) {
49
+ throw new TypeError(`Cannot delete key ${String(key)}: map is read-only`);
50
+ }
51
+ /**
52
+ * Throws a `TypeError` exception because the map is read-only.
53
+ *
54
+ * @throws {@link !TypeError} Indeed: map is read-only.
55
+ */
56
+ clear() {
57
+ throw new TypeError('Cannot clear map: map is read-only');
58
+ }
59
+ }
60
+ const createdMaps = new WeakSet();
61
+ /*
62
+ * This approach is slightly unconventional, but it allows the class to serve as
63
+ * a transparent implementation of the `ReadonlyMap` type.
64
+ */
65
+ [
66
+ [ROMap, 'name'],
67
+ [ROMap.prototype, Symbol.toStringTag],
68
+ ].forEach(([obj, prop]) => {
69
+ Object.defineProperty(obj, prop, {
70
+ value: 'ReadonlyMap',
71
+ configurable: true,
72
+ });
73
+ });
74
+ //# sourceMappingURL=map.js.map
package/dist/object.d.ts CHANGED
@@ -1,21 +1,100 @@
1
- import type { ConditionalExcept } from 'type-fest';
2
- import type { OmitNilProps, Value } from '@budsbox/lib-types/object';
3
- export declare function pick<T extends object, Keys extends PropertyKey = keyof T>(source: T, ...keys: readonly Keys[]): Pick<T, Keys & keyof T>;
4
- export declare const pickStrict: <T extends object, Keys extends keyof T = keyof T>(source: T, ...keys: readonly Keys[]) => Pick<T, Keys>;
1
+ /**
2
+ * Object utility functions for selecting, omitting, filtering, reducing, and
3
+ * strongly-typing common object operations.
4
+ *
5
+ * @module
6
+ * @importTarget ./object
7
+ */
8
+ import type { ValueOf } from 'type-fest';
9
+ import type { AnyRecord, EntryUnion, OmitNilProps } from '@budsbox/lib-types';
10
+ /**
11
+ * Creates an object composed of the picked `source` properties.
12
+ *
13
+ * @param source - The source object.
14
+ * @param keys - The property keys to pick.
15
+ * @returns A new object with the picked properties.
16
+ * @typeParam TSource - The type of the source object.
17
+ * @typeParam TKeys - The type of the keys to pick.
18
+ */
19
+ export declare function pick<TSource extends object, TKeys extends PropertyKey = keyof TSource>(source: TSource, ...keys: readonly TKeys[]): Pick<TSource, TKeys & keyof TSource>;
20
+ /**
21
+ * A strict version of {@link pick} that restricts keys to those present in `TSource`.
22
+ *
23
+ * @param source - The source object.
24
+ * @param keys - The property keys to pick.
25
+ * @returns A new object with the picked properties.
26
+ * @typeParam TSource - The type of the source object.
27
+ * @typeParam Keys - The type of the keys to pick, restricted to keys of `TSource`.
28
+ */
29
+ export declare const pickStrict: <TSource extends object, Keys extends keyof TSource = keyof TSource>(source: TSource, ...keys: readonly Keys[]) => Pick<TSource, Keys>;
30
+ /**
31
+ * The opposite of {@link pick}; this method creates an object
32
+ * composed of the own enumerable string keyed properties of `source` that are not omitted.
33
+ *
34
+ * @param source - The source object.
35
+ * @param keys - The property keys to omit.
36
+ * @returns A new object without the omitted properties.
37
+ * @typeParam T - The type of the source object.
38
+ * @typeParam K - The type of the keys to omit.
39
+ */
5
40
  export declare function omit<T extends object, K extends PropertyKey>(source: T, ...keys: readonly K[]): Omit<T, K>;
41
+ /**
42
+ * A strict version of {@link omit} that restricts keys to those present in `TSource`.
43
+ *
44
+ * @param source - The source object.
45
+ * @param keys - The property keys to omit.
46
+ * @returns A new object without the omitted properties.
47
+ * @typeParam TSource - The type of the source object.
48
+ * @typeParam TKey - The type of the keys to omit, restricted to keys of `TSource`.
49
+ */
6
50
  export declare const omitStrict: <TSource extends object, TKey extends keyof TSource>(source: TSource, ...keys: readonly TKey[]) => Omit<TSource, TKey>;
7
- export declare function filterBy<T, K extends string, R extends T>(value: Partial<Record<K, T>>, test: (value: T) => value is R): ConditionalExcept<Record<K, T>, R>;
8
- export declare function filterBy<T, K extends string, R extends T>(value: Partial<Record<K, T>> | Record<K, T>, test: (value: T) => value is R): ConditionalExcept<Record<K, T>, R>;
9
- export declare function filterBy<V extends object>(obj: V, filter: (value: V[keyof V], key: keyof V, obj: V) => boolean): Partial<V>;
51
+ /**
52
+ * Iterates over own enumerable string keyed properties of an object and returns a new object
53
+ * with all properties that pass `test`.
54
+ *
55
+ * @param obj - The object to filter.
56
+ * @param test - The function invoked per iteration.
57
+ * @returns A new object containing properties that satisfy the predicate.
58
+ * @typeParam TSource - The type of the source object.
59
+ */
60
+ export declare function filter<TSource extends object>(obj: TSource, test: (value: ValueOf<TSource>, key: keyof TSource, obj: TSource) => boolean): Partial<TSource>;
61
+ /**
62
+ * Returns a new object with all `null` or `undefined` properties removed using {@link filter} and {@link isNotNil}.
63
+ *
64
+ * @param object - The object to strip of nils.
65
+ * @returns A new object without nil properties.
66
+ * @typeParam T - The type of the source object.
67
+ */
10
68
  export declare function omitNils<T extends object>(object: T): OmitNilProps<T>;
11
- export declare function reduce<U>(obj: Readonly<Record<string, unknown>>, callback: (previousValue: U, currentValue: Value<typeof obj>, currentKey: keyof typeof obj, object: typeof obj) => U, initialValue: Partial<U>): U;
12
69
  /**
13
- * Returns the first key of the given object.
14
- * Useful when working with objects that have only one key.
70
+ * Transforms the values of an object using the provided callback function.
71
+ *
72
+ * @param object - The source object whose values are to be transformed.
73
+ * @param callback - A function that is called for each key-value pair in the source object.
74
+ * It receives the value, key, and the original object as arguments and returns the transformed value.
75
+ * @returns A new object with the same keys as the source object but with values transformed by the callback function.
76
+ * @typeParam TSource - The type of the source object.
77
+ * @typeParam TValue - The type of the transformed values in the resulting object.
78
+ */
79
+ export declare const map: <TSource extends AnyRecord, TValue>(object: TSource, callback: (value: ValueOf<TSource>, key: keyof TSource, object: TSource) => TValue) => Record<keyof TSource, TValue>;
80
+ /**
81
+ * Reduces `obj` to a value which is the accumulated result of running each element in `obj`
82
+ * through `callback`.
83
+ *
84
+ * @param obj - The object to iterate over.
85
+ * @param callback - The function invoked per iteration.
86
+ * @param initialValue - The initial value of the accumulation.
87
+ * @returns The accumulated value.
88
+ * @typeParam TSource - The type of the source object.
89
+ * @typeParam TResult - The type of the accumulated result.
90
+ */
91
+ export declare function reduce<TSource extends object, TResult>(obj: TSource, callback: (previousValue: TResult, currentValue: ValueOf<TSource>, currentKey: keyof TSource, object: TSource) => TResult, initialValue: Partial<TResult>): TResult;
92
+ /**
93
+ * Returns an array of a given object's own enumerable string-keyed property [key, value] pairs, typed as {@link EntryUnion}.
15
94
  *
16
- * @param value
95
+ * @param source - The object whose entries are to be returned.
96
+ * @returns An array of entry tuples.
97
+ * @typeParam T - The type of the source object.
17
98
  */
18
- export declare function getKey<T extends string>(value: Record<T, unknown>): T;
19
- export declare function getKey<T extends string>(value: Partial<Record<T, unknown>>): T | undefined;
20
- export declare function getKey<T extends object>(value: T): keyof T;
99
+ export declare const entries: <T extends object>(source: T) => Array<EntryUnion<T>>;
21
100
  //# sourceMappingURL=object.d.ts.map