@naturalcycles/js-lib 14.191.0 → 14.192.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/array/range.d.ts +6 -0
- package/dist/array/range.js +16 -2
- package/dist/datetime/localDate.d.ts +5 -0
- package/dist/datetime/localDate.js +22 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/iter/iterable2.d.ts +21 -0
- package/dist/iter/iterable2.js +75 -0
- package/dist/string/stringify.d.ts +1 -1
- package/dist/string/stringify.js +1 -1
- package/dist-esm/array/range.js +14 -1
- package/dist-esm/datetime/localDate.js +22 -11
- package/dist-esm/index.js +1 -1
- package/dist-esm/iter/iterable2.js +71 -0
- package/dist-esm/string/stringify.js +1 -1
- package/package.json +1 -1
- package/src/array/range.ts +22 -0
- package/src/datetime/localDate.ts +30 -11
- package/src/index.ts +1 -1
- package/src/iter/iterable2.ts +74 -0
- package/src/string/stringify.ts +1 -1
- package/dist/seq/seq.d.ts +0 -54
- package/dist/seq/seq.js +0 -257
- package/dist-esm/seq/seq.js +0 -251
- package/src/seq/seq.ts +0 -277
package/dist/array/range.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Iterable2 } from '../iter/iterable2';
|
|
1
2
|
/**
|
|
2
3
|
* Returns an array with ranges from `from` up to (but not including) `to`.
|
|
3
4
|
*
|
|
@@ -10,3 +11,8 @@
|
|
|
10
11
|
*/
|
|
11
12
|
export declare function _range(toExcl: number): number[];
|
|
12
13
|
export declare function _range(fromIncl: number, toExcl: number, step?: number): number[];
|
|
14
|
+
/**
|
|
15
|
+
* Like _range, but returns an Iterable2.
|
|
16
|
+
*/
|
|
17
|
+
export declare function _rangeIt(toExcl: number): Iterable2<number>;
|
|
18
|
+
export declare function _rangeIt(fromIncl: number, toExcl: number, step?: number): Iterable2<number>;
|
package/dist/array/range.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable no-redeclare, unicorn/no-new-array */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports._range = void 0;
|
|
3
|
+
exports._rangeIt = exports._range = void 0;
|
|
4
|
+
const iterable2_1 = require("../iter/iterable2");
|
|
5
5
|
function _range(fromIncl, toExcl, step = 1) {
|
|
6
6
|
if (toExcl === undefined) {
|
|
7
7
|
return Array.from(new Array(fromIncl), (_, i) => i);
|
|
@@ -9,3 +9,17 @@ function _range(fromIncl, toExcl, step = 1) {
|
|
|
9
9
|
return Array.from({ length: Math.ceil((toExcl - fromIncl) / step) }, (_, i) => i * step + fromIncl);
|
|
10
10
|
}
|
|
11
11
|
exports._range = _range;
|
|
12
|
+
function _rangeIt(fromIncl, toExcl, step = 1) {
|
|
13
|
+
if (toExcl === undefined) {
|
|
14
|
+
toExcl = fromIncl;
|
|
15
|
+
fromIncl = 0;
|
|
16
|
+
}
|
|
17
|
+
return iterable2_1.Iterable2.of({
|
|
18
|
+
*[Symbol.iterator]() {
|
|
19
|
+
for (let i = fromIncl; i < toExcl; i += step) {
|
|
20
|
+
yield i;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
exports._rangeIt = _rangeIt;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Iterable2 } from '../iter/iterable2';
|
|
1
2
|
import type { IsoDateString, IsoDateTimeString, MonthId, SortDirection, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
|
|
2
3
|
import { LocalTime } from './localTime';
|
|
3
4
|
export type LocalDateUnit = LocalDateUnitStrict | 'week';
|
|
@@ -35,6 +36,10 @@ export declare class LocalDate {
|
|
|
35
36
|
static latestOrUndefined(items: LocalDateInput[]): LocalDate | undefined;
|
|
36
37
|
static latest(items: LocalDateInput[]): LocalDate;
|
|
37
38
|
static range(min: LocalDateInput, max: LocalDateInput, incl?: Inclusiveness, step?: number, stepUnit?: LocalDateUnit): LocalDate[];
|
|
39
|
+
/**
|
|
40
|
+
* Experimental, returns the range as Iterable2.
|
|
41
|
+
*/
|
|
42
|
+
static rangeIt(min: LocalDateInput, max: LocalDateInput, incl?: Inclusiveness, step?: number, stepUnit?: LocalDateUnit): Iterable2<LocalDate>;
|
|
38
43
|
get(unit: LocalDateUnitStrict): number;
|
|
39
44
|
set(unit: LocalDateUnitStrict, v: number, mutate?: boolean): LocalDate;
|
|
40
45
|
year(): number;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.localDateOrToday = exports.localDateOrUndefined = exports.localDateToday = exports.localDate = exports.LocalDate = void 0;
|
|
4
4
|
const assert_1 = require("../error/assert");
|
|
5
|
+
const iterable2_1 = require("../iter/iterable2");
|
|
5
6
|
const localTime_1 = require("./localTime");
|
|
6
7
|
const MDAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
7
8
|
const DATE_REGEX = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
@@ -104,27 +105,37 @@ class LocalDate {
|
|
|
104
105
|
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
105
106
|
}
|
|
106
107
|
static range(min, max, incl = '[)', step = 1, stepUnit = 'day') {
|
|
108
|
+
return this.rangeIt(min, max, incl, step, stepUnit).toArray();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Experimental, returns the range as Iterable2.
|
|
112
|
+
*/
|
|
113
|
+
static rangeIt(min, max, incl = '[)', step = 1, stepUnit = 'day') {
|
|
107
114
|
if (stepUnit === 'week') {
|
|
108
115
|
step *= 7;
|
|
109
116
|
stepUnit = 'day';
|
|
110
117
|
}
|
|
111
|
-
const
|
|
112
|
-
const $min = LocalDate.of(min);
|
|
118
|
+
const $min = LocalDate.of(min).startOf(stepUnit);
|
|
113
119
|
const $max = LocalDate.of(max).startOf(stepUnit);
|
|
114
|
-
let
|
|
120
|
+
let value = $min;
|
|
115
121
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
116
|
-
if (
|
|
122
|
+
if (value.isAfter($min, incl[0] === '[')) {
|
|
117
123
|
// ok
|
|
118
124
|
}
|
|
119
125
|
else {
|
|
120
|
-
|
|
126
|
+
value.plus(1, stepUnit, true);
|
|
121
127
|
}
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
const rightInclusive = incl[1] === ']';
|
|
129
|
+
return iterable2_1.Iterable2.of({
|
|
130
|
+
*[Symbol.iterator]() {
|
|
131
|
+
while (value.isBefore($max, rightInclusive)) {
|
|
132
|
+
yield value;
|
|
133
|
+
// We don't mutate, because we already returned `current`
|
|
134
|
+
// in the previous iteration
|
|
135
|
+
value = value.plus(step, stepUnit);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
});
|
|
128
139
|
}
|
|
129
140
|
get(unit) {
|
|
130
141
|
return unit === 'year' ? this.$year : unit === 'month' ? this.$month : this.$day;
|
package/dist/index.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export * from './log/commonLogger';
|
|
|
60
60
|
export * from './string/safeJsonStringify';
|
|
61
61
|
export * from './promise/pQueue';
|
|
62
62
|
export * from './promise/abortable';
|
|
63
|
-
export * from './
|
|
63
|
+
export * from './iter/iterable2';
|
|
64
64
|
export * from './math/stack.util';
|
|
65
65
|
export * from './string/leven';
|
|
66
66
|
export * from './datetime/localDate';
|
package/dist/index.js
CHANGED
|
@@ -64,7 +64,7 @@ tslib_1.__exportStar(require("./log/commonLogger"), exports);
|
|
|
64
64
|
tslib_1.__exportStar(require("./string/safeJsonStringify"), exports);
|
|
65
65
|
tslib_1.__exportStar(require("./promise/pQueue"), exports);
|
|
66
66
|
tslib_1.__exportStar(require("./promise/abortable"), exports);
|
|
67
|
-
tslib_1.__exportStar(require("./
|
|
67
|
+
tslib_1.__exportStar(require("./iter/iterable2"), exports);
|
|
68
68
|
tslib_1.__exportStar(require("./math/stack.util"), exports);
|
|
69
69
|
tslib_1.__exportStar(require("./string/leven"), exports);
|
|
70
70
|
tslib_1.__exportStar(require("./datetime/localDate"), exports);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AbortableMapper, AbortablePredicate, END, Predicate } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Iterable2 is a wrapper around Iterable that implements "Iterator Helpers proposal":
|
|
4
|
+
* https://github.com/tc39/proposal-iterator-helpers
|
|
5
|
+
*
|
|
6
|
+
* Iterable2 can be removed after the proposal is widely implemented in Node & browsers.
|
|
7
|
+
*
|
|
8
|
+
* @experimental
|
|
9
|
+
*/
|
|
10
|
+
export declare class Iterable2<T> implements Iterable<T> {
|
|
11
|
+
private it;
|
|
12
|
+
private constructor();
|
|
13
|
+
static of<T>(it: Iterable<T>): Iterable2<T>;
|
|
14
|
+
static empty<T>(): Iterable2<T>;
|
|
15
|
+
[Symbol.iterator](): Iterator<T>;
|
|
16
|
+
toArray(): T[];
|
|
17
|
+
forEach(cb: (v: T, i: number) => any | typeof END): void;
|
|
18
|
+
find(cb: Predicate<T>): T | undefined;
|
|
19
|
+
filter(cb: AbortablePredicate<T>): Iterable2<T>;
|
|
20
|
+
map<OUT>(mapper: AbortableMapper<T, OUT>): Iterable2<OUT>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Iterable2 = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
/**
|
|
6
|
+
* Iterable2 is a wrapper around Iterable that implements "Iterator Helpers proposal":
|
|
7
|
+
* https://github.com/tc39/proposal-iterator-helpers
|
|
8
|
+
*
|
|
9
|
+
* Iterable2 can be removed after the proposal is widely implemented in Node & browsers.
|
|
10
|
+
*
|
|
11
|
+
* @experimental
|
|
12
|
+
*/
|
|
13
|
+
class Iterable2 {
|
|
14
|
+
constructor(it) {
|
|
15
|
+
this.it = it;
|
|
16
|
+
}
|
|
17
|
+
static of(it) {
|
|
18
|
+
return new Iterable2(it);
|
|
19
|
+
}
|
|
20
|
+
static empty() {
|
|
21
|
+
return new Iterable2([]);
|
|
22
|
+
}
|
|
23
|
+
[Symbol.iterator]() {
|
|
24
|
+
return this.it[Symbol.iterator]();
|
|
25
|
+
}
|
|
26
|
+
toArray() {
|
|
27
|
+
return [...this.it];
|
|
28
|
+
}
|
|
29
|
+
forEach(cb) {
|
|
30
|
+
let i = 0;
|
|
31
|
+
for (const v of this.it) {
|
|
32
|
+
if (cb(v, i++) === types_1.END)
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
find(cb) {
|
|
37
|
+
let i = 0;
|
|
38
|
+
for (const v of this.it) {
|
|
39
|
+
if (cb(v, i++))
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
filter(cb) {
|
|
44
|
+
const { it } = this;
|
|
45
|
+
return new Iterable2({
|
|
46
|
+
*[Symbol.iterator]() {
|
|
47
|
+
let i = 0;
|
|
48
|
+
for (const v of it) {
|
|
49
|
+
const r = cb(v, i++);
|
|
50
|
+
if (r === types_1.END)
|
|
51
|
+
return;
|
|
52
|
+
if (r)
|
|
53
|
+
yield v;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
map(mapper) {
|
|
59
|
+
const { it } = this;
|
|
60
|
+
return new Iterable2({
|
|
61
|
+
*[Symbol.iterator]() {
|
|
62
|
+
let i = 0;
|
|
63
|
+
for (const v of it) {
|
|
64
|
+
const r = mapper(v, i++);
|
|
65
|
+
if (r === types_1.END)
|
|
66
|
+
return;
|
|
67
|
+
if (r === types_1.SKIP)
|
|
68
|
+
continue;
|
|
69
|
+
yield r;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.Iterable2 = Iterable2;
|
|
@@ -7,7 +7,7 @@ import type { Reviver } from '../types';
|
|
|
7
7
|
*
|
|
8
8
|
* Defaults to _safeJsonStringify.
|
|
9
9
|
*
|
|
10
|
-
* Node.js project can set it to
|
|
10
|
+
* Node.js project can set it to _inspect, which allows to use `util.inspect`
|
|
11
11
|
* as pretty-printing function.
|
|
12
12
|
*
|
|
13
13
|
* It's recommended that this function is circular-reference-safe.
|
package/dist/string/stringify.js
CHANGED
|
@@ -14,7 +14,7 @@ let globalStringifyFunction = safeJsonStringify_1._safeJsonStringify;
|
|
|
14
14
|
*
|
|
15
15
|
* Defaults to _safeJsonStringify.
|
|
16
16
|
*
|
|
17
|
-
* Node.js project can set it to
|
|
17
|
+
* Node.js project can set it to _inspect, which allows to use `util.inspect`
|
|
18
18
|
* as pretty-printing function.
|
|
19
19
|
*
|
|
20
20
|
* It's recommended that this function is circular-reference-safe.
|
package/dist-esm/array/range.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import { Iterable2 } from '../iter/iterable2';
|
|
2
2
|
export function _range(fromIncl, toExcl, step = 1) {
|
|
3
3
|
if (toExcl === undefined) {
|
|
4
4
|
return Array.from(new Array(fromIncl), (_, i) => i);
|
|
5
5
|
}
|
|
6
6
|
return Array.from({ length: Math.ceil((toExcl - fromIncl) / step) }, (_, i) => i * step + fromIncl);
|
|
7
7
|
}
|
|
8
|
+
export function _rangeIt(fromIncl, toExcl, step = 1) {
|
|
9
|
+
if (toExcl === undefined) {
|
|
10
|
+
toExcl = fromIncl;
|
|
11
|
+
fromIncl = 0;
|
|
12
|
+
}
|
|
13
|
+
return Iterable2.of({
|
|
14
|
+
*[Symbol.iterator]() {
|
|
15
|
+
for (let i = fromIncl; i < toExcl; i += step) {
|
|
16
|
+
yield i;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _assert } from '../error/assert';
|
|
2
|
+
import { Iterable2 } from '../iter/iterable2';
|
|
2
3
|
import { LocalTime } from './localTime';
|
|
3
4
|
const MDAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
4
5
|
const DATE_REGEX = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
@@ -101,27 +102,37 @@ export class LocalDate {
|
|
|
101
102
|
.reduce((max, item) => (max.isSameOrAfter(item) ? max : item));
|
|
102
103
|
}
|
|
103
104
|
static range(min, max, incl = '[)', step = 1, stepUnit = 'day') {
|
|
105
|
+
return this.rangeIt(min, max, incl, step, stepUnit).toArray();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Experimental, returns the range as Iterable2.
|
|
109
|
+
*/
|
|
110
|
+
static rangeIt(min, max, incl = '[)', step = 1, stepUnit = 'day') {
|
|
104
111
|
if (stepUnit === 'week') {
|
|
105
112
|
step *= 7;
|
|
106
113
|
stepUnit = 'day';
|
|
107
114
|
}
|
|
108
|
-
const
|
|
109
|
-
const $min = LocalDate.of(min);
|
|
115
|
+
const $min = LocalDate.of(min).startOf(stepUnit);
|
|
110
116
|
const $max = LocalDate.of(max).startOf(stepUnit);
|
|
111
|
-
let
|
|
117
|
+
let value = $min;
|
|
112
118
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
113
|
-
if (
|
|
119
|
+
if (value.isAfter($min, incl[0] === '[')) {
|
|
114
120
|
// ok
|
|
115
121
|
}
|
|
116
122
|
else {
|
|
117
|
-
|
|
123
|
+
value.plus(1, stepUnit, true);
|
|
118
124
|
}
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
const rightInclusive = incl[1] === ']';
|
|
126
|
+
return Iterable2.of({
|
|
127
|
+
*[Symbol.iterator]() {
|
|
128
|
+
while (value.isBefore($max, rightInclusive)) {
|
|
129
|
+
yield value;
|
|
130
|
+
// We don't mutate, because we already returned `current`
|
|
131
|
+
// in the previous iteration
|
|
132
|
+
value = value.plus(step, stepUnit);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
});
|
|
125
136
|
}
|
|
126
137
|
get(unit) {
|
|
127
138
|
return unit === 'year' ? this.$year : unit === 'month' ? this.$month : this.$day;
|
package/dist-esm/index.js
CHANGED
|
@@ -60,7 +60,7 @@ export * from './log/commonLogger';
|
|
|
60
60
|
export * from './string/safeJsonStringify';
|
|
61
61
|
export * from './promise/pQueue';
|
|
62
62
|
export * from './promise/abortable';
|
|
63
|
-
export * from './
|
|
63
|
+
export * from './iter/iterable2';
|
|
64
64
|
export * from './math/stack.util';
|
|
65
65
|
export * from './string/leven';
|
|
66
66
|
export * from './datetime/localDate';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { END, SKIP } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Iterable2 is a wrapper around Iterable that implements "Iterator Helpers proposal":
|
|
4
|
+
* https://github.com/tc39/proposal-iterator-helpers
|
|
5
|
+
*
|
|
6
|
+
* Iterable2 can be removed after the proposal is widely implemented in Node & browsers.
|
|
7
|
+
*
|
|
8
|
+
* @experimental
|
|
9
|
+
*/
|
|
10
|
+
export class Iterable2 {
|
|
11
|
+
constructor(it) {
|
|
12
|
+
this.it = it;
|
|
13
|
+
}
|
|
14
|
+
static of(it) {
|
|
15
|
+
return new Iterable2(it);
|
|
16
|
+
}
|
|
17
|
+
static empty() {
|
|
18
|
+
return new Iterable2([]);
|
|
19
|
+
}
|
|
20
|
+
[Symbol.iterator]() {
|
|
21
|
+
return this.it[Symbol.iterator]();
|
|
22
|
+
}
|
|
23
|
+
toArray() {
|
|
24
|
+
return [...this.it];
|
|
25
|
+
}
|
|
26
|
+
forEach(cb) {
|
|
27
|
+
let i = 0;
|
|
28
|
+
for (const v of this.it) {
|
|
29
|
+
if (cb(v, i++) === END)
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
find(cb) {
|
|
34
|
+
let i = 0;
|
|
35
|
+
for (const v of this.it) {
|
|
36
|
+
if (cb(v, i++))
|
|
37
|
+
return v;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
filter(cb) {
|
|
41
|
+
const { it } = this;
|
|
42
|
+
return new Iterable2({
|
|
43
|
+
*[Symbol.iterator]() {
|
|
44
|
+
let i = 0;
|
|
45
|
+
for (const v of it) {
|
|
46
|
+
const r = cb(v, i++);
|
|
47
|
+
if (r === END)
|
|
48
|
+
return;
|
|
49
|
+
if (r)
|
|
50
|
+
yield v;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
map(mapper) {
|
|
56
|
+
const { it } = this;
|
|
57
|
+
return new Iterable2({
|
|
58
|
+
*[Symbol.iterator]() {
|
|
59
|
+
let i = 0;
|
|
60
|
+
for (const v of it) {
|
|
61
|
+
const r = mapper(v, i++);
|
|
62
|
+
if (r === END)
|
|
63
|
+
return;
|
|
64
|
+
if (r === SKIP)
|
|
65
|
+
continue;
|
|
66
|
+
yield r;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -11,7 +11,7 @@ let globalStringifyFunction = _safeJsonStringify;
|
|
|
11
11
|
*
|
|
12
12
|
* Defaults to _safeJsonStringify.
|
|
13
13
|
*
|
|
14
|
-
* Node.js project can set it to
|
|
14
|
+
* Node.js project can set it to _inspect, which allows to use `util.inspect`
|
|
15
15
|
* as pretty-printing function.
|
|
16
16
|
*
|
|
17
17
|
* It's recommended that this function is circular-reference-safe.
|
package/package.json
CHANGED
package/src/array/range.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Iterable2 } from '../iter/iterable2'
|
|
2
|
+
|
|
1
3
|
/* eslint-disable no-redeclare, unicorn/no-new-array */
|
|
2
4
|
|
|
3
5
|
/**
|
|
@@ -22,3 +24,23 @@ export function _range(fromIncl: number, toExcl?: number, step = 1): number[] {
|
|
|
22
24
|
(_, i) => i * step + fromIncl,
|
|
23
25
|
)
|
|
24
26
|
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Like _range, but returns an Iterable2.
|
|
30
|
+
*/
|
|
31
|
+
export function _rangeIt(toExcl: number): Iterable2<number>
|
|
32
|
+
export function _rangeIt(fromIncl: number, toExcl: number, step?: number): Iterable2<number>
|
|
33
|
+
export function _rangeIt(fromIncl: number, toExcl?: number, step = 1): Iterable2<number> {
|
|
34
|
+
if (toExcl === undefined) {
|
|
35
|
+
toExcl = fromIncl
|
|
36
|
+
fromIncl = 0
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return Iterable2.of({
|
|
40
|
+
*[Symbol.iterator]() {
|
|
41
|
+
for (let i = fromIncl; i < toExcl!; i += step) {
|
|
42
|
+
yield i
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _assert } from '../error/assert'
|
|
2
|
+
import { Iterable2 } from '../iter/iterable2'
|
|
2
3
|
import type {
|
|
3
4
|
IsoDateString,
|
|
4
5
|
IsoDateTimeString,
|
|
@@ -149,30 +150,48 @@ export class LocalDate {
|
|
|
149
150
|
step = 1,
|
|
150
151
|
stepUnit: LocalDateUnit = 'day',
|
|
151
152
|
): LocalDate[] {
|
|
153
|
+
return this.rangeIt(min, max, incl, step, stepUnit).toArray()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Experimental, returns the range as Iterable2.
|
|
158
|
+
*/
|
|
159
|
+
static rangeIt(
|
|
160
|
+
min: LocalDateInput,
|
|
161
|
+
max: LocalDateInput,
|
|
162
|
+
incl: Inclusiveness = '[)',
|
|
163
|
+
step = 1,
|
|
164
|
+
stepUnit: LocalDateUnit = 'day',
|
|
165
|
+
): Iterable2<LocalDate> {
|
|
152
166
|
if (stepUnit === 'week') {
|
|
153
167
|
step *= 7
|
|
154
168
|
stepUnit = 'day'
|
|
155
169
|
}
|
|
156
170
|
|
|
157
|
-
const
|
|
158
|
-
const $min = LocalDate.of(min)
|
|
171
|
+
const $min = LocalDate.of(min).startOf(stepUnit)
|
|
159
172
|
const $max = LocalDate.of(max).startOf(stepUnit)
|
|
160
173
|
|
|
161
|
-
let
|
|
174
|
+
let value = $min
|
|
162
175
|
// eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
|
|
163
|
-
if (
|
|
176
|
+
if (value.isAfter($min, incl[0] === '[')) {
|
|
164
177
|
// ok
|
|
165
178
|
} else {
|
|
166
|
-
|
|
179
|
+
value.plus(1, stepUnit, true)
|
|
167
180
|
}
|
|
168
181
|
|
|
169
|
-
const
|
|
170
|
-
while (current.isBefore($max, incl2)) {
|
|
171
|
-
dates.push(current)
|
|
172
|
-
current = current.plus(step, stepUnit)
|
|
173
|
-
}
|
|
182
|
+
const rightInclusive = incl[1] === ']'
|
|
174
183
|
|
|
175
|
-
return
|
|
184
|
+
return Iterable2.of({
|
|
185
|
+
*[Symbol.iterator]() {
|
|
186
|
+
while (value.isBefore($max, rightInclusive)) {
|
|
187
|
+
yield value
|
|
188
|
+
|
|
189
|
+
// We don't mutate, because we already returned `current`
|
|
190
|
+
// in the previous iteration
|
|
191
|
+
value = value.plus(step, stepUnit)
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
})
|
|
176
195
|
}
|
|
177
196
|
|
|
178
197
|
get(unit: LocalDateUnitStrict): number {
|
package/src/index.ts
CHANGED
|
@@ -60,7 +60,7 @@ export * from './log/commonLogger'
|
|
|
60
60
|
export * from './string/safeJsonStringify'
|
|
61
61
|
export * from './promise/pQueue'
|
|
62
62
|
export * from './promise/abortable'
|
|
63
|
-
export * from './
|
|
63
|
+
export * from './iter/iterable2'
|
|
64
64
|
export * from './math/stack.util'
|
|
65
65
|
export * from './string/leven'
|
|
66
66
|
export * from './datetime/localDate'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { AbortableMapper, AbortablePredicate, END, Predicate, SKIP } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Iterable2 is a wrapper around Iterable that implements "Iterator Helpers proposal":
|
|
5
|
+
* https://github.com/tc39/proposal-iterator-helpers
|
|
6
|
+
*
|
|
7
|
+
* Iterable2 can be removed after the proposal is widely implemented in Node & browsers.
|
|
8
|
+
*
|
|
9
|
+
* @experimental
|
|
10
|
+
*/
|
|
11
|
+
export class Iterable2<T> implements Iterable<T> {
|
|
12
|
+
private constructor(private it: Iterable<T>) {}
|
|
13
|
+
|
|
14
|
+
static of<T>(it: Iterable<T>): Iterable2<T> {
|
|
15
|
+
return new Iterable2(it)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static empty<T>(): Iterable2<T> {
|
|
19
|
+
return new Iterable2([])
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
[Symbol.iterator](): Iterator<T> {
|
|
23
|
+
return this.it[Symbol.iterator]()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toArray(): T[] {
|
|
27
|
+
return [...this.it]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
forEach(cb: (v: T, i: number) => any | typeof END): void {
|
|
31
|
+
let i = 0
|
|
32
|
+
for (const v of this.it) {
|
|
33
|
+
if (cb(v, i++) === END) return
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
find(cb: Predicate<T>): T | undefined {
|
|
38
|
+
let i = 0
|
|
39
|
+
for (const v of this.it) {
|
|
40
|
+
if (cb(v, i++)) return v
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
filter(cb: AbortablePredicate<T>): Iterable2<T> {
|
|
45
|
+
const { it } = this
|
|
46
|
+
|
|
47
|
+
return new Iterable2<T>({
|
|
48
|
+
*[Symbol.iterator]() {
|
|
49
|
+
let i = 0
|
|
50
|
+
for (const v of it) {
|
|
51
|
+
const r = cb(v, i++)
|
|
52
|
+
if (r === END) return
|
|
53
|
+
if (r) yield v
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
map<OUT>(mapper: AbortableMapper<T, OUT>): Iterable2<OUT> {
|
|
60
|
+
const { it } = this
|
|
61
|
+
|
|
62
|
+
return new Iterable2<OUT>({
|
|
63
|
+
*[Symbol.iterator]() {
|
|
64
|
+
let i = 0
|
|
65
|
+
for (const v of it) {
|
|
66
|
+
const r = mapper(v, i++)
|
|
67
|
+
if (r === END) return
|
|
68
|
+
if (r === SKIP) continue
|
|
69
|
+
yield r
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
}
|
package/src/string/stringify.ts
CHANGED
|
@@ -15,7 +15,7 @@ let globalStringifyFunction: JsonStringifyFunction = _safeJsonStringify
|
|
|
15
15
|
*
|
|
16
16
|
* Defaults to _safeJsonStringify.
|
|
17
17
|
*
|
|
18
|
-
* Node.js project can set it to
|
|
18
|
+
* Node.js project can set it to _inspect, which allows to use `util.inspect`
|
|
19
19
|
* as pretty-printing function.
|
|
20
20
|
*
|
|
21
21
|
* It's recommended that this function is circular-reference-safe.
|