shelving 1.33.0 → 1.37.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/db/Pagination.js +2 -2
- package/package.json +7 -7
- package/query/Filters.d.ts +1 -0
- package/query/Filters.js +5 -0
- package/query/Query.d.ts +4 -2
- package/query/Query.js +8 -2
- package/query/Rules.d.ts +1 -1
- package/query/Rules.js +1 -1
- package/query/Sorts.d.ts +1 -0
- package/query/Sorts.js +6 -1
- package/query/types.d.ts +7 -2
- package/stream/ArrayState.d.ts +2 -2
- package/stream/ArrayState.js +4 -4
- package/util/array.d.ts +12 -0
- package/util/array.js +9 -0
- package/util/assert.d.ts +14 -8
- package/util/assert.js +20 -10
- package/util/iterate.d.ts +0 -5
- package/util/iterate.js +3 -10
- package/util/number.d.ts +10 -1
- package/util/number.js +26 -1
package/db/Pagination.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getLastItem,
|
|
1
|
+
import { getLastItem, assertNumber, yieldMerged, toMap, LOADING, assertMaximum } from "../util/index.js";
|
|
2
2
|
import { State } from "../stream/index.js";
|
|
3
3
|
import { ConditionError } from "../index.js";
|
|
4
4
|
/**
|
|
@@ -40,7 +40,7 @@ export class Pagination extends State {
|
|
|
40
40
|
};
|
|
41
41
|
this.ref = ref;
|
|
42
42
|
assertNumber(ref.limit); // Collection must have a numeric limit to paginate (otherwise you'd be retrieving the entire set of documents).
|
|
43
|
-
|
|
43
|
+
assertMaximum(ref.sorts.size, 1); // Collection must have at least one sort order to paginate.
|
|
44
44
|
this.limit = ref.limit;
|
|
45
45
|
}
|
|
46
46
|
/**
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"state-management",
|
|
12
12
|
"query-builder"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.37.0",
|
|
15
15
|
"repository": "https://github.com/dhoulb/shelving",
|
|
16
16
|
"author": "Dave Houlbrooke <dave@shax.com>",
|
|
17
17
|
"license": "0BSD",
|
|
@@ -63,20 +63,20 @@
|
|
|
63
63
|
"@types/jest": "^27.0.3",
|
|
64
64
|
"@types/react": "^17.0.37",
|
|
65
65
|
"@types/react-dom": "^17.0.11",
|
|
66
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
67
|
-
"@typescript-eslint/parser": "^5.
|
|
68
|
-
"eslint": "^8.
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
|
67
|
+
"@typescript-eslint/parser": "^5.7.0",
|
|
68
|
+
"eslint": "^8.5.0",
|
|
69
69
|
"eslint-config-prettier": "^8.3.0",
|
|
70
70
|
"eslint-plugin-import": "^2.25.3",
|
|
71
71
|
"eslint-plugin-prettier": "^4.0.0",
|
|
72
72
|
"firebase": "^9.6.1",
|
|
73
|
-
"jest": "^27.4.
|
|
73
|
+
"jest": "^27.4.5",
|
|
74
74
|
"jest-ts-webcompat-resolver": "^1.0.0",
|
|
75
75
|
"prettier": "^2.5.1",
|
|
76
76
|
"react": "^17.0.2",
|
|
77
77
|
"react-dom": "^17.0.2",
|
|
78
|
-
"ts-jest": "^27.1.
|
|
79
|
-
"typescript": "^4.5.
|
|
78
|
+
"ts-jest": "^27.1.2",
|
|
79
|
+
"typescript": "^4.5.4"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
82
|
"@google-cloud/firestore": ">=4.0.0",
|
package/query/Filters.d.ts
CHANGED
|
@@ -13,5 +13,6 @@ export declare class Filters<T extends Data> extends Rules<T, Filter<T>> impleme
|
|
|
13
13
|
gt<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
14
14
|
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
15
15
|
match(entry: Entry<T>): boolean;
|
|
16
|
+
get unfiltered(): this;
|
|
16
17
|
transform(iterable: Results<T>): Results<T>;
|
|
17
18
|
}
|
package/query/Filters.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ArrayContainsFilter, EqualFilter, GreaterThanEqualFilter, GreaterThanFi
|
|
|
3
3
|
import { Rules } from "./Rules.js";
|
|
4
4
|
/** A set of filters. */
|
|
5
5
|
export class Filters extends Rules {
|
|
6
|
+
// Implement `Filterable`
|
|
6
7
|
is(key, value) {
|
|
7
8
|
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [...this._rules, new EqualFilter(key, value)] };
|
|
8
9
|
}
|
|
@@ -33,6 +34,10 @@ export class Filters extends Rules {
|
|
|
33
34
|
return false;
|
|
34
35
|
return true;
|
|
35
36
|
}
|
|
37
|
+
get unfiltered() {
|
|
38
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [] };
|
|
39
|
+
}
|
|
40
|
+
// Implement `Rule`
|
|
36
41
|
transform(iterable) {
|
|
37
42
|
return this._rules.length ? yieldFiltered(iterable, this) : iterable;
|
|
38
43
|
}
|
package/query/Query.d.ts
CHANGED
|
@@ -17,9 +17,11 @@ export declare class Query<T extends Data> extends Rule<T> implements Queryable<
|
|
|
17
17
|
lte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
18
18
|
gt<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
19
19
|
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
20
|
+
get unfiltered(): this;
|
|
20
21
|
match(entry: Entry<T>): boolean;
|
|
21
|
-
asc(key
|
|
22
|
-
desc(key
|
|
22
|
+
asc(key: QueryKey<T>): this;
|
|
23
|
+
desc(key: QueryKey<T>): this;
|
|
24
|
+
get unsorted(): this;
|
|
23
25
|
rank(left: Entry<T>, right: Entry<T>): number;
|
|
24
26
|
/** Return a new instance of this class with a limit defined. */
|
|
25
27
|
max(limit: number | null): this;
|
package/query/Query.js
CHANGED
|
@@ -40,16 +40,22 @@ export class Query extends Rule {
|
|
|
40
40
|
gte(key, value) {
|
|
41
41
|
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.gte(key, value) };
|
|
42
42
|
}
|
|
43
|
+
get unfiltered() {
|
|
44
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, filters: this.filters.unfiltered };
|
|
45
|
+
}
|
|
43
46
|
match(entry) {
|
|
44
47
|
return this.filters.match(entry);
|
|
45
48
|
}
|
|
46
49
|
// Implement `Sortable`
|
|
47
|
-
asc(key
|
|
50
|
+
asc(key) {
|
|
48
51
|
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.asc(key) };
|
|
49
52
|
}
|
|
50
|
-
desc(key
|
|
53
|
+
desc(key) {
|
|
51
54
|
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.desc(key) };
|
|
52
55
|
}
|
|
56
|
+
get unsorted() {
|
|
57
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, sorts: this.sorts.unsorted };
|
|
58
|
+
}
|
|
53
59
|
rank(left, right) {
|
|
54
60
|
return this.sorts.rank(left, right);
|
|
55
61
|
}
|
package/query/Rules.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare abstract class Rules<T extends Data, R extends Rule<T>> extends R
|
|
|
8
8
|
/** Get the last rule. */
|
|
9
9
|
get last(): R | undefined;
|
|
10
10
|
/** Get the number of rules. */
|
|
11
|
-
get
|
|
11
|
+
get size(): number;
|
|
12
12
|
constructor(...rules: R[]);
|
|
13
13
|
toString(): string;
|
|
14
14
|
/** Iterate over the rules. */
|
package/query/Rules.js
CHANGED
package/query/Sorts.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { Rules } from "./Rules.js";
|
|
|
6
6
|
export declare class Sorts<T extends Data> extends Rules<T, Sort<T>> implements Sortable<T> {
|
|
7
7
|
asc(key: QueryKey<T>): this;
|
|
8
8
|
desc(key: QueryKey<T>): this;
|
|
9
|
+
get unsorted(): this;
|
|
9
10
|
rank(left: Entry<T>, right: Entry<T>): number;
|
|
10
11
|
transform(iterable: Results<T>): Results<T>;
|
|
11
12
|
}
|
package/query/Sorts.js
CHANGED
|
@@ -3,20 +3,25 @@ import { AscendingSort, DescendingSort } from "./Sort.js";
|
|
|
3
3
|
import { Rules } from "./Rules.js";
|
|
4
4
|
/** A set of sorts. */
|
|
5
5
|
export class Sorts extends Rules {
|
|
6
|
+
// Implement `Sortable`
|
|
6
7
|
asc(key) {
|
|
7
8
|
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [...this._rules, new AscendingSort(key)] };
|
|
8
9
|
}
|
|
9
10
|
desc(key) {
|
|
10
11
|
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [...this._rules, new DescendingSort(key)] };
|
|
11
12
|
}
|
|
13
|
+
get unsorted() {
|
|
14
|
+
return { __proto__: Object.getPrototypeOf(this), ...this, _rules: [] };
|
|
15
|
+
}
|
|
12
16
|
rank(left, right) {
|
|
13
|
-
for (const rule of this) {
|
|
17
|
+
for (const rule of this._rules) {
|
|
14
18
|
const l = rule.rank(left, right);
|
|
15
19
|
if (l !== 0)
|
|
16
20
|
return l;
|
|
17
21
|
}
|
|
18
22
|
return 0;
|
|
19
23
|
}
|
|
24
|
+
// Implement `Rule`
|
|
20
25
|
transform(iterable) {
|
|
21
26
|
return this._rules.length ? sortItems(iterable, this) : iterable;
|
|
22
27
|
}
|
package/query/types.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export interface Filterable<T extends Data> extends Matchable<Entry<T>, void> {
|
|
|
16
16
|
lte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
17
17
|
gt<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
18
18
|
gte<K extends QueryKey<T>>(key: K, value: K extends "id" ? string : T[K]): this;
|
|
19
|
+
/** Return a new instance of this class with no sorts specified. */
|
|
20
|
+
unfiltered: this;
|
|
21
|
+
/** Match an entry against the filters specified for this object. */
|
|
19
22
|
match(entry: Entry<T>): boolean;
|
|
20
23
|
}
|
|
21
24
|
/**
|
|
@@ -24,9 +27,11 @@ export interface Filterable<T extends Data> extends Matchable<Entry<T>, void> {
|
|
|
24
27
|
*/
|
|
25
28
|
export interface Sortable<T extends Data> extends Rankable<Entry<T>> {
|
|
26
29
|
/** Return a new instance of this class with an ascending order sort defined. */
|
|
27
|
-
asc(key
|
|
30
|
+
asc(key: QueryKey<T>): this;
|
|
28
31
|
/** Return a new instance of this class with a descending order sort defined. */
|
|
29
|
-
desc(key
|
|
32
|
+
desc(key: QueryKey<T>): this;
|
|
33
|
+
/** Return a new instance of this class with no sorts specified. */
|
|
34
|
+
unsorted: this;
|
|
30
35
|
}
|
|
31
36
|
/** Possible operator references. */
|
|
32
37
|
export declare type SortDirection = "ASC" | "DESC";
|
package/stream/ArrayState.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { State } from "./State.js";
|
|
|
3
3
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
4
|
export declare class ArrayState<T> extends State<ImmutableArray<T>> implements Iterable<T> {
|
|
5
5
|
_value: never[];
|
|
6
|
-
/**
|
|
7
|
-
get
|
|
6
|
+
/** Get the length of the current value of this state. */
|
|
7
|
+
get length(): number;
|
|
8
8
|
/** Add an item to this array. */
|
|
9
9
|
add(item: T): void;
|
|
10
10
|
/** Remove an item from this array. */
|
package/stream/ArrayState.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { swapItem, toggleItem, withItem, withoutItem
|
|
1
|
+
import { swapItem, toggleItem, withItem, withoutItem } from "../util/index.js";
|
|
2
2
|
import { State } from "./State.js";
|
|
3
3
|
/** State that stores an array and has additional methods to help with that. */
|
|
4
4
|
export class ArrayState extends State {
|
|
@@ -7,9 +7,9 @@ export class ArrayState extends State {
|
|
|
7
7
|
// Set default value to be empty array.
|
|
8
8
|
this._value = [];
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
get
|
|
12
|
-
return
|
|
10
|
+
/** Get the length of the current value of this state. */
|
|
11
|
+
get length() {
|
|
12
|
+
return this.value.length;
|
|
13
13
|
}
|
|
14
14
|
/** Add an item to this array. */
|
|
15
15
|
add(item) {
|
package/util/array.d.ts
CHANGED
|
@@ -163,3 +163,15 @@ export declare function removeItems<T>(arr: MutableArray<T>, items: Iterable<T>)
|
|
|
163
163
|
export declare function uniqueArray<T>(input: Iterable<T>): ImmutableArray<T>;
|
|
164
164
|
/** Apply a limit to an array. */
|
|
165
165
|
export declare function limitArray<T>(arr: ImmutableArray<T>, limit: number): ImmutableArray<T>;
|
|
166
|
+
/** Does an array have the specified minimum length. */
|
|
167
|
+
export declare function isMinimumLength<T>(arr: ImmutableArray<T>, min?: 1): arr is [T, ...T[]];
|
|
168
|
+
export declare function isMinimumLength<T>(arr: ImmutableArray<T>, min: 2): arr is [T, T, ...T[]];
|
|
169
|
+
export declare function isMinimumLength<T>(arr: ImmutableArray<T>, min: 3): arr is [T, T, T, ...T[]];
|
|
170
|
+
export declare function isMinimumLength<T>(arr: ImmutableArray<T>, min: 4): arr is [T, T, T, T, ...T[]];
|
|
171
|
+
export declare function isMinimumLength<T>(arr: ImmutableArray<T>, min: number): arr is [T, T, T, T, T, ...T[]];
|
|
172
|
+
/** Get an array if it has the specified minimum length. */
|
|
173
|
+
export declare function getMinimumLength<T>(arr: ImmutableArray<T>, min?: 1): [T, ...T[]];
|
|
174
|
+
export declare function getMinimumLength<T>(arr: ImmutableArray<T>, min: 2): [T, T, ...T[]];
|
|
175
|
+
export declare function getMinimumLength<T>(arr: ImmutableArray<T>, min: 3): [T, T, T, ...T[]];
|
|
176
|
+
export declare function getMinimumLength<T>(arr: ImmutableArray<T>, min: 4): [T, T, T, T, ...T[]];
|
|
177
|
+
export declare function getMinimumLength<T>(arr: ImmutableArray<T>, min: number): [T, T, T, T, T, ...T[]];
|
package/util/array.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AssertionError } from "../error/index.js";
|
|
1
2
|
/** Is an unknown value an array? */
|
|
2
3
|
export const isArray = (v) => v instanceof Array;
|
|
3
4
|
/** Is an unknown value an item in a specified array? */
|
|
@@ -244,3 +245,11 @@ export function uniqueArray(input) {
|
|
|
244
245
|
export function limitArray(arr, limit) {
|
|
245
246
|
return limit > arr.length ? arr : arr.slice(0, limit);
|
|
246
247
|
}
|
|
248
|
+
export function isMinimumLength(arr, min = 1) {
|
|
249
|
+
return arr.length >= min;
|
|
250
|
+
}
|
|
251
|
+
export function getMinimumLength(arr, min = 1) {
|
|
252
|
+
if (arr.length >= min)
|
|
253
|
+
return arr;
|
|
254
|
+
throw new AssertionError(`Must have minimum length ${min}`, arr);
|
|
255
|
+
}
|
package/util/assert.d.ts
CHANGED
|
@@ -24,15 +24,21 @@ export declare function assertProp<K extends string | number | symbol, T extends
|
|
|
24
24
|
[L in K]: unknown;
|
|
25
25
|
}>(value: T | unknown, key: K): asserts value is T;
|
|
26
26
|
/** Assert that a value is an array. */
|
|
27
|
-
export declare function assertArray<T
|
|
27
|
+
export declare function assertArray<T>(value: ImmutableArray<T> | unknown): asserts value is ImmutableArray<T>;
|
|
28
28
|
/** Assert that a value has a specific length (or length is in a specific range). */
|
|
29
|
-
export declare function
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
export declare function assertMinimumLength<T>(value: ImmutableArray<T> | unknown, min?: 1): asserts value is [T, ...T[]];
|
|
30
|
+
export declare function assertMinimumLength<T>(value: ImmutableArray<T> | unknown, min: 2): asserts value is [T, T, ...T[]];
|
|
31
|
+
export declare function assertMinimumLength<T>(value: ImmutableArray<T> | unknown, min: 3): asserts value is [T, T, T, ...T[]];
|
|
32
|
+
export declare function assertMinimumLength<T>(value: ImmutableArray<T> | unknown, min: 4): asserts value is [T, T, T, T, ...T[]];
|
|
33
|
+
export declare function assertMinimumLength<T>(value: ImmutableArray<T> | unknown, min: number): asserts value is [T, T, T, T, T, ...T[]];
|
|
34
|
+
/** Assert that a value has a specific length (or length is in a specific range). */
|
|
35
|
+
export declare function assertLength<T>(value: ImmutableArray<T> | unknown, min: number, max?: number): asserts value is ImmutableArray<T>;
|
|
36
|
+
/** Assert that a value is a number greater than. */
|
|
37
|
+
export declare function assertBetween(value: number | unknown, min: number, max: number): asserts value is number;
|
|
32
38
|
/** Assert that a value is a number greater than. */
|
|
33
|
-
export declare function
|
|
39
|
+
export declare function assertMaximum(value: number | unknown, max: number): asserts value is number;
|
|
34
40
|
/** Assert that a value is a number less than. */
|
|
35
|
-
export declare function
|
|
41
|
+
export declare function assertMinimum(value: number | unknown, min: number): asserts value is number;
|
|
36
42
|
/** Assert that a value is an instance of something. */
|
|
37
43
|
export declare function assertInstance<T>(value: T | unknown, type: Class<T>): asserts value is T;
|
|
38
44
|
/** Assert that a value is a function. */
|
|
@@ -42,8 +48,8 @@ export declare function assertValue<T>(value: T | typeof NOVALUE): asserts value
|
|
|
42
48
|
/** Assert that a value is not the `NOVALUE` constant. */
|
|
43
49
|
export declare function assertDefined<T>(value: T | undefined): asserts value is T;
|
|
44
50
|
/** Expect a synchronous value. */
|
|
45
|
-
export declare function
|
|
51
|
+
export declare function assertSynchronous<T>(value: Promise<T> | T): asserts value is T;
|
|
46
52
|
/** Expect an asynchronous value. */
|
|
47
|
-
export declare function
|
|
53
|
+
export declare function assertAsynchronous<T>(value: PromiseLike<T> | T): asserts value is PromiseLike<T>;
|
|
48
54
|
/** Expect a promise. */
|
|
49
55
|
export declare function assertPromise<T>(value: Promise<T> | T): asserts value is Promise<T>;
|
package/util/assert.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AssertionError } from "../error/index.js";
|
|
2
2
|
import { debug } from "./debug.js";
|
|
3
3
|
import { isObject } from "./object.js";
|
|
4
|
+
import { isArray } from "./array.js";
|
|
4
5
|
import { NOVALUE } from "./constants.js";
|
|
5
6
|
import { isAsync } from "./async.js";
|
|
6
7
|
/** Assert a boolean condition is true. */
|
|
@@ -53,20 +54,29 @@ export function assertArray(value) {
|
|
|
53
54
|
if (!(value instanceof Array))
|
|
54
55
|
throw new AssertionError(`Must be array`, value);
|
|
55
56
|
}
|
|
57
|
+
export function assertMinimumLength(value, min = 1) {
|
|
58
|
+
if (!isArray(value) || value.length < min)
|
|
59
|
+
throw new AssertionError(`Must be array with minimum length ${min}`, value);
|
|
60
|
+
}
|
|
56
61
|
/** Assert that a value has a specific length (or length is in a specific range). */
|
|
57
62
|
export function assertLength(value, min, max = min) {
|
|
58
|
-
if (!
|
|
59
|
-
throw new AssertionError(`Must
|
|
63
|
+
if (!isArray(value) || value.length < min || value.length > max)
|
|
64
|
+
throw new AssertionError(`Must be array with length ${min}-${max}`, value);
|
|
65
|
+
}
|
|
66
|
+
/** Assert that a value is a number greater than. */
|
|
67
|
+
export function assertBetween(value, min, max) {
|
|
68
|
+
if (typeof value !== "number" || value < min || value > max)
|
|
69
|
+
throw new AssertionError(`Must be number between ${min}-${max}`, value);
|
|
60
70
|
}
|
|
61
71
|
/** Assert that a value is a number greater than. */
|
|
62
|
-
export function
|
|
63
|
-
if (typeof value !== "number" || value
|
|
64
|
-
throw new AssertionError(`Must be
|
|
72
|
+
export function assertMaximum(value, max) {
|
|
73
|
+
if (typeof value !== "number" || value > max)
|
|
74
|
+
throw new AssertionError(`Must be number with maximum ${max}`, value);
|
|
65
75
|
}
|
|
66
76
|
/** Assert that a value is a number less than. */
|
|
67
|
-
export function
|
|
68
|
-
if (typeof value !== "number" || value
|
|
69
|
-
throw new AssertionError(`Must be
|
|
77
|
+
export function assertMinimum(value, min) {
|
|
78
|
+
if (typeof value !== "number" || value < min)
|
|
79
|
+
throw new AssertionError(`Must be number with minimum ${min}`, value);
|
|
70
80
|
}
|
|
71
81
|
/** Assert that a value is an instance of something. */
|
|
72
82
|
export function assertInstance(value, type) {
|
|
@@ -89,12 +99,12 @@ export function assertDefined(value) {
|
|
|
89
99
|
throw new AssertionError("Must be defined", value);
|
|
90
100
|
}
|
|
91
101
|
/** Expect a synchronous value. */
|
|
92
|
-
export function
|
|
102
|
+
export function assertSynchronous(value) {
|
|
93
103
|
if (isAsync(value))
|
|
94
104
|
throw new AssertionError("Must be synchronous", value);
|
|
95
105
|
}
|
|
96
106
|
/** Expect an asynchronous value. */
|
|
97
|
-
export function
|
|
107
|
+
export function assertAsynchronous(value) {
|
|
98
108
|
if (!isAsync(value))
|
|
99
109
|
throw new AssertionError("Must be asynchronous", value);
|
|
100
110
|
}
|
package/util/iterate.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ImmutableMap } from "./map.js";
|
|
2
1
|
import type { ImmutableArray } from "./array.js";
|
|
3
2
|
import type { Entry } from "./entry.js";
|
|
4
3
|
import { DONE } from "./constants.js";
|
|
@@ -23,8 +22,6 @@ export declare const isIterable: <T extends Iterable<unknown>>(value: unknown) =
|
|
|
23
22
|
* - Note: Array and Map instances etc will return true because they implement `Symbol.iterator`
|
|
24
23
|
*/
|
|
25
24
|
export declare const isAsyncIterable: <T extends AsyncIterable<unknown>>(value: unknown) => value is T;
|
|
26
|
-
/** Get the known size or length of an object (e.g. `Array`, `Map`, and `Set` have known size), or return `undefined` if the size cannot be established. */
|
|
27
|
-
export declare const getSize: (obj: Iterable<unknown> | ImmutableMap | ImmutableArray) => number | undefined;
|
|
28
25
|
/**
|
|
29
26
|
* Count the number items of an iterable.
|
|
30
27
|
* - Checks `items.size` or `items.length` first, or consumes the iterable and counts its iterations.
|
|
@@ -35,8 +32,6 @@ export declare function countItems(items: Iterable<unknown>): number;
|
|
|
35
32
|
* - Note: this consumes the iterable so you won't be able to use it again.
|
|
36
33
|
*/
|
|
37
34
|
export declare function countIterations(items: Iterable<unknown>): number;
|
|
38
|
-
/** Sum an iterable set of numbers and return the total. */
|
|
39
|
-
export declare function sumItems(input: Iterable<number>): number;
|
|
40
35
|
/**
|
|
41
36
|
* Yield a range of numbers from `start` to `end`
|
|
42
37
|
* - Yields in descending order if `end` is lower than `start`
|
package/util/iterate.js
CHANGED
|
@@ -13,14 +13,14 @@ export const isIterable = (value) => typeof value === "object" && !!value && Sym
|
|
|
13
13
|
*/
|
|
14
14
|
export const isAsyncIterable = (value) => typeof value === "object" && !!value && Symbol.asyncIterator in value;
|
|
15
15
|
/** Get the known size or length of an object (e.g. `Array`, `Map`, and `Set` have known size), or return `undefined` if the size cannot be established. */
|
|
16
|
-
|
|
16
|
+
const getKnownSize = (obj) => ("size" in obj && typeof obj.size === "number" ? obj.size : "length" in obj && typeof obj.length === "number" ? obj.length : undefined);
|
|
17
17
|
/**
|
|
18
18
|
* Count the number items of an iterable.
|
|
19
19
|
* - Checks `items.size` or `items.length` first, or consumes the iterable and counts its iterations.
|
|
20
20
|
*/
|
|
21
21
|
export function countItems(items) {
|
|
22
22
|
var _a;
|
|
23
|
-
return (_a =
|
|
23
|
+
return (_a = getKnownSize(items)) !== null && _a !== void 0 ? _a : countIterations(items);
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Count the number of iterations an iterable does.
|
|
@@ -32,13 +32,6 @@ export function countIterations(items) {
|
|
|
32
32
|
count++; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
33
33
|
return count;
|
|
34
34
|
}
|
|
35
|
-
/** Sum an iterable set of numbers and return the total. */
|
|
36
|
-
export function sumItems(input) {
|
|
37
|
-
let sum = 0;
|
|
38
|
-
for (const num of input)
|
|
39
|
-
sum += num;
|
|
40
|
-
return sum;
|
|
41
|
-
}
|
|
42
35
|
/**
|
|
43
36
|
* Yield a range of numbers from `start` to `end`
|
|
44
37
|
* - Yields in descending order if `end` is lower than `start`
|
|
@@ -57,7 +50,7 @@ export function* yieldRange(start, end) {
|
|
|
57
50
|
*/
|
|
58
51
|
export function limitItems(items, limit) {
|
|
59
52
|
var _a;
|
|
60
|
-
const size = (_a =
|
|
53
|
+
const size = (_a = getKnownSize(items)) !== null && _a !== void 0 ? _a : Infinity;
|
|
61
54
|
return size <= limit ? items : yieldUntilLimit(items, limit);
|
|
62
55
|
}
|
|
63
56
|
/** Yield items from a source iterable until we hit a maximum iteration count. */
|
package/util/number.d.ts
CHANGED
|
@@ -11,6 +11,11 @@ export declare const IS_NUMBER: (v: unknown) => v is number;
|
|
|
11
11
|
* - Everything else returns `null`
|
|
12
12
|
*/
|
|
13
13
|
export declare function toNumber(value: unknown): number | null;
|
|
14
|
+
/**
|
|
15
|
+
* Assertively convert an unknown value to a finite number.
|
|
16
|
+
* @throws `AssertionError` if the value cannot be converted.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getNumber(value: unknown): number;
|
|
14
19
|
/**
|
|
15
20
|
* Round numbers to a given step.
|
|
16
21
|
*
|
|
@@ -44,10 +49,14 @@ export declare const formatNumber: (num: number, precision?: number) => string;
|
|
|
44
49
|
*/
|
|
45
50
|
export declare const isBetween: (num: number, start: number, end: number) => boolean;
|
|
46
51
|
/**
|
|
47
|
-
*
|
|
52
|
+
* Apply a min/max to a number to return a number that's definitely in the specified range.
|
|
48
53
|
*
|
|
49
54
|
* @param num The number to apply the min/max to, e.g. `17`
|
|
50
55
|
* @param start The start of the range, e.g. `10`
|
|
51
56
|
* @param end The end of the range, e.g. `20`
|
|
52
57
|
*/
|
|
53
58
|
export declare const getBetween: (num: number, start: number, end: number) => number;
|
|
59
|
+
/** Sum an iterable set of numbers and return the total. */
|
|
60
|
+
export declare function sumNumbers(nums: Iterable<number>): number;
|
|
61
|
+
/** Find the number that's closest to a target in an iterable set of numbers. */
|
|
62
|
+
export declare function getClosestNumber<T extends number>(nums: Iterable<T>, target: number): T | undefined;
|
package/util/number.js
CHANGED
|
@@ -21,6 +21,16 @@ export function toNumber(value) {
|
|
|
21
21
|
return null;
|
|
22
22
|
}
|
|
23
23
|
const NUMERIC = /[^0-9-.]/g;
|
|
24
|
+
/**
|
|
25
|
+
* Assertively convert an unknown value to a finite number.
|
|
26
|
+
* @throws `AssertionError` if the value cannot be converted.
|
|
27
|
+
*/
|
|
28
|
+
export function getNumber(value) {
|
|
29
|
+
const num = toNumber(value);
|
|
30
|
+
if (num === null)
|
|
31
|
+
throw new AssertionError("Must be number", value);
|
|
32
|
+
return num;
|
|
33
|
+
}
|
|
24
34
|
/**
|
|
25
35
|
* Round numbers to a given step.
|
|
26
36
|
*
|
|
@@ -58,10 +68,25 @@ export const formatNumber = (num, precision = 10) => new Intl.NumberFormat(undef
|
|
|
58
68
|
*/
|
|
59
69
|
export const isBetween = (num, start, end) => num >= start && num <= end;
|
|
60
70
|
/**
|
|
61
|
-
*
|
|
71
|
+
* Apply a min/max to a number to return a number that's definitely in the specified range.
|
|
62
72
|
*
|
|
63
73
|
* @param num The number to apply the min/max to, e.g. `17`
|
|
64
74
|
* @param start The start of the range, e.g. `10`
|
|
65
75
|
* @param end The end of the range, e.g. `20`
|
|
66
76
|
*/
|
|
67
77
|
export const getBetween = (num, start, end) => Math.max(start, Math.min(end, num));
|
|
78
|
+
/** Sum an iterable set of numbers and return the total. */
|
|
79
|
+
export function sumNumbers(nums) {
|
|
80
|
+
let sum = 0;
|
|
81
|
+
for (const num of nums)
|
|
82
|
+
sum += num;
|
|
83
|
+
return sum;
|
|
84
|
+
}
|
|
85
|
+
/** Find the number that's closest to a target in an iterable set of numbers. */
|
|
86
|
+
export function getClosestNumber(nums, target) {
|
|
87
|
+
let closest = undefined;
|
|
88
|
+
for (const item of nums)
|
|
89
|
+
if (closest === undefined || Math.abs(item - target) < Math.abs(closest - target))
|
|
90
|
+
closest = item;
|
|
91
|
+
return closest;
|
|
92
|
+
}
|