@1nkvi/utils 0.1.3 → 0.2.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,9 @@
1
+ /**
2
+ * Creates array from `startIndex` to `length¨
3
+ *
4
+ * Useful for quickly creating skeleton placeholders
5
+ *
6
+ * @param length size of the array
7
+ * @param startIndex defaults to 0
8
+ */
9
+ export declare function createArray(length: number, startIndex?: number): number[];
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Creates array from `startIndex` to `length¨
3
+ *
4
+ * Useful for quickly creating skeleton placeholders
5
+ *
6
+ * @param length size of the array
7
+ * @param startIndex defaults to 0
8
+ */
9
+ export function createArray(length, startIndex = 0) {
10
+ return Array.from({ length }, (_, i) => i + startIndex);
11
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns array of numbers from interval `<min, max>`
3
+ * @param min min value (inclusive)
4
+ * @param max max value (inclusive)
5
+ * @example ```tsx
6
+ * createRangeArray(-2, 1) // [-2, -1, 0, 1]
7
+ * ```
8
+ */
9
+ export declare function createRangeArray(min: number, max: number): number[];
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns array of numbers from interval `<min, max>`
3
+ * @param min min value (inclusive)
4
+ * @param max max value (inclusive)
5
+ * @example ```tsx
6
+ * createRangeArray(-2, 1) // [-2, -1, 0, 1]
7
+ * ```
8
+ */
9
+ export function createRangeArray(min, max) {
10
+ return Array.from({ length: max - min + 1 }, (_, i) => min + i);
11
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./tuplify";
2
+ export * from "./createArray";
3
+ export * from "./createRangeArray";
@@ -0,0 +1,3 @@
1
+ export * from "./tuplify";
2
+ export * from "./createArray";
3
+ export * from "./createRangeArray";
@@ -0,0 +1 @@
1
+ export * from "./triggerExhaustiveSwitch";
@@ -0,0 +1 @@
1
+ export * from "./triggerExhaustiveSwitch";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Used for checking that all values are accounted for in a switch
3
+ * ```typescript
4
+ * type Test = "a"|"b"|"c"
5
+ * switch(test) {
6
+ * case "a": ...
7
+ * case "b": ...
8
+ * default: triggerExhaustiveSwitch(test, "My component name")
9
+ * }
10
+ * ```
11
+ * @param value value in switch
12
+ * @param componentName name used for debugging purposes. Usually name of the component where switch lives
13
+ */
14
+ export declare function triggerExhaustiveSwitch(value: never, componentName: string): never;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Used for checking that all values are accounted for in a switch
3
+ * ```typescript
4
+ * type Test = "a"|"b"|"c"
5
+ * switch(test) {
6
+ * case "a": ...
7
+ * case "b": ...
8
+ * default: triggerExhaustiveSwitch(test, "My component name")
9
+ * }
10
+ * ```
11
+ * @param value value in switch
12
+ * @param componentName name used for debugging purposes. Usually name of the component where switch lives
13
+ */
14
+ export function triggerExhaustiveSwitch(value, componentName) {
15
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
16
+ throw new Error(`Unhandled ${componentName} type for value [${value}]`);
17
+ }
@@ -1,5 +1,5 @@
1
- export * from "./merge/merge";
2
- export * from "./merge/mergeArrays";
3
- export * from "./merge/utils";
4
- export * from "./merge/filterValidPrimitiveArrayValues";
5
- export * from "./tuplify";
1
+ export * from "./array";
2
+ export * from "./merge";
3
+ export * from "./guard";
4
+ export * from "./map";
5
+ export * from "./random";
@@ -1,5 +1,5 @@
1
- export * from "./merge/merge";
2
- export * from "./merge/mergeArrays";
3
- export * from "./merge/utils";
4
- export * from "./merge/filterValidPrimitiveArrayValues";
5
- export * from "./tuplify";
1
+ export * from "./array";
2
+ export * from "./merge";
3
+ export * from "./guard";
4
+ export * from "./map";
5
+ export * from "./random";
@@ -0,0 +1 @@
1
+ export * from "./upsert";
@@ -0,0 +1 @@
1
+ export * from "./upsert";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Upserts existing map by `value`, following the `fn` behavior
3
+ * @param map existing map
4
+ * @param key key to be upserted
5
+ * @param value value to be upserted
6
+ * @param fn function used when value exists in the map
7
+ * @example ```tsx
8
+ * const map = new Map<string, string[]>()
9
+ * map.set("a", ["1", "2"])
10
+ * upsert(map, "a", ["3"], (prev, value) => [...prev, ...value])
11
+ * // output: ["1", "2", "3"]
12
+ * ```
13
+ * @remarks if key does not exist, sets the value
14
+ */
15
+ export declare function upsert<TKey, TValue>(map: Map<TKey, TValue>, key: TKey, value: TValue, fn: (prev: TValue, value: TValue) => TValue): TValue;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Upserts existing map by `value`, following the `fn` behavior
3
+ * @param map existing map
4
+ * @param key key to be upserted
5
+ * @param value value to be upserted
6
+ * @param fn function used when value exists in the map
7
+ * @example ```tsx
8
+ * const map = new Map<string, string[]>()
9
+ * map.set("a", ["1", "2"])
10
+ * upsert(map, "a", ["3"], (prev, value) => [...prev, ...value])
11
+ * // output: ["1", "2", "3"]
12
+ * ```
13
+ * @remarks if key does not exist, sets the value
14
+ */
15
+ export function upsert(map, key, value, fn) {
16
+ if (map.has(key)) {
17
+ const prev = map.get(key);
18
+ const next = fn(prev, value);
19
+ map.set(key, next);
20
+ return next;
21
+ }
22
+ map.set(key, value);
23
+ return value;
24
+ }
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Expects json object. Walks through the children and makes all keys optional
3
+ */
1
4
  export type DeepPartial<T> = T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends object ? {
2
5
  [K in keyof T]?: DeepPartial<T[K]>;
3
6
  } : T;
@@ -0,0 +1,4 @@
1
+ export * from "./merge";
2
+ export * from "./mergeArrays";
3
+ export * from "./utils";
4
+ export * from "./filterValidPrimitiveArrayValues";
@@ -0,0 +1,4 @@
1
+ export * from "./merge";
2
+ export * from "./mergeArrays";
3
+ export * from "./utils";
4
+ export * from "./filterValidPrimitiveArrayValues";
@@ -1,6 +1,6 @@
1
1
  import { isInvalidPrimitive } from "../merge/isInvalidPrimitive";
2
2
  import { isPlainObject } from "../merge/utils";
3
- import { tuplify } from "../tuplify";
3
+ import { tuplify } from "../array/tuplify";
4
4
  import { mergeArrays } from "../merge/mergeArrays";
5
5
  /**
6
6
  * Deeply merges inputs into new object. Generally goes through the following steps:
@@ -0,0 +1 @@
1
+ export * from "../random/random";
@@ -0,0 +1 @@
1
+ export * from "../random/random";
@@ -0,0 +1,63 @@
1
+ export interface RandomOptions {
2
+ excludeMin?: true;
3
+ excludeMax?: true;
4
+ }
5
+ /**
6
+ * Returns random integer number between `min` and `max` based on the `options`
7
+ * @param min min value (inclusive by default). Must be less than `max`
8
+ * @param max max value (inclusive by default). Must be greater than `min`
9
+ * @param options further options for modifying generator behavior
10
+ *
11
+ * @example ```tsx
12
+ * random(1, 10)
13
+ * // returns single value from inclusive interval <1, 10>
14
+ * ```
15
+ */
16
+ export declare function random(min: number, max: number, options?: RandomOptions): number;
17
+ export interface RandomMarginalChangeOptions {
18
+ /**
19
+ * Value added to the `min` in the random function
20
+ * @default 0
21
+ */
22
+ minFixed?: number;
23
+ /**
24
+ * Value added to the `max` in the random function
25
+ * @default 0
26
+ */
27
+ maxFixed?: number;
28
+ /**
29
+ * Percentage value (as decimal) multiplied the resulting `min` in the random function
30
+ * @default 1.00
31
+ */
32
+ minPercentage?: number;
33
+ /**
34
+ * Percentage value (as decimal) multiplied the resulting `max` in the random function
35
+ * @default 1.00
36
+ */
37
+ maxPercentage?: number;
38
+ /**
39
+ * Return this number if computed result is less than absolute minimum
40
+ */
41
+ absoluteMin?: number;
42
+ /**
43
+ * Return this number if computed result is greater than absolute maximum
44
+ */
45
+ absoluteMax?: number;
46
+ }
47
+ /**
48
+ * Takes initial value and creates marginal change based on options values.
49
+ *
50
+ * Insert percentages as decimals - 100% = 1.00; 1% = 0.01 calculated from initial value.
51
+ * @example
52
+ * ```typescript
53
+ * randomMarginalChange(100, {minFixed: -10, maxFixed: 10, minPercentage: 0.9, maxPercentage: 1.1})
54
+ * // results in interval min: (100 - 10) * 0.9; max: (100 + 10) * 1.1
55
+ * // where result will be <89; 121>
56
+ *
57
+ * ```
58
+ * @remark Returns floored random value
59
+ *
60
+ * @param value initial value to be derived
61
+ * @param options fixed values default to 0, percentage values defaults to 1
62
+ */
63
+ export declare function randomMarginalChange(value: number, options: RandomMarginalChangeOptions): number;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Returns random integer number between `min` and `max` based on the `options`
3
+ * @param min min value (inclusive by default). Must be less than `max`
4
+ * @param max max value (inclusive by default). Must be greater than `min`
5
+ * @param options further options for modifying generator behavior
6
+ *
7
+ * @example ```tsx
8
+ * random(1, 10)
9
+ * // returns single value from inclusive interval <1, 10>
10
+ * ```
11
+ */
12
+ export function random(min, max, options) {
13
+ if (min === max) {
14
+ return Math.floor(min);
15
+ }
16
+ if (min > max || max < min) {
17
+ throw new Error(`Min must be greater than max. Got min: ${min}, max: ${max}`);
18
+ }
19
+ if (Math.abs(Math.floor(min) - Math.floor(max)) === 1 && options?.excludeMin && options?.excludeMax) {
20
+ throw new Error(`Cannot generate random non-inclusive value from interval (${min}; ${max})`);
21
+ }
22
+ if (options?.excludeMin) {
23
+ return Math.floor(Math.random() * (max - min)) + min + 1;
24
+ }
25
+ if (options?.excludeMax) {
26
+ return Math.floor(Math.random() * (max - min)) + min;
27
+ }
28
+ return Math.floor(Math.random() * (max - min + 1)) + min;
29
+ }
30
+ /**
31
+ * Takes initial value and creates marginal change based on options values.
32
+ *
33
+ * Insert percentages as decimals - 100% = 1.00; 1% = 0.01 calculated from initial value.
34
+ * @example
35
+ * ```typescript
36
+ * randomMarginalChange(100, {minFixed: -10, maxFixed: 10, minPercentage: 0.9, maxPercentage: 1.1})
37
+ * // results in interval min: (100 - 10) * 0.9; max: (100 + 10) * 1.1
38
+ * // where result will be <89; 121>
39
+ *
40
+ * ```
41
+ * @remark Returns floored random value
42
+ *
43
+ * @param value initial value to be derived
44
+ * @param options fixed values default to 0, percentage values defaults to 1
45
+ */
46
+ export function randomMarginalChange(value, options) {
47
+ const min = (value + (options.minFixed ?? 0)) * (options.minPercentage ?? 1);
48
+ const max = (value + (options.maxFixed ?? 0)) * (options.maxPercentage ?? 1);
49
+ const computedResult = Math.round(random(min, max));
50
+ if (options.absoluteMin && computedResult < options.absoluteMin) {
51
+ return options.absoluteMin;
52
+ }
53
+ if (options.absoluteMax && computedResult > options.absoluteMax) {
54
+ return options.absoluteMax;
55
+ }
56
+ return computedResult;
57
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1nkvi/utils",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Helper functions",
5
5
  "keywords": [
6
6
  "merge"