utilitish 0.0.5 → 0.0.6

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.
@@ -53,26 +53,30 @@ declare global {
53
53
  *
54
54
  * @example
55
55
  * // 1D array with primitive values
56
- * Array.create('x', 5);
57
- * // => ['x', 'x', 'x', 'x', 'x']
56
+ * const arr1 = Array.create('x', 5);
57
+ * // type: string[]
58
+ * // value: ['x', 'x', 'x', 'x', 'x']
58
59
  *
59
60
  * @example
60
61
  * // 1D array with random numbers
61
- * Array.create(() => Math.random(), 5);
62
- * // => [0.12, 0.87, 0.45, 0.76, 0.33] (values will differ)
62
+ * const arr2 = Array.create(() => Math.random(), 5);
63
+ * // type: number[]
64
+ * // value: [0.12, 0.87, 0.45, 0.76, 0.33] (values will differ)
63
65
  *
64
66
  * @example
65
67
  * // 2D array (matrix)
66
- * Array.create(0, 2, 3);
67
- * // => [[0, 0, 0], [0, 0, 0]]
68
+ * const arr3 = Array.create(0, 2, 3);
69
+ * // type: number[][]
70
+ * // value: [[0, 0, 0], [0, 0, 0]]
68
71
  *
69
72
  * @example
70
73
  * // 2D array with distinct objects
71
- * Array.create(() => ({ id: 0 }), 2, 3);
72
- * // => [
73
- * // [{id:0}, {id:0}, {id:0}],
74
- * // [{id:0}, {id:0}, {id:0}]
75
- * // ]
74
+ * const arr4 = Array.create(() => ({ id: 0 }), 2, 3);
75
+ * // type: { id: number }[][]
76
+ * // value: [
77
+ * // [{ id: 0 }, { id: 0 }, { id: 0 }],
78
+ * // [{ id: 0 }, { id: 0 }, { id: 0 }]
79
+ * // ]
76
80
  *
77
81
  * @notes
78
82
  * - If `sizes.length === 0`, returns `[]`.
@@ -83,11 +87,13 @@ declare global {
83
87
  * @template T
84
88
  * @param {T | (() => T)} valueOrFactory The value to fill the array with, or a factory function producing values.
85
89
  * @param {...number} sizes Sizes for each dimension (1D => one number, 2D => two numbers, etc.).
86
- * @returns {any[]} A multi-dimensional array of depth `sizes.length` filled with values from `valueOrFactory`.
90
+ * @returns {Array} A multi-dimensional array of the specified depth filled with the given values.
87
91
  *
88
92
  * @remarks
89
93
  * - This method is **static** and must be called on `Array`, not on an instance.
90
94
  */
91
- create<T>(valueOrFactory: T | (() => T), ...sizes: number[]): any[];
95
+ create<T, Dims extends number[]>(valueOrFactory: T | (() => T), ...sizes: Dims): MultiDimensionalArray<WidenLiterals<T>, Dims>;
92
96
  }
93
97
  }
98
+ type MultiDimensionalArray<T, Dims extends number[]> = Dims extends [number, ...infer Rest extends number[]] ? MultiDimensionalArray<T[], Rest> : T;
99
+ type WidenLiterals<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import './array/array-constructor';
2
2
  import './array/array-prototype';
3
+ import './map/map-prototype';
3
4
  import './object/object-prototype';
5
+ import './set/set-prototype';
4
6
  import './string/string-prototype';
package/dist/index.js CHANGED
@@ -2,5 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("./array/array-constructor");
4
4
  require("./array/array-prototype");
5
+ require("./map/map-prototype");
5
6
  require("./object/object-prototype");
7
+ require("./set/set-prototype");
6
8
  require("./string/string-prototype");
