@naturalcycles/js-lib 14.268.0 → 14.270.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.
@@ -108,7 +108,7 @@ exports.topbar = {
108
108
  return currentProgress;
109
109
  }
110
110
  if (typeof to === 'string') {
111
- to = (to.indexOf('+') >= 0 || to.indexOf('-') >= 0 ? currentProgress : 0) + parseFloat(to);
111
+ to = (to.includes('+') || to.includes('-') ? currentProgress : 0) + parseFloat(to);
112
112
  }
113
113
  currentProgress = to > 1 ? 1 : to;
114
114
  repaint();
@@ -52,7 +52,7 @@ class LocalTime {
52
52
  * Opposite of `.utc()` method.
53
53
  */
54
54
  toLocal() {
55
- return new LocalTime(new Date(this.$date.getTime()));
55
+ return new LocalTime(new Date(this.$date));
56
56
  }
57
57
  /**
58
58
  * Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
@@ -1,7 +1,7 @@
1
1
  import type { CommonLogger } from '../log/commonLogger';
2
- import { AnyAsyncFunction, AnyFunction, AnyObject } from '../types';
3
- import { AsyncMemoCache } from './memo.util';
4
- export interface AsyncMemoOptions {
2
+ import { AnyAsyncFunction, AnyFunction, AnyObject, MaybeParameters } from '../types';
3
+ import { AsyncMemoCache, MethodDecorator } from './memo.util';
4
+ export interface AsyncMemoOptions<FN> {
5
5
  /**
6
6
  * Provide a custom implementation of AsyncMemoCache.
7
7
  * Function that creates an instance of `AsyncMemoCache`.
@@ -10,7 +10,7 @@ export interface AsyncMemoOptions {
10
10
  /**
11
11
  * Provide a custom implementation of CacheKey function.
12
12
  */
13
- cacheKeyFn?: (args: any[]) => any;
13
+ cacheKeyFn?: (args: MaybeParameters<FN>) => any;
14
14
  /**
15
15
  * Default to `console`
16
16
  */
@@ -32,7 +32,7 @@ export interface AsyncMemoInstance {
32
32
  *
33
33
  * @experimental consider normal @_Memo for most of the cases, it's stable and predictable
34
34
  */
35
- export declare const _AsyncMemo: (opt: AsyncMemoOptions) => MethodDecorator;
35
+ export declare const _AsyncMemo: <FN>(opt: AsyncMemoOptions<FN>) => MethodDecorator<FN>;
36
36
  /**
37
37
  Call it on a method that is decorated with `@_AsyncMemo` to get access to additional functions,
38
38
  e.g `clear` to clear the cache, or get its underlying data.
@@ -16,9 +16,7 @@ const memo_util_1 = require("./memo.util");
16
16
  */
17
17
  // eslint-disable-next-line @typescript-eslint/naming-convention
18
18
  const _AsyncMemo = (opt) => (target, key, descriptor) => {
19
- if (typeof descriptor.value !== 'function') {
20
- throw new TypeError('Memoization can be applied only to methods');
21
- }
19
+ (0, assert_1._assertTypeOf)(descriptor.value, 'function', 'Memoization can be applied only to methods');
22
20
  const originalFn = descriptor.value;
23
21
  // Map from "instance" of the Class where @_AsyncMemo is applied to AsyncMemoCache instance.
24
22
  const instanceCache = new Map();
@@ -1,7 +1,8 @@
1
1
  import type { CommonLogger } from '../log/commonLogger';
2
- import { AnyFunction, AnyObject } from '../types';
2
+ import { AnyFunction, AnyObject, MaybeParameters } from '../types';
3
3
  import type { MemoCache } from './memo.util';
4
- export interface MemoOptions {
4
+ import { MethodDecorator } from './memo.util';
5
+ export interface MemoOptions<FN> {
5
6
  /**
6
7
  * Provide a custom implementation of MemoCache.
7
8
  * Function that creates an instance of `MemoCache`.
@@ -11,7 +12,7 @@ export interface MemoOptions {
11
12
  /**
12
13
  * Provide a custom implementation of CacheKey function.
13
14
  */
14
- cacheKeyFn?: (args: any[]) => any;
15
+ cacheKeyFn?: (args: MaybeParameters<FN>) => any;
15
16
  /**
16
17
  * Default to `console`
17
18
  */
@@ -45,7 +46,7 @@ export interface MemoInstance {
45
46
  * http://inlehmansterms.net/2015/03/01/javascript-memoization/
46
47
  * https://community.risingstack.com/the-worlds-fastest-javascript-memoization-library/
47
48
  */
48
- export declare const _Memo: (opt?: MemoOptions) => MethodDecorator;
49
+ export declare const _Memo: <FN>(opt?: MemoOptions<FN>) => MethodDecorator<FN>;
49
50
  /**
50
51
  Call it on a method that is decorated with `@_Memo` to get access to additional functions,
51
52
  e.g `clear` to clear the cache, or get its underlying data.
@@ -28,9 +28,7 @@ const memo_util_1 = require("./memo.util");
28
28
  */
29
29
  // eslint-disable-next-line @typescript-eslint/naming-convention
30
30
  const _Memo = (opt = {}) => (target, key, descriptor) => {
31
- if (typeof descriptor.value !== 'function') {
32
- throw new TypeError('Memoization can be applied only to methods');
33
- }
31
+ (0, assert_1._assertTypeOf)(descriptor.value, 'function', 'Memoization can be applied only to methods');
34
32
  const originalFn = descriptor.value;
35
33
  // Map<ctx => MemoCache<cacheKey, result>>
36
34
  //
@@ -1,4 +1,4 @@
1
- import type { UnixTimestamp } from '../types';
1
+ import type { AnyObject, UnixTimestamp } from '../types';
2
2
  import { MISS } from '../types';
3
3
  export type MemoSerializer = (args: any[]) => any;
4
4
  export declare const jsonMemoSerializer: MemoSerializer;
@@ -59,3 +59,9 @@ export declare class MapAsyncMemoCache<KEY = any, VALUE = any> implements AsyncM
59
59
  set(k: KEY, v: VALUE): Promise<void>;
60
60
  clear(): Promise<void>;
61
61
  }
62
+ /**
63
+ * Generic override of Typescript's built in legacy MethodDecorator, that
64
+ * allows us to infer the parameters of the decorated method from the parameters
65
+ * of a decorator.
66
+ */
67
+ export type MethodDecorator<T> = (target: AnyObject, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | undefined;
@@ -1,3 +1,4 @@
1
+ import { AnyFunction } from '../types';
1
2
  import type { MemoOptions } from './memo.decorator';
2
3
  import type { MemoCache } from './memo.util';
3
4
  export interface MemoizedFunction {
@@ -10,4 +11,4 @@ export interface MemoizedFunction {
10
11
  *
11
12
  * @experimental
12
13
  */
13
- export declare function _memoFn<T extends (...args: any[]) => any>(fn: T, opt?: MemoOptions): T & MemoizedFunction;
14
+ export declare function _memoFn<FN extends AnyFunction>(fn: FN, opt?: MemoOptions<FN>): FN & MemoizedFunction;
@@ -1,3 +1,4 @@
1
+ import { AnyAsyncFunction } from '../types';
1
2
  import type { AsyncMemoOptions } from './asyncMemo.decorator';
2
3
  import type { AsyncMemoCache } from './memo.util';
3
4
  export interface MemoizedAsyncFunction {
@@ -6,4 +7,4 @@ export interface MemoizedAsyncFunction {
6
7
  /**
7
8
  * @experimental
8
9
  */
9
- export declare function _memoFnAsync<T extends (...args: any[]) => Promise<any>>(fn: T, opt: AsyncMemoOptions): T & MemoizedAsyncFunction;
10
+ export declare function _memoFnAsync<FN extends AnyAsyncFunction>(fn: FN, opt: AsyncMemoOptions<FN>): FN & MemoizedAsyncFunction;
package/dist/types.d.ts CHANGED
@@ -97,6 +97,10 @@ export type LazyPromise<T> = () => Promise<T>;
97
97
  * A function that lazily calculates something async, that can return null.
98
98
  */
99
99
  export type LazyNullablePromise<T> = () => Promise<T | null>;
100
+ /**
101
+ * Evaluates to the parameters if T is a function, otherwise never
102
+ */
103
+ export type MaybeParameters<FN> = FN extends AnyFunction ? Parameters<FN> : never;
100
104
  /**
101
105
  * Symbol to indicate END of Sequence.
102
106
  */
@@ -105,7 +105,7 @@ export const topbar = {
105
105
  return currentProgress;
106
106
  }
107
107
  if (typeof to === 'string') {
108
- to = (to.indexOf('+') >= 0 || to.indexOf('-') >= 0 ? currentProgress : 0) + parseFloat(to);
108
+ to = (to.includes('+') || to.includes('-') ? currentProgress : 0) + parseFloat(to);
109
109
  }
110
110
  currentProgress = to > 1 ? 1 : to;
111
111
  repaint();
@@ -49,7 +49,7 @@ export class LocalTime {
49
49
  * Opposite of `.utc()` method.
50
50
  */
51
51
  toLocal() {
52
- return new LocalTime(new Date(this.$date.getTime()));
52
+ return new LocalTime(new Date(this.$date));
53
53
  }
54
54
  /**
55
55
  * Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
@@ -1,5 +1,5 @@
1
- import { _assert } from '../error/assert';
2
- import { _objectAssign, MISS } from '../types';
1
+ import { _assert, _assertTypeOf } from '../error/assert';
2
+ import { _objectAssign, MISS, } from '../types';
3
3
  import { _getTargetMethodSignature } from './decorator.util';
4
4
  import { jsonMemoSerializer } from './memo.util';
5
5
  /**
@@ -12,9 +12,7 @@ import { jsonMemoSerializer } from './memo.util';
12
12
  */
13
13
  // eslint-disable-next-line @typescript-eslint/naming-convention
14
14
  export const _AsyncMemo = (opt) => (target, key, descriptor) => {
15
- if (typeof descriptor.value !== 'function') {
16
- throw new TypeError('Memoization can be applied only to methods');
17
- }
15
+ _assertTypeOf(descriptor.value, 'function', 'Memoization can be applied only to methods');
18
16
  const originalFn = descriptor.value;
19
17
  // Map from "instance" of the Class where @_AsyncMemo is applied to AsyncMemoCache instance.
20
18
  const instanceCache = new Map();
@@ -1,4 +1,4 @@
1
- import { _assert } from '../error/assert';
1
+ import { _assert, _assertTypeOf } from '../error/assert';
2
2
  import { _objectAssign } from '../types';
3
3
  import { _getTargetMethodSignature } from './decorator.util';
4
4
  import { jsonMemoSerializer, MapMemoCache } from './memo.util';
@@ -24,9 +24,7 @@ import { jsonMemoSerializer, MapMemoCache } from './memo.util';
24
24
  */
25
25
  // eslint-disable-next-line @typescript-eslint/naming-convention
26
26
  export const _Memo = (opt = {}) => (target, key, descriptor) => {
27
- if (typeof descriptor.value !== 'function') {
28
- throw new TypeError('Memoization can be applied only to methods');
29
- }
27
+ _assertTypeOf(descriptor.value, 'function', 'Memoization can be applied only to methods');
30
28
  const originalFn = descriptor.value;
31
29
  // Map<ctx => MemoCache<cacheKey, result>>
32
30
  //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.268.0",
3
+ "version": "14.270.0",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build": "dev-lib build-esm-cjs",
@@ -120,7 +120,7 @@ export const topbar = {
120
120
  return currentProgress
121
121
  }
122
122
  if (typeof to === 'string') {
123
- to = (to.indexOf('+') >= 0 || to.indexOf('-') >= 0 ? currentProgress : 0) + parseFloat(to)
123
+ to = (to.includes('+') || to.includes('-') ? currentProgress : 0) + parseFloat(to)
124
124
  }
125
125
  currentProgress = (to as number) > 1 ? 1 : to
126
126
  repaint()
@@ -84,7 +84,7 @@ export class LocalTime {
84
84
  * Opposite of `.utc()` method.
85
85
  */
86
86
  toLocal(): LocalTime {
87
- return new LocalTime(new Date(this.$date.getTime()))
87
+ return new LocalTime(new Date(this.$date))
88
88
  }
89
89
 
90
90
  /**
@@ -1,10 +1,17 @@
1
- import { _assert } from '../error/assert'
1
+ import { _assert, _assertTypeOf } from '../error/assert'
2
2
  import type { CommonLogger } from '../log/commonLogger'
3
- import { _objectAssign, AnyAsyncFunction, AnyFunction, AnyObject, MISS } from '../types'
3
+ import {
4
+ _objectAssign,
5
+ AnyAsyncFunction,
6
+ AnyFunction,
7
+ AnyObject,
8
+ MaybeParameters,
9
+ MISS,
10
+ } from '../types'
4
11
  import { _getTargetMethodSignature } from './decorator.util'
5
- import { AsyncMemoCache, jsonMemoSerializer } from './memo.util'
12
+ import { AsyncMemoCache, jsonMemoSerializer, MethodDecorator } from './memo.util'
6
13
 
7
- export interface AsyncMemoOptions {
14
+ export interface AsyncMemoOptions<FN> {
8
15
  /**
9
16
  * Provide a custom implementation of AsyncMemoCache.
10
17
  * Function that creates an instance of `AsyncMemoCache`.
@@ -14,7 +21,7 @@ export interface AsyncMemoOptions {
14
21
  /**
15
22
  * Provide a custom implementation of CacheKey function.
16
23
  */
17
- cacheKeyFn?: (args: any[]) => any
24
+ cacheKeyFn?: (args: MaybeParameters<FN>) => any
18
25
 
19
26
  /**
20
27
  * Default to `console`
@@ -43,11 +50,13 @@ export interface AsyncMemoInstance {
43
50
  */
44
51
  // eslint-disable-next-line @typescript-eslint/naming-convention
45
52
  export const _AsyncMemo =
46
- (opt: AsyncMemoOptions): MethodDecorator =>
53
+ <FN>(opt: AsyncMemoOptions<FN>): MethodDecorator<FN> =>
47
54
  (target, key, descriptor) => {
48
- if (typeof descriptor.value !== 'function') {
49
- throw new TypeError('Memoization can be applied only to methods')
50
- }
55
+ _assertTypeOf<AnyFunction>(
56
+ descriptor.value,
57
+ 'function',
58
+ 'Memoization can be applied only to methods',
59
+ )
51
60
 
52
61
  const originalFn = descriptor.value
53
62
 
@@ -66,7 +75,7 @@ export const _AsyncMemo =
66
75
  const methodSignature = _getTargetMethodSignature(target, keyStr)
67
76
 
68
77
  // eslint-disable-next-line @typescript-eslint/promise-function-async
69
- descriptor.value = function (this: typeof target, ...args: any[]): Promise<any> {
78
+ descriptor.value = function (this: typeof target, ...args: MaybeParameters<FN>): Promise<any> {
70
79
  const ctx = this
71
80
  const cacheKey = cacheKeyFn(args)
72
81
 
@@ -1,11 +1,11 @@
1
- import { _assert } from '../error/assert'
1
+ import { _assert, _assertTypeOf } from '../error/assert'
2
2
  import type { CommonLogger } from '../log/commonLogger'
3
- import { _objectAssign, AnyFunction, AnyObject } from '../types'
3
+ import { _objectAssign, AnyFunction, AnyObject, MaybeParameters } from '../types'
4
4
  import { _getTargetMethodSignature } from './decorator.util'
5
5
  import type { MemoCache } from './memo.util'
6
- import { jsonMemoSerializer, MapMemoCache } from './memo.util'
6
+ import { jsonMemoSerializer, MapMemoCache, MethodDecorator } from './memo.util'
7
7
 
8
- export interface MemoOptions {
8
+ export interface MemoOptions<FN> {
9
9
  /**
10
10
  * Provide a custom implementation of MemoCache.
11
11
  * Function that creates an instance of `MemoCache`.
@@ -16,7 +16,7 @@ export interface MemoOptions {
16
16
  /**
17
17
  * Provide a custom implementation of CacheKey function.
18
18
  */
19
- cacheKeyFn?: (args: any[]) => any
19
+ cacheKeyFn?: (args: MaybeParameters<FN>) => any
20
20
 
21
21
  /**
22
22
  * Default to `console`
@@ -57,11 +57,13 @@ export interface MemoInstance {
57
57
  */
58
58
  // eslint-disable-next-line @typescript-eslint/naming-convention
59
59
  export const _Memo =
60
- (opt: MemoOptions = {}): MethodDecorator =>
60
+ <FN>(opt: MemoOptions<FN> = {}): MethodDecorator<FN> =>
61
61
  (target, key, descriptor) => {
62
- if (typeof descriptor.value !== 'function') {
63
- throw new TypeError('Memoization can be applied only to methods')
64
- }
62
+ _assertTypeOf<AnyFunction>(
63
+ descriptor.value,
64
+ 'function',
65
+ 'Memoization can be applied only to methods',
66
+ )
65
67
 
66
68
  const originalFn = descriptor.value
67
69
 
@@ -83,7 +85,7 @@ export const _Memo =
83
85
  const keyStr = String(key)
84
86
  const methodSignature = _getTargetMethodSignature(target, keyStr)
85
87
 
86
- descriptor.value = function (this: typeof target, ...args: any[]): any {
88
+ descriptor.value = function (this: typeof target, ...args: MaybeParameters<FN>): any {
87
89
  const ctx = this
88
90
  const cacheKey = cacheKeyFn(args)
89
91
 
@@ -1,6 +1,6 @@
1
1
  import { _isPrimitive } from '../is.util'
2
2
  import { pDelay } from '../promise/pDelay'
3
- import type { UnixTimestamp } from '../types'
3
+ import type { AnyObject, UnixTimestamp } from '../types'
4
4
  import { MISS } from '../types'
5
5
 
6
6
  export type MemoSerializer = (args: any[]) => any
@@ -147,3 +147,14 @@ export class MapAsyncMemoCache<KEY = any, VALUE = any> implements AsyncMemoCache
147
147
  this.m.clear()
148
148
  }
149
149
  }
150
+
151
+ /**
152
+ * Generic override of Typescript's built in legacy MethodDecorator, that
153
+ * allows us to infer the parameters of the decorated method from the parameters
154
+ * of a decorator.
155
+ */
156
+ export type MethodDecorator<T> = (
157
+ target: AnyObject,
158
+ propertyKey: string | symbol,
159
+ descriptor: TypedPropertyDescriptor<T>,
160
+ ) => TypedPropertyDescriptor<T> | undefined
@@ -1,3 +1,4 @@
1
+ import { AnyFunction, MaybeParameters } from '../types'
1
2
  import type { MemoOptions } from './memo.decorator'
2
3
  import type { MemoCache } from './memo.util'
3
4
  import { jsonMemoSerializer, MapMemoCache } from './memo.util'
@@ -13,10 +14,10 @@ export interface MemoizedFunction {
13
14
  *
14
15
  * @experimental
15
16
  */
16
- export function _memoFn<T extends (...args: any[]) => any>(
17
- fn: T,
18
- opt: MemoOptions = {},
19
- ): T & MemoizedFunction {
17
+ export function _memoFn<FN extends AnyFunction>(
18
+ fn: FN,
19
+ opt: MemoOptions<FN> = {},
20
+ ): FN & MemoizedFunction {
20
21
  const {
21
22
  logger = console,
22
23
  cacheFactory = () => new MapMemoCache(),
@@ -25,7 +26,7 @@ export function _memoFn<T extends (...args: any[]) => any>(
25
26
 
26
27
  const cache = cacheFactory()
27
28
 
28
- const memoizedFn = function (this: any, ...args: any[]): T {
29
+ const memoizedFn = function (this: any, ...args: MaybeParameters<FN>): FN {
29
30
  const ctx = this
30
31
  const cacheKey = cacheKeyFn(args)
31
32
 
@@ -45,5 +46,5 @@ export function _memoFn<T extends (...args: any[]) => any>(
45
46
  }
46
47
 
47
48
  Object.assign(memoizedFn, { cache })
48
- return memoizedFn as T & MemoizedFunction
49
+ return memoizedFn as FN & MemoizedFunction
49
50
  }
@@ -1,4 +1,4 @@
1
- import { MISS } from '../types'
1
+ import { AnyAsyncFunction, MaybeParameters, MISS } from '../types'
2
2
  import type { AsyncMemoOptions } from './asyncMemo.decorator'
3
3
  import type { AsyncMemoCache } from './memo.util'
4
4
  import { jsonMemoSerializer, MapMemoCache } from './memo.util'
@@ -10,10 +10,10 @@ export interface MemoizedAsyncFunction {
10
10
  /**
11
11
  * @experimental
12
12
  */
13
- export function _memoFnAsync<T extends (...args: any[]) => Promise<any>>(
14
- fn: T,
15
- opt: AsyncMemoOptions,
16
- ): T & MemoizedAsyncFunction {
13
+ export function _memoFnAsync<FN extends AnyAsyncFunction>(
14
+ fn: FN,
15
+ opt: AsyncMemoOptions<FN>,
16
+ ): FN & MemoizedAsyncFunction {
17
17
  const {
18
18
  logger = console,
19
19
  cacheFactory = () => new MapMemoCache(),
@@ -22,7 +22,7 @@ export function _memoFnAsync<T extends (...args: any[]) => Promise<any>>(
22
22
 
23
23
  const cache = cacheFactory()
24
24
 
25
- const memoizedFn = async function (this: any, ...args: any[]): Promise<any> {
25
+ const memoizedFn = async function (this: any, ...args: MaybeParameters<FN>): Promise<any> {
26
26
  const ctx = this
27
27
  const cacheKey = cacheKeyFn(args)
28
28
  let value: any
@@ -51,5 +51,5 @@ export function _memoFnAsync<T extends (...args: any[]) => Promise<any>>(
51
51
  }
52
52
 
53
53
  Object.assign(memoizedFn, { cache })
54
- return memoizedFn as T & MemoizedAsyncFunction
54
+ return memoizedFn as FN & MemoizedAsyncFunction
55
55
  }
package/src/types.ts CHANGED
@@ -119,6 +119,10 @@ export type LazyPromise<T> = () => Promise<T>
119
119
  * A function that lazily calculates something async, that can return null.
120
120
  */
121
121
  export type LazyNullablePromise<T> = () => Promise<T | null>
122
+ /**
123
+ * Evaluates to the parameters if T is a function, otherwise never
124
+ */
125
+ export type MaybeParameters<FN> = FN extends AnyFunction ? Parameters<FN> : never
122
126
 
123
127
  /**
124
128
  * Symbol to indicate END of Sequence.