spliterator 1.5.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/LICENSE.md +650 -0
- package/README.md +119 -0
- package/out/index.d.ts +21 -0
- package/out/index.d.ts.map +1 -0
- package/out/index.js +21 -0
- package/out/index.js.map +1 -0
- package/out/lib/AsyncSpliterator.d.ts +127 -0
- package/out/lib/AsyncSpliterator.d.ts.map +1 -0
- package/out/lib/AsyncSpliterator.js +332 -0
- package/out/lib/AsyncSpliterator.js.map +1 -0
- package/out/lib/BufferController.d.ts +62 -0
- package/out/lib/BufferController.d.ts.map +1 -0
- package/out/lib/BufferController.js +93 -0
- package/out/lib/BufferController.js.map +1 -0
- package/out/lib/CSVSpliterator.d.ts +104 -0
- package/out/lib/CSVSpliterator.d.ts.map +1 -0
- package/out/lib/CSVSpliterator.js +83 -0
- package/out/lib/CSVSpliterator.js.map +1 -0
- package/out/lib/CharacterSequence.d.ts +103 -0
- package/out/lib/CharacterSequence.d.ts.map +1 -0
- package/out/lib/CharacterSequence.js +184 -0
- package/out/lib/CharacterSequence.js.map +1 -0
- package/out/lib/CompositeDataView.d.ts +104 -0
- package/out/lib/CompositeDataView.d.ts.map +1 -0
- package/out/lib/CompositeDataView.js +242 -0
- package/out/lib/CompositeDataView.js.map +1 -0
- package/out/lib/DelimitedChunkReader.d.ts +67 -0
- package/out/lib/DelimitedChunkReader.d.ts.map +1 -0
- package/out/lib/DelimitedChunkReader.js +113 -0
- package/out/lib/DelimitedChunkReader.js.map +1 -0
- package/out/lib/DelimiterTransformer.d.ts +27 -0
- package/out/lib/DelimiterTransformer.d.ts.map +1 -0
- package/out/lib/DelimiterTransformer.js +26 -0
- package/out/lib/DelimiterTransformer.js.map +1 -0
- package/out/lib/IndexQueue.d.ts +48 -0
- package/out/lib/IndexQueue.d.ts.map +1 -0
- package/out/lib/IndexQueue.js +80 -0
- package/out/lib/IndexQueue.js.map +1 -0
- package/out/lib/JSONSpliterator.d.ts +19 -0
- package/out/lib/JSONSpliterator.d.ts.map +1 -0
- package/out/lib/JSONSpliterator.js +55 -0
- package/out/lib/JSONSpliterator.js.map +1 -0
- package/out/lib/SlidingWindow.d.ts +93 -0
- package/out/lib/SlidingWindow.d.ts.map +1 -0
- package/out/lib/SlidingWindow.js +176 -0
- package/out/lib/SlidingWindow.js.map +1 -0
- package/out/lib/Spliterator.d.ts +51 -0
- package/out/lib/Spliterator.d.ts.map +1 -0
- package/out/lib/Spliterator.js +238 -0
- package/out/lib/Spliterator.js.map +1 -0
- package/out/lib/TextSpliterator.d.ts +40 -0
- package/out/lib/TextSpliterator.d.ts.map +1 -0
- package/out/lib/TextSpliterator.js +56 -0
- package/out/lib/TextSpliterator.js.map +1 -0
- package/out/lib/casing.d.ts +28 -0
- package/out/lib/casing.d.ts.map +1 -0
- package/out/lib/casing.js +69 -0
- package/out/lib/casing.js.map +1 -0
- package/out/lib/node/fs.d.ts +98 -0
- package/out/lib/node/fs.d.ts.map +1 -0
- package/out/lib/node/fs.js +162 -0
- package/out/lib/node/fs.js.map +1 -0
- package/out/lib/shared.d.ts +167 -0
- package/out/lib/shared.d.ts.map +1 -0
- package/out/lib/shared.js +92 -0
- package/out/lib/shared.js.map +1 -0
- package/out/lib/take.d.ts +26 -0
- package/out/lib/take.d.ts.map +1 -0
- package/out/lib/take.js +71 -0
- package/out/lib/take.js.map +1 -0
- package/out/lib/writer.d.ts +34 -0
- package/out/lib/writer.d.ts.map +1 -0
- package/out/lib/writer.js +41 -0
- package/out/lib/writer.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A class to manage a buffer of bytes, growing and shrinking as needed.
|
|
8
|
+
*/
|
|
9
|
+
export declare class BufferController {
|
|
10
|
+
#private;
|
|
11
|
+
/**
|
|
12
|
+
* The underlying buffer containing the data.
|
|
13
|
+
*
|
|
14
|
+
* This property is mutable for performance reasons. Consumers should treat it as immutable.
|
|
15
|
+
*/
|
|
16
|
+
bytes: Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* The total number of bytes currently written to the buffer.
|
|
19
|
+
*
|
|
20
|
+
* This property is mutable for performance reasons. Consumers should treat it as immutable.
|
|
21
|
+
*/
|
|
22
|
+
bytesWritten: number;
|
|
23
|
+
/**
|
|
24
|
+
* The minimum byte length of the buffer.
|
|
25
|
+
*/
|
|
26
|
+
get byteLengthMinimum(): number;
|
|
27
|
+
constructor(init: {
|
|
28
|
+
initialBufferSize: number;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Grow the buffer to the desired byte length, typically double the current byte length.
|
|
32
|
+
*/
|
|
33
|
+
grow(desiredByteLength?: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* Modify the buffer in place, keeping only the bytes between the start and end indices.
|
|
36
|
+
*
|
|
37
|
+
* This is performed after we're confident that any data preceeding `start` or following `end` is
|
|
38
|
+
* no longer needed.
|
|
39
|
+
*
|
|
40
|
+
* @param start - The starting byte index of which bytes to keep.
|
|
41
|
+
* @param end - The ending byte index of which bytes to keep.
|
|
42
|
+
*/
|
|
43
|
+
compress(start?: number, end?: number): void;
|
|
44
|
+
/**
|
|
45
|
+
* Clear the buffer, zeroing out all bytes.
|
|
46
|
+
*
|
|
47
|
+
* @param begin The starting byte index from which to clear.
|
|
48
|
+
* @param end The ending byte index to clear.
|
|
49
|
+
*/
|
|
50
|
+
clear(begin?: number, end?: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements at
|
|
53
|
+
* begin, inclusive, up to end, exclusive.
|
|
54
|
+
*
|
|
55
|
+
* @param begin — The index of the beginning of the array.
|
|
56
|
+
* @param end — The index of the end of the array
|
|
57
|
+
* @throws If the start index is greater than the end index.
|
|
58
|
+
* @throws If the end index is greater than the current byte length.
|
|
59
|
+
*/
|
|
60
|
+
subarray(begin?: number, end?: number): Uint8Array;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=BufferController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BufferController.d.ts","sourceRoot":"","sources":["../../lib/BufferController.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,qBAAa,gBAAgB;;IAM5B;;;;OAIG;IACH,KAAK,EAAE,UAAU,CAAA;IAEjB;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,IAAW,iBAAiB,IAAI,MAAM,CAErC;gBAEW,IAAI,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE;IAM/C;;OAEG;IACI,IAAI,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI;IAa7C;;;;;;;;OAQG;IACI,QAAQ,CAAC,KAAK,GAAE,MAAU,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAStD;;;;;OAKG;IACI,KAAK,CAAC,KAAK,GAAE,MAAU,EAAE,GAAG,GAAE,MAA0B,GAAG,IAAI;IAKtE;;;;;;;;OAQG;IACI,QAAQ,CAAC,KAAK,GAAE,MAAU,EAAE,GAAG,GAAE,MAA0B,GAAG,UAAU;CAW/E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A class to manage a buffer of bytes, growing and shrinking as needed.
|
|
8
|
+
*/
|
|
9
|
+
export class BufferController {
|
|
10
|
+
/**
|
|
11
|
+
* The initial size of the buffer.
|
|
12
|
+
*/
|
|
13
|
+
#initialBufferSize;
|
|
14
|
+
/**
|
|
15
|
+
* The underlying buffer containing the data.
|
|
16
|
+
*
|
|
17
|
+
* This property is mutable for performance reasons. Consumers should treat it as immutable.
|
|
18
|
+
*/
|
|
19
|
+
bytes;
|
|
20
|
+
/**
|
|
21
|
+
* The total number of bytes currently written to the buffer.
|
|
22
|
+
*
|
|
23
|
+
* This property is mutable for performance reasons. Consumers should treat it as immutable.
|
|
24
|
+
*/
|
|
25
|
+
bytesWritten;
|
|
26
|
+
/**
|
|
27
|
+
* The minimum byte length of the buffer.
|
|
28
|
+
*/
|
|
29
|
+
get byteLengthMinimum() {
|
|
30
|
+
return Math.max(this.bytesWritten, this.#initialBufferSize);
|
|
31
|
+
}
|
|
32
|
+
constructor(init) {
|
|
33
|
+
this.#initialBufferSize = init.initialBufferSize;
|
|
34
|
+
this.bytes = new Uint8Array(this.#initialBufferSize);
|
|
35
|
+
this.bytesWritten = 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Grow the buffer to the desired byte length, typically double the current byte length.
|
|
39
|
+
*/
|
|
40
|
+
grow(desiredByteLength) {
|
|
41
|
+
desiredByteLength ??= this.bytes.length * 2;
|
|
42
|
+
if (desiredByteLength <= this.bytes.length)
|
|
43
|
+
return;
|
|
44
|
+
// console.debug(`Growing buffer from ${this.bytes.length} to ${desiredByteLength} bytes.`)
|
|
45
|
+
const newBytes = new Uint8Array(desiredByteLength);
|
|
46
|
+
newBytes.set(this.bytes);
|
|
47
|
+
this.bytes = newBytes;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Modify the buffer in place, keeping only the bytes between the start and end indices.
|
|
51
|
+
*
|
|
52
|
+
* This is performed after we're confident that any data preceeding `start` or following `end` is
|
|
53
|
+
* no longer needed.
|
|
54
|
+
*
|
|
55
|
+
* @param start - The starting byte index of which bytes to keep.
|
|
56
|
+
* @param end - The ending byte index of which bytes to keep.
|
|
57
|
+
*/
|
|
58
|
+
compress(start = 0, end) {
|
|
59
|
+
end ??= Math.max(this.byteLengthMinimum, this.bytes.length);
|
|
60
|
+
const adjustedBytesWritten = Math.min(this.bytesWritten, end - start);
|
|
61
|
+
this.bytes = this.bytes.subarray(start, end);
|
|
62
|
+
this.bytesWritten = adjustedBytesWritten;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Clear the buffer, zeroing out all bytes.
|
|
66
|
+
*
|
|
67
|
+
* @param begin The starting byte index from which to clear.
|
|
68
|
+
* @param end The ending byte index to clear.
|
|
69
|
+
*/
|
|
70
|
+
clear(begin = 0, end = this.bytesWritten) {
|
|
71
|
+
this.bytes.fill(0, begin, end);
|
|
72
|
+
this.bytesWritten = 0;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements at
|
|
76
|
+
* begin, inclusive, up to end, exclusive.
|
|
77
|
+
*
|
|
78
|
+
* @param begin — The index of the beginning of the array.
|
|
79
|
+
* @param end — The index of the end of the array
|
|
80
|
+
* @throws If the start index is greater than the end index.
|
|
81
|
+
* @throws If the end index is greater than the current byte length.
|
|
82
|
+
*/
|
|
83
|
+
subarray(begin = 0, end = this.bytesWritten) {
|
|
84
|
+
if (begin > end) {
|
|
85
|
+
throw new RangeError(`Start index ${begin} is greater than end index ${end}.`);
|
|
86
|
+
}
|
|
87
|
+
if (end > this.bytesWritten) {
|
|
88
|
+
throw new RangeError(`End index ${end} is greater than the current byte length ${this.bytesWritten}.`);
|
|
89
|
+
}
|
|
90
|
+
return this.bytes.subarray(begin, end);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=BufferController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BufferController.js","sourceRoot":"","sources":["../../lib/BufferController.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAC5B;;OAEG;IACH,kBAAkB,CAAQ;IAE1B;;;;OAIG;IACH,KAAK,CAAY;IAEjB;;;;OAIG;IACH,YAAY,CAAQ;IAEpB;;OAEG;IACH,IAAW,iBAAiB;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC5D,CAAC;IAED,YAAY,IAAmC;QAC9C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAA;QAChD,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QACpD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;IACtB,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,iBAA0B;QACrC,iBAAiB,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QAE3C,IAAI,iBAAiB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QAElD,2FAA2F;QAC3F,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,iBAAiB,CAAC,CAAA;QAElD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAExB,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;IACtB,CAAC;IAED;;;;;;;;OAQG;IACI,QAAQ,CAAC,QAAgB,CAAC,EAAE,GAAY;QAC9C,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAC3D,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,KAAK,CAAC,CAAA;QAErE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAE5C,IAAI,CAAC,YAAY,GAAG,oBAAoB,CAAA;IACzC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,QAAgB,CAAC,EAAE,MAAc,IAAI,CAAC,YAAY;QAC9D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAC9B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;IACtB,CAAC;IAED;;;;;;;;OAQG;IACI,QAAQ,CAAC,QAAgB,CAAC,EAAE,MAAc,IAAI,CAAC,YAAY;QACjE,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,UAAU,CAAC,eAAe,KAAK,8BAA8B,GAAG,GAAG,CAAC,CAAA;QAC/E,CAAC;QAED,IAAI,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC7B,MAAM,IAAI,UAAU,CAAC,aAAa,GAAG,4CAA4C,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACvG,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACvC,CAAC;CACD"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
import { CharacterSequenceInput } from "./CharacterSequence.js";
|
|
7
|
+
import { AsyncDataResource } from "./shared.js";
|
|
8
|
+
import { AsyncSpliteratorInit, SpliteratorInit } from "./Spliterator.js";
|
|
9
|
+
/**
|
|
10
|
+
* An output mode for the CSV generator.
|
|
11
|
+
*/
|
|
12
|
+
export type CSVOutputMode = "array" | "object" | "entries";
|
|
13
|
+
export type CSVEmitter<T = unknown> = (columns: Iterable<string>, headerColumns?: Iterable<string>) => T;
|
|
14
|
+
export type CSVSpliteratorEmittedRecord = {
|
|
15
|
+
[key: string]: string | number | undefined;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A row emitted by the CSV generator, as a 3-tuple:
|
|
19
|
+
*
|
|
20
|
+
* - The key of the column.
|
|
21
|
+
* - The value of the column.
|
|
22
|
+
* - The index of the row.
|
|
23
|
+
*/
|
|
24
|
+
export type RowTuple = [key: string, value: string | number, idx: number];
|
|
25
|
+
export declare const CSVSpliteratorEmitters: {
|
|
26
|
+
readonly array: null;
|
|
27
|
+
readonly entries: (columns: Iterable<string>, headerColumns?: Iterable<string>) => RowTuple[];
|
|
28
|
+
readonly object: (columns: Iterable<string>, headerColumns?: Iterable<string>) => CSVSpliteratorEmittedRecord;
|
|
29
|
+
};
|
|
30
|
+
export interface CSVSpliteratorOptions {
|
|
31
|
+
/**
|
|
32
|
+
* The mode determines the shape of the data emitted by the generator.
|
|
33
|
+
*
|
|
34
|
+
* - `object` will emit each row as an object with the header names as keys.
|
|
35
|
+
* - `array` will emit each row as an array.
|
|
36
|
+
* - `entries` will emit each row as an array of key-value pairs.
|
|
37
|
+
*/
|
|
38
|
+
mode?: CSVOutputMode;
|
|
39
|
+
/**
|
|
40
|
+
* The delimiter to use for columns in a row.
|
|
41
|
+
*
|
|
42
|
+
* @default Delimiter.Comma
|
|
43
|
+
*/
|
|
44
|
+
columnDelimiter?: CharacterSequenceInput;
|
|
45
|
+
/**
|
|
46
|
+
* Whether to normalize the keys of the header row.
|
|
47
|
+
*
|
|
48
|
+
* This will convert all header names to lowercase and replace spaces with underscores, making
|
|
49
|
+
* them more suitable for use as object keys.
|
|
50
|
+
*/
|
|
51
|
+
normalizeKeys?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether to treat the first row as a header.
|
|
54
|
+
*
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
header?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* How many rows to skip before emitting data.
|
|
60
|
+
*
|
|
61
|
+
* This is useful for skipping headers or other metadata.
|
|
62
|
+
*
|
|
63
|
+
* Defaults to 1 if `header` is true, otherwise 0.
|
|
64
|
+
*/
|
|
65
|
+
skip?: number;
|
|
66
|
+
}
|
|
67
|
+
export declare abstract class CSVSpliterator {
|
|
68
|
+
constructor();
|
|
69
|
+
static from<T extends CSVSpliteratorEmittedRecord = CSVSpliteratorEmittedRecord>(source: CharacterSequenceInput, options: CSVSpliteratorOptions & SpliteratorInit & {
|
|
70
|
+
mode: "object";
|
|
71
|
+
}): Generator<T>;
|
|
72
|
+
/**
|
|
73
|
+
* @yields Each row as a 3-tuple [key, value, idx].
|
|
74
|
+
*/
|
|
75
|
+
static from<T extends RowTuple[] = RowTuple[]>(source: CharacterSequenceInput, options: CSVSpliteratorOptions & SpliteratorInit & {
|
|
76
|
+
mode: "entries";
|
|
77
|
+
}): Generator<T>;
|
|
78
|
+
/**
|
|
79
|
+
* Given a byte array or string, yield each row as an array of columns.
|
|
80
|
+
*
|
|
81
|
+
* @yields Each row as an array of columns.
|
|
82
|
+
*/
|
|
83
|
+
static from<T extends string[] = string[]>(source: CharacterSequenceInput, options: CSVSpliteratorOptions & SpliteratorInit & {
|
|
84
|
+
mode?: "array";
|
|
85
|
+
}): Generator<T>;
|
|
86
|
+
static fromAsync<T extends CSVSpliteratorEmittedRecord = CSVSpliteratorEmittedRecord>(source: AsyncDataResource, options?: CSVSpliteratorOptions & AsyncSpliteratorInit & {
|
|
87
|
+
mode: "object";
|
|
88
|
+
}): AsyncGenerator<T>;
|
|
89
|
+
/**
|
|
90
|
+
* @yields Each row as a 3-tuple [key, value, idx].
|
|
91
|
+
*/
|
|
92
|
+
static fromAsync<T extends RowTuple[] = RowTuple[]>(source: AsyncDataResource, options?: CSVSpliteratorOptions & AsyncSpliteratorInit & {
|
|
93
|
+
mode: "entries";
|
|
94
|
+
}): AsyncGenerator<T>;
|
|
95
|
+
/**
|
|
96
|
+
* Given a byte array or string, yield each row as an array of columns.
|
|
97
|
+
*
|
|
98
|
+
* @yields Each row as an array of columns.
|
|
99
|
+
*/
|
|
100
|
+
static fromAsync<T extends string[] = string[]>(source: AsyncDataResource, options?: CSVSpliteratorOptions & AsyncSpliteratorInit & {
|
|
101
|
+
mode?: "array";
|
|
102
|
+
}): AsyncGenerator<T>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=CSVSpliterator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CSVSpliterator.d.ts","sourceRoot":"","sources":["../../lib/CSVSpliterator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
import { normalizeColumnNames } from "./casing.js";
|
|
7
|
+
import { CharacterSequence, Delimiters, takeDelimited } from "./CharacterSequence.js";
|
|
8
|
+
import { zipSync } from "./shared.js";
|
|
9
|
+
import { Spliterator } from "./Spliterator.js";
|
|
10
|
+
export const CSVSpliteratorEmitters = {
|
|
11
|
+
array: null,
|
|
12
|
+
entries(columns, headerColumns = []) {
|
|
13
|
+
return Array.from(zipSync(headerColumns, columns), ([key, value], idx) => {
|
|
14
|
+
return [key ?? `column_${idx}`, value ?? "", idx];
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
object(columns, headerColumns = []) {
|
|
18
|
+
const record = Object.fromEntries(Array.from(zipSync(headerColumns, columns)));
|
|
19
|
+
return record;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export class CSVSpliterator {
|
|
23
|
+
constructor() {
|
|
24
|
+
throw new TypeError("Static class cannot be instantiated. Did you mean `CSVSpliterator.from`?");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Given a byte array or string, yield each row as an array of columns.
|
|
28
|
+
*
|
|
29
|
+
* @yields Each row as an array of columns.
|
|
30
|
+
*/
|
|
31
|
+
static *from(source, options = {}) {
|
|
32
|
+
const {
|
|
33
|
+
// ---
|
|
34
|
+
header = true, skip = header ? 1 : 0, normalizeKeys, mode = "array", columnDelimiter: columnDelimiterInput = Delimiters.Comma, ...rowOptions } = options;
|
|
35
|
+
let headerColumns = [];
|
|
36
|
+
const emitter = CSVSpliteratorEmitters[mode];
|
|
37
|
+
let rowCursor = 0;
|
|
38
|
+
const decoder = new TextDecoder();
|
|
39
|
+
const columnDelimiter = new CharacterSequence(columnDelimiterInput);
|
|
40
|
+
const spliterator = Spliterator.from(source, rowOptions);
|
|
41
|
+
for (const row of spliterator) {
|
|
42
|
+
let columns = Array.from(takeDelimited(row, columnDelimiter), (column) => decoder.decode(column));
|
|
43
|
+
if (header && rowCursor === 0) {
|
|
44
|
+
headerColumns = normalizeKeys ? normalizeColumnNames(columns) : columns;
|
|
45
|
+
columns = headerColumns;
|
|
46
|
+
}
|
|
47
|
+
if (skip && rowCursor < skip) {
|
|
48
|
+
rowCursor++;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
yield emitter ? emitter(columns, headerColumns) : columns;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Given a byte array or string, yield each row as an array of columns.
|
|
56
|
+
*
|
|
57
|
+
* @yields Each row as an array of columns.
|
|
58
|
+
*/
|
|
59
|
+
static async *fromAsync(source, options = {}) {
|
|
60
|
+
const {
|
|
61
|
+
// ---
|
|
62
|
+
header = true, skip = header ? 1 : 0, mode = "array", normalizeKeys = mode !== "array", columnDelimiter: columnDelimiterInput, ...rowOptions } = options;
|
|
63
|
+
let headerColumns = [];
|
|
64
|
+
const emitter = CSVSpliteratorEmitters[mode];
|
|
65
|
+
let rowCursor = 0;
|
|
66
|
+
const columnDelimiter = new CharacterSequence(columnDelimiterInput ?? Delimiters.Comma);
|
|
67
|
+
const decoder = new TextDecoder();
|
|
68
|
+
const splitter = await Spliterator.fromAsync(source, rowOptions);
|
|
69
|
+
for await (const row of splitter) {
|
|
70
|
+
let columns = Array.from(takeDelimited(row, columnDelimiter), (column) => decoder.decode(column));
|
|
71
|
+
if (header && rowCursor === 0) {
|
|
72
|
+
headerColumns = normalizeKeys ? normalizeColumnNames(columns) : columns;
|
|
73
|
+
columns = headerColumns;
|
|
74
|
+
}
|
|
75
|
+
if (skip && rowCursor < skip) {
|
|
76
|
+
rowCursor++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
yield emitter ? emitter(columns, headerColumns) : columns;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=CSVSpliterator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CSVSpliterator.js","sourceRoot":"","sources":["../../lib/CSVSpliterator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
import { TypedArray } from "./shared.js";
|
|
7
|
+
/**
|
|
8
|
+
* Type-predicate to determine if a value is an array-like object.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isArrayLike<T>(input: unknown): input is ArrayLike<T>;
|
|
11
|
+
/**
|
|
12
|
+
* A possible input for a delimiter:
|
|
13
|
+
*
|
|
14
|
+
* - A single character code.
|
|
15
|
+
* - A string of characters.
|
|
16
|
+
* - An array of character codes.
|
|
17
|
+
* - A buffer.
|
|
18
|
+
* - An iterable of character codes.
|
|
19
|
+
*/
|
|
20
|
+
export type CharacterSequenceInput = number | string | Uint8Array | Buffer | Iterable<number>;
|
|
21
|
+
/**
|
|
22
|
+
* Common delimiter values.
|
|
23
|
+
*/
|
|
24
|
+
export declare const Delimiters: {
|
|
25
|
+
/**
|
|
26
|
+
* Null (␀)
|
|
27
|
+
*/
|
|
28
|
+
readonly Null: 0;
|
|
29
|
+
/**
|
|
30
|
+
* Newline (␊)
|
|
31
|
+
*/
|
|
32
|
+
readonly LineFeed: 10;
|
|
33
|
+
/**
|
|
34
|
+
* Carriage return (␍)
|
|
35
|
+
*/
|
|
36
|
+
readonly CarriageReturn: 13;
|
|
37
|
+
/**
|
|
38
|
+
* Comma (–)
|
|
39
|
+
*/
|
|
40
|
+
readonly Comma: 44;
|
|
41
|
+
/**
|
|
42
|
+
* Tab (␉)
|
|
43
|
+
*/
|
|
44
|
+
readonly Tab: 9;
|
|
45
|
+
/**
|
|
46
|
+
* Space (␠)
|
|
47
|
+
*/
|
|
48
|
+
readonly Space: 32;
|
|
49
|
+
/**
|
|
50
|
+
* One (1)
|
|
51
|
+
*/
|
|
52
|
+
readonly One: 49;
|
|
53
|
+
/**
|
|
54
|
+
* Zero (0)
|
|
55
|
+
*/
|
|
56
|
+
readonly Zero: 48;
|
|
57
|
+
/**
|
|
58
|
+
* Double quote (")
|
|
59
|
+
*/
|
|
60
|
+
readonly DoubleQuote: 34;
|
|
61
|
+
/**
|
|
62
|
+
* Record separator (␞)
|
|
63
|
+
*/
|
|
64
|
+
readonly RecordSeparator: 30;
|
|
65
|
+
};
|
|
66
|
+
export declare const VisibleDelimiterMap: Map<number, string>;
|
|
67
|
+
export declare function debugAsVisibleCharacters(delimiter: Uint8Array): string;
|
|
68
|
+
export declare function normalizeCharacterInput(input: CharacterSequenceInput): Uint8Array;
|
|
69
|
+
/**
|
|
70
|
+
* An encoded sequence of characters, typically bytes representing a delimiter.
|
|
71
|
+
*
|
|
72
|
+
* Unlike a string, this class is optimized for searching and slicing.
|
|
73
|
+
*
|
|
74
|
+
* This also allows for multi-byte delimiters, such as CRLF or unicode characters.
|
|
75
|
+
*/
|
|
76
|
+
export declare class CharacterSequence extends Uint8Array {
|
|
77
|
+
#private;
|
|
78
|
+
/**
|
|
79
|
+
* Perform a Boyer-Moore-Horspool search for the pattern in the text.
|
|
80
|
+
*
|
|
81
|
+
* @param text The encoded text to search.
|
|
82
|
+
* @param start The byte index to start searching from.
|
|
83
|
+
*
|
|
84
|
+
* @returns The byte index of the pattern in the text, or -1 if not found.
|
|
85
|
+
*/
|
|
86
|
+
search(text: Uint8Array, start?: number): number;
|
|
87
|
+
/**
|
|
88
|
+
* Create a new character sequence from a delimiter.
|
|
89
|
+
*/
|
|
90
|
+
constructor(input?: CharacterSequenceInput);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Given a delimited line, split it into fields using the specified separator.
|
|
94
|
+
*
|
|
95
|
+
* Unlike `String.prototype.split`, this function correctly handles fields that contain the
|
|
96
|
+
* separator character within double quotes.
|
|
97
|
+
*
|
|
98
|
+
* @param source The line to split.
|
|
99
|
+
* @param needle The character that separates fields.
|
|
100
|
+
* @yields Each field in the line.
|
|
101
|
+
*/
|
|
102
|
+
export declare function takeDelimited<T extends TypedArray | string>(source: T, needle?: Uint8Array): Generator<Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | BigUint64Array | BigInt64Array | Float32Array | Float64Array, void, unknown>;
|
|
103
|
+
//# sourceMappingURL=CharacterSequence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CharacterSequence.d.ts","sourceRoot":"","sources":["../../lib/CharacterSequence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,CAEpE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;AAE7F;;GAEG;AACH,eAAO,MAAM,UAAU;IACtB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;CAEuC,CAAA;AAE3C,eAAO,MAAM,mBAAmB,qBAS9B,CAAA;AAEF,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAQtE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,UAAU,CAwBjF;AAED;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;;IAMhD;;;;;;;OAOG;IACI,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,GAAE,MAAU,GAAG,MAAM;IAwB1D;;OAEG;gBACS,KAAK,GAAE,sBAA4C;CAY/D;AAID;;;;;;;;;GASG;AACH,wBAAiB,aAAa,CAAC,CAAC,SAAS,UAAU,GAAG,MAAM,EAC3D,MAAM,EAAE,CAAC,EACT,MAAM,GAAE,UAAuC,6LAkC/C"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Type-predicate to determine if a value is an array-like object.
|
|
8
|
+
*/
|
|
9
|
+
export function isArrayLike(input) {
|
|
10
|
+
return Boolean(input && typeof input === "object" && "length" in input);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Common delimiter values.
|
|
14
|
+
*/
|
|
15
|
+
export const Delimiters = {
|
|
16
|
+
/**
|
|
17
|
+
* Null (␀)
|
|
18
|
+
*/
|
|
19
|
+
Null: 0,
|
|
20
|
+
/**
|
|
21
|
+
* Newline (␊)
|
|
22
|
+
*/
|
|
23
|
+
LineFeed: 10,
|
|
24
|
+
/**
|
|
25
|
+
* Carriage return (␍)
|
|
26
|
+
*/
|
|
27
|
+
CarriageReturn: 13,
|
|
28
|
+
/**
|
|
29
|
+
* Comma (–)
|
|
30
|
+
*/
|
|
31
|
+
Comma: 44,
|
|
32
|
+
/**
|
|
33
|
+
* Tab (␉)
|
|
34
|
+
*/
|
|
35
|
+
Tab: 9,
|
|
36
|
+
/**
|
|
37
|
+
* Space (␠)
|
|
38
|
+
*/
|
|
39
|
+
Space: 32,
|
|
40
|
+
/**
|
|
41
|
+
* One (1)
|
|
42
|
+
*/
|
|
43
|
+
One: 49,
|
|
44
|
+
/**
|
|
45
|
+
* Zero (0)
|
|
46
|
+
*/
|
|
47
|
+
Zero: 48,
|
|
48
|
+
/**
|
|
49
|
+
* Double quote (")
|
|
50
|
+
*/
|
|
51
|
+
DoubleQuote: 34,
|
|
52
|
+
/**
|
|
53
|
+
* Record separator (␞)
|
|
54
|
+
*/
|
|
55
|
+
RecordSeparator: 30,
|
|
56
|
+
};
|
|
57
|
+
export const VisibleDelimiterMap = new Map([
|
|
58
|
+
[Delimiters.LineFeed, ""],
|
|
59
|
+
[Delimiters.CarriageReturn, "␍"],
|
|
60
|
+
[Delimiters.Comma, "-"],
|
|
61
|
+
[Delimiters.Tab, "␉"],
|
|
62
|
+
[Delimiters.Space, "␠"],
|
|
63
|
+
[Delimiters.DoubleQuote, '"'],
|
|
64
|
+
[Delimiters.RecordSeparator, "␞"],
|
|
65
|
+
[Delimiters.Null, "␀"],
|
|
66
|
+
]);
|
|
67
|
+
export function debugAsVisibleCharacters(delimiter) {
|
|
68
|
+
return Array.from(delimiter)
|
|
69
|
+
.map((charCode) => {
|
|
70
|
+
const visible = VisibleDelimiterMap.get(charCode);
|
|
71
|
+
return visible ?? String.fromCharCode(charCode);
|
|
72
|
+
})
|
|
73
|
+
.join("");
|
|
74
|
+
}
|
|
75
|
+
export function normalizeCharacterInput(input) {
|
|
76
|
+
switch (typeof input) {
|
|
77
|
+
case "number":
|
|
78
|
+
if (!Number.isInteger(input)) {
|
|
79
|
+
throw new TypeError(`Numeric delimiters must be integers. Received: ${input}`);
|
|
80
|
+
}
|
|
81
|
+
return Uint8Array.from([input]);
|
|
82
|
+
case "string":
|
|
83
|
+
return new TextEncoder().encode(input);
|
|
84
|
+
case "object":
|
|
85
|
+
if (isArrayLike(input)) {
|
|
86
|
+
return input;
|
|
87
|
+
}
|
|
88
|
+
if (Symbol.iterator in input) {
|
|
89
|
+
return Uint8Array.from(input);
|
|
90
|
+
}
|
|
91
|
+
throw new TypeError(`Invalid delimiter type. Received an object, but it is not an array or buffer.`);
|
|
92
|
+
default:
|
|
93
|
+
throw new TypeError(`Invalid delimiter type. Received: ${input}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* An encoded sequence of characters, typically bytes representing a delimiter.
|
|
98
|
+
*
|
|
99
|
+
* Unlike a string, this class is optimized for searching and slicing.
|
|
100
|
+
*
|
|
101
|
+
* This also allows for multi-byte delimiters, such as CRLF or unicode characters.
|
|
102
|
+
*/
|
|
103
|
+
export class CharacterSequence extends Uint8Array {
|
|
104
|
+
/**
|
|
105
|
+
* A jump table for the Boyer-Moore-Horspool search algorithm.
|
|
106
|
+
*/
|
|
107
|
+
#skipIndex;
|
|
108
|
+
/**
|
|
109
|
+
* Perform a Boyer-Moore-Horspool search for the pattern in the text.
|
|
110
|
+
*
|
|
111
|
+
* @param text The encoded text to search.
|
|
112
|
+
* @param start The byte index to start searching from.
|
|
113
|
+
*
|
|
114
|
+
* @returns The byte index of the pattern in the text, or -1 if not found.
|
|
115
|
+
*/
|
|
116
|
+
search(text, start = 0) {
|
|
117
|
+
const n = text.length;
|
|
118
|
+
const m = this.length;
|
|
119
|
+
let i = start;
|
|
120
|
+
while (i <= n - m) {
|
|
121
|
+
let j = m - 1;
|
|
122
|
+
// Match pattern from right to left
|
|
123
|
+
while (j >= 0 && this[j] === text[i + j]) {
|
|
124
|
+
j--;
|
|
125
|
+
}
|
|
126
|
+
// Pattern found
|
|
127
|
+
if (j < 0)
|
|
128
|
+
return i;
|
|
129
|
+
// Jump based on the last character in the window
|
|
130
|
+
i += this.#skipIndex[text[i + m - 1]];
|
|
131
|
+
}
|
|
132
|
+
return -1;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Create a new character sequence from a delimiter.
|
|
136
|
+
*/
|
|
137
|
+
constructor(input = Delimiters.LineFeed) {
|
|
138
|
+
const bytes = normalizeCharacterInput(input);
|
|
139
|
+
super(bytes);
|
|
140
|
+
this.#skipIndex = new Array(256).fill(this.length);
|
|
141
|
+
// Build the jump table - simpler than full Boyer-Moore
|
|
142
|
+
for (let i = 0; i < this.length - 1; i++) {
|
|
143
|
+
this.#skipIndex[this[i]] = this.length - 1 - i;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const encoder = new TextEncoder();
|
|
148
|
+
/**
|
|
149
|
+
* Given a delimited line, split it into fields using the specified separator.
|
|
150
|
+
*
|
|
151
|
+
* Unlike `String.prototype.split`, this function correctly handles fields that contain the
|
|
152
|
+
* separator character within double quotes.
|
|
153
|
+
*
|
|
154
|
+
* @param source The line to split.
|
|
155
|
+
* @param needle The character that separates fields.
|
|
156
|
+
* @yields Each field in the line.
|
|
157
|
+
*/
|
|
158
|
+
export function* takeDelimited(source, needle = new CharacterSequence(",")) {
|
|
159
|
+
const haystack = (typeof source === "string" ? encoder.encode(source) : source);
|
|
160
|
+
const contentDelimiters = [];
|
|
161
|
+
let doubleQuoteCount = 0;
|
|
162
|
+
// First, we traverse the line to find the field delimiters...
|
|
163
|
+
for (let byteIndex = 0; byteIndex < haystack.byteLength; byteIndex++) {
|
|
164
|
+
const byte = haystack[byteIndex];
|
|
165
|
+
if (byte === Delimiters.DoubleQuote) {
|
|
166
|
+
doubleQuoteCount++;
|
|
167
|
+
}
|
|
168
|
+
// TODO: handle escaped double quotes
|
|
169
|
+
// TODO: handle delimiters with a length greater than 1
|
|
170
|
+
if (byte === needle[0] && doubleQuoteCount % 2 === 0) {
|
|
171
|
+
contentDelimiters.push(byteIndex);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Now, we slice the line into fields.
|
|
175
|
+
let sliceStart = 0;
|
|
176
|
+
for (let delimiterIndex = 0; delimiterIndex < contentDelimiters.length; delimiterIndex++) {
|
|
177
|
+
const sliceEnd = contentDelimiters[delimiterIndex];
|
|
178
|
+
yield haystack.subarray(sliceStart, sliceEnd);
|
|
179
|
+
sliceStart = sliceEnd + 1;
|
|
180
|
+
}
|
|
181
|
+
// Finally, our last slice is the remainder of the line.
|
|
182
|
+
yield haystack.subarray(sliceStart);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=CharacterSequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CharacterSequence.js","sourceRoot":"","sources":["../../lib/CharacterSequence.ts"],"names":[],"mappings":"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"}
|