package/dist/utils.d.ts CHANGED
@@ -1,28 +1,103 @@
1
- export declare const defineIfNotExists: <T extends object>(prototype: T, name: string, fn: Function) => void;
2
1
  /**
3
- * Defines a **static** property on a constructor if it does not already exist
4
- * (or if the existing property is writable **or** configurable).
2
+ * Defines a **non-enumerable, non-writable, non-configurable** property on a prototype
3
+ * if it does not already exist, or if the existing property is writable or configurable.
4
+ *
5
+ * - Intended for instance prototype methods (e.g., `Array.prototype`, `String.prototype`).
6
+ * - Does **not** overwrite non-configurable and non-writable properties.
7
+ * - Ensures immutability and hides the property from enumeration.
8
+ *
9
+ * @example
10
+ * defineIfNotExists(Array.prototype, 'last', function() {
11
+ * return this[this.length - 1];
12
+ * });
5
13
  *
6
- * - Does **not** affect instance prototypes (use `defineIfNotExists` for `Foo.prototype`).
7
- * - The property is created with: { enumerable: false, configurable: false, writable: false }
8
- * making it non-enumerable and immutable after definition.
9
- * - If an existing property is non-configurable AND non-writable, it will **not** be replaced.
14
+ * @template T The prototype object type (e.g., `Array.prototype`).
15
+ * @param {T} prototype The prototype on which to define the method.
16
+ * @param {string} name The name of the method to define.
17
+ * @param {Function} fn The function to assign as the method.
18
+ *
19
+ * @remarks
20
+ * Use this function to safely add prototype methods without overwriting stable or built-in ones.
21
+ */
22
+ export declare const defineIfNotExists: <T extends object>(prototype: T, name: string, fn: Function) => void;
23
+ /**
24
+ * Defines a **static** property on a constructor if it does not already exist,
25
+ * or if the existing property is writable or configurable.
10
26
  *
11
- * @template T
12
- * @param {T} constructor The constructor object (e.g., `Array`, `String`, `Map`, ...)
13
- * @param {string} name The name of the static method to define (e.g., `'create'`, `'range'`)
14
- * @param {Function} fn The function to attach as a static property
27
+ * - Only affects static properties on constructors (e.g., `Array`, `Map`).
28
+ * - The property is created as non-enumerable, immutable, and non-configurable.
29
+ * - Does **not** overwrite existing properties that are non-configurable and non-writable.
15
30
  *
16
31
  * @example
17
- * // Define Array.range if possible
18
- * defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) { ... });
32
+ * defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) {
33
+ * // implementation
34
+ * });
35
+ *
36
+ * @template T The constructor type (e.g., `typeof Array`).
37
+ * @param {T} constructor The constructor object on which to define the static method.
38
+ * @param {string} name The name of the static method to define.
39
+ * @param {Function} fn The function to assign as the static method.
19
40
  *
20
41
  * @remarks
21
- * - To force replacement, delete the property first or use Object.defineProperty directly.
22
- * - This function is meant to standardize the addition of static methods in utilitish.
42
+ * To forcefully replace an existing property, delete it first or use `Object.defineProperty` directly.
23
43
  */
24
44
  export declare const defineStaticIfNotExists: <T extends object>(constructor: T, name: string, fn: Function) => void;
45
+ /**
46
+ * Resolves a selector parameter into a function that extracts a value from an item.
47
+ *
48
+ * The selector can be:
49
+ * - a key string of the object (returns the value at that key),
50
+ * - a function transforming the item to the desired value,
51
+ * - or undefined, in which case a fallback function must be provided.
52
+ *
53
+ * @example
54
+ * const sel1 = resolveSelector<{name: string}, string>('name');
55
+ * sel1({name: 'Alice'}); // 'Alice'
56
+ *
57
+ * const sel2 = resolveSelector<{value: number}, number>(item => item.value * 2);
58
+ * sel2({value: 5}); // 10
59
+ *
60
+ * const sel3 = resolveSelector(undefined, (item) => item.toString());
61
+ * sel3(42); // '42'
62
+ *
63
+ * @template T The type of the input items.
64
+ * @template R The type of the selected value.
65
+ * @param {keyof T | ((item: T) => R) | undefined} selector The selector key or function.
66
+ * @param {(item: T, index?: number) => R} [fallback] A fallback function if no selector is provided.
67
+ * @param {string} [name='selector'] Name used in error messages.
68
+ * @returns {(item: T, index?: number) => R} The resolved selector function.
69
+ *
70
+ * @throws {TypeError} If the selector is not a function or string key.
71
+ * @throws {TypeError} If no selector is provided and no fallback is given.
72
+ */
25
73
  export declare function resolveSelector<T, R>(selector?: keyof T | ((item: T) => R), fallback?: (item: T, index?: number) => R, name?: string): (item: T, index?: number) => R;
