@naturalcycles/js-lib 14.78.0 → 14.80.1

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.
@@ -56,7 +56,7 @@ function _LogMethod(opt = {}) {
56
56
  })
57
57
  .catch((err) => {
58
58
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err);
59
- return Promise.reject(err);
59
+ throw err;
60
60
  });
61
61
  }
62
62
  else {
@@ -80,7 +80,7 @@ const _Memo = (opt = {}) => (target, key, descriptor) => {
80
80
  // Wrap as Error if it's not Error
81
81
  cache.get(ctx).set(cacheKey, err instanceof Error ? err : new Error(err));
82
82
  }
83
- return Promise.reject(err);
83
+ throw err;
84
84
  });
85
85
  }
86
86
  else {
@@ -49,7 +49,7 @@ function _memoFn(fn, opt = {}) {
49
49
  // Wrap as Error if it's not Error
50
50
  cache.set(cacheKey, err instanceof Error ? err : new Error(err));
51
51
  }
52
- return Promise.reject(err);
52
+ throw err;
53
53
  });
54
54
  }
55
55
  else {
package/dist/error/try.js CHANGED
@@ -27,8 +27,6 @@ function _try(fn) {
27
27
  }
28
28
  }
29
29
  exports._try = _try;
30
- // todo: remove when eslint starts to know about Awaited
31
- /* eslint-disable no-undef */
32
30
  /**
33
31
  * Like _try, but for Promises.
34
32
  *
@@ -113,8 +113,8 @@ export declare class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSc
113
113
  minProps(minProperties: number): this;
114
114
  maxProps(maxProperties: number): this;
115
115
  additionalProps(additionalProperties: boolean): this;
116
- baseDBEntity(): JsonSchemaObjectBuilder<T & BaseDBEntity>;
117
- savedDBEntity(): JsonSchemaObjectBuilder<T & SavedDBEntity>;
116
+ baseDBEntity<ID = string>(idType?: string): JsonSchemaObjectBuilder<T & BaseDBEntity<ID>>;
117
+ savedDBEntity<ID = string>(idType?: string): JsonSchemaObjectBuilder<T & SavedDBEntity<ID>>;
118
118
  extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2>;
119
119
  }
120
120
  export declare class JsonSchemaArrayBuilder<ITEM> extends JsonSchemaAnyBuilder<ITEM[], JsonSchemaArray<ITEM>> {
@@ -306,16 +306,16 @@ class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
306
306
  Object.assign(this.schema, { additionalProperties });
307
307
  return this;
308
308
  }
309
- baseDBEntity() {
309
+ baseDBEntity(idType = 'string') {
310
310
  Object.assign(this.schema.properties, {
311
- id: { type: 'string' },
311
+ id: { type: idType },
312
312
  created: { type: 'number', format: 'unixTimestamp' },
313
313
  updated: { type: 'number', format: 'unixTimestamp' },
314
314
  });
315
315
  return this;
316
316
  }
317
- savedDBEntity() {
318
- return this.baseDBEntity().addRequired(['id', 'created', 'updated']);
317
+ savedDBEntity(idType = 'string') {
318
+ return this.baseDBEntity(idType).addRequired(['id', 'created', 'updated']);
319
319
  }
320
320
  extend(s2) {
321
321
  const builder = new JsonSchemaObjectBuilder();
@@ -1,3 +1,3 @@
1
1
  import { SavedDBEntity } from '../types';
2
- export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<Partial<SavedDBEntity>>;
3
- export declare const savedDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<SavedDBEntity>;
2
+ export declare const baseDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<Partial<SavedDBEntity<string>>>;
3
+ export declare const savedDBEntityJsonSchema: import("./jsonSchemaBuilder").JsonSchemaObjectBuilder<SavedDBEntity<string>>;
@@ -1,10 +1,19 @@
1
- import { PMapOptions } from './pMap';
2
1
  /**
3
2
  * Promise.all for Object instead of Array.
4
- * Supports concurrency.
3
+ *
4
+ * Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
5
+ *
6
+ * Improvements:
7
+ *
8
+ * - Exported as { pProps }, so IDE auto-completion works
9
+ * - Simpler: no support for Map, Mapper, Options
10
+ * - Included Typescript typings (no need for @types/p-props)
11
+ *
12
+ * Concurrency implementation via pMap was removed in favor of preserving async
13
+ * stack traces (more important!).
5
14
  */
6
15
  export declare function pProps<T>(input: {
7
16
  [K in keyof T]: T[K] | Promise<T[K]>;
8
- }, opt?: PMapOptions): Promise<{
17
+ }): Promise<{
9
18
  [K in keyof T]: Awaited<T[K]>;
10
19
  }>;
@@ -1,26 +1,22 @@
1
1
  "use strict";
2
- /*
3
- Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
4
-
5
- Improvements:
6
-
7
- - Exported as { pProps }, so IDE auto-completion works
8
- - Simpler: no support for Map, Mapper, Options
9
- - Included Typescript typings (no need for @types/p-props)
10
- */
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.pProps = void 0;
13
- const pMap_1 = require("./pMap");
14
- // todo: remove when eslint starts to know about Awaited
15
- /* eslint-disable no-undef */
16
4
  /**
17
5
  * Promise.all for Object instead of Array.
18
- * Supports concurrency.
6
+ *
7
+ * Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
8
+ *
9
+ * Improvements:
10
+ *
11
+ * - Exported as { pProps }, so IDE auto-completion works
12
+ * - Simpler: no support for Map, Mapper, Options
13
+ * - Included Typescript typings (no need for @types/p-props)
14
+ *
15
+ * Concurrency implementation via pMap was removed in favor of preserving async
16
+ * stack traces (more important!).
19
17
  */
20
- async function pProps(input, opt) {
21
- const r = {};
18
+ async function pProps(input) {
22
19
  const keys = Object.keys(input);
23
- await (0, pMap_1.pMap)(Object.values(input), (v, i) => (r[keys[i]] = v), opt);
24
- return r;
20
+ return Object.fromEntries((await Promise.all(Object.values(input))).map((v, i) => [keys[i], v]));
25
21
  }
26
22
  exports.pProps = pProps;
@@ -17,6 +17,14 @@ export interface PTimeoutOptions {
17
17
  * Can be used to thrown a custom error OR resolve a promise without throwing.
18
18
  */
19
19
  onTimeout?: () => any;
20
+ /**
21
+ * Defaults to true.
22
+ * If true - preserves the stack trace in case of a Timeout (usually - very useful!).
23
+ * It has a certain perf cost.
24
+ *
25
+ * @experimental
26
+ */
27
+ keepStackTrace?: boolean;
20
28
  }
21
29
  /**
22
30
  * Decorates a Function with a timeout.
@@ -24,7 +24,8 @@ exports.pTimeoutFn = pTimeoutFn;
24
24
  */
25
25
  async function pTimeout(promise, opt) {
26
26
  // todo: check how we can automatically infer function name (only applicable to named functions)
27
- const { timeout, name, onTimeout } = opt;
27
+ const { timeout, name, onTimeout, keepStackTrace = true } = opt;
28
+ const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
28
29
  // eslint-disable-next-line no-async-promise-executor
29
30
  return await new Promise(async (resolve, reject) => {
30
31
  // Prepare the timeout timer
@@ -34,11 +35,16 @@ async function pTimeout(promise, opt) {
34
35
  resolve(onTimeout());
35
36
  }
36
37
  catch (err) {
38
+ if (fakeError)
39
+ err.stack = fakeError.stack; // keep original stack
37
40
  reject(err);
38
41
  }
39
42
  return;
40
43
  }
41
- reject(new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`));
44
+ const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`);
45
+ if (fakeError)
46
+ err.stack = fakeError.stack; // keep original stack
47
+ reject(err);
42
48
  }, timeout);
43
49
  // Execute the Function
44
50
  try {
package/dist/types.d.ts CHANGED
@@ -24,13 +24,13 @@ export interface CreatedUpdated {
24
24
  created: number;
25
25
  updated: number;
26
26
  }
27
- export interface CreatedUpdatedId extends CreatedUpdated {
28
- id: string;
27
+ export interface CreatedUpdatedId<ID = string> extends CreatedUpdated {
28
+ id: ID;
29
29
  }
30
- export interface ObjectWithId {
31
- id: string;
30
+ export interface ObjectWithId<ID = string> {
31
+ id: ID;
32
32
  }
33
- export interface AnyObjectWithId extends AnyObject, ObjectWithId {
33
+ export interface AnyObjectWithId<ID = string> extends AnyObject, ObjectWithId<ID> {
34
34
  }
35
35
  /**
36
36
  * Convenience type shorthand.
@@ -127,8 +127,8 @@ export declare type UnixTimestamp = number;
127
127
  /**
128
128
  * Base interface for any Entity that was saved to DB.
129
129
  */
130
- export interface SavedDBEntity {
131
- id: string;
130
+ export interface SavedDBEntity<ID = string> {
131
+ id: ID;
132
132
  /**
133
133
  * unixTimestamp of when the entity was first created (in the DB).
134
134
  */
@@ -144,9 +144,9 @@ export interface SavedDBEntity {
144
144
  * hence `id`, `created` and `updated` fields CAN BE undefined (yet).
145
145
  * When it's known to be saved - `SavedDBEntity` interface can be used instead.
146
146
  */
147
- export declare type BaseDBEntity = Partial<SavedDBEntity>;
148
- export declare type Saved<E> = Merge<E, SavedDBEntity>;
149
- export declare type Unsaved<E> = Merge<E, BaseDBEntity>;
147
+ export declare type BaseDBEntity<ID = string> = Partial<SavedDBEntity<ID>>;
148
+ export declare type Saved<E, ID = string> = Merge<E, SavedDBEntity<ID>>;
149
+ export declare type Unsaved<E, ID = string> = Merge<E, BaseDBEntity<ID>>;
150
150
  /**
151
151
  * Named type for JSON.parse / JSON.stringify second argument
152
152
  */
@@ -53,7 +53,7 @@ export function _LogMethod(opt = {}) {
53
53
  })
54
54
  .catch((err) => {
55
55
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err);
56
- return Promise.reject(err);
56
+ throw err;
57
57
  });
58
58
  }
59
59
  else {
@@ -77,7 +77,7 @@ export const _Memo = (opt = {}) => (target, key, descriptor) => {
77
77
  // Wrap as Error if it's not Error
78
78
  cache.get(ctx).set(cacheKey, err instanceof Error ? err : new Error(err));
79
79
  }
80
- return Promise.reject(err);
80
+ throw err;
81
81
  });
82
82
  }
83
83
  else {
@@ -46,7 +46,7 @@ export function _memoFn(fn, opt = {}) {
46
46
  // Wrap as Error if it's not Error
47
47
  cache.set(cacheKey, err instanceof Error ? err : new Error(err));
48
48
  }
49
- return Promise.reject(err);
49
+ throw err;
50
50
  });
51
51
  }
52
52
  else {
@@ -23,8 +23,6 @@ export function _try(fn) {
23
23
  return [err, undefined];
24
24
  }
25
25
  }
26
- // todo: remove when eslint starts to know about Awaited
27
- /* eslint-disable no-undef */
28
26
  /**
29
27
  * Like _try, but for Promises.
30
28
  *
@@ -301,16 +301,16 @@ export class JsonSchemaObjectBuilder extends JsonSchemaAnyBuilder {
301
301
  Object.assign(this.schema, { additionalProperties });
302
302
  return this;
303
303
  }
304
- baseDBEntity() {
304
+ baseDBEntity(idType = 'string') {
305
305
  Object.assign(this.schema.properties, {
306
- id: { type: 'string' },
306
+ id: { type: idType },
307
307
  created: { type: 'number', format: 'unixTimestamp' },
308
308
  updated: { type: 'number', format: 'unixTimestamp' },
309
309
  });
310
310
  return this;
311
311
  }
312
- savedDBEntity() {
313
- return this.baseDBEntity().addRequired(['id', 'created', 'updated']);
312
+ savedDBEntity(idType = 'string') {
313
+ return this.baseDBEntity(idType).addRequired(['id', 'created', 'updated']);
314
314
  }
315
315
  extend(s2) {
316
316
  const builder = new JsonSchemaObjectBuilder();
@@ -1,22 +1,18 @@
1
- /*
2
- Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
3
-
4
- Improvements:
5
-
6
- - Exported as { pProps }, so IDE auto-completion works
7
- - Simpler: no support for Map, Mapper, Options
8
- - Included Typescript typings (no need for @types/p-props)
9
- */
10
- import { pMap } from './pMap';
11
- // todo: remove when eslint starts to know about Awaited
12
- /* eslint-disable no-undef */
13
1
  /**
14
2
  * Promise.all for Object instead of Array.
15
- * Supports concurrency.
3
+ *
4
+ * Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
5
+ *
6
+ * Improvements:
7
+ *
8
+ * - Exported as { pProps }, so IDE auto-completion works
9
+ * - Simpler: no support for Map, Mapper, Options
10
+ * - Included Typescript typings (no need for @types/p-props)
11
+ *
12
+ * Concurrency implementation via pMap was removed in favor of preserving async
13
+ * stack traces (more important!).
16
14
  */
17
- export async function pProps(input, opt) {
18
- const r = {};
15
+ export async function pProps(input) {
19
16
  const keys = Object.keys(input);
20
- await pMap(Object.values(input), (v, i) => (r[keys[i]] = v), opt);
21
- return r;
17
+ return Object.fromEntries((await Promise.all(Object.values(input))).map((v, i) => [keys[i], v]));
22
18
  }
@@ -19,7 +19,8 @@ export function pTimeoutFn(fn, opt) {
19
19
  */
20
20
  export async function pTimeout(promise, opt) {
21
21
  // todo: check how we can automatically infer function name (only applicable to named functions)
22
- const { timeout, name, onTimeout } = opt;
22
+ const { timeout, name, onTimeout, keepStackTrace = true } = opt;
23
+ const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined;
23
24
  // eslint-disable-next-line no-async-promise-executor
24
25
  return await new Promise(async (resolve, reject) => {
25
26
  // Prepare the timeout timer
@@ -29,11 +30,16 @@ export async function pTimeout(promise, opt) {
29
30
  resolve(onTimeout());
30
31
  }
31
32
  catch (err) {
33
+ if (fakeError)
34
+ err.stack = fakeError.stack; // keep original stack
32
35
  reject(err);
33
36
  }
34
37
  return;
35
38
  }
36
- reject(new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`));
39
+ const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`);
40
+ if (fakeError)
41
+ err.stack = fakeError.stack; // keep original stack
42
+ reject(err);
37
43
  }, timeout);
38
44
  // Execute the Function
39
45
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.78.0",
3
+ "version": "14.80.1",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -14,13 +14,14 @@
14
14
  "@naturalcycles/bench-lib": "^1.5.0",
15
15
  "@naturalcycles/dev-lib": "^12.0.0",
16
16
  "@naturalcycles/nodejs-lib": "^12.33.4",
17
- "@types/node": "^16.0.0",
17
+ "@types/node": "^17.0.4",
18
18
  "jest": "^27.0.1",
19
19
  "patch-package": "^6.2.1",
20
20
  "prettier": "^2.1.2",
21
21
  "rxjs": "^7.0.1",
22
22
  "vuepress": "^1.7.1",
23
- "vuepress-plugin-typescript": "^0.3.1"
23
+ "vuepress-plugin-typescript": "^0.3.1",
24
+ "weak-napi": "^2.0.2"
24
25
  },
25
26
  "files": [
26
27
  "dist",
@@ -110,7 +110,7 @@ export function _LogMethod(opt: LogMethodOptions = {}): MethodDecorator {
110
110
  })
111
111
  .catch((err: any) => {
112
112
  logFinished(logger, callSignature, started, sma, logResultFn, undefined, err)
113
- return Promise.reject(err)
113
+ throw err
114
114
  })
115
115
  } else {
116
116
  // not a Promise
@@ -163,7 +163,7 @@ export const _Memo =
163
163
  cache.get(ctx)!.set(cacheKey, err instanceof Error ? err : new Error(err))
164
164
  }
165
165
 
166
- return Promise.reject(err)
166
+ throw err
167
167
  })
168
168
  } else {
169
169
  if (logMiss) {
@@ -83,7 +83,7 @@ export function _memoFn<T extends (...args: any[]) => any>(
83
83
  cache.set(cacheKey, err instanceof Error ? err : new Error(err))
84
84
  }
85
85
 
86
- return Promise.reject(err)
86
+ throw err
87
87
  }) as any
88
88
  } else {
89
89
  if (logMiss) {
package/src/error/try.ts CHANGED
@@ -27,9 +27,6 @@ export function _try<ERR = unknown, RETURN = void>(
27
27
  }
28
28
  }
29
29
 
30
- // todo: remove when eslint starts to know about Awaited
31
- /* eslint-disable no-undef */
32
-
33
30
  /**
34
31
  * Like _try, but for Promises.
35
32
  *
@@ -365,9 +365,9 @@ export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyB
365
365
  return this
366
366
  }
367
367
 
368
- baseDBEntity(): JsonSchemaObjectBuilder<T & BaseDBEntity> {
368
+ baseDBEntity<ID = string>(idType = 'string'): JsonSchemaObjectBuilder<T & BaseDBEntity<ID>> {
369
369
  Object.assign(this.schema.properties, {
370
- id: { type: 'string' },
370
+ id: { type: idType },
371
371
  created: { type: 'number', format: 'unixTimestamp' },
372
372
  updated: { type: 'number', format: 'unixTimestamp' },
373
373
  })
@@ -375,8 +375,8 @@ export class JsonSchemaObjectBuilder<T extends AnyObject> extends JsonSchemaAnyB
375
375
  return this
376
376
  }
377
377
 
378
- savedDBEntity(): JsonSchemaObjectBuilder<T & SavedDBEntity> {
379
- return this.baseDBEntity().addRequired(['id', 'created', 'updated']) as any
378
+ savedDBEntity<ID = string>(idType = 'string'): JsonSchemaObjectBuilder<T & SavedDBEntity<ID>> {
379
+ return this.baseDBEntity(idType).addRequired(['id', 'created', 'updated']) as any
380
380
  }
381
381
 
382
382
  extend<T2 extends AnyObject>(s2: JsonSchemaObjectBuilder<T2>): JsonSchemaObjectBuilder<T & T2> {
@@ -1,28 +1,20 @@
1
- /*
2
- Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
3
-
4
- Improvements:
5
-
6
- - Exported as { pProps }, so IDE auto-completion works
7
- - Simpler: no support for Map, Mapper, Options
8
- - Included Typescript typings (no need for @types/p-props)
9
- */
10
-
11
- import { pMap, PMapOptions } from './pMap'
12
-
13
- // todo: remove when eslint starts to know about Awaited
14
- /* eslint-disable no-undef */
15
-
16
1
  /**
17
2
  * Promise.all for Object instead of Array.
18
- * Supports concurrency.
3
+ *
4
+ * Inspired by Bluebird Promise.props() and https://github.com/sindresorhus/p-props
5
+ *
6
+ * Improvements:
7
+ *
8
+ * - Exported as { pProps }, so IDE auto-completion works
9
+ * - Simpler: no support for Map, Mapper, Options
10
+ * - Included Typescript typings (no need for @types/p-props)
11
+ *
12
+ * Concurrency implementation via pMap was removed in favor of preserving async
13
+ * stack traces (more important!).
19
14
  */
20
- export async function pProps<T>(
21
- input: { [K in keyof T]: T[K] | Promise<T[K]> },
22
- opt?: PMapOptions,
23
- ): Promise<{ [K in keyof T]: Awaited<T[K]> }> {
24
- const r = {} as { [K in keyof T]: Awaited<T[K]> }
25
- const keys = Object.keys(input) as (keyof T)[]
26
- await pMap(Object.values(input), (v, i) => (r[keys[i]!] = v), opt)
27
- return r
15
+ export async function pProps<T>(input: { [K in keyof T]: T[K] | Promise<T[K]> }): Promise<{
16
+ [K in keyof T]: Awaited<T[K]>
17
+ }> {
18
+ const keys = Object.keys(input)
19
+ return Object.fromEntries((await Promise.all(Object.values(input))).map((v, i) => [keys[i], v]))
28
20
  }
@@ -20,6 +20,15 @@ export interface PTimeoutOptions {
20
20
  * Can be used to thrown a custom error OR resolve a promise without throwing.
21
21
  */
22
22
  onTimeout?: () => any
23
+
24
+ /**
25
+ * Defaults to true.
26
+ * If true - preserves the stack trace in case of a Timeout (usually - very useful!).
27
+ * It has a certain perf cost.
28
+ *
29
+ * @experimental
30
+ */
31
+ keepStackTrace?: boolean
23
32
  }
24
33
 
25
34
  /**
@@ -42,7 +51,8 @@ export function pTimeoutFn<T extends AnyFunction>(fn: T, opt: PTimeoutOptions):
42
51
  */
43
52
  export async function pTimeout<T>(promise: Promise<T>, opt: PTimeoutOptions): Promise<T> {
44
53
  // todo: check how we can automatically infer function name (only applicable to named functions)
45
- const { timeout, name, onTimeout } = opt
54
+ const { timeout, name, onTimeout, keepStackTrace = true } = opt
55
+ const fakeError = keepStackTrace ? new Error('TimeoutError') : undefined
46
56
 
47
57
  // eslint-disable-next-line no-async-promise-executor
48
58
  return await new Promise(async (resolve, reject) => {
@@ -51,13 +61,16 @@ export async function pTimeout<T>(promise: Promise<T>, opt: PTimeoutOptions): Pr
51
61
  if (onTimeout) {
52
62
  try {
53
63
  resolve(onTimeout())
54
- } catch (err) {
64
+ } catch (err: any) {
65
+ if (fakeError) err.stack = fakeError.stack // keep original stack
55
66
  reject(err)
56
67
  }
57
68
  return
58
69
  }
59
70
 
60
- reject(new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`))
71
+ const err = new TimeoutError(`"${name || 'pTimeout function'}" timed out after ${timeout} ms`)
72
+ if (fakeError) err.stack = fakeError.stack // keep original stack
73
+ reject(err)
61
74
  }, timeout)
62
75
 
63
76
  // Execute the Function
package/src/types.ts CHANGED
@@ -29,15 +29,15 @@ export interface CreatedUpdated {
29
29
  updated: number
30
30
  }
31
31
 
32
- export interface CreatedUpdatedId extends CreatedUpdated {
33
- id: string
32
+ export interface CreatedUpdatedId<ID = string> extends CreatedUpdated {
33
+ id: ID
34
34
  }
35
35
 
36
- export interface ObjectWithId {
37
- id: string
36
+ export interface ObjectWithId<ID = string> {
37
+ id: ID
38
38
  }
39
39
 
40
- export interface AnyObjectWithId extends AnyObject, ObjectWithId {}
40
+ export interface AnyObjectWithId<ID = string> extends AnyObject, ObjectWithId<ID> {}
41
41
 
42
42
  /**
43
43
  * Convenience type shorthand.
@@ -169,8 +169,8 @@ export type UnixTimestamp = number
169
169
  /**
170
170
  * Base interface for any Entity that was saved to DB.
171
171
  */
172
- export interface SavedDBEntity {
173
- id: string
172
+ export interface SavedDBEntity<ID = string> {
173
+ id: ID
174
174
 
175
175
  /**
176
176
  * unixTimestamp of when the entity was first created (in the DB).
@@ -189,10 +189,10 @@ export interface SavedDBEntity {
189
189
  * hence `id`, `created` and `updated` fields CAN BE undefined (yet).
190
190
  * When it's known to be saved - `SavedDBEntity` interface can be used instead.
191
191
  */
192
- export type BaseDBEntity = Partial<SavedDBEntity>
192
+ export type BaseDBEntity<ID = string> = Partial<SavedDBEntity<ID>>
193
193
 
194
- export type Saved<E> = Merge<E, SavedDBEntity>
195
- export type Unsaved<E> = Merge<E, BaseDBEntity>
194
+ export type Saved<E, ID = string> = Merge<E, SavedDBEntity<ID>>
195
+ export type Unsaved<E, ID = string> = Merge<E, BaseDBEntity<ID>>
196
196
 
197
197
  /**
198
198
  * Named type for JSON.parse / JSON.stringify second argument