@naturalcycles/js-lib 15.94.1 → 15.96.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/array.util.d.ts +9 -3
- package/dist/array/array.util.js +11 -3
- package/dist/buffer/buffer.util.d.ts +17 -0
- package/dist/buffer/buffer.util.js +29 -0
- package/dist/buffer/index.d.ts +1 -0
- package/dist/buffer/index.js +1 -0
- package/dist/types.d.ts +11 -0
- package/package.json +3 -1
- package/src/array/array.util.ts +24 -6
- package/src/buffer/buffer.util.ts +31 -0
- package/src/buffer/index.ts +1 -0
- package/src/types.ts +12 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AbortablePredicate, FalsyValue, Mapper, MutateOptions, Predicate, StringMap } from '../types.js';
|
|
1
|
+
import type { AbortablePredicate, FalsyValue, Mapper, MutateOptions, NonEmptyArray, Predicate, StringMap } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
|
|
4
4
|
* final chunk will be the remaining elements.
|
|
@@ -11,7 +11,7 @@ import type { AbortablePredicate, FalsyValue, Mapper, MutateOptions, Predicate,
|
|
|
11
11
|
*
|
|
12
12
|
* Based on: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_chunk
|
|
13
13
|
*/
|
|
14
|
-
export declare function _chunk<T>(array: readonly T[], size?: number): T[]
|
|
14
|
+
export declare function _chunk<T>(array: readonly T[], size?: number): NonEmptyArray<T>[];
|
|
15
15
|
/**
|
|
16
16
|
* Removes duplicates from given array.
|
|
17
17
|
*/
|
|
@@ -89,7 +89,7 @@ export declare function _mapBy<ITEM, KEY>(items: readonly ITEM[], mapper: Mapper
|
|
|
89
89
|
*
|
|
90
90
|
* Returning `undefined` from the Mapper will EXCLUDE the item.
|
|
91
91
|
*/
|
|
92
|
-
export declare function _groupBy<T>(items: readonly T[], mapper: Mapper<T, any>): StringMap<T
|
|
92
|
+
export declare function _groupBy<T>(items: readonly T[], mapper: Mapper<T, any>): StringMap<NonEmptyArray<T>>;
|
|
93
93
|
/**
|
|
94
94
|
* Similar to `Array.find`, but the `predicate` may return `END` to stop the iteration early.
|
|
95
95
|
*
|
|
@@ -217,6 +217,12 @@ export declare function _first<T>(array: readonly T[]): T;
|
|
|
217
217
|
* Returns first item of the array (or undefined if array is empty).
|
|
218
218
|
*/
|
|
219
219
|
export declare function _firstOrUndefined<T>(array: readonly T[]): T | undefined;
|
|
220
|
+
/**
|
|
221
|
+
* Type guard that narrows an array to NonEmptyArray (array with at least one element).
|
|
222
|
+
* Readonly arrays are narrowed to `Readonly<NonEmptyArray<T>>`.
|
|
223
|
+
*/
|
|
224
|
+
export declare function _isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T>;
|
|
225
|
+
export declare function _isNonEmptyArray<T>(array: readonly T[]): array is Readonly<NonEmptyArray<T>>;
|
|
220
226
|
/**
|
|
221
227
|
* Returns the first item of a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
222
228
|
* Throws if the iterable is empty.
|
package/dist/array/array.util.js
CHANGED
|
@@ -144,9 +144,14 @@ export function _groupBy(items, mapper) {
|
|
|
144
144
|
const map = {};
|
|
145
145
|
for (const item of items) {
|
|
146
146
|
const key = mapper(item);
|
|
147
|
-
if (key
|
|
148
|
-
;
|
|
149
|
-
|
|
147
|
+
if (key === undefined)
|
|
148
|
+
continue;
|
|
149
|
+
const group = map[key];
|
|
150
|
+
if (group) {
|
|
151
|
+
group.push(item);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
map[key] = [item];
|
|
150
155
|
}
|
|
151
156
|
}
|
|
152
157
|
return map;
|
|
@@ -403,6 +408,9 @@ export function _first(array) {
|
|
|
403
408
|
export function _firstOrUndefined(array) {
|
|
404
409
|
return array[0];
|
|
405
410
|
}
|
|
411
|
+
export function _isNonEmptyArray(array) {
|
|
412
|
+
return array.length > 0;
|
|
413
|
+
}
|
|
406
414
|
/**
|
|
407
415
|
* Returns the first item of a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
408
416
|
* Throws if the iterable is empty.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an ArrayBuffer that contains exactly the bytes of the given view (e.g Uint8Array or Buffer).
|
|
3
|
+
*
|
|
4
|
+
* Safe alternative to `view.buffer`, which returns the whole underlying ArrayBuffer.
|
|
5
|
+
* It can be larger than the view, and the view may start at a non-zero offset:
|
|
6
|
+
* e.g Node.js allocates small Buffers from a shared pool (`Buffer.from(string)`,
|
|
7
|
+
* `fs.readFileSync` of small files), or the view was created with `subarray()`.
|
|
8
|
+
*
|
|
9
|
+
* Zero-copy when the view covers the whole ArrayBuffer, otherwise copies exactly its bytes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function _toArrayBuffer<T extends ArrayBufferLike>(view: ArrayBufferView<T>): T;
|
|
12
|
+
/**
|
|
13
|
+
* Same as _chunk, but for Uint8Array (or Buffer).
|
|
14
|
+
* Chunks are zero-copy views (subarray) into the input, and preserve its type
|
|
15
|
+
* (e.g Buffer in - Buffer[] out).
|
|
16
|
+
*/
|
|
17
|
+
export declare function _chunkBuffer<T extends Uint8Array>(buf: T, size: number): T[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an ArrayBuffer that contains exactly the bytes of the given view (e.g Uint8Array or Buffer).
|
|
3
|
+
*
|
|
4
|
+
* Safe alternative to `view.buffer`, which returns the whole underlying ArrayBuffer.
|
|
5
|
+
* It can be larger than the view, and the view may start at a non-zero offset:
|
|
6
|
+
* e.g Node.js allocates small Buffers from a shared pool (`Buffer.from(string)`,
|
|
7
|
+
* `fs.readFileSync` of small files), or the view was created with `subarray()`.
|
|
8
|
+
*
|
|
9
|
+
* Zero-copy when the view covers the whole ArrayBuffer, otherwise copies exactly its bytes.
|
|
10
|
+
*/
|
|
11
|
+
export function _toArrayBuffer(view) {
|
|
12
|
+
const { buffer, byteOffset, byteLength } = view;
|
|
13
|
+
if (byteOffset === 0 && byteLength === buffer.byteLength)
|
|
14
|
+
return buffer;
|
|
15
|
+
return buffer.slice(byteOffset, byteOffset + byteLength);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Same as _chunk, but for Uint8Array (or Buffer).
|
|
19
|
+
* Chunks are zero-copy views (subarray) into the input, and preserve its type
|
|
20
|
+
* (e.g Buffer in - Buffer[] out).
|
|
21
|
+
*/
|
|
22
|
+
export function _chunkBuffer(buf, size) {
|
|
23
|
+
const out = [];
|
|
24
|
+
for (let i = 0; i < buf.length; i += size) {
|
|
25
|
+
// subarray preserves the subclass at runtime (Buffer#subarray returns a Buffer)
|
|
26
|
+
out.push(buf.subarray(i, i + size));
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './buffer.util.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './buffer.util.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -181,6 +181,17 @@ export interface BatchResult<RES = any, ERR = Error> {
|
|
|
181
181
|
* type Foo = ValuesOf<typeof arr> // 'a' | 'b'
|
|
182
182
|
*/
|
|
183
183
|
export type ValuesOf<T extends readonly any[]> = T[number];
|
|
184
|
+
/**
|
|
185
|
+
* Array with at least one element.
|
|
186
|
+
* Index 0 is typed as `T` (not `T | undefined`) under `noUncheckedIndexedAccess`.
|
|
187
|
+
*
|
|
188
|
+
* Use `_isNonEmptyArray` to narrow a regular array to it.
|
|
189
|
+
*
|
|
190
|
+
* Caveats:
|
|
191
|
+
* - Mutating methods (pop, shift, splice, `length = 0`) can empty it without the type noticing.
|
|
192
|
+
* - Non-emptiness is lost after map, filter, slice, concat (they return `T[]`). Spread preserves it.
|
|
193
|
+
*/
|
|
194
|
+
export type NonEmptyArray<T> = [T, ...T[]];
|
|
184
195
|
/**
|
|
185
196
|
* Based on: https://stackoverflow.com/a/49286056/4919972
|
|
186
197
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/js-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.96.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"tslib": "^2"
|
|
7
7
|
},
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
"./array/*.js": "./dist/array/*.js",
|
|
29
29
|
"./browser": "./dist/browser/index.js",
|
|
30
30
|
"./browser/*.js": "./dist/browser/*.js",
|
|
31
|
+
"./buffer": "./dist/buffer/index.js",
|
|
32
|
+
"./buffer/*.js": "./dist/buffer/*.js",
|
|
31
33
|
"./datetime": "./dist/datetime/index.js",
|
|
32
34
|
"./datetime/*.js": "./dist/datetime/*.js",
|
|
33
35
|
"./decorators": "./dist/decorators/index.js",
|
package/src/array/array.util.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
FalsyValue,
|
|
5
5
|
Mapper,
|
|
6
6
|
MutateOptions,
|
|
7
|
+
NonEmptyArray,
|
|
7
8
|
Predicate,
|
|
8
9
|
StringMap,
|
|
9
10
|
} from '../types.js'
|
|
@@ -21,12 +22,12 @@ import { END } from '../types.js'
|
|
|
21
22
|
*
|
|
22
23
|
* Based on: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_chunk
|
|
23
24
|
*/
|
|
24
|
-
export function _chunk<T>(array: readonly T[], size = 1): T[]
|
|
25
|
+
export function _chunk<T>(array: readonly T[], size = 1): NonEmptyArray<T>[] {
|
|
25
26
|
const a: T[][] = []
|
|
26
27
|
for (let i = 0; i < array.length; i += size) {
|
|
27
28
|
a.push(array.slice(i, i + size))
|
|
28
29
|
}
|
|
29
|
-
return a
|
|
30
|
+
return a as NonEmptyArray<T>[]
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
/**
|
|
@@ -158,13 +159,20 @@ export function _mapBy<ITEM, KEY>(
|
|
|
158
159
|
*
|
|
159
160
|
* Returning `undefined` from the Mapper will EXCLUDE the item.
|
|
160
161
|
*/
|
|
161
|
-
export function _groupBy<T>(
|
|
162
|
-
|
|
162
|
+
export function _groupBy<T>(
|
|
163
|
+
items: readonly T[],
|
|
164
|
+
mapper: Mapper<T, any>,
|
|
165
|
+
): StringMap<NonEmptyArray<T>> {
|
|
166
|
+
const map: StringMap<NonEmptyArray<T>> = {}
|
|
163
167
|
|
|
164
168
|
for (const item of items) {
|
|
165
169
|
const key = mapper(item)
|
|
166
|
-
if (key
|
|
167
|
-
|
|
170
|
+
if (key === undefined) continue
|
|
171
|
+
const group = map[key]
|
|
172
|
+
if (group) {
|
|
173
|
+
group.push(item)
|
|
174
|
+
} else {
|
|
175
|
+
map[key] = [item]
|
|
168
176
|
}
|
|
169
177
|
}
|
|
170
178
|
return map
|
|
@@ -468,6 +476,16 @@ export function _firstOrUndefined<T>(array: readonly T[]): T | undefined {
|
|
|
468
476
|
return array[0]
|
|
469
477
|
}
|
|
470
478
|
|
|
479
|
+
/**
|
|
480
|
+
* Type guard that narrows an array to NonEmptyArray (array with at least one element).
|
|
481
|
+
* Readonly arrays are narrowed to `Readonly<NonEmptyArray<T>>`.
|
|
482
|
+
*/
|
|
483
|
+
export function _isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T>
|
|
484
|
+
export function _isNonEmptyArray<T>(array: readonly T[]): array is Readonly<NonEmptyArray<T>>
|
|
485
|
+
export function _isNonEmptyArray(array: readonly unknown[]): boolean {
|
|
486
|
+
return array.length > 0
|
|
487
|
+
}
|
|
488
|
+
|
|
471
489
|
/**
|
|
472
490
|
* Returns the first item of a non-empty iterable (Set, Map.values(), generator, etc.).
|
|
473
491
|
* Throws if the iterable is empty.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an ArrayBuffer that contains exactly the bytes of the given view (e.g Uint8Array or Buffer).
|
|
3
|
+
*
|
|
4
|
+
* Safe alternative to `view.buffer`, which returns the whole underlying ArrayBuffer.
|
|
5
|
+
* It can be larger than the view, and the view may start at a non-zero offset:
|
|
6
|
+
* e.g Node.js allocates small Buffers from a shared pool (`Buffer.from(string)`,
|
|
7
|
+
* `fs.readFileSync` of small files), or the view was created with `subarray()`.
|
|
8
|
+
*
|
|
9
|
+
* Zero-copy when the view covers the whole ArrayBuffer, otherwise copies exactly its bytes.
|
|
10
|
+
*/
|
|
11
|
+
export function _toArrayBuffer<T extends ArrayBufferLike>(view: ArrayBufferView<T>): T {
|
|
12
|
+
const { buffer, byteOffset, byteLength } = view
|
|
13
|
+
if (byteOffset === 0 && byteLength === buffer.byteLength) return buffer
|
|
14
|
+
return buffer.slice(byteOffset, byteOffset + byteLength) as T
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Same as _chunk, but for Uint8Array (or Buffer).
|
|
19
|
+
* Chunks are zero-copy views (subarray) into the input, and preserve its type
|
|
20
|
+
* (e.g Buffer in - Buffer[] out).
|
|
21
|
+
*/
|
|
22
|
+
export function _chunkBuffer<T extends Uint8Array>(buf: T, size: number): T[] {
|
|
23
|
+
const out: T[] = []
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < buf.length; i += size) {
|
|
26
|
+
// subarray preserves the subclass at runtime (Buffer#subarray returns a Buffer)
|
|
27
|
+
out.push(buf.subarray(i, i + size) as T)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return out
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './buffer.util.js'
|
package/src/types.ts
CHANGED
|
@@ -225,6 +225,18 @@ export interface BatchResult<RES = any, ERR = Error> {
|
|
|
225
225
|
*/
|
|
226
226
|
export type ValuesOf<T extends readonly any[]> = T[number]
|
|
227
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Array with at least one element.
|
|
230
|
+
* Index 0 is typed as `T` (not `T | undefined`) under `noUncheckedIndexedAccess`.
|
|
231
|
+
*
|
|
232
|
+
* Use `_isNonEmptyArray` to narrow a regular array to it.
|
|
233
|
+
*
|
|
234
|
+
* Caveats:
|
|
235
|
+
* - Mutating methods (pop, shift, splice, `length = 0`) can empty it without the type noticing.
|
|
236
|
+
* - Non-emptiness is lost after map, filter, slice, concat (they return `T[]`). Spread preserves it.
|
|
237
|
+
*/
|
|
238
|
+
export type NonEmptyArray<T> = [T, ...T[]]
|
|
239
|
+
|
|
228
240
|
/**
|
|
229
241
|
* Based on: https://stackoverflow.com/a/49286056/4919972
|
|
230
242
|
*
|