74
+ /**
75
+ * Asserts that a selector parameter is valid, i.e., a function or a string.
76
+ *
77
+ * @template T The type of the input items.
78
+ * @template R The type of the selected value.
79
+ * @param {any} selector The selector to validate.
80
+ * @param {string} [name='selector'] The name to use in error messages.
81
+ *
82
+ * @throws {TypeError} If the selector is neither a function nor a string.
83
+ *
84
+ * @remarks
85
+ * Used internally by `resolveSelector` to provide clearer type safety and errors.
86
+ */
26
87
  export declare function assertValidSelector<T, R>(selector: any, name?: string): asserts selector is Selector<T, R>;
88
+ /**
89
+ * Type guard to check if a value is a string or number.
90
+ *
91
+ * @example
92
+ * isNumberOrString('hello'); // true
93
+ * isNumberOrString(42); // true
94
+ * isNumberOrString(true); // false
95
+ *
96
+ * @param {unknown} value The value to test.
97
+ * @returns {value is string | number} True if the value is a string or number, else false.
98
+ */
27
99
  export declare function isNumberOrString(value: unknown): value is string | number;
100
+ /**
101
+ * Type for a selector: either a key of T or a function from T to K.
102
+ */
28
103
  export type Selector<T, K> = keyof T | ((item: T) => K);
package/dist/utils.js CHANGED
@@ -4,6 +4,27 @@ exports.defineStaticIfNotExists = exports.defineIfNotExists = void 0;
4
4
  exports.resolveSelector = resolveSelector;
5
5
  exports.assertValidSelector = assertValidSelector;
6
6
  exports.isNumberOrString = isNumberOrString;
7
+ /**
8
+ * Defines a **non-enumerable, non-writable, non-configurable** property on a prototype
9
+ * if it does not already exist, or if the existing property is writable or configurable.
10
+ *
11
+ * - Intended for instance prototype methods (e.g., `Array.prototype`, `String.prototype`).
12
+ * - Does **not** overwrite non-configurable and non-writable properties.
13
+ * - Ensures immutability and hides the property from enumeration.
14
+ *
15
+ * @example
16
+ * defineIfNotExists(Array.prototype, 'last', function() {
17
+ * return this[this.length - 1];
18
+ * });
19
+ *
20
+ * @template T The prototype object type (e.g., `Array.prototype`).
21
+ * @param {T} prototype The prototype on which to define the method.
22
+ * @param {string} name The name of the method to define.
23
+ * @param {Function} fn The function to assign as the method.
24
+ *
25
+ * @remarks
26
+ * Use this function to safely add prototype methods without overwriting stable or built-in ones.
27
+ */
7
28
  const defineIfNotExists = (prototype, name, fn) => {
8
29
  const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
9
30
  if (!descriptor || descriptor.writable || descriptor.configurable) {
@@ -17,26 +38,25 @@ const defineIfNotExists = (prototype, name, fn) => {
17
38
  };
18
39
  exports.defineIfNotExists = defineIfNotExists;
19
40
  /**
20
- * Defines a **static** property on a constructor if it does not already exist
21
- * (or if the existing property is writable **or** configurable).
41
+ * Defines a **static** property on a constructor if it does not already exist,
42
+ * or if the existing property is writable or configurable.
22
43
  *
23
- * - Does **not** affect instance prototypes (use `defineIfNotExists` for `Foo.prototype`).
24
- * - The property is created with: { enumerable: false, configurable: false, writable: false }
25
- * making it non-enumerable and immutable after definition.
26
- * - If an existing property is non-configurable AND non-writable, it will **not** be replaced.
27
- *
28
- * @template T
29
- * @param {T} constructor The constructor object (e.g., `Array`, `String`, `Map`, ...)
30
- * @param {string} name The name of the static method to define (e.g., `'create'`, `'range'`)
31
- * @param {Function} fn The function to attach as a static property
44
+ * - Only affects static properties on constructors (e.g., `Array`, `Map`).
45
+ * - The property is created as non-enumerable, immutable, and non-configurable.
46
+ * - Does **not** overwrite existing properties that are non-configurable and non-writable.
32
47
  *
33
48
  * @example
34
- * // Define Array.range if possible
35
- * defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) { ... });
49
+ * defineStaticIfNotExists(Array, 'range', function(start: number, end?: number) {
50
+ * // implementation
51
+ * });
52
+ *
53
+ * @template T The constructor type (e.g., `typeof Array`).
54
+ * @param {T} constructor The constructor object on which to define the static method.
55
+ * @param {string} name The name of the static method to define.
56
+ * @param {Function} fn The function to assign as the static method.
36
57
  *
37
58
  * @remarks
38
- * - To force replacement, delete the property first or use Object.defineProperty directly.
39
- * - This function is meant to standardize the addition of static methods in utilitish.
59
+ * To forcefully replace an existing property, delete it first or use `Object.defineProperty` directly.
40
60
  */
41
61
  const defineStaticIfNotExists = (constructor, name, fn) => {
42
62
  const descriptor = Object.getOwnPropertyDescriptor(constructor, name);
@@ -50,6 +70,34 @@ const defineStaticIfNotExists = (constructor, name, fn) => {
50
70
  }
51
71
  };
52
72
  exports.defineStaticIfNotExists = defineStaticIfNotExists;
73
+ /**
74
+ * Resolves a selector parameter into a function that extracts a value from an item.
75
+ *
76
+ * The selector can be:
77
+ * - a key string of the object (returns the value at that key),
78
+ * - a function transforming the item to the desired value,
79
+ * - or undefined, in which case a fallback function must be provided.
80
+ *
81
+ * @example
82
+ * const sel1 = resolveSelector<{name: string}, string>('name');
83
+ * sel1({name: 'Alice'}); // 'Alice'
84
+ *
85
+ * const sel2 = resolveSelector<{value: number}, number>(item => item.value * 2);
86
+ * sel2({value: 5}); // 10
87
+ *
88
+ * const sel3 = resolveSelector(undefined, (item) => item.toString());
89
+ * sel3(42); // '42'
90
+ *
91
+ * @template T The type of the input items.
92
+ * @template R The type of the selected value.
93
+ * @param {keyof T | ((item: T) => R) | undefined} selector The selector key or function.
94
+ * @param {(item: T, index?: number) => R} [fallback] A fallback function if no selector is provided.
95
+ * @param {string} [name='selector'] Name used in error messages.
96
+ * @returns {(item: T, index?: number) => R} The resolved selector function.
97
+ *
98
+ * @throws {TypeError} If the selector is not a function or string key.
99
+ * @throws {TypeError} If no selector is provided and no fallback is given.
100
+ */
53
101
  function resolveSelector(selector, fallback, name = 'selector') {
54
102
  assertValidSelector(selector);
55
103
  if (typeof selector === 'function') {
@@ -69,12 +117,36 @@ function resolveSelector(selector, fallback, name = 'selector') {
69
117
  }
70
118
  throw new TypeError(`fallback must be given if no selector`);
71
119
  }
120
+ /**
121
+ * Asserts that a selector parameter is valid, i.e., a function or a string.
122
+ *
123
+ * @template T The type of the input items.
124
+ * @template R The type of the selected value.
125
+ * @param {any} selector The selector to validate.
126
+ * @param {string} [name='selector'] The name to use in error messages.
127
+ *
128
+ * @throws {TypeError} If the selector is neither a function nor a string.
129
+ *
130
+ * @remarks
131
+ * Used internally by `resolveSelector` to provide clearer type safety and errors.
132
+ */
72
133
  function assertValidSelector(selector, name = 'selector') {
73
134
  const isValid = typeof selector === 'function' || typeof selector === 'string';
74
135
  if (selector !== undefined && !isValid) {
75
136
  throw new TypeError(`${name} must be a function or a string key`);
76
137
  }
77
138
  }
139
+ /**
140
+ * Type guard to check if a value is a string or number.
141
+ *
142
+ * @example
143
+ * isNumberOrString('hello'); // true
144
+ * isNumberOrString(42); // true
145
+ * isNumberOrString(true); // false
146
+ *
147
+ * @param {unknown} value The value to test.
148
+ * @returns {value is string | number} True if the value is a string or number, else false.
149
+ */
78
150
  function isNumberOrString(value) {
79
151
  return typeof value === 'string' || typeof value === 'number';
80
152
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "utilitish",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",