@naturalcycles/js-lib 14.216.0 → 14.218.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.
@@ -115,8 +115,13 @@ export declare function _dropWhile<T>(items: T[], predicate: Predicate<T>): T[];
115
115
  export declare function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[];
116
116
  /**
117
117
  * Counts how many items match the predicate.
118
+ *
119
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
120
+ */
121
+ export declare function _count<T>(items: T[], predicate: AbortablePredicate<T>, limit?: number): number;
122
+ /**
123
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
118
124
  */
119
- export declare function _count<T>(items: T[], predicate: AbortablePredicate<T>): number;
120
125
  export declare function _countBy<T>(items: T[], mapper: Mapper<T, any>): StringMap<number>;
121
126
  /**
122
127
  * Returns an intersection between 2 arrays.
@@ -42,10 +42,10 @@ exports._uniq = _uniq;
42
42
  * a = _uniq([...a, item])
43
43
  */
44
44
  function _pushUniq(a, ...items) {
45
- items.forEach(item => {
45
+ for (const item of items) {
46
46
  if (!a.includes(item))
47
47
  a.push(item);
48
- });
48
+ }
49
49
  return a;
50
50
  }
51
51
  exports._pushUniq = _pushUniq;
@@ -206,23 +206,33 @@ function _dropRightWhile(items, predicate) {
206
206
  exports._dropRightWhile = _dropRightWhile;
207
207
  /**
208
208
  * Counts how many items match the predicate.
209
+ *
210
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
209
211
  */
210
- function _count(items, predicate) {
212
+ function _count(items, predicate, limit) {
213
+ if (limit === 0)
214
+ return 0;
211
215
  let count = 0;
212
216
  for (const [i, item] of items.entries()) {
213
217
  const r = predicate(item, i);
214
218
  if (r === types_1.END)
215
219
  break;
216
- if (r)
220
+ if (r) {
217
221
  count++;
222
+ if (limit && count >= limit)
223
+ break;
224
+ }
218
225
  }
219
226
  return count;
220
227
  }
221
228
  exports._count = _count;
229
+ /**
230
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
231
+ */
222
232
  function _countBy(items, mapper) {
223
233
  const map = {};
224
- items.forEach((item, index) => {
225
- const key = mapper(item, index);
234
+ items.forEach((item, i) => {
235
+ const key = mapper(item, i);
226
236
  map[key] = (map[key] || 0) + 1;
227
237
  });
228
238
  return map;
@@ -296,12 +306,12 @@ exports._sumBy = _sumBy;
296
306
  */
297
307
  function _mapToObject(array, mapper) {
298
308
  const m = {};
299
- array.forEach(item => {
309
+ for (const item of array) {
300
310
  const r = mapper(item);
301
311
  if (!r)
302
- return; // filtering
312
+ continue; // filtering
303
313
  m[r[0]] = r[1];
304
- });
314
+ }
305
315
  return m;
306
316
  }
307
317
  exports._mapToObject = _mapToObject;
@@ -400,13 +410,13 @@ function _maxByOrUndefined(array, mapper) {
400
410
  return;
401
411
  let maxItem;
402
412
  let max;
403
- array.forEach((item, i) => {
413
+ for (const [i, item] of array.entries()) {
404
414
  const v = mapper(item, i);
405
415
  if (v !== undefined && (max === undefined || v > max)) {
406
416
  maxItem = item;
407
417
  max = v;
408
418
  }
409
- });
419
+ }
410
420
  return maxItem;
411
421
  }
412
422
  exports._maxByOrUndefined = _maxByOrUndefined;
@@ -415,13 +425,13 @@ function _minByOrUndefined(array, mapper) {
415
425
  return;
416
426
  let minItem;
417
427
  let min;
418
- array.forEach((item, i) => {
428
+ for (const [i, item] of array.entries()) {
419
429
  const v = mapper(item, i);
420
430
  if (v !== undefined && (min === undefined || v < min)) {
421
431
  minItem = item;
422
432
  min = v;
423
433
  }
424
- });
434
+ }
425
435
  return minItem;
426
436
  }
427
437
  exports._minByOrUndefined = _minByOrUndefined;
package/dist/form.util.js CHANGED
@@ -9,7 +9,9 @@ exports.formDataToObject = exports.objectToFormData = void 0;
9
9
  */
10
10
  function objectToFormData(obj = {}) {
11
11
  const fd = new FormData();
12
- Object.entries(obj).forEach(([k, v]) => fd.append(k, v));
12
+ for (const [k, v] of Object.entries(obj)) {
13
+ fd.append(k, v);
14
+ }
13
15
  return fd;
14
16
  }
15
17
  exports.objectToFormData = objectToFormData;
@@ -48,7 +48,7 @@ class Fetcher {
48
48
  }
49
49
  this.cfg = this.normalizeCfg(cfg);
50
50
  // Dynamically create all helper methods
51
- http_model_1.HTTP_METHODS.forEach(method => {
51
+ for (const method of http_model_1.HTTP_METHODS) {
52
52
  const m = method.toLowerCase();
53
53
  this[`${m}Void`] = async (url, opt) => {
54
54
  return await this.fetch({
@@ -77,7 +77,7 @@ class Fetcher {
77
77
  ...opt,
78
78
  });
79
79
  };
80
- });
80
+ }
81
81
  }
82
82
  /**
83
83
  * Add BeforeRequest hook at the end of the hooks list.
@@ -58,14 +58,14 @@ exports._percentile = _percentile;
58
58
  function _percentiles(values, pcs) {
59
59
  const r = {};
60
60
  const sorted = (0, number_util_1._sortNumbers)(values);
61
- pcs.forEach(pc => {
61
+ for (const pc of pcs) {
62
62
  // Floating pos in the range of [0; length - 1]
63
63
  const pos = ((values.length - 1) * pc) / 100;
64
64
  const dec = pos % 1;
65
65
  const floorPos = Math.floor(pos);
66
66
  const ceilPos = Math.ceil(pos);
67
67
  r[pc] = _averageWeighted([sorted[floorPos], sorted[ceilPos]], [1 - dec, dec]);
68
- });
68
+ }
69
69
  return r;
70
70
  }
71
71
  exports._percentiles = _percentiles;
@@ -402,8 +402,11 @@ exports._deepFreeze = _deepFreeze;
402
402
  */
403
403
  function _objectAssignExact(target, source) {
404
404
  Object.assign(target, source);
405
- Object.keys(target)
406
- .filter(k => !(k in source))
407
- .forEach(k => delete target[k]);
405
+ for (const k of Object.keys(target)) {
406
+ if (!(k in source)) {
407
+ // consider setting it to undefined maybe?
408
+ delete target[k];
409
+ }
410
+ }
408
411
  }
409
412
  exports._objectAssignExact = _objectAssignExact;
@@ -2,5 +2,8 @@
2
2
  * Modified version of: https://github.com/sindresorhus/leven/
3
3
  *
4
4
  * Returns a Levenshtein distance between first and second word.
5
+ *
6
+ * `limit` optional parameter can be used to limit the distance calculation
7
+ * and skip unnecessary iterations when limit is reached.
5
8
  */
6
- export declare function _leven(first: string, second: string): number;
9
+ export declare function _leven(first: string, second: string, limit?: number): number;
@@ -8,9 +8,12 @@ const characterCodeCache = [];
8
8
  * Modified version of: https://github.com/sindresorhus/leven/
9
9
  *
10
10
  * Returns a Levenshtein distance between first and second word.
11
+ *
12
+ * `limit` optional parameter can be used to limit the distance calculation
13
+ * and skip unnecessary iterations when limit is reached.
11
14
  */
12
- function _leven(first, second) {
13
- if (first === second) {
15
+ function _leven(first, second, limit) {
16
+ if (first === second || limit === 0) {
14
17
  return 0;
15
18
  }
16
19
  const swap = first;
@@ -40,6 +43,8 @@ function _leven(first, second) {
40
43
  firstLength -= start;
41
44
  secondLength -= start;
42
45
  if (firstLength === 0) {
46
+ if (limit && secondLength >= limit)
47
+ return limit;
43
48
  return secondLength;
44
49
  }
45
50
  let bCharacterCode;
@@ -56,6 +61,8 @@ function _leven(first, second) {
56
61
  bCharacterCode = second.charCodeAt(start + index2);
57
62
  temporary = index2++;
58
63
  result = index2;
64
+ if (limit && result >= limit)
65
+ return limit; // exit early on limit
59
66
  for (index = 0; index < firstLength; index++) {
60
67
  temporary2 = bCharacterCode === characterCodeCache[index] ? temporary : temporary + 1;
61
68
  temporary = array[index];
@@ -37,10 +37,10 @@ export function _uniq(a) {
37
37
  * a = _uniq([...a, item])
38
38
  */
39
39
  export function _pushUniq(a, ...items) {
40
- items.forEach(item => {
40
+ for (const item of items) {
41
41
  if (!a.includes(item))
42
42
  a.push(item);
43
- });
43
+ }
44
44
  return a;
45
45
  }
46
46
  /**
@@ -188,22 +188,32 @@ export function _dropRightWhile(items, predicate) {
188
188
  }
189
189
  /**
190
190
  * Counts how many items match the predicate.
191
+ *
192
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
191
193
  */
192
- export function _count(items, predicate) {
194
+ export function _count(items, predicate, limit) {
195
+ if (limit === 0)
196
+ return 0;
193
197
  let count = 0;
194
198
  for (const [i, item] of items.entries()) {
195
199
  const r = predicate(item, i);
196
200
  if (r === END)
197
201
  break;
198
- if (r)
202
+ if (r) {
199
203
  count++;
204
+ if (limit && count >= limit)
205
+ break;
206
+ }
200
207
  }
201
208
  return count;
202
209
  }
210
+ /**
211
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
212
+ */
203
213
  export function _countBy(items, mapper) {
204
214
  const map = {};
205
- items.forEach((item, index) => {
206
- const key = mapper(item, index);
215
+ items.forEach((item, i) => {
216
+ const key = mapper(item, i);
207
217
  map[key] = (map[key] || 0) + 1;
208
218
  });
209
219
  return map;
@@ -271,12 +281,12 @@ export function _sumBy(items, mapper) {
271
281
  */
272
282
  export function _mapToObject(array, mapper) {
273
283
  const m = {};
274
- array.forEach(item => {
284
+ for (const item of array) {
275
285
  const r = mapper(item);
276
286
  if (!r)
277
- return; // filtering
287
+ continue; // filtering
278
288
  m[r[0]] = r[1];
279
- });
289
+ }
280
290
  return m;
281
291
  }
282
292
  /**
@@ -364,13 +374,13 @@ export function _maxByOrUndefined(array, mapper) {
364
374
  return;
365
375
  let maxItem;
366
376
  let max;
367
- array.forEach((item, i) => {
377
+ for (const [i, item] of array.entries()) {
368
378
  const v = mapper(item, i);
369
379
  if (v !== undefined && (max === undefined || v > max)) {
370
380
  maxItem = item;
371
381
  max = v;
372
382
  }
373
- });
383
+ }
374
384
  return maxItem;
375
385
  }
376
386
  export function _minByOrUndefined(array, mapper) {
@@ -378,13 +388,13 @@ export function _minByOrUndefined(array, mapper) {
378
388
  return;
379
389
  let minItem;
380
390
  let min;
381
- array.forEach((item, i) => {
391
+ for (const [i, item] of array.entries()) {
382
392
  const v = mapper(item, i);
383
393
  if (v !== undefined && (min === undefined || v < min)) {
384
394
  minItem = item;
385
395
  min = v;
386
396
  }
387
- });
397
+ }
388
398
  return minItem;
389
399
  }
390
400
  export function _zip(array1, array2) {
@@ -6,7 +6,9 @@
6
6
  */
7
7
  export function objectToFormData(obj = {}) {
8
8
  const fd = new FormData();
9
- Object.entries(obj).forEach(([k, v]) => fd.append(k, v));
9
+ for (const [k, v] of Object.entries(obj)) {
10
+ fd.append(k, v);
11
+ }
10
12
  return fd;
11
13
  }
12
14
  export function formDataToObject(formData) {
@@ -38,7 +38,7 @@ export class Fetcher {
38
38
  }
39
39
  this.cfg = this.normalizeCfg(cfg);
40
40
  // Dynamically create all helper methods
41
- HTTP_METHODS.forEach(method => {
41
+ for (const method of HTTP_METHODS) {
42
42
  const m = method.toLowerCase();
43
43
  this[`${m}Void`] = async (url, opt) => {
44
44
  return await this.fetch(Object.assign({ url,
@@ -55,7 +55,7 @@ export class Fetcher {
55
55
  return await this.fetch(Object.assign({ url,
56
56
  method, responseType: 'json' }, opt));
57
57
  };
58
- });
58
+ }
59
59
  }
60
60
  /**
61
61
  * Add BeforeRequest hook at the end of the hooks list.
@@ -51,14 +51,14 @@ export function _percentile(values, pc) {
51
51
  export function _percentiles(values, pcs) {
52
52
  const r = {};
53
53
  const sorted = _sortNumbers(values);
54
- pcs.forEach(pc => {
54
+ for (const pc of pcs) {
55
55
  // Floating pos in the range of [0; length - 1]
56
56
  const pos = ((values.length - 1) * pc) / 100;
57
57
  const dec = pos % 1;
58
58
  const floorPos = Math.floor(pos);
59
59
  const ceilPos = Math.ceil(pos);
60
60
  r[pc] = _averageWeighted([sorted[floorPos], sorted[ceilPos]], [1 - dec, dec]);
61
- });
61
+ }
62
62
  return r;
63
63
  }
64
64
  /**
@@ -376,7 +376,10 @@ export function _deepFreeze(o) {
376
376
  */
377
377
  export function _objectAssignExact(target, source) {
378
378
  Object.assign(target, source);
379
- Object.keys(target)
380
- .filter(k => !(k in source))
381
- .forEach(k => delete target[k]);
379
+ for (const k of Object.keys(target)) {
380
+ if (!(k in source)) {
381
+ // consider setting it to undefined maybe?
382
+ delete target[k];
383
+ }
384
+ }
382
385
  }
@@ -5,9 +5,12 @@ const characterCodeCache = [];
5
5
  * Modified version of: https://github.com/sindresorhus/leven/
6
6
  *
7
7
  * Returns a Levenshtein distance between first and second word.
8
+ *
9
+ * `limit` optional parameter can be used to limit the distance calculation
10
+ * and skip unnecessary iterations when limit is reached.
8
11
  */
9
- export function _leven(first, second) {
10
- if (first === second) {
12
+ export function _leven(first, second, limit) {
13
+ if (first === second || limit === 0) {
11
14
  return 0;
12
15
  }
13
16
  const swap = first;
@@ -37,6 +40,8 @@ export function _leven(first, second) {
37
40
  firstLength -= start;
38
41
  secondLength -= start;
39
42
  if (firstLength === 0) {
43
+ if (limit && secondLength >= limit)
44
+ return limit;
40
45
  return secondLength;
41
46
  }
42
47
  let bCharacterCode;
@@ -53,6 +58,8 @@ export function _leven(first, second) {
53
58
  bCharacterCode = second.charCodeAt(start + index2);
54
59
  temporary = index2++;
55
60
  result = index2;
61
+ if (limit && result >= limit)
62
+ return limit; // exit early on limit
56
63
  for (index = 0; index < firstLength; index++) {
57
64
  temporary2 = bCharacterCode === characterCodeCache[index] ? temporary : temporary + 1;
58
65
  temporary = array[index];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.216.0",
3
+ "version": "14.218.0",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build-prod": "build-prod-esm-cjs",
@@ -48,9 +48,9 @@ export function _uniq<T>(a: readonly T[]): T[] {
48
48
  * a = _uniq([...a, item])
49
49
  */
50
50
  export function _pushUniq<T>(a: T[], ...items: T[]): T[] {
51
- items.forEach(item => {
51
+ for (const item of items) {
52
52
  if (!a.includes(item)) a.push(item)
53
- })
53
+ }
54
54
  return a
55
55
  }
56
56
 
@@ -229,24 +229,33 @@ export function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
229
229
 
230
230
  /**
231
231
  * Counts how many items match the predicate.
232
+ *
233
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
232
234
  */
233
- export function _count<T>(items: T[], predicate: AbortablePredicate<T>): number {
235
+ export function _count<T>(items: T[], predicate: AbortablePredicate<T>, limit?: number): number {
236
+ if (limit === 0) return 0
234
237
  let count = 0
235
238
 
236
239
  for (const [i, item] of items.entries()) {
237
240
  const r = predicate(item, i)
238
241
  if (r === END) break
239
- if (r) count++
242
+ if (r) {
243
+ count++
244
+ if (limit && count >= limit) break
245
+ }
240
246
  }
241
247
 
242
248
  return count
243
249
  }
244
250
 
251
+ /**
252
+ * `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
253
+ */
245
254
  export function _countBy<T>(items: T[], mapper: Mapper<T, any>): StringMap<number> {
246
255
  const map: StringMap<number> = {}
247
256
 
248
- items.forEach((item, index) => {
249
- const key = mapper(item, index)
257
+ items.forEach((item, i) => {
258
+ const key = mapper(item, i)
250
259
  map[key] = (map[key] || 0) + 1
251
260
  })
252
261
 
@@ -326,12 +335,12 @@ export function _mapToObject<T, V>(
326
335
  ): StringMap<V> {
327
336
  const m: StringMap<V> = {}
328
337
 
329
- array.forEach(item => {
338
+ for (const item of array) {
330
339
  const r = mapper(item)
331
- if (!r) return // filtering
340
+ if (!r) continue // filtering
332
341
 
333
342
  m[r[0]] = r[1]
334
- })
343
+ }
335
344
 
336
345
  return m
337
346
  }
@@ -428,13 +437,14 @@ export function _maxByOrUndefined<T>(
428
437
  if (!array.length) return
429
438
  let maxItem: T | undefined
430
439
  let max: number | string | undefined
431
- array.forEach((item, i) => {
440
+
441
+ for (const [i, item] of array.entries()) {
432
442
  const v = mapper(item, i)
433
443
  if (v !== undefined && (max === undefined || v > max)) {
434
444
  maxItem = item
435
445
  max = v
436
446
  }
437
- })
447
+ }
438
448
 
439
449
  return maxItem
440
450
  }
@@ -446,13 +456,14 @@ export function _minByOrUndefined<T>(
446
456
  if (!array.length) return
447
457
  let minItem: T | undefined
448
458
  let min: number | string | undefined
449
- array.forEach((item, i) => {
459
+
460
+ for (const [i, item] of array.entries()) {
450
461
  const v = mapper(item, i)
451
462
  if (v !== undefined && (min === undefined || v < min)) {
452
463
  minItem = item
453
464
  min = v
454
465
  }
455
- })
466
+ }
456
467
 
457
468
  return minItem
458
469
  }
package/src/form.util.ts CHANGED
@@ -8,7 +8,9 @@ import type { AnyObject } from './types'
8
8
  */
9
9
  export function objectToFormData(obj: AnyObject = {}): FormData {
10
10
  const fd = new FormData()
11
- Object.entries(obj).forEach(([k, v]) => fd.append(k, v))
11
+ for (const [k, v] of Object.entries(obj)) {
12
+ fd.append(k, v)
13
+ }
12
14
  return fd
13
15
  }
14
16
 
@@ -82,7 +82,7 @@ export class Fetcher {
82
82
  this.cfg = this.normalizeCfg(cfg)
83
83
 
84
84
  // Dynamically create all helper methods
85
- HTTP_METHODS.forEach(method => {
85
+ for (const method of HTTP_METHODS) {
86
86
  const m = method.toLowerCase()
87
87
 
88
88
  // responseType=void
@@ -114,7 +114,7 @@ export class Fetcher {
114
114
  ...opt,
115
115
  })
116
116
  }
117
- })
117
+ }
118
118
  }
119
119
 
120
120
  /**
@@ -62,7 +62,7 @@ export function _percentiles(values: number[], pcs: number[]): Record<number, nu
62
62
 
63
63
  const sorted = _sortNumbers(values)
64
64
 
65
- pcs.forEach(pc => {
65
+ for (const pc of pcs) {
66
66
  // Floating pos in the range of [0; length - 1]
67
67
  const pos = ((values.length - 1) * pc) / 100
68
68
  const dec = pos % 1
@@ -70,7 +70,7 @@ export function _percentiles(values: number[], pcs: number[]): Record<number, nu
70
70
  const ceilPos = Math.ceil(pos)
71
71
 
72
72
  r[pc] = _averageWeighted([sorted[floorPos]!, sorted[ceilPos]!], [1 - dec, dec])
73
- })
73
+ }
74
74
 
75
75
  return r
76
76
  }
@@ -440,7 +440,11 @@ export function _deepFreeze(o: any): void {
440
440
  */
441
441
  export function _objectAssignExact<T extends AnyObject>(target: T, source: T): void {
442
442
  Object.assign(target, source)
443
- Object.keys(target)
444
- .filter(k => !(k in source))
445
- .forEach(k => delete target[k])
443
+
444
+ for (const k of Object.keys(target)) {
445
+ if (!(k in source)) {
446
+ // consider setting it to undefined maybe?
447
+ delete target[k]
448
+ }
449
+ }
446
450
  }
@@ -7,9 +7,12 @@ const characterCodeCache: number[] = []
7
7
  * Modified version of: https://github.com/sindresorhus/leven/
8
8
  *
9
9
  * Returns a Levenshtein distance between first and second word.
10
+ *
11
+ * `limit` optional parameter can be used to limit the distance calculation
12
+ * and skip unnecessary iterations when limit is reached.
10
13
  */
11
- export function _leven(first: string, second: string): number {
12
- if (first === second) {
14
+ export function _leven(first: string, second: string, limit?: number): number {
15
+ if (first === second || limit === 0) {
13
16
  return 0
14
17
  }
15
18
 
@@ -47,6 +50,7 @@ export function _leven(first: string, second: string): number {
47
50
  secondLength -= start
48
51
 
49
52
  if (firstLength === 0) {
53
+ if (limit && secondLength >= limit) return limit
50
54
  return secondLength
51
55
  }
52
56
 
@@ -66,6 +70,7 @@ export function _leven(first: string, second: string): number {
66
70
  bCharacterCode = second.charCodeAt(start + index2)
67
71
  temporary = index2++
68
72
  result = index2
73
+ if (limit && result >= limit) return limit // exit early on limit
69
74
 
70
75
  for (index = 0; index < firstLength; index++) {
71
76
  temporary2 = bCharacterCode === characterCodeCache[index] ? temporary : temporary + 1