@naturalcycles/js-lib 15.9.1 → 15.11.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.
@@ -1,5 +1,5 @@
1
1
  import type { MutateOptions } from '../array/array.util.js';
2
- import type { AnyObject, KeyValueTuple, ObjectMapper, ObjectPredicate, Reviver, ValueOf } from '../types.js';
2
+ import type { AnyObject, KeyValueTuple, ObjectMapper, ObjectPredicate, Reviver, StringMap, ValueOf } from '../types.js';
3
3
  import { SKIP } from '../types.js';
4
4
  /**
5
5
  * Returns clone of `obj` with only `props` preserved.
@@ -93,6 +93,18 @@ export declare function _objectNullValuesToUndefined<T extends AnyObject>(obj: T
93
93
  * Deep copy object (by json parse/stringify, since it has unbeatable performance+simplicity combo).
94
94
  */
95
95
  export declare function _deepCopy<T>(o: T, reviver?: Reviver): T;
96
+ /**
97
+ * Performance-optimized implementation of merging two objects
98
+ * without mutating any of them.
99
+ * (if you are allowed to mutate - there can be a faster implementation).
100
+ *
101
+ * Gives ~40% speedup with map sizes between 10 and 100k items,
102
+ * compared to {...obj1, ...obj2} or Object.assign({}, obj1, obj2).
103
+ *
104
+ * Only use it in hot paths that are known to be performance bottlenecks,
105
+ * otherwise it's not worth it (use normal object spread then).
106
+ */
107
+ export declare function _mergeObjects<T>(obj1: StringMap<T>, obj2: StringMap<T>): StringMap<T>;
96
108
  /**
97
109
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
98
110
  * otherwise returns the original object.
@@ -192,6 +192,25 @@ export function _objectNullValuesToUndefined(obj, opt = {}) {
192
192
  export function _deepCopy(o, reviver) {
193
193
  return JSON.parse(JSON.stringify(o), reviver);
194
194
  }
195
+ /**
196
+ * Performance-optimized implementation of merging two objects
197
+ * without mutating any of them.
198
+ * (if you are allowed to mutate - there can be a faster implementation).
199
+ *
200
+ * Gives ~40% speedup with map sizes between 10 and 100k items,
201
+ * compared to {...obj1, ...obj2} or Object.assign({}, obj1, obj2).
202
+ *
203
+ * Only use it in hot paths that are known to be performance bottlenecks,
204
+ * otherwise it's not worth it (use normal object spread then).
205
+ */
206
+ export function _mergeObjects(obj1, obj2) {
207
+ const map = {};
208
+ for (const k of Object.keys(obj1))
209
+ map[k] = obj1[k];
210
+ for (const k of Object.keys(obj2))
211
+ map[k] = obj2[k];
212
+ return map;
213
+ }
195
214
  /**
196
215
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
197
216
  * otherwise returns the original object.
@@ -1,11 +1,11 @@
1
1
  import { z } from 'zod/v4';
2
- import type { IsoDate } from '../types.js';
2
+ import type { IsoDate, UnixTimestamp, UnixTimestampMillis } from '../types.js';
3
3
  export declare const TS_2500 = 16725225600;
4
4
  export declare const TS_2000 = 946684800;
5
- export declare const zUnixTimestamp: () => z.ZodNumber;
6
- export declare const zUnixTimestamp2000: () => z.ZodNumber;
7
- export declare const zUnixTimestampMillis: () => z.ZodNumber;
8
- export declare const zUnixTimestampMillis2000: () => z.ZodNumber;
5
+ export declare const zUnixTimestamp: () => z.ZodCustom<UnixTimestamp>;
6
+ export declare const zUnixTimestamp2000: () => z.ZodCustom<UnixTimestamp>;
7
+ export declare const zUnixTimestampMillis: () => z.ZodCustom<UnixTimestampMillis>;
8
+ export declare const zUnixTimestampMillis2000: () => z.ZodCustom<UnixTimestampMillis>;
9
9
  export declare const zSemVer: () => z.ZodString;
10
10
  export declare const zIsoDate: () => z.ZodCustom<IsoDate>;
11
11
  export declare const zEmail: () => z.ZodEmail;
@@ -32,8 +32,8 @@ export declare const customZodSchemas: {
32
32
  jwt: () => z.ZodString;
33
33
  slug: () => z.ZodString;
34
34
  semver: () => z.ZodString;
35
- unixTimestamp: () => z.ZodNumber;
36
- unixTimestamp2000: () => z.ZodNumber;
37
- unixTimestampMillis: () => z.ZodNumber;
38
- unixTimestampMillis2000: () => z.ZodNumber;
35
+ unixTimestamp: () => z.ZodCustom<UnixTimestamp>;
36
+ unixTimestamp2000: () => z.ZodCustom<UnixTimestamp>;
37
+ unixTimestampMillis: () => z.ZodCustom<UnixTimestampMillis>;
38
+ unixTimestampMillis2000: () => z.ZodCustom<UnixTimestampMillis>;
39
39
  };
@@ -6,28 +6,24 @@ export const zUnixTimestamp = () => z
6
6
  .int()
7
7
  .min(0)
8
8
  .max(TS_2500, 'Must be a UnixTimestamp number')
9
- // .transform(v => v as UnixTimestamp) // breaks jsonSchema
10
9
  .describe('UnixTimestamp');
11
10
  export const zUnixTimestamp2000 = () => z
12
11
  .number()
13
12
  .int()
14
13
  .min(TS_2000)
15
14
  .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
16
- // .transform(v => v as UnixTimestamp)
17
15
  .describe('UnixTimestamp2000');
18
16
  export const zUnixTimestampMillis = () => z
19
17
  .number()
20
18
  .int()
21
19
  .min(0)
22
20
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
23
- // .transform(v => v as UnixTimestampMillis)
24
21
  .describe('UnixTimestampMillis');
25
22
  export const zUnixTimestampMillis2000 = () => z
26
23
  .number()
27
24
  .int()
28
25
  .min(TS_2000 * 1000)
29
26
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
30
- // .transform(v => v as UnixTimestampMillis)
31
27
  .describe('UnixTimestampMillis2000');
32
28
  export const zSemVer = () => z
33
29
  .string()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.9.1",
4
+ "version": "15.11.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "zod": "^3"
@@ -6,6 +6,7 @@ import type {
6
6
  ObjectMapper,
7
7
  ObjectPredicate,
8
8
  Reviver,
9
+ StringMap,
9
10
  ValueOf,
10
11
  } from '../types.js'
11
12
  import { _objectEntries, SKIP } from '../types.js'
@@ -246,6 +247,24 @@ export function _deepCopy<T>(o: T, reviver?: Reviver): T {
246
247
  return JSON.parse(JSON.stringify(o), reviver)
247
248
  }
248
249
 
250
+ /**
251
+ * Performance-optimized implementation of merging two objects
252
+ * without mutating any of them.
253
+ * (if you are allowed to mutate - there can be a faster implementation).
254
+ *
255
+ * Gives ~40% speedup with map sizes between 10 and 100k items,
256
+ * compared to {...obj1, ...obj2} or Object.assign({}, obj1, obj2).
257
+ *
258
+ * Only use it in hot paths that are known to be performance bottlenecks,
259
+ * otherwise it's not worth it (use normal object spread then).
260
+ */
261
+ export function _mergeObjects<T>(obj1: StringMap<T>, obj2: StringMap<T>): StringMap<T> {
262
+ const map: StringMap<T> = {}
263
+ for (const k of Object.keys(obj1)) map[k] = obj1[k]
264
+ for (const k of Object.keys(obj2)) map[k] = obj2[k]
265
+ return map
266
+ }
267
+
249
268
  /**
250
269
  * Returns `undefined` if it's empty (according to `_isEmpty()` specification),
251
270
  * otherwise returns the original object.
@@ -1,44 +1,40 @@
1
1
  import { z } from 'zod/v4'
2
- import type { IsoDate } from '../types.js'
2
+ import type { IsoDate, UnixTimestamp, UnixTimestampMillis } from '../types.js'
3
3
 
4
4
  export const TS_2500 = 16725225600 // 2500-01-01
5
5
  export const TS_2000 = 946684800 // 2000-01-01
6
6
 
7
- export const zUnixTimestamp = (): z.ZodNumber =>
7
+ export const zUnixTimestamp = (): z.ZodCustom<UnixTimestamp> =>
8
8
  z
9
9
  .number()
10
10
  .int()
11
11
  .min(0)
12
12
  .max(TS_2500, 'Must be a UnixTimestamp number')
13
- // .transform(v => v as UnixTimestamp) // breaks jsonSchema
14
- .describe('UnixTimestamp')
13
+ .describe('UnixTimestamp') as unknown as z.ZodCustom<UnixTimestamp>
15
14
 
16
- export const zUnixTimestamp2000 = (): z.ZodNumber =>
15
+ export const zUnixTimestamp2000 = (): z.ZodCustom<UnixTimestamp> =>
17
16
  z
18
17
  .number()
19
18
  .int()
20
19
  .min(TS_2000)
21
20
  .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
22
- // .transform(v => v as UnixTimestamp)
23
- .describe('UnixTimestamp2000')
21
+ .describe('UnixTimestamp2000') as unknown as z.ZodCustom<UnixTimestamp>
24
22
 
25
- export const zUnixTimestampMillis = (): z.ZodNumber =>
23
+ export const zUnixTimestampMillis = (): z.ZodCustom<UnixTimestampMillis> =>
26
24
  z
27
25
  .number()
28
26
  .int()
29
27
  .min(0)
30
28
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
31
- // .transform(v => v as UnixTimestampMillis)
32
- .describe('UnixTimestampMillis')
29
+ .describe('UnixTimestampMillis') as unknown as z.ZodCustom<UnixTimestampMillis>
33
30
 
34
- export const zUnixTimestampMillis2000 = (): z.ZodNumber =>
31
+ export const zUnixTimestampMillis2000 = (): z.ZodCustom<UnixTimestampMillis> =>
35
32
  z
36
33
  .number()
37
34
  .int()
38
35
  .min(TS_2000 * 1000)
39
36
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
40
- // .transform(v => v as UnixTimestampMillis)
41
- .describe('UnixTimestampMillis2000')
37
+ .describe('UnixTimestampMillis2000') as unknown as z.ZodCustom<UnixTimestampMillis>
42
38
 
43
39
  export const zSemVer = (): z.ZodString =>
44
40
  z