@vpmedia/simplify 1.61.0 โ†’ 1.63.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/CHANGELOG.md CHANGED
@@ -1,3 +1,49 @@
1
+ ## [1.63.0] - 2026-01-28
2
+
3
+ ### ๐Ÿ’ผ Other
4
+
5
+ - *(deps)* Bump dependency versions
6
+ - *(deps)* Bump dependency versions
7
+ - *(deps)* Bump dependency versions
8
+ - *(deps)* Bump dependency versions
9
+ - *(deps)* Bump dependency versions
10
+ - *(deps)* Bump dependency versions
11
+ - *(deps)* Bump dependency versions
12
+ - *(deps)* Bump dependency versions
13
+ - *(deps)* Bump dependency versions
14
+ - *(deps)* Bump dependency versions
15
+ - *(deps)* Bump dependency versions
16
+ - *(deps)* Bump dependency versions
17
+ - *(deps)* Bump dependency versions
18
+ - *(deps)* Bump dependency versions
19
+ - *(deps)* Bump dependency versions
20
+ - *(deps)* Bump dependency versions
21
+ - *(deps)* Bump dependency versions
22
+
23
+ ### ๐Ÿšœ Refactor
24
+
25
+ - Improve fetch retry options and abort usage
26
+
27
+ ### ๐Ÿงช Testing
28
+
29
+ - Optimize vitest performance, use standard config format
30
+
31
+ ### โš™๏ธ Miscellaneous Tasks
32
+
33
+ - Release
34
+ - Use eslint plugin jsdoc typescript flavor
35
+ - Regenerate types
36
+ - *(release)* V1.63.0
37
+ ## [1.62.0] - 2026-01-14
38
+
39
+ ### ๐Ÿงช Testing
40
+
41
+ - Improve test coverage, added getTypedError
42
+
43
+ ### โš™๏ธ Miscellaneous Tasks
44
+
45
+ - Release
46
+ - *(release)* V1.62.0
1
47
  ## [1.61.0] - 2026-01-14
2
48
 
3
49
  ### ๐Ÿšœ Refactor
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpmedia/simplify",
3
- "version": "1.61.0",
3
+ "version": "1.63.0",
4
4
  "description": "@vpmedia/simplify",
5
5
  "author": "Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)",
6
6
  "license": "MIT",
@@ -19,36 +19,31 @@
19
19
  "types": "./types/index.d.ts",
20
20
  "type": "module",
21
21
  "dependencies": {
22
- "eventemitter3": "^5.0.1"
22
+ "eventemitter3": "^5.0.4"
23
23
  },
24
24
  "optionalDependencies": {
25
- "@sentry/browser": "^10.33.0"
25
+ "@sentry/browser": "^10.37.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@commitlint/cli": "^20.3.1",
29
29
  "@commitlint/config-conventional": "^20.3.1",
30
30
  "@eslint/js": "^9.39.2",
31
- "@types/node": "^25.0.8",
32
- "@vitest/coverage-v8": "^4.0.17",
31
+ "@types/node": "^25.0.10",
32
+ "@vitest/coverage-v8": "^4.0.18",
33
33
  "eslint": "^9.39.2",
34
- "eslint-plugin-jsdoc": "^62.0.0",
35
- "eslint-plugin-oxlint": "^1.39.0",
34
+ "eslint-plugin-jsdoc": "^62.4.1",
35
+ "eslint-plugin-oxlint": "^1.42.0",
36
36
  "eslint-plugin-unicorn": "^62.0.0",
37
- "globals": "^17.0.0",
37
+ "globals": "^17.2.0",
38
38
  "jsdom": "^27.4.0",
39
- "oxlint": "^1.39.0",
40
- "oxlint-tsgolint": "^0.11.0",
41
- "prettier": "^3.7.4",
39
+ "msw": "^2.12.7",
40
+ "oxlint": "^1.42.0",
41
+ "oxlint-tsgolint": "^0.11.2",
42
+ "prettier": "^3.8.1",
42
43
  "typescript": "^5.9.3",
43
- "typescript-eslint": "^8.53.0",
44
- "vitest": "^4.0.17"
44
+ "typescript-eslint": "^8.54.0",
45
+ "vitest": "^4.0.18"
45
46
  },
46
- "browserslist": [
47
- "> 0.5%",
48
- "not dead",
49
- "not op_mini all",
50
- "iOS >= 14"
51
- ],
52
47
  "scripts": {
53
48
  "build": "rm -rf types && tsc -p ./tsconfig.build.json",
54
49
  "check": "pnpm build && pnpm lint && pnpm test && pnpm typecheck",
package/src/index.js CHANGED
@@ -20,7 +20,7 @@ export { typeChecker } from './typecheck/TypeChecker.js';
20
20
  export { TypeCheckError } from './typecheck/TypeCheckError.js';
21
21
  export { typeCheck, typeCheckArray, typeCheckEnum } from './typecheck/util.js';
22
22
  export { delayPromise, loadJSON } from './util/async.js';
23
- export { getErrorDetails } from './util/error.js';
23
+ export { getErrorDetails, getTypedError } from './util/error.js';
24
24
  export { FetchError, fetchRetry, HTTP_0_ANY } from './util/fetch.js';
25
25
  export {
26
26
  addFloat,
@@ -10,7 +10,7 @@ describe('delayPromise', () => {
10
10
  expect(end - start).toBeGreaterThanOrEqual(9);
11
11
  });
12
12
 
13
- test('Handles zero delay correctly', async () => {
13
+ test('delayPromise with zero delay', async () => {
14
14
  const start = Date.now();
15
15
  await delayPromise(0);
16
16
  const end = Date.now();
package/src/util/error.js CHANGED
@@ -22,3 +22,10 @@ export const getErrorDetails = (error, excludes = ['stack']) => {
22
22
  }
23
23
  return errorDetails;
24
24
  };
25
+
26
+ /**
27
+ * Get typed error from an unknown type.
28
+ * @param {unknown} error - The error to cast.
29
+ * @returns {Error} The typed error object.
30
+ */
31
+ export const getTypedError = (error) => (error instanceof Error ? error : new Error(String(error)));
@@ -1,20 +1,33 @@
1
- import { getErrorDetails } from './error.js';
1
+ /* eslint-disable unicorn/no-useless-undefined */
2
2
 
3
- test('Tests getErrorDetails', () => {
4
- const error = new Error('Test error', { cause: 'Test cause' });
5
- const errorDetails = getErrorDetails(error);
6
- expect(errorDetails.type).toBe('Error');
7
- expect(errorDetails.message).toBe('Test error');
8
- expect(errorDetails.cause).toBe('Test cause');
9
- });
3
+ import { getErrorDetails, getTypedError } from './error.js';
4
+
5
+ describe('error', () => {
6
+ test('getErrorDetails', () => {
7
+ const error = new Error('Test error', { cause: 'Test cause' });
8
+ const errorDetails = getErrorDetails(error);
9
+ expect(errorDetails.type).toBe('Error');
10
+ expect(errorDetails.message).toBe('Test error');
11
+ expect(errorDetails.cause).toBe('Test cause');
12
+ });
13
+
14
+ test('getErrorDetails with Error cause', () => {
15
+ const error = new SyntaxError('Test error', { cause: new TypeError('Cause error') });
16
+ const errorDetails = getErrorDetails(error);
17
+ expect(errorDetails.type).toBe('SyntaxError');
18
+ expect(errorDetails.message).toBe('Test error');
19
+ expect(errorDetails.cause instanceof Error).toBe(true);
20
+ if (errorDetails.cause instanceof Error) {
21
+ expect(errorDetails.cause.message).toBe('Cause error');
22
+ }
23
+ });
10
24
 
11
- test('Tests getErrorDetails with Error cause', () => {
12
- const error = new SyntaxError('Test error', { cause: new TypeError('Cause error') });
13
- const errorDetails = getErrorDetails(error);
14
- expect(errorDetails.type).toBe('SyntaxError');
15
- expect(errorDetails.message).toBe('Test error');
16
- expect(errorDetails.cause instanceof Error).toBe(true);
17
- if (errorDetails.cause instanceof Error) {
18
- expect(errorDetails.cause.message).toBe('Cause error');
19
- }
25
+ test('getTypedError', () => {
26
+ expect(getTypedError(new Error('Error message')).message).toBe('Error message');
27
+ expect(getTypedError('Error message').message).toBe('Error message');
28
+ expect(getTypedError(1).message).toBe('1');
29
+ expect(getTypedError(true).message).toBe('true');
30
+ expect(getTypedError(null).message).toBe('null');
31
+ expect(getTypedError(undefined).message).toBe('undefined');
32
+ });
20
33
  });
package/src/util/fetch.js CHANGED
@@ -54,12 +54,18 @@ export const fetchRetry = async (resource, fetchOptions, retryOptions) => {
54
54
  while (retryOptions.numTries > 0) {
55
55
  logger.info('request', { resource, fetchOptions, retryOptions });
56
56
  const controller = new AbortController();
57
- const timeoutId = setTimeout(() => controller.abort('Fetch timed out'), retryOptions.timeout);
58
- fetchOptions.signal = controller.signal;
57
+ const timeoutId = setTimeout(
58
+ () => controller.abort(new DOMException('Fetch timed out', 'AbortError')),
59
+ retryOptions.timeout
60
+ );
61
+ const options = {
62
+ ...fetchOptions,
63
+ signal: controller.signal,
64
+ };
59
65
  try {
60
- const response = await fetch(resource, fetchOptions);
66
+ const response = await fetch(resource, options);
61
67
  if (!response.ok) {
62
- throw new FetchError(`Fetch error ${response.status}`, resource, fetchOptions, response);
68
+ throw new FetchError(`Fetch error ${response.status}`, resource, options, response);
63
69
  }
64
70
  logger.info('response', response);
65
71
  return response;
@@ -1,45 +1,47 @@
1
1
  import { serverDataToState } from './state.js';
2
2
 
3
- test('serverDataToState() recursive', () => {
4
- const state = serverDataToState(
5
- {
6
- my_array: [{ key_a: 'value1' }],
7
- my_data: { key_a: 'value1' },
8
- my_list: [1, 2, 3],
9
- my_null: null,
10
- my_number: 1000,
11
- my_string: 'a',
12
- my_var: 'test',
13
- },
14
- true
15
- );
16
- expect(state.myArray[0].keyA).toBe('value1');
17
- expect(state.myData.keyA).toBe('value1');
18
- expect(state.myList[0]).toBe(1);
19
- expect(state.myNull).toBe(null);
20
- expect(state.myNumber).toBe(1000);
21
- expect(state.myString).toBe('a');
22
- expect(state.myVar).toBe('test');
23
- });
3
+ describe('state', () => {
4
+ test('serverDataToState() recursive', () => {
5
+ const state = serverDataToState(
6
+ {
7
+ my_array: [{ key_a: 'value1' }],
8
+ my_data: { key_a: 'value1' },
9
+ my_list: [1, 2, 3],
10
+ my_null: null,
11
+ my_number: 1000,
12
+ my_string: 'a',
13
+ my_var: 'test',
14
+ },
15
+ true
16
+ );
17
+ expect(state.myArray[0].keyA).toBe('value1');
18
+ expect(state.myData.keyA).toBe('value1');
19
+ expect(state.myList[0]).toBe(1);
20
+ expect(state.myNull).toBe(null);
21
+ expect(state.myNumber).toBe(1000);
22
+ expect(state.myString).toBe('a');
23
+ expect(state.myVar).toBe('test');
24
+ });
24
25
 
25
- test('serverDataToState() non-recursive', () => {
26
- const state = serverDataToState(
27
- {
28
- my_array: [{ key_a: 'value1' }],
29
- my_data: { key_a: 'value1' },
30
- my_list: [1, 2, 3],
31
- my_null: null,
32
- my_number: 1000,
33
- my_string: 'a',
34
- my_var: 'test',
35
- },
36
- false
37
- );
38
- expect(state.myArray[0].key_a).toBe('value1');
39
- expect(state.myData.key_a).toBe('value1');
40
- expect(state.myList[0]).toBe(1);
41
- expect(state.myNull).toBe(null);
42
- expect(state.myNumber).toBe(1000);
43
- expect(state.myString).toBe('a');
44
- expect(state.myVar).toBe('test');
26
+ test('serverDataToState() non-recursive', () => {
27
+ const state = serverDataToState(
28
+ {
29
+ my_array: [{ key_a: 'value1' }],
30
+ my_data: { key_a: 'value1' },
31
+ my_list: [1, 2, 3],
32
+ my_null: null,
33
+ my_number: 1000,
34
+ my_string: 'a',
35
+ my_var: 'test',
36
+ },
37
+ false
38
+ );
39
+ expect(state.myArray[0].key_a).toBe('value1');
40
+ expect(state.myData.key_a).toBe('value1');
41
+ expect(state.myList[0]).toBe(1);
42
+ expect(state.myNull).toBe(null);
43
+ expect(state.myNumber).toBe(1000);
44
+ expect(state.myString).toBe('a');
45
+ expect(state.myVar).toBe('test');
46
+ });
45
47
  });
@@ -1,70 +1,66 @@
1
1
  /* eslint-disable unicorn/no-useless-undefined */
2
2
 
3
- import { underscoreToCamelCase, capitalize, addLeadingZero, getTypeFromValue, getDisplayValue } from './string.js';
3
+ import {
4
+ underscoreToCamelCase,
5
+ capitalize,
6
+ addLeadingZero,
7
+ getTypeFromValue,
8
+ getDisplayValue,
9
+ saveAsFile,
10
+ } from './string.js';
4
11
 
5
- test('Tests add leading zero', () => {
6
- expect(addLeadingZero(1)).toBe('01');
7
- expect(addLeadingZero('1')).toBe('01');
8
- expect(addLeadingZero(1, 3)).toBe('001');
9
- expect(addLeadingZero('21')).toBe('21');
10
- expect(addLeadingZero(21)).toBe('21');
11
- expect(addLeadingZero(null)).toBe(null);
12
- expect(addLeadingZero(undefined)).toBe(null);
13
- });
12
+ describe('string', () => {
13
+ test('addLeadingZero', () => {
14
+ expect(addLeadingZero(1)).toBe('01');
15
+ expect(addLeadingZero('1')).toBe('01');
16
+ expect(addLeadingZero(1, 3)).toBe('001');
17
+ expect(addLeadingZero('21')).toBe('21');
18
+ expect(addLeadingZero(21)).toBe('21');
19
+ expect(addLeadingZero(null)).toBe(null);
20
+ expect(addLeadingZero(undefined)).toBe(null);
21
+ });
14
22
 
15
- describe('capitalize', () => {
16
- test('Capitalizes first letter of string', () => {
23
+ test('capitalize', () => {
17
24
  expect(capitalize('test')).toBe('Test');
18
25
  expect(capitalize('TEST')).toBe('Test');
19
26
  expect(capitalize('tEST')).toBe('Test');
20
- });
21
-
22
- test('Handles null input', () => {
23
27
  expect(capitalize(null)).toBe(null);
24
- });
25
-
26
- test('Handles empty string', () => {
27
28
  expect(capitalize('')).toBe('');
28
- });
29
-
30
- test('Handles empty string with whitespace', () => {
31
29
  expect(capitalize(' ')).toBe(' ');
32
- });
33
-
34
- test('Handles single character', () => {
35
30
  expect(capitalize('a')).toBe('A');
36
31
  expect(capitalize('A')).toBe('A');
32
+ expect(capitalize('test123')).toBe('Test123');
37
33
  });
38
34
 
39
- test('Handles strings with numbers', () => {
40
- expect(capitalize('test123')).toBe('Test123');
35
+ test('underscoreToCamelCase', () => {
36
+ expect(underscoreToCamelCase('test')).toBe('test');
37
+ expect(underscoreToCamelCase('test_variable')).toBe('testVariable');
38
+ expect(underscoreToCamelCase('test_variable_name')).toBe('testVariableName');
41
39
  });
42
- });
43
40
 
44
- test('Converts underscore to camelCase', () => {
45
- expect(underscoreToCamelCase('test')).toBe('test');
46
- expect(underscoreToCamelCase('test_variable')).toBe('testVariable');
47
- expect(underscoreToCamelCase('test_variable_name')).toBe('testVariableName');
48
- });
41
+ test('getTypeFromValue', () => {
42
+ expect(getTypeFromValue('test')).toBe('string');
43
+ expect(getTypeFromValue(() => null)).toBe('function');
44
+ expect(getTypeFromValue([])).toBe('array');
45
+ expect(getTypeFromValue({})).toBe('object');
46
+ expect(getTypeFromValue(new Date())).toBe('date');
47
+ expect(getTypeFromValue(null)).toBe('null');
48
+ expect(getTypeFromValue(true)).toBe('boolean');
49
+ expect(getTypeFromValue(undefined)).toBe('undefined');
50
+ });
49
51
 
50
- test('getTypeFromValue', () => {
51
- expect(getTypeFromValue('test')).toBe('string');
52
- expect(getTypeFromValue(() => null)).toBe('function');
53
- expect(getTypeFromValue([])).toBe('array');
54
- expect(getTypeFromValue({})).toBe('object');
55
- expect(getTypeFromValue(new Date())).toBe('date');
56
- expect(getTypeFromValue(null)).toBe('null');
57
- expect(getTypeFromValue(true)).toBe('boolean');
58
- expect(getTypeFromValue(undefined)).toBe('undefined');
59
- });
52
+ test('getDisplayValue', () => {
53
+ expect(getDisplayValue('test')).toBe('"test"');
54
+ expect(getDisplayValue(() => null)).toBe('() => null');
55
+ expect(getDisplayValue([])).toBe('[]');
56
+ expect(getDisplayValue({})).toBe('{}');
57
+ expect(getDisplayValue(new Date())).not.toBe(null);
58
+ expect(getDisplayValue(null)).toBe('null');
59
+ expect(getDisplayValue(true)).toBe('true');
60
+ expect(getDisplayValue(undefined)).toBe('undefined');
61
+ });
60
62
 
61
- test('getDisplayValue', () => {
62
- expect(getDisplayValue('test')).toBe('"test"');
63
- expect(getDisplayValue(() => null)).toBe('() => null');
64
- expect(getDisplayValue([])).toBe('[]');
65
- expect(getDisplayValue({})).toBe('{}');
66
- expect(getDisplayValue(new Date())).not.toBe(null);
67
- expect(getDisplayValue(null)).toBe('null');
68
- expect(getDisplayValue(true)).toBe('true');
69
- expect(getDisplayValue(undefined)).toBe('undefined');
63
+ test('saveAsFile', () => {
64
+ expect(() => saveAsFile('test.txt', 'test content')).not.toThrowError(Error);
65
+ });
70
66
  });
package/types/index.d.ts CHANGED
@@ -10,12 +10,12 @@ export { OpenTelemetryLogHandler } from "./logging/OpenTelemetryLogHandler.js";
10
10
  export { SentryLogHandler } from "./logging/SentryLogHandler.js";
11
11
  export { typeChecker } from "./typecheck/TypeChecker.js";
12
12
  export { TypeCheckError } from "./typecheck/TypeCheckError.js";
13
- export { getErrorDetails } from "./util/error.js";
14
13
  export { serverDataToState } from "./util/state.js";
15
14
  export { formatLogMessage, getLogLevelName } from "./logging/util.js";
16
15
  export { addPageLifecycleCallback, getDocumentState, getPageLifecycleEventEmitter, getPageLifecycleState, initPageLifecycle, isPageLifecycleInitialized } from "./pagelifecycle/util.js";
17
16
  export { typeCheck, typeCheckArray, typeCheckEnum } from "./typecheck/util.js";
18
17
  export { delayPromise, loadJSON } from "./util/async.js";
18
+ export { getErrorDetails, getTypedError } from "./util/error.js";
19
19
  export { FetchError, fetchRetry, HTTP_0_ANY } from "./util/fetch.js";
20
20
  export { addFloat, deg2rad, fixFloat, fixFloatPrecision, getRandomInt, isEqual, isGreater, isGreaterOrEqual, isInRange, isLess, isLessOrEqual, subFloat } from "./util/number.js";
21
21
  export { purgeObject, deepMerge, getObjArrayPropSum, getObjValueByPath, setObjValueByPath } from "./util/object.js";
@@ -1,2 +1,3 @@
1
1
  export function getErrorDetails(error: Error, excludes?: string[]): object;
2
+ export function getTypedError(error: unknown): Error;
2
3
  //# sourceMappingURL=error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/util/error.js"],"names":[],"mappings":"AAMO,uCAJI,KAAK,aACL,MAAM,EAAE,GACN,MAAM,CAmBlB"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/util/error.js"],"names":[],"mappings":"AAMO,uCAJI,KAAK,aACL,MAAM,EAAE,GACN,MAAM,CAmBlB;AAOM,qCAHI,OAAO,GACL,KAAK,CAEiF"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/util/fetch.js"],"names":[],"mappings":"AAeA,yBAA0B,CAAC,CAAC;AAE5B;IACE;;;;;;OAMG;IACH,qBALW,MAAM,YACN,MAAM,GAAG,GAAG,GAAG,OAAO,gBACtB,WAAW,YACX,QAAQ,EASlB;IAJC,iCAAwB;IACxB,0BAAgC;IAChC,mBAAwB;IACxB,cAAqC;CAExC;AASM,qCALI,MAAM,GAAG,GAAG,GAAG,OAAO,gBACtB,WAAW,iBACX;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAC,GAC9E,OAAO,CAAC,QAAQ,CAAC,CA4C7B"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/util/fetch.js"],"names":[],"mappings":"AAeA,yBAA0B,CAAC,CAAC;AAE5B;IACE;;;;;;OAMG;IACH,qBALW,MAAM,YACN,MAAM,GAAG,GAAG,GAAG,OAAO,gBACtB,WAAW,YACX,QAAQ,EASlB;IAJC,iCAAwB;IACxB,0BAAgC;IAChC,mBAAwB;IACxB,cAAqC;CAExC;AASM,qCALI,MAAM,GAAG,GAAG,GAAG,OAAO,gBACtB,WAAW,iBACX;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAC,GAC9E,OAAO,CAAC,QAAQ,CAAC,CAkD7B"}