@naturalcycles/js-lib 14.71.0 → 14.75.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/dist/seq/seq.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._seq = exports.Seq = void 0;
3
+ exports.AsyncSequence = exports._seq = exports.Sequence = void 0;
4
4
  const types_1 = require("../types");
5
5
  /**
6
6
  * Inspired by Kotlin Sequences.
@@ -10,7 +10,7 @@ const types_1 = require("../types");
10
10
  *
11
11
  * @experimental
12
12
  */
13
- class Seq {
13
+ class Sequence {
14
14
  constructor(initialValue, nextFn) {
15
15
  this.nextFn = nextFn;
16
16
  this.sentInitialValue = false;
@@ -26,18 +26,18 @@ class Seq {
26
26
  };
27
27
  }
28
28
  static create(initialValue, nextFn) {
29
- return new Seq(initialValue, nextFn);
29
+ return new Sequence(initialValue, nextFn);
30
30
  }
31
31
  static range(minIncl, maxExcl, step = 1) {
32
32
  const max = maxExcl - step;
33
- return new Seq(minIncl, n => (n < max ? n + step : types_1.END));
33
+ return new Sequence(minIncl, n => (n < max ? n + step : types_1.END));
34
34
  }
35
35
  static from(a) {
36
36
  const it = a[Symbol.iterator]();
37
37
  const v = it.next();
38
38
  if (v.done)
39
- return new Seq(types_1.END, () => { });
40
- return new Seq(v.value, () => {
39
+ return new Sequence(types_1.END, () => { });
40
+ return new Sequence(v.value, () => {
41
41
  const v = it.next();
42
42
  if (v.done)
43
43
  return types_1.END;
@@ -45,7 +45,7 @@ class Seq {
45
45
  });
46
46
  }
47
47
  static empty() {
48
- return new Seq(types_1.END, () => { });
48
+ return new Sequence(types_1.END, () => { });
49
49
  }
50
50
  next() {
51
51
  if (this.currentValue === types_1.END)
@@ -131,11 +131,118 @@ class Seq {
131
131
  }
132
132
  }
133
133
  }
134
- exports.Seq = Seq;
134
+ exports.Sequence = Sequence;
135
135
  /**
136
136
  * Convenience function to create a Sequence.
137
137
  */
138
138
  function _seq(initialValue, nextFn) {
139
- return Seq.create(initialValue, nextFn);
139
+ return Sequence.create(initialValue, nextFn);
140
140
  }
141
141
  exports._seq = _seq;
142
+ /* eslint-disable no-await-in-loop */
143
+ /**
144
+ * Experimental.
145
+ * Feasibility to be proven.
146
+ *
147
+ * @experimental
148
+ */
149
+ class AsyncSequence {
150
+ constructor(initialValue, nextFn) {
151
+ this.nextFn = nextFn;
152
+ this.sentInitialValue = false;
153
+ this.i = -1;
154
+ this.currentValue = initialValue;
155
+ }
156
+ [Symbol.asyncIterator]() {
157
+ return {
158
+ next: async () => {
159
+ const value = await this.next();
160
+ return value === types_1.END ? { done: true, value: undefined } : { value };
161
+ },
162
+ };
163
+ }
164
+ static create(initialValue, nextFn) {
165
+ return new AsyncSequence(initialValue, nextFn);
166
+ }
167
+ static async from(a) {
168
+ const it = a[Symbol.asyncIterator]();
169
+ const v = await it.next();
170
+ if (v.done)
171
+ return new AsyncSequence(types_1.END, () => { });
172
+ return new AsyncSequence(v.value, async () => {
173
+ const v = await it.next();
174
+ if (v.done)
175
+ return types_1.END;
176
+ return v.value;
177
+ });
178
+ }
179
+ static empty() {
180
+ return new AsyncSequence(types_1.END, () => { });
181
+ }
182
+ async next() {
183
+ if (this.currentValue === types_1.END)
184
+ return types_1.END;
185
+ this.i++;
186
+ let v;
187
+ if (!this.sentInitialValue) {
188
+ this.sentInitialValue = true;
189
+ v = this.currentValue;
190
+ }
191
+ else {
192
+ v = await this.nextFn(this.currentValue, this.i);
193
+ }
194
+ // console.log(`_seq`, v)
195
+ if (v === types_1.SKIP)
196
+ return await this.next();
197
+ return (this.currentValue = v);
198
+ }
199
+ // Final functions - return final value, not a chained sequence
200
+ async find(predicate) {
201
+ do {
202
+ const v = await this.next();
203
+ if (v === types_1.END)
204
+ return; // not found, end of sequence
205
+ const r = await predicate(v, this.i);
206
+ if (r === types_1.END)
207
+ return;
208
+ if (r)
209
+ return v;
210
+ // otherwise proceed
211
+ } while (true); // eslint-disable-line no-constant-condition
212
+ }
213
+ async some(predicate) {
214
+ do {
215
+ const v = await this.next();
216
+ if (v === types_1.END)
217
+ return false;
218
+ const r = await predicate(v, this.i);
219
+ if (r === types_1.END)
220
+ return false;
221
+ if (r)
222
+ return true;
223
+ } while (true); // eslint-disable-line no-constant-condition
224
+ }
225
+ async every(predicate) {
226
+ do {
227
+ const v = await this.next();
228
+ if (v === types_1.END)
229
+ return true;
230
+ const r = await predicate(v, this.i);
231
+ if (r === types_1.END)
232
+ return true;
233
+ if (!r)
234
+ return false;
235
+ } while (true); // eslint-disable-line no-constant-condition
236
+ }
237
+ async toArray() {
238
+ const a = [];
239
+ // eslint-disable-next-line no-constant-condition
240
+ while (true) {
241
+ const v = await this.next();
242
+ if (v === types_1.END)
243
+ return a;
244
+ a.push(v);
245
+ }
246
+ }
247
+ }
248
+ exports.AsyncSequence = AsyncSequence;
package/dist-esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { _by, _chunk, _countBy, _difference, _dropRightWhile, _dropWhile, _findLast, _flatten, _flattenDeep, _groupBy, _intersection, _last, _mapToObject, _shuffle, _sortBy, _sum, _sumBy, _takeRightWhile, _takeWhile, _uniq, _uniqBy, } from './array/array.util';
2
- import { _defineLazyProperty, _defineLazyProps, _lazyValue } from './lazy';
3
- import { _parseQueryString } from './string/url.util';
4
- import { _range } from './array/range';
1
+ export * from './array/array.util';
2
+ export * from './lazy';
3
+ export * from './string/url.util';
4
+ export * from './array/range';
5
5
  import { _createPromiseDecorator, } from './decorators/createPromiseDecorator';
6
6
  import { _debounce, _throttle } from './decorators/debounce';
7
7
  import { _Debounce, _Throttle } from './decorators/debounce.decorator';
@@ -22,29 +22,29 @@ import { generateJsonSchemaFromData } from './json-schema/from-data/generateJson
22
22
  import { JSON_SCHEMA_ORDER } from './json-schema/jsonSchema.cnst';
23
23
  import { mergeJsonSchemaObjects } from './json-schema/jsonSchema.util';
24
24
  import { jsonSchema, JsonSchemaAnyBuilder, } from './json-schema/jsonSchemaBuilder';
25
- import { _average, _averageWeighted, _median, _percentile } from './math/math.util';
26
- import { SimpleMovingAverage } from './math/sma';
27
- import { _createDeterministicRandom } from './number/createDeterministicRandom';
28
- import { _clamp, _inRange, _randomInt, _randomArrayItem, _round, _sortNumbers, _toFixed, _toPrecision, } from './number/number.util';
29
- import { _deepEquals } from './object/deepEquals';
30
- import { _deepCopy, _deepTrim, _filterEmptyArrays, _filterEmptyValues, _filterFalsyValues, _filterNullishValues, _filterObject, _filterUndefinedValues, _findKeyByValue, _get, _has, _invert, _invertMap, _isEmpty, _isEmptyObject, _isObject, _isPrimitive, _mapKeys, _mapObject, _mapValues, _mask, _merge, _objectNullValuesToUndefined, _omit, _pick, _set, _undefinedIfEmpty, _unset, } from './object/object.util';
31
- import { _sortObject } from './object/sortObject';
32
- import { _sortObjectDeep } from './object/sortObjectDeep';
25
+ export * from './math/math.util';
26
+ export * from './math/sma';
27
+ export * from './number/createDeterministicRandom';
28
+ export * from './number/number.util';
29
+ export * from './object/deepEquals';
30
+ export * from './object/object.util';
31
+ export * from './object/sortObject';
32
+ export * from './object/sortObjectDeep';
33
33
  import { AggregatedError } from './promise/AggregatedError';
34
- import { pBatch } from './promise/pBatch';
34
+ export * from './promise/pBatch';
35
35
  import { pDefer } from './promise/pDefer';
36
- import { pDelay } from './promise/pDelay';
37
- import { pFilter } from './promise/pFilter';
38
- import { pHang } from './promise/pHang';
36
+ export * from './promise/pDelay';
37
+ export * from './promise/pFilter';
38
+ export * from './promise/pHang';
39
39
  import { pMap } from './promise/pMap';
40
- import { pProps } from './promise/pProps';
40
+ export * from './promise/pProps';
41
41
  import { pRetry } from './promise/pRetry';
42
- import { pState } from './promise/pState';
42
+ export * from './promise/pState';
43
43
  import { pTimeout } from './promise/pTimeout';
44
- import { pTuple } from './promise/pTuple';
45
- import { _camelCase, _kebabCase, _snakeCase } from './string/case';
46
- import { _jsonParseIfPossible } from './string/json.util';
47
- import { _capitalize, _lowerFirst, _nl2br, _removeWhitespace, _replaceAll, _split, _substringAfter, _substringAfterLast, _substringBefore, _substringBeforeLast, _substringBetweenLast, _truncate, _truncateMiddle, _upperFirst, } from './string/string.util';
44
+ export * from './promise/pTuple';
45
+ export * from './string/case';
46
+ export * from './string/json.util';
47
+ export * from './string/string.util';
48
48
  import { _stringifyAny } from './string/stringifyAny';
49
49
  import { _ms, _since } from './time/time.util';
50
50
  import { END, SKIP, _noop, _objectKeys, _passNothingPredicate, _passthroughMapper, _passthroughPredicate, _passUndefinedMapper, _stringMapEntries, _stringMapValues, } from './types';
@@ -54,4 +54,5 @@ import { commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLog
54
54
  import { _safeJsonStringify } from './string/safeJsonStringify';
55
55
  import { PQueue } from './promise/pQueue';
56
56
  export * from './seq/seq';
57
- export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _randomInt, _randomArrayItem, _createDeterministicRandom, _inRange, _stringMapValues, _stringMapEntries, _objectKeys, _capitalize, _upperFirst, _lowerFirst, _split, _removeWhitespace, _substringBefore, _substringBeforeLast, _substringAfter, _substringAfterLast, _substringBetweenLast, _replaceAll, _nl2br, _truncate, _truncateMiddle, _pick, _omit, _filterFalsyValues, _filterUndefinedValues, _filterNullishValues, _filterEmptyArrays, _filterEmptyValues, _filterObject, _undefinedIfEmpty, _isObject, _isPrimitive, _mapKeys, _mapValues, _mapObject, _objectNullValuesToUndefined, _deepEquals, _deepCopy, _isEmptyObject, _isEmpty, _merge, _deepTrim, _sortObjectDeep, _sortObject, _get, _set, _has, _unset, _mask, _invert, _invertMap, _by, _groupBy, _sortBy, _sortNumbers, _toFixed, _toPrecision, _round, _findLast, _takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile, _countBy, _intersection, _difference, _shuffle, _mapToObject, _findKeyByValue, _range, _uniq, _uniqBy, _flatten, _flattenDeep, _chunk, SimpleMovingAverage, _average, _averageWeighted, _percentile, _median, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, pBatch, ErrorMode, pFilter, pProps, pDelay, pDefer, pHang, pState, AggregatedError, pRetry, pTimeout, pTuple, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _jsonParseIfPossible, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, _snakeCase, _camelCase, _kebabCase, _sum, _sumBy, _clamp, _last, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, _parseQueryString, _defineLazyProperty, _defineLazyProps, _lazyValue, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, _safeJsonStringify, PQueue, END, SKIP, };
57
+ export * from './math/stack.util';
58
+ export { is, _Memo, _memoFn, _LogMethod, _getArgsSignature, _createPromiseDecorator, AppError, HttpError, AssertionError, _assert, _assertEquals, _assertDeepEquals, _assertIsError, _assertIsString, _assertIsNumber, _assertTypeOf, _stringMapValues, _stringMapEntries, _objectKeys, _debounce, _throttle, _Debounce, _Throttle, pMap, _passthroughMapper, _passUndefinedMapper, _passthroughPredicate, _passNothingPredicate, _noop, ErrorMode, pDefer, AggregatedError, pRetry, pTimeout, _Retry, _Timeout, _tryCatch, _TryCatch, _try, pTry, _stringifyAny, _ms, _since, _hb, _gb, _mb, _kb, mergeJsonSchemaObjects, jsonSchema, JsonSchemaAnyBuilder, JSON_SCHEMA_ORDER, generateJsonSchemaFromData, commonLoggerMinLevel, commonLoggerNoop, commonLogLevelNumber, commonLoggerPipe, commonLoggerPrefix, commonLoggerCreate, _safeJsonStringify, PQueue, END, SKIP, };
@@ -39,6 +39,22 @@ export function _percentile(values, pc) {
39
39
  const ceilPos = Math.ceil(pos);
40
40
  return _averageWeighted([sorted[floorPos], sorted[ceilPos]], [1 - dec, dec]);
41
41
  }
42
+ /**
43
+ * A tiny bit more efficient function than calling _percentile individually.
44
+ */
45
+ export function _percentiles(values, pcs) {
46
+ const r = {};
47
+ const sorted = _sortNumbers(values);
48
+ pcs.forEach(pc => {
49
+ // Floating pos in the range of [0; length - 1]
50
+ const pos = ((values.length - 1) * pc) / 100;
51
+ const dec = pos % 1;
52
+ const floorPos = Math.floor(pos);
53
+ const ceilPos = Math.ceil(pos);
54
+ r[pc] = _averageWeighted([sorted[floorPos], sorted[ceilPos]], [1 - dec, dec]);
55
+ });
56
+ return r;
57
+ }
42
58
  /**
43
59
  * @example
44
60
  *
@@ -0,0 +1,82 @@
1
+ import { _average, _percentile, _percentiles, _range } from '../index';
2
+ /**
3
+ * Implements a "round-robin" Stack ("first-in last-out" aka FILO) with a limited size.
4
+ * Like an array of a fixed size. When it runs out of space - it starts writing on top of itself
5
+ * from index 0.
6
+ *
7
+ *
8
+ */
9
+ export class Stack {
10
+ constructor(size) {
11
+ this.size = size;
12
+ /**
13
+ * Index of a slot to get written TO next.
14
+ * Currently this slot contains OLDEST item (if any).
15
+ */
16
+ this.nextIndex = 0;
17
+ this.items = [];
18
+ }
19
+ push(item) {
20
+ this.items[this.nextIndex] = item;
21
+ this.nextIndex = this.nextIndex === this.size - 1 ? 0 : this.nextIndex + 1;
22
+ return this;
23
+ }
24
+ /**
25
+ * Fill (overwrite) the whole Stack (all its items) with the passed `item`.
26
+ */
27
+ fill(item) {
28
+ _range(this.size).forEach(i => (this.items[i] = item));
29
+ return this;
30
+ }
31
+ /**
32
+ * Returns last items in the right order.
33
+ * Unlike raw `items` property that returns "items buffer" as-is (not ordered properly).
34
+ */
35
+ get itemsOrdered() {
36
+ if (this.items.length < this.size) {
37
+ // Buffer is not filled yet, just return it as-is
38
+ return this.items;
39
+ }
40
+ // Buffer was filled and started to "overwrite itself", will need to return 2 slices
41
+ return [...this.items.slice(this.nextIndex), ...this.items.slice(0, this.nextIndex)];
42
+ }
43
+ }
44
+ /**
45
+ * Fixed-size FILO stack of Numbers.
46
+ * Has convenience stat methods, e.g percentile, avg, etc.
47
+ */
48
+ export class NumberStack extends Stack {
49
+ avg() {
50
+ // _assert(this.items.length, 'NumberStack.avg cannot be called on empty stack')
51
+ return _average(this.items);
52
+ }
53
+ /**
54
+ * Returns null if Stack is empty.
55
+ */
56
+ avgOrNull() {
57
+ return this.items.length === 0 ? null : _average(this.items);
58
+ }
59
+ median() {
60
+ return _percentile(this.items, 50);
61
+ }
62
+ medianOrNull() {
63
+ return this.items.length === 0 ? null : _percentile(this.items, 50);
64
+ }
65
+ /**
66
+ * `pc` is a number from 0 to 100 inclusive.
67
+ */
68
+ percentile(pc) {
69
+ // _assert(this.items.length, 'NumberStack.percentile cannot be called on empty stack')
70
+ return _percentile(this.items, pc);
71
+ }
72
+ /**
73
+ * `pc` is a number from 0 to 100 inclusive.
74
+ * Returns null if Stack is empty.
75
+ */
76
+ percentileOrNull(pc) {
77
+ return this.items.length === 0 ? null : _percentile(this.items, pc);
78
+ }
79
+ percentiles(pcs) {
80
+ return _percentiles(this.items, pcs);
81
+ }
82
+ }
@@ -58,7 +58,7 @@ export function _toFixed(n, fractionDigits) {
58
58
  * _toPrecision(1634.56, 1)
59
59
  * // 2000
60
60
  *
61
- * _toPrecision(1234.56, 2)
61
+ * _toPrecision(1634.56, 2)
62
62
  * // 1600
63
63
  */
64
64
  export function _toPrecision(n, precision) {
@@ -1,4 +1,4 @@
1
- import { END, SKIP } from '../types';
1
+ import { END, SKIP, } from '../types';
2
2
  /**
3
3
  * Inspired by Kotlin Sequences.
4
4
  * Similar to arrays, but with lazy evaluation, abortable.
@@ -7,7 +7,7 @@ import { END, SKIP } from '../types';
7
7
  *
8
8
  * @experimental
9
9
  */
10
- export class Seq {
10
+ export class Sequence {
11
11
  constructor(initialValue, nextFn) {
12
12
  this.nextFn = nextFn;
13
13
  this.sentInitialValue = false;
@@ -23,18 +23,18 @@ export class Seq {
23
23
  };
24
24
  }
25
25
  static create(initialValue, nextFn) {
26
- return new Seq(initialValue, nextFn);
26
+ return new Sequence(initialValue, nextFn);
27
27
  }
28
28
  static range(minIncl, maxExcl, step = 1) {
29
29
  const max = maxExcl - step;
30
- return new Seq(minIncl, n => (n < max ? n + step : END));
30
+ return new Sequence(minIncl, n => (n < max ? n + step : END));
31
31
  }
32
32
  static from(a) {
33
33
  const it = a[Symbol.iterator]();
34
34
  const v = it.next();
35
35
  if (v.done)
36
- return new Seq(END, () => { });
37
- return new Seq(v.value, () => {
36
+ return new Sequence(END, () => { });
37
+ return new Sequence(v.value, () => {
38
38
  const v = it.next();
39
39
  if (v.done)
40
40
  return END;
@@ -42,7 +42,7 @@ export class Seq {
42
42
  });
43
43
  }
44
44
  static empty() {
45
- return new Seq(END, () => { });
45
+ return new Sequence(END, () => { });
46
46
  }
47
47
  next() {
48
48
  if (this.currentValue === END)
@@ -132,5 +132,111 @@ export class Seq {
132
132
  * Convenience function to create a Sequence.
133
133
  */
134
134
  export function _seq(initialValue, nextFn) {
135
- return Seq.create(initialValue, nextFn);
135
+ return Sequence.create(initialValue, nextFn);
136
+ }
137
+ /* eslint-disable no-await-in-loop */
138
+ /**
139
+ * Experimental.
140
+ * Feasibility to be proven.
141
+ *
142
+ * @experimental
143
+ */
144
+ export class AsyncSequence {
145
+ constructor(initialValue, nextFn) {
146
+ this.nextFn = nextFn;
147
+ this.sentInitialValue = false;
148
+ this.i = -1;
149
+ this.currentValue = initialValue;
150
+ }
151
+ [Symbol.asyncIterator]() {
152
+ return {
153
+ next: async () => {
154
+ const value = await this.next();
155
+ return value === END ? { done: true, value: undefined } : { value };
156
+ },
157
+ };
158
+ }
159
+ static create(initialValue, nextFn) {
160
+ return new AsyncSequence(initialValue, nextFn);
161
+ }
162
+ static async from(a) {
163
+ const it = a[Symbol.asyncIterator]();
164
+ const v = await it.next();
165
+ if (v.done)
166
+ return new AsyncSequence(END, () => { });
167
+ return new AsyncSequence(v.value, async () => {
168
+ const v = await it.next();
169
+ if (v.done)
170
+ return END;
171
+ return v.value;
172
+ });
173
+ }
174
+ static empty() {
175
+ return new AsyncSequence(END, () => { });
176
+ }
177
+ async next() {
178
+ if (this.currentValue === END)
179
+ return END;
180
+ this.i++;
181
+ let v;
182
+ if (!this.sentInitialValue) {
183
+ this.sentInitialValue = true;
184
+ v = this.currentValue;
185
+ }
186
+ else {
187
+ v = await this.nextFn(this.currentValue, this.i);
188
+ }
189
+ // console.log(`_seq`, v)
190
+ if (v === SKIP)
191
+ return await this.next();
192
+ return (this.currentValue = v);
193
+ }
194
+ // Final functions - return final value, not a chained sequence
195
+ async find(predicate) {
196
+ do {
197
+ const v = await this.next();
198
+ if (v === END)
199
+ return; // not found, end of sequence
200
+ const r = await predicate(v, this.i);
201
+ if (r === END)
202
+ return;
203
+ if (r)
204
+ return v;
205
+ // otherwise proceed
206
+ } while (true); // eslint-disable-line no-constant-condition
207
+ }
208
+ async some(predicate) {
209
+ do {
210
+ const v = await this.next();
211
+ if (v === END)
212
+ return false;
213
+ const r = await predicate(v, this.i);
214
+ if (r === END)
215
+ return false;
216
+ if (r)
217
+ return true;
218
+ } while (true); // eslint-disable-line no-constant-condition
219
+ }
220
+ async every(predicate) {
221
+ do {
222
+ const v = await this.next();
223
+ if (v === END)
224
+ return true;
225
+ const r = await predicate(v, this.i);
226
+ if (r === END)
227
+ return true;
228
+ if (!r)
229
+ return false;
230
+ } while (true); // eslint-disable-line no-constant-condition
231
+ }
232
+ async toArray() {
233
+ const a = [];
234
+ // eslint-disable-next-line no-constant-condition
235
+ while (true) {
236
+ const v = await this.next();
237
+ if (v === END)
238
+ return a;
239
+ a.push(v);
240
+ }
241
+ }
136
242
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
- "version": "14.71.0",
3
+ "version": "14.75.0",
4
4
  "scripts": {
5
5
  "prepare": "husky install",
6
6
  "build-prod": "build-prod-esm-cjs",