spliterator 6.0.1 → 6.2.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.
Files changed (195) hide show
  1. package/README.md +70 -0
  2. package/out/index.d.ts +26 -23
  3. package/out/index.d.ts.map +1 -1
  4. package/out/index.js +26 -23
  5. package/out/index.js.map +1 -1
  6. package/out/lib/AsyncSpliterator.d.ts.map +1 -1
  7. package/out/lib/AsyncSpliterator.js +28 -0
  8. package/out/lib/AsyncSpliterator.js.map +1 -1
  9. package/out/lib/CSVSpliterator.d.ts +8 -18
  10. package/out/lib/CSVSpliterator.d.ts.map +1 -1
  11. package/out/lib/CSVSpliterator.js +4 -47
  12. package/out/lib/CSVSpliterator.js.map +1 -1
  13. package/out/lib/CharacterSequence.d.ts +16 -1
  14. package/out/lib/CharacterSequence.d.ts.map +1 -1
  15. package/out/lib/CharacterSequence.js +37 -0
  16. package/out/lib/CharacterSequence.js.map +1 -1
  17. package/out/lib/XLSXSpliterator.d.ts +143 -0
  18. package/out/lib/XLSXSpliterator.d.ts.map +1 -0
  19. package/out/lib/XLSXSpliterator.js +161 -0
  20. package/out/lib/XLSXSpliterator.js.map +1 -0
  21. package/out/lib/core/AsyncSpliterator.d.ts +227 -0
  22. package/out/lib/core/AsyncSpliterator.d.ts.map +1 -0
  23. package/out/lib/core/AsyncSpliterator.js +510 -0
  24. package/out/lib/core/AsyncSpliterator.js.map +1 -0
  25. package/out/lib/core/BufferController.d.ts +77 -0
  26. package/out/lib/core/BufferController.d.ts.map +1 -0
  27. package/out/lib/core/BufferController.js +118 -0
  28. package/out/lib/core/BufferController.js.map +1 -0
  29. package/out/lib/core/CharacterSequence.d.ts +72 -0
  30. package/out/lib/core/CharacterSequence.d.ts.map +1 -0
  31. package/out/lib/core/CharacterSequence.js +347 -0
  32. package/out/lib/core/CharacterSequence.js.map +1 -0
  33. package/out/lib/core/CompositeDataView.d.ts +111 -0
  34. package/out/lib/core/CompositeDataView.d.ts.map +1 -0
  35. package/out/lib/core/CompositeDataView.js +241 -0
  36. package/out/lib/core/CompositeDataView.js.map +1 -0
  37. package/out/lib/core/IndexQueue.d.ts +48 -0
  38. package/out/lib/core/IndexQueue.d.ts.map +1 -0
  39. package/out/lib/core/IndexQueue.js +111 -0
  40. package/out/lib/core/IndexQueue.js.map +1 -0
  41. package/out/lib/core/SlidingWindow.d.ts +47 -0
  42. package/out/lib/core/SlidingWindow.d.ts.map +1 -0
  43. package/out/lib/core/SlidingWindow.js +63 -0
  44. package/out/lib/core/SlidingWindow.js.map +1 -0
  45. package/out/lib/core/Spliterator.d.ts +96 -0
  46. package/out/lib/core/Spliterator.d.ts.map +1 -0
  47. package/out/lib/core/Spliterator.js +330 -0
  48. package/out/lib/core/Spliterator.js.map +1 -0
  49. package/out/lib/core/wasm_base64.d.ts +19 -0
  50. package/out/lib/core/wasm_base64.d.ts.map +1 -0
  51. package/out/lib/core/wasm_base64.js +19 -0
  52. package/out/lib/core/wasm_base64.js.map +1 -0
  53. package/out/lib/core/wasm_module.d.ts +57 -0
  54. package/out/lib/core/wasm_module.d.ts.map +1 -0
  55. package/out/lib/core/wasm_module.js +34 -0
  56. package/out/lib/core/wasm_module.js.map +1 -0
  57. package/out/lib/formats/CSVSpliterator.d.ts +131 -0
  58. package/out/lib/formats/CSVSpliterator.d.ts.map +1 -0
  59. package/out/lib/formats/CSVSpliterator.js +172 -0
  60. package/out/lib/formats/CSVSpliterator.js.map +1 -0
  61. package/out/lib/formats/JSONSpliterator.d.ts +44 -0
  62. package/out/lib/formats/JSONSpliterator.d.ts.map +1 -0
  63. package/out/lib/formats/JSONSpliterator.js +77 -0
  64. package/out/lib/formats/JSONSpliterator.js.map +1 -0
  65. package/out/lib/formats/PSVSpliterator.d.ts +21 -0
  66. package/out/lib/formats/PSVSpliterator.d.ts.map +1 -0
  67. package/out/lib/formats/PSVSpliterator.js +22 -0
  68. package/out/lib/formats/PSVSpliterator.js.map +1 -0
  69. package/out/lib/formats/TSVSpliterator.d.ts +21 -0
  70. package/out/lib/formats/TSVSpliterator.d.ts.map +1 -0
  71. package/out/lib/formats/TSVSpliterator.js +22 -0
  72. package/out/lib/formats/TSVSpliterator.js.map +1 -0
  73. package/out/lib/formats/TextSpliterator.d.ts +53 -0
  74. package/out/lib/formats/TextSpliterator.d.ts.map +1 -0
  75. package/out/lib/formats/TextSpliterator.js +67 -0
  76. package/out/lib/formats/TextSpliterator.js.map +1 -0
  77. package/out/lib/formats/XLSXSpliterator.d.ts +143 -0
  78. package/out/lib/formats/XLSXSpliterator.d.ts.map +1 -0
  79. package/out/lib/formats/XLSXSpliterator.js +161 -0
  80. package/out/lib/formats/XLSXSpliterator.js.map +1 -0
  81. package/out/lib/formats/casing.d.ts +27 -0
  82. package/out/lib/formats/casing.d.ts.map +1 -0
  83. package/out/lib/formats/casing.js +68 -0
  84. package/out/lib/formats/casing.js.map +1 -0
  85. package/out/lib/formats/row-emitters.d.ts +35 -0
  86. package/out/lib/formats/row-emitters.d.ts.map +1 -0
  87. package/out/lib/formats/row-emitters.js +50 -0
  88. package/out/lib/formats/row-emitters.js.map +1 -0
  89. package/out/lib/internal/shared.d.ts +155 -0
  90. package/out/lib/internal/shared.d.ts.map +1 -0
  91. package/out/lib/internal/shared.js +41 -0
  92. package/out/lib/internal/shared.js.map +1 -0
  93. package/out/lib/internal/utils.d.ts +37 -0
  94. package/out/lib/internal/utils.d.ts.map +1 -0
  95. package/out/lib/internal/utils.js +39 -0
  96. package/out/lib/internal/utils.js.map +1 -0
  97. package/out/lib/io/adaptive-source.d.ts +39 -0
  98. package/out/lib/io/adaptive-source.d.ts.map +1 -0
  99. package/out/lib/io/adaptive-source.js +95 -0
  100. package/out/lib/io/adaptive-source.js.map +1 -0
  101. package/out/lib/io/writer.d.ts +45 -0
  102. package/out/lib/io/writer.d.ts.map +1 -0
  103. package/out/lib/io/writer.js +57 -0
  104. package/out/lib/io/writer.js.map +1 -0
  105. package/out/lib/iterators/AsyncSequence.d.ts +180 -0
  106. package/out/lib/iterators/AsyncSequence.d.ts.map +1 -0
  107. package/out/lib/iterators/AsyncSequence.js +432 -0
  108. package/out/lib/iterators/AsyncSequence.js.map +1 -0
  109. package/out/lib/iterators/chunks.d.ts +20 -0
  110. package/out/lib/iterators/chunks.d.ts.map +1 -0
  111. package/out/lib/iterators/chunks.js +36 -0
  112. package/out/lib/iterators/chunks.js.map +1 -0
  113. package/out/lib/iterators/pivot.d.ts +30 -0
  114. package/out/lib/iterators/pivot.d.ts.map +1 -0
  115. package/out/lib/iterators/pivot.js +47 -0
  116. package/out/lib/iterators/pivot.js.map +1 -0
  117. package/out/lib/iterators/zip.d.ts +33 -0
  118. package/out/lib/iterators/zip.d.ts.map +1 -0
  119. package/out/lib/iterators/zip.js +59 -0
  120. package/out/lib/iterators/zip.js.map +1 -0
  121. package/out/lib/parallel/merge-async-iterators.d.ts +12 -0
  122. package/out/lib/parallel/merge-async-iterators.d.ts.map +1 -0
  123. package/out/lib/parallel/merge-async-iterators.js +39 -0
  124. package/out/lib/parallel/merge-async-iterators.js.map +1 -0
  125. package/out/lib/parallel/parallel-map-runtime.d.ts +22 -0
  126. package/out/lib/parallel/parallel-map-runtime.d.ts.map +1 -0
  127. package/out/lib/parallel/parallel-map-runtime.js +60 -0
  128. package/out/lib/parallel/parallel-map-runtime.js.map +1 -0
  129. package/out/lib/parallel/parallel-map-worker-entry.d.ts +11 -0
  130. package/out/lib/parallel/parallel-map-worker-entry.d.ts.map +1 -0
  131. package/out/lib/parallel/parallel-map-worker-entry.js +41 -0
  132. package/out/lib/parallel/parallel-map-worker-entry.js.map +1 -0
  133. package/out/lib/parallel/parallel-map-workers.d.ts +57 -0
  134. package/out/lib/parallel/parallel-map-workers.d.ts.map +1 -0
  135. package/out/lib/parallel/parallel-map-workers.js +82 -0
  136. package/out/lib/parallel/parallel-map-workers.js.map +1 -0
  137. package/out/lib/parallel/parallel-map.d.ts +28 -0
  138. package/out/lib/parallel/parallel-map.d.ts.map +1 -0
  139. package/out/lib/parallel/parallel-map.js +30 -0
  140. package/out/lib/parallel/parallel-map.js.map +1 -0
  141. package/out/lib/parallel/segment-runtime.d.ts +27 -0
  142. package/out/lib/parallel/segment-runtime.d.ts.map +1 -0
  143. package/out/lib/parallel/segment-runtime.js +41 -0
  144. package/out/lib/parallel/segment-runtime.js.map +1 -0
  145. package/out/lib/parallel/segment-worker-entry.d.ts +10 -0
  146. package/out/lib/parallel/segment-worker-entry.d.ts.map +1 -0
  147. package/out/lib/parallel/segment-worker-entry.js +59 -0
  148. package/out/lib/parallel/segment-worker-entry.js.map +1 -0
  149. package/out/lib/parallel/segment-workers.d.ts +56 -0
  150. package/out/lib/parallel/segment-workers.d.ts.map +1 -0
  151. package/out/lib/parallel/segment-workers.js +110 -0
  152. package/out/lib/parallel/segment-workers.js.map +1 -0
  153. package/out/lib/parallel/segments.d.ts +31 -0
  154. package/out/lib/parallel/segments.d.ts.map +1 -0
  155. package/out/lib/parallel/segments.js +52 -0
  156. package/out/lib/parallel/segments.js.map +1 -0
  157. package/out/lib/row-emitters.d.ts +35 -0
  158. package/out/lib/row-emitters.d.ts.map +1 -0
  159. package/out/lib/row-emitters.js +50 -0
  160. package/out/lib/row-emitters.js.map +1 -0
  161. package/out/lib/wasm_base64.d.ts +4 -1
  162. package/out/lib/wasm_base64.d.ts.map +1 -1
  163. package/out/lib/wasm_base64.js +4 -1
  164. package/out/lib/wasm_base64.js.map +1 -1
  165. package/out/lib/wasm_module.d.ts +15 -0
  166. package/out/lib/wasm_module.d.ts.map +1 -1
  167. package/out/lib/wasm_module.js +2 -1
  168. package/out/lib/wasm_module.js.map +1 -1
  169. package/out/node/cli/commands/csv.d.ts +113 -0
  170. package/out/node/cli/commands/csv.d.ts.map +1 -1
  171. package/out/node/cli/commands/csv.js +34 -36
  172. package/out/node/cli/commands/csv.js.map +1 -1
  173. package/out/node/cli/commands/iterate.d.ts +92 -0
  174. package/out/node/cli/commands/iterate.d.ts.map +1 -1
  175. package/out/node/cli/commands/iterate.js +26 -28
  176. package/out/node/cli/commands/iterate.js.map +1 -1
  177. package/out/node/cli/commands/parallel.d.ts +102 -0
  178. package/out/node/cli/commands/parallel.d.ts.map +1 -0
  179. package/out/node/cli/commands/parallel.js +426 -0
  180. package/out/node/cli/commands/parallel.js.map +1 -0
  181. package/out/node/cli/index.js +5 -0
  182. package/out/node/cli/index.js.map +1 -1
  183. package/out/node/cli/spec.d.ts +51 -0
  184. package/out/node/cli/spec.d.ts.map +1 -0
  185. package/out/node/cli/spec.js +78 -0
  186. package/out/node/cli/spec.js.map +1 -0
  187. package/out/node/cli/utils.d.ts +36 -18
  188. package/out/node/cli/utils.d.ts.map +1 -1
  189. package/out/node/cli/utils.js +48 -39
  190. package/out/node/cli/utils.js.map +1 -1
  191. package/out/node/fs/index.d.ts +1 -1
  192. package/out/node/fs/index.d.ts.map +1 -1
  193. package/out/node/fs/index.js +1 -1
  194. package/out/node/fs/index.js.map +1 -1
  195. package/package.json +18 -8
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { type CharacterSequenceInput } from "../core/CharacterSequence.js";
7
+ import { type AsyncSpliteratorInit, type SpliteratorInit } from "../core/Spliterator.js";
8
+ import type { AsyncChunkIterator, AsyncDataResource } from "../internal/shared.js";
9
+ import { AsyncSequence } from "../iterators/AsyncSequence.js";
10
+ import { type RowEmitter, type RowOutputMode, type RowTransformer, type RowTransformerEntry, type RowTransformerRecord, type RowTuple } from "./row-emitters.js";
11
+ export type { RowTuple } from "./row-emitters.js";
12
+ /**
13
+ * An output mode for the CSV generator.
14
+ */
15
+ export type CSVOutputMode = RowOutputMode;
16
+ export type CSVTransformer<T = unknown> = RowTransformer<string, T>;
17
+ export type CSVTransformerEntry<T = unknown> = RowTransformerEntry<string, T>;
18
+ export type CSVTransformerRecord = RowTransformerRecord<string>;
19
+ export type CSVEmitter<T = unknown> = RowEmitter<string, T>;
20
+ export type CSVSpliteratorEmittedRecord<V = string | number | undefined> = Record<string, V>;
21
+ export declare const CSVSpliteratorEmitters: Record<CSVOutputMode, CSVEmitter | null>;
22
+ export interface CSVSpliteratorInit extends SpliteratorInit {
23
+ /**
24
+ * The mode determines the shape of the data emitted by the generator.
25
+ *
26
+ * - `object` will emit each row as an object with the header names as keys.
27
+ * - `array` will emit each row as an array.
28
+ * - `entries` will emit each row as an array of key-value pairs.
29
+ *
30
+ * Note that {@linkcode CSVSpliteratorInit.header} defaults to `true` in every mode — the first row is consumed as the
31
+ * header even in `array` mode. Pass `header: false` for headerless data.
32
+ *
33
+ * When {@linkcode SpliteratorInit.enableQuoteHandling} is set, quoting is handled end-to-end: rows do not split on
34
+ * delimiters inside quotes (embedded newlines stay in their row), columns do not split on quoted column delimiters,
35
+ * wrapping quotes are stripped, and doubled quotes (`""`) unescape to `"`.
36
+ *
37
+ * {@linkcode SpliteratorInit.crlf} defaults to `true` here (unlike everywhere else): RFC 4180 mandates CRLF row
38
+ * terminators, so a correct CSV parser must accept them without leaking `\r` into the last column.
39
+ */
40
+ mode?: CSVOutputMode;
41
+ /**
42
+ * The delimiter to use for columns in a row.
43
+ *
44
+ * @default Delimiter.Comma
45
+ */
46
+ columnDelimiter?: CharacterSequenceInput;
47
+ /**
48
+ * Whether to normalize the keys of the header row into `snake_case`, and to disambiguate duplicates by suffixing
49
+ * `_2`, `_3`, … — making them usable as object keys.
50
+ *
51
+ * **A header that is already ALL CAPS is left alone**, on the reasoning that its casing is deliberate. So an
52
+ * OpenAddresses header (`LON,LAT,NUMBER,STREET`) normalizes to `LON`/`NUMBER`, NOT `lon`/`number`, and a row is read
53
+ * as `row.STREET`. Lower-case your own keys if you want case-folding — this option does not provide it.
54
+ *
55
+ * @default `mode !== "array"` — object and entries rows need keyable names; array rows have no keys to normalize.
56
+ */
57
+ normalizeKeys?: boolean;
58
+ /**
59
+ * Whether to treat the first row as a header.
60
+ *
61
+ * @default true
62
+ */
63
+ header?: boolean;
64
+ transformers?: Iterable<CSVTransformerEntry> | CSVTransformerRecord;
65
+ }
66
+ /**
67
+ * A static class spliterator for comma-separated values.
68
+ *
69
+ * **Performance:** the SIMD delimiter scan wins when scanning dominates — many rows, a few columns pulled out cheaply,
70
+ * streaming to bound memory. When per-row work is heavy (a full `JSON.parse`, expensive transforms) it can dominate the
71
+ * scan and erase the advantage; benchmark against a mature native parser before swapping an existing loop for speed.
72
+ * See {@link JSONSpliterator} for the measured case where per-row `JSON.parse` makes the streamed path a net loss.
73
+ *
74
+ * @see {@linkcode CSVSpliterator.from} for synchronous usage.
75
+ * @see {@linkcode CSVSpliterator.fromAsync} for asynchronous usage.
76
+ */
77
+ export declare abstract class CSVSpliterator {
78
+ /**
79
+ * The column delimiter used by the spliterator.
80
+ *
81
+ * @default Delimiters.Comma
82
+ */
83
+ static ColumnDelimiter: number;
84
+ constructor();
85
+ static from<T extends CSVSpliteratorEmittedRecord = CSVSpliteratorEmittedRecord>(source: CharacterSequenceInput, options?: CSVSpliteratorInit & {
86
+ mode: "object";
87
+ }): Generator<T>;
88
+ /**
89
+ * @yields Each row as a 3-tuple [key, value, idx].
90
+ */
91
+ static from<T extends RowTuple[] = RowTuple[]>(source: CharacterSequenceInput, options?: CSVSpliteratorInit & {
92
+ mode: "entries";
93
+ }): Generator<T>;
94
+ /**
95
+ * Given a byte array or string, yield each row as an array of columns.
96
+ *
97
+ * @yields Each row as an array of columns.
98
+ */
99
+ static from<T extends string[] = string[]>(source: CharacterSequenceInput, options?: CSVSpliteratorInit & {
100
+ mode?: "array";
101
+ }): Generator<T>;
102
+ /**
103
+ * @yields Each row as an object with the header names as keys.
104
+ */
105
+ static fromAsync<T extends CSVSpliteratorEmittedRecord = CSVSpliteratorEmittedRecord>(source: AsyncDataResource | AsyncChunkIterator, options?: CSVSpliteratorInit & AsyncSpliteratorInit & {
106
+ mode: "object";
107
+ }): AsyncSequence<T>;
108
+ /**
109
+ * @yields Each row as a 3-tuple [key, value, idx].
110
+ */
111
+ static fromAsync<T extends RowTuple[] = RowTuple[]>(source: AsyncDataResource | AsyncChunkIterator, options?: CSVSpliteratorInit & AsyncSpliteratorInit & {
112
+ mode: "entries";
113
+ }): AsyncSequence<T>;
114
+ /**
115
+ * @yields Each row as an array of columns.
116
+ */
117
+ static fromAsync<T extends string[] = string[]>(source: AsyncDataResource | AsyncChunkIterator, options?: CSVSpliteratorInit & AsyncSpliteratorInit & {
118
+ mode?: "array";
119
+ }): AsyncSequence<T>;
120
+ /**
121
+ * Given an asychronous data source, splits the data by rows(usually by newline) and then by columns (usually by
122
+ * comma).
123
+ *
124
+ * @param source The data source to split.
125
+ * @param init Options for the spliterator.
126
+ *
127
+ * @yields Each row, shaped according to the `mode` option.
128
+ */
129
+ static fromAsync(source: AsyncDataResource | AsyncChunkIterator, init?: CSVSpliteratorInit & AsyncSpliteratorInit): AsyncSequence<unknown>;
130
+ }
131
+ //# sourceMappingURL=CSVSpliterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSVSpliterator.d.ts","sourceRoot":"","sources":["../../../lib/formats/CSVSpliterator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { CharacterSequence, Delimiters } from "../core/CharacterSequence.js";
7
+ import { Spliterator } from "../core/Spliterator.js";
8
+ import { openDelimitedRows } from "../io/adaptive-source.js";
9
+ import { AsyncSequence } from "../iterators/AsyncSequence.js";
10
+ import { normalizeColumnNames } from "./casing.js";
11
+ import { bindTransformers, createRowEmitters, } from "./row-emitters.js";
12
+ const doubleQuoteSequence = new CharacterSequence('"');
13
+ /**
14
+ * Decode a single column, stripping wrapping quotes and unescaping doubled quotes (`""` → `"`) when quote handling is
15
+ * on. The unescape allocates only when the field was actually quoted.
16
+ */
17
+ function decodeColumn(bytes, decoder, enableQuoteHandling) {
18
+ const value = decoder.decode(bytes);
19
+ if (enableQuoteHandling && value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
20
+ return value.slice(1, -1).replaceAll('""', '"');
21
+ }
22
+ return value;
23
+ }
24
+ /**
25
+ * Split one row's bytes into decoded column strings.
26
+ *
27
+ * Without quote handling this is a plain delimiter scan. With it, a column delimiter inside a double-quoted region does
28
+ * not split, and each field is unquoted/unescaped via {@linkcode decodeColumn}. Empty columns are always preserved — a
29
+ * 30-column row must stay 30 columns regardless of the caller's row-level `skipEmpty`.
30
+ */
31
+ function splitRowColumns(row, columnDelimiter, decoder, enableQuoteHandling) {
32
+ if (!enableQuoteHandling) {
33
+ return columnDelimiter.searchAll(row).map(([start, end]) => decoder.decode(row.subarray(start, end)));
34
+ }
35
+ const columns = [];
36
+ let sliceStart = 0;
37
+ let insideQuotes = false;
38
+ for (const match of columnDelimiter.searchMatches(row, doubleQuoteSequence)) {
39
+ if (match.patternId === 1) {
40
+ insideQuotes = !insideQuotes;
41
+ continue;
42
+ }
43
+ if (insideQuotes)
44
+ continue;
45
+ columns.push(decodeColumn(row.subarray(sliceStart, match.offset), decoder, enableQuoteHandling));
46
+ sliceStart = match.offset + columnDelimiter.length;
47
+ }
48
+ columns.push(decodeColumn(row.subarray(sliceStart), decoder, enableQuoteHandling));
49
+ return columns;
50
+ }
51
+ export const CSVSpliteratorEmitters = createRowEmitters("");
52
+ /**
53
+ * A static class spliterator for comma-separated values.
54
+ *
55
+ * **Performance:** the SIMD delimiter scan wins when scanning dominates — many rows, a few columns pulled out cheaply,
56
+ * streaming to bound memory. When per-row work is heavy (a full `JSON.parse`, expensive transforms) it can dominate the
57
+ * scan and erase the advantage; benchmark against a mature native parser before swapping an existing loop for speed.
58
+ * See {@link JSONSpliterator} for the measured case where per-row `JSON.parse` makes the streamed path a net loss.
59
+ *
60
+ * @see {@linkcode CSVSpliterator.from} for synchronous usage.
61
+ * @see {@linkcode CSVSpliterator.fromAsync} for asynchronous usage.
62
+ */
63
+ export class CSVSpliterator {
64
+ /**
65
+ * The column delimiter used by the spliterator.
66
+ *
67
+ * @default Delimiters.Comma
68
+ */
69
+ static ColumnDelimiter = Delimiters.Comma;
70
+ constructor() {
71
+ throw new TypeError("Static class cannot be instantiated. Did you mean `CSVSpliterator.from`?");
72
+ }
73
+ /**
74
+ * Given a byte array or string, yield each row as an array of columns.
75
+ *
76
+ * @yields Each row as an array of columns.
77
+ */
78
+ static *from(source, init = {}) {
79
+ const {
80
+ // ---
81
+ header = true,
82
+ // `mode` is destructured before `normalizeKeys` because the latter's default reads it.
83
+ mode = "array", transformers: transformersInput = [],
84
+ // Matches `fromAsync`. These two defaulted differently until 4.0.1, so the same options
85
+ // object produced `row.some_name` from one entry point and `row["Some Name"]` from the other.
86
+ normalizeKeys = mode !== "array", columnDelimiter: columnDelimiterInput = this.ColumnDelimiter, enableQuoteHandling = false,
87
+ // RFC 4180 mandates CRLF row terminators — accept them by default so the last column
88
+ // never carries a stray `\r` on Windows-lineage sources.
89
+ crlf = true, take = Infinity, drop = 0, ...rowInit } = init;
90
+ const emitter = CSVSpliteratorEmitters[mode];
91
+ let transformers = [];
92
+ let yieldCount = 0;
93
+ const yieldLimit = take + drop;
94
+ const decoder = new TextDecoder();
95
+ const columnDelimiter = new CharacterSequence(columnDelimiterInput ?? this.ColumnDelimiter);
96
+ // Quote handling applies at both levels: rows must not split on newlines inside quotes,
97
+ // columns must not split on quoted column delimiters.
98
+ const rows = Spliterator.fromSync(source, { ...rowInit, crlf, enableQuoteHandling });
99
+ if (header) {
100
+ const result = rows.next();
101
+ if (result.done)
102
+ return;
103
+ const columns = splitRowColumns(result.value, columnDelimiter, decoder, enableQuoteHandling);
104
+ const headers = normalizeKeys ? normalizeColumnNames(columns) : columns;
105
+ transformers = bindTransformers(headers, transformersInput);
106
+ }
107
+ for (const row of rows) {
108
+ if (yieldCount < drop) {
109
+ yieldCount++;
110
+ continue;
111
+ }
112
+ if (yieldCount >= yieldLimit)
113
+ break;
114
+ const columns = splitRowColumns(row, columnDelimiter, decoder, enableQuoteHandling);
115
+ yield emitter ? emitter(columns, transformers) : columns;
116
+ yieldCount++;
117
+ }
118
+ }
119
+ /**
120
+ * Given an asychronous data source, splits the data by rows (usually by newline) and then by columns (usually by
121
+ * comma).
122
+ *
123
+ * @param source The data source to split.
124
+ * @param init Options for the spliterator.
125
+ *
126
+ * @yields Each row, shaped according to the `mode` option.
127
+ */
128
+ static fromAsync(source, init = {}) {
129
+ const defaultColumnDelimiter = this.ColumnDelimiter;
130
+ const {
131
+ // ---
132
+ header = true, mode = "array", transformers: transformersInput = [], normalizeKeys = mode !== "array", columnDelimiter: columnDelimiterInput, enableQuoteHandling = false,
133
+ // RFC 4180 mandates CRLF row terminators — accept them by default so the last column
134
+ // never carries a stray `\r` on Windows-lineage sources.
135
+ crlf = true, take = Infinity, drop = 0, ...rowInit } = init;
136
+ const emitter = CSVSpliteratorEmitters[mode];
137
+ const columnDelimiter = new CharacterSequence(columnDelimiterInput ?? defaultColumnDelimiter);
138
+ const decoder = new TextDecoder();
139
+ // Populated by the header pass below before the first row op runs, since the source thunk resolves on the first
140
+ // pull and the ops only run against what it returns.
141
+ let transformers = [];
142
+ const openRows = async () => {
143
+ // Quote handling applies at both levels: rows must not split on newlines inside quotes,
144
+ // columns must not split on quoted column delimiters.
145
+ const rows = await openDelimitedRows(source, { ...rowInit, crlf, enableQuoteHandling });
146
+ if (header) {
147
+ // Both engines return `this` from their iterator method, so consuming the header row here advances the very
148
+ // cursor the row ops will go on to read — returning `rows` afterwards resumes at row two, not row one.
149
+ const iterator = Symbol.asyncIterator in rows ? rows[Symbol.asyncIterator]() : rows[Symbol.iterator]();
150
+ const result = await iterator.next();
151
+ if (result.done)
152
+ return rows;
153
+ const columns = splitRowColumns(result.value, columnDelimiter, decoder, enableQuoteHandling);
154
+ const headers = normalizeKeys ? normalizeColumnNames(columns) : columns;
155
+ transformers = bindTransformers(headers, transformersInput);
156
+ }
157
+ return rows;
158
+ };
159
+ let sequence = AsyncSequence.from(openRows).map((row) => {
160
+ const columns = splitRowColumns(row, columnDelimiter, decoder, enableQuoteHandling);
161
+ return emitter ? emitter(columns, transformers) : columns;
162
+ });
163
+ if (drop > 0) {
164
+ sequence = sequence.drop(drop);
165
+ }
166
+ if (Number.isFinite(take)) {
167
+ sequence = sequence.take(take);
168
+ }
169
+ return sequence;
170
+ }
171
+ }
172
+ //# sourceMappingURL=CSVSpliterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSVSpliterator.js","sourceRoot":"","sources":["../../../lib/formats/CSVSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAA+B,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzG,OAAO,EAA6B,WAAW,EAAwB,MAAM,wBAAwB,CAAA;AAErG,OAAO,EAA2B,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EACN,gBAAgB,EAChB,iBAAiB,GAOjB,MAAM,mBAAmB,CAAA;AAiB1B,MAAM,mBAAmB,GAAG,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAA;AAEtD;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAiB,EAAE,OAAoB,EAAE,mBAA4B;IAC1F,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAEnC,IAAI,mBAAmB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9F,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACvB,GAAe,EACf,eAAkC,EAClC,OAAoB,EACpB,mBAA4B;IAE5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC1B,OAAO,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,YAAY,GAAG,KAAK,CAAA;IAExB,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,aAAa,CAAC,GAAG,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC7E,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YAC3B,YAAY,GAAG,CAAC,YAAY,CAAA;YAE5B,SAAQ;QACT,CAAC;QAED,IAAI,YAAY;YAAE,SAAQ;QAE1B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAA;QAChG,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CAAA;IACnD,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAA;IAElF,OAAO,OAAO,CAAA;AACf,CAAC;AAID,MAAM,CAAC,MAAM,sBAAsB,GAA6C,iBAAiB,CAAS,EAAE,CAAC,CAAA;AAmD7G;;;;;;;;;;GAUG;AACH,MAAM,OAAgB,cAAc;IACnC;;;;OAIG;IACI,MAAM,CAAC,eAAe,GAAW,UAAU,CAAC,KAAK,CAAA;IAExD;QACC,MAAM,IAAI,SAAS,CAAC,0EAA0E,CAAC,CAAA;IAChG,CAAC;IAuBD;;;;OAIG;IACH,MAAM,CAAC,CAAC,IAAI,CAAC,MAA8B,EAAE,IAAI,GAAuB,EAAE;QACzE,MAAM;QACL,MAAM;QACN,MAAM,GAAG,IAAI;QACb,uFAAuF;QACvF,IAAI,GAAG,OAAO,EACd,YAAY,EAAE,iBAAiB,GAAG,EAAE;QACpC,wFAAwF;QACxF,8FAA8F;QAC9F,aAAa,GAAG,IAAI,KAAK,OAAO,EAChC,eAAe,EAAE,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAC5D,mBAAmB,GAAG,KAAK;QAC3B,qFAAqF;QACrF,yDAAyD;QACzD,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,QAAQ,EACf,IAAI,GAAG,CAAC,EACR,GAAG,OAAO,EACV,GAAG,IAAI,CAAA;QAER,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,YAAY,GAA0B,EAAE,CAAA;QAC5C,IAAI,UAAU,GAAG,CAAC,CAAA;QAClB,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAA;QAE9B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;QACjC,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,oBAAoB,IAAI,IAAI,CAAC,eAAe,CAAC,CAAA;QAE3F,wFAAwF;QACxF,sDAAsD;QACtD,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAA;QAEpF,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;YAE1B,IAAI,MAAM,CAAC,IAAI;gBAAE,OAAM;YAEvB,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAA;YAC5F,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YAEvE,YAAY,GAAG,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;QAC5D,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,UAAU,GAAG,IAAI,EAAE,CAAC;gBACvB,UAAU,EAAE,CAAA;gBAEZ,SAAQ;YACT,CAAC;YAED,IAAI,UAAU,IAAI,UAAU;gBAAE,MAAK;YAEnC,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAA;YAEnF,MAAM,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YAExD,UAAU,EAAE,CAAA;QACb,CAAC;IACF,CAAC;IAqCD;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CACf,MAA8C,EAC9C,IAAI,GAA4C,EAAE;QAElD,MAAM,sBAAsB,GAAG,IAAI,CAAC,eAAe,CAAA;QAEnD,MAAM;QACL,MAAM;QACN,MAAM,GAAG,IAAI,EACb,IAAI,GAAG,OAAO,EACd,YAAY,EAAE,iBAAiB,GAAG,EAAE,EACpC,aAAa,GAAG,IAAI,KAAK,OAAO,EAChC,eAAe,EAAE,oBAAoB,EACrC,mBAAmB,GAAG,KAAK;QAC3B,qFAAqF;QACrF,yDAAyD;QACzD,IAAI,GAAG,IAAI,EACX,IAAI,GAAG,QAAQ,EACf,IAAI,GAAG,CAAC,EACR,GAAG,OAAO,EACV,GAAG,IAAI,CAAA;QAER,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,eAAe,GAAG,IAAI,iBAAiB,CAAC,oBAAoB,IAAI,sBAAsB,CAAC,CAAA;QAC7F,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;QAEjC,gHAAgH;QAChH,qDAAqD;QACrD,IAAI,YAAY,GAA0B,EAAE,CAAA;QAE5C,MAAM,QAAQ,GAAG,KAAK,IAA+D,EAAE;YACtF,wFAAwF;YACxF,sDAAsD;YACtD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAA;YAEvF,IAAI,MAAM,EAAE,CAAC;gBACZ,4GAA4G;gBAC5G,uGAAuG;gBACvG,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAA;gBACtG,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;gBAEpC,IAAI,MAAM,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAA;gBAE5B,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAA;gBAC5F,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;gBAEvE,YAAY,GAAG,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;YAC5D,CAAC;YAED,OAAO,IAAI,CAAA;QACZ,CAAC,CAAA;QAED,IAAI,QAAQ,GAA2B,aAAa,CAAC,IAAI,CAAa,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3F,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAA;YAEnF,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QAC1D,CAAC,CAAC,CAAA;QAEF,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACd,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;QAED,OAAO,QAAQ,CAAA;IAChB,CAAC;CACD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { CharacterSequenceInput } from "../core/CharacterSequence.js";
7
+ import { type SpliteratorInit } from "../core/Spliterator.js";
8
+ import type { AsyncDataResource } from "../internal/shared.js";
9
+ import { type AdaptiveSourceInit } from "../io/adaptive-source.js";
10
+ import { AsyncSequence } from "../iterators/AsyncSequence.js";
11
+ /**
12
+ * Stream a delimited byte source and `JSON.parse` each row — one parsed value per line, for JSONL / NDJSON. The row
13
+ * delimiter defaults to a line feed; override it via `options.delimiter`. `skipEmpty` (on by default) drops blank
14
+ * rows.
15
+ *
16
+ * **Performance caveat — this path is `JSON.parse`-bound, not scan-bound.** Measured over 500k rows (88MB, ~177B per
17
+ * row, Node 26): the delimiter scan is ~140ms and decoding ~46ms, while `JSON.parse` and the per-row async machinery
18
+ * account for the rest of ~1280ms. Against Node's `readline` + `JSON.parse` at ~630ms, this runs **roughly half the
19
+ * speed — a net loss.** Use it for API convenience, or when streaming to bound memory; do NOT swap a working `readline`
20
+ * loop to it expecting a speedup on parse-heavy JSONL.
21
+ *
22
+ * The scan advantage only shows when you _don't_ fully parse every row. Filtering on the raw text and parsing only what
23
+ * survives is the shape that wins — parsing 20% of rows measured ~2.5× faster than parsing all of them:
24
+ *
25
+ * ```ts
26
+ * TextSpliterator.fromAsync(path, { delimiter: "\n" })
27
+ * .filter((line) => line.includes('"category":"Novelty"'))
28
+ * .map((line) => JSON.parse(line))
29
+ * ```
30
+ *
31
+ * For segmentation or counting, use {@link Spliterator} (raw byte ranges) or {@link TextSpliterator}. When unsure,
32
+ * benchmark.
33
+ */
34
+ export declare abstract class JSONSpliterator {
35
+ constructor();
36
+ static from<T = unknown>(source: CharacterSequenceInput, options?: SpliteratorInit): Generator<T>;
37
+ /**
38
+ * Given a byte array or string, yield each row as an array of columns.
39
+ *
40
+ * @yields Each row as an array of columns.
41
+ */
42
+ static fromAsync<T = unknown>(source: AsyncDataResource, options?: AdaptiveSourceInit): AsyncSequence<T>;
43
+ }
44
+ //# sourceMappingURL=JSONSpliterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONSpliterator.d.ts","sourceRoot":"","sources":["../../../lib/formats/JSONSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAC1E,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,0BAA0B,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,8BAAsB,eAAe;IACpC,cAEC;IAED,MAAM,CAAE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,OAAO,GAAE,eAAoB,GAAG,SAAS,CAAC,CAAC,CAAC,CAwBrG;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAAC,CAAC,CAAC,CAgB3G;CACD"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { Spliterator } from "../core/Spliterator.js";
7
+ import { openDelimitedRows } from "../io/adaptive-source.js";
8
+ import { AsyncSequence } from "../iterators/AsyncSequence.js";
9
+ /**
10
+ * Stream a delimited byte source and `JSON.parse` each row — one parsed value per line, for JSONL / NDJSON. The row
11
+ * delimiter defaults to a line feed; override it via `options.delimiter`. `skipEmpty` (on by default) drops blank
12
+ * rows.
13
+ *
14
+ * **Performance caveat — this path is `JSON.parse`-bound, not scan-bound.** Measured over 500k rows (88MB, ~177B per
15
+ * row, Node 26): the delimiter scan is ~140ms and decoding ~46ms, while `JSON.parse` and the per-row async machinery
16
+ * account for the rest of ~1280ms. Against Node's `readline` + `JSON.parse` at ~630ms, this runs **roughly half the
17
+ * speed — a net loss.** Use it for API convenience, or when streaming to bound memory; do NOT swap a working `readline`
18
+ * loop to it expecting a speedup on parse-heavy JSONL.
19
+ *
20
+ * The scan advantage only shows when you _don't_ fully parse every row. Filtering on the raw text and parsing only what
21
+ * survives is the shape that wins — parsing 20% of rows measured ~2.5× faster than parsing all of them:
22
+ *
23
+ * ```ts
24
+ * TextSpliterator.fromAsync(path, { delimiter: "\n" })
25
+ * .filter((line) => line.includes('"category":"Novelty"'))
26
+ * .map((line) => JSON.parse(line))
27
+ * ```
28
+ *
29
+ * For segmentation or counting, use {@link Spliterator} (raw byte ranges) or {@link TextSpliterator}. When unsure,
30
+ * benchmark.
31
+ */
32
+ export class JSONSpliterator {
33
+ constructor() {
34
+ throw new TypeError("Static class cannot be instantiated. Did you mean `JSONSpliterator.from`?");
35
+ }
36
+ static *from(source, options = {}) {
37
+ const decoder = new TextDecoder();
38
+ let rowCursor = 0;
39
+ const spliterator = Spliterator.fromSync(source, options);
40
+ for (const row of spliterator) {
41
+ let parsed;
42
+ try {
43
+ const content = decoder.decode(row);
44
+ parsed = JSON.parse(content);
45
+ }
46
+ catch (parsedError) {
47
+ const error = new SyntaxError(`Failed to parse JSON at row ${rowCursor}`);
48
+ error.cause = parsedError;
49
+ throw error;
50
+ }
51
+ yield parsed;
52
+ rowCursor++;
53
+ }
54
+ }
55
+ /**
56
+ * Given a byte array or string, yield each row as an array of columns.
57
+ *
58
+ * @yields Each row as an array of columns.
59
+ */
60
+ static fromAsync(source, options = {}) {
61
+ const decoder = new TextDecoder();
62
+ // Parsing is an op on the sequence, not a generator wrapped inside one. An allocating row body makes the extra
63
+ // async frame a wrapping generator adds disproportionately expensive: 1460ms against 1278ms over 500k rows, where
64
+ // the same layer costs a third as much when the body only decodes.
65
+ return AsyncSequence.from(() => openDelimitedRows(source, options)).map((row, rowCursor) => {
66
+ try {
67
+ return JSON.parse(decoder.decode(row));
68
+ }
69
+ catch (parsedError) {
70
+ const error = new SyntaxError(`Failed to parse JSON at row ${rowCursor}`);
71
+ error.cause = parsedError;
72
+ throw error;
73
+ }
74
+ });
75
+ }
76
+ }
77
+ //# sourceMappingURL=JSONSpliterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONSpliterator.js","sourceRoot":"","sources":["../../../lib/formats/JSONSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAA6B,WAAW,EAAwB,MAAM,wBAAwB,CAAA;AAErG,OAAO,EAA2B,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAgB,eAAe;IACpC;QACC,MAAM,IAAI,SAAS,CAAC,2EAA2E,CAAC,CAAA;IACjG,CAAC;IAED,MAAM,CAAC,CAAC,IAAI,CAAc,MAA8B,EAAE,OAAO,GAAoB,EAAE;QACtF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;QACjC,IAAI,SAAS,GAAG,CAAC,CAAA;QAEjB,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAEzD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,MAAS,CAAA;YAEb,IAAI,CAAC;gBACJ,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAEnC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAA;YAClC,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAA;gBACzE,KAAK,CAAC,KAAK,GAAG,WAAW,CAAA;gBAEzB,MAAM,KAAK,CAAA;YACZ,CAAC;YAED,MAAM,MAAM,CAAA;YAEZ,SAAS,EAAE,CAAA;QACZ,CAAC;IACF,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAc,MAAyB,EAAE,OAAO,GAAuB,EAAE;QACxF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;QAEjC,+GAA+G;QAC/G,kHAAkH;QAClH,mEAAmE;QACnE,OAAO,aAAa,CAAC,IAAI,CAAa,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;YACtG,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAM,CAAA;YAC5C,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAA;gBACzE,KAAK,CAAC,KAAK,GAAG,WAAW,CAAA;gBAEzB,MAAM,KAAK,CAAA;YACZ,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;CACD"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { CSVSpliterator } from "./CSVSpliterator.js";
7
+ /**
8
+ * A static class spliterator for pipe-separated values.
9
+ *
10
+ * @see {@linkcode PSVSpliterator.from} for synchronous usage.
11
+ * @see {@linkcode PSVSpliterator.fromAsync} for asynchronous usage.
12
+ */
13
+ export declare abstract class PSVSpliterator extends CSVSpliterator {
14
+ /**
15
+ * The column delimiter used by the spliterator.
16
+ *
17
+ * @default Delimiters.Pipe
18
+ */
19
+ static ColumnDelimiter: number;
20
+ }
21
+ //# sourceMappingURL=PSVSpliterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PSVSpliterator.d.ts","sourceRoot":"","sources":["../../../lib/formats/PSVSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;GAKG;AACH,8BAAsB,cAAe,SAAQ,cAAc;IAC1D;;;;OAIG;IACH,OAAuB,eAAe,EAAE,MAAM,CAAkB;CAChE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { Delimiters } from "../core/CharacterSequence.js";
7
+ import { CSVSpliterator } from "./CSVSpliterator.js";
8
+ /**
9
+ * A static class spliterator for pipe-separated values.
10
+ *
11
+ * @see {@linkcode PSVSpliterator.from} for synchronous usage.
12
+ * @see {@linkcode PSVSpliterator.fromAsync} for asynchronous usage.
13
+ */
14
+ export class PSVSpliterator extends CSVSpliterator {
15
+ /**
16
+ * The column delimiter used by the spliterator.
17
+ *
18
+ * @default Delimiters.Pipe
19
+ */
20
+ static ColumnDelimiter = Delimiters.Pipe;
21
+ }
22
+ //# sourceMappingURL=PSVSpliterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PSVSpliterator.js","sourceRoot":"","sources":["../../../lib/formats/PSVSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,OAAgB,cAAe,SAAQ,cAAc;IAC1D;;;;OAIG;IACI,MAAM,CAAU,eAAe,GAAW,UAAU,CAAC,IAAI,CAAA;CAChE"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { CSVSpliterator } from "./CSVSpliterator.js";
7
+ /**
8
+ * A static class spliterator for tab-separated values.
9
+ *
10
+ * @see {@linkcode TSVSpliterator.from} for synchronous usage.
11
+ * @see {@linkcode TSVSpliterator.fromAsync} for asynchronous usage.
12
+ */
13
+ export declare abstract class TSVSpliterator extends CSVSpliterator {
14
+ /**
15
+ * The column delimiter used by the spliterator.
16
+ *
17
+ * @default Delimiters.Tab
18
+ */
19
+ static ColumnDelimiter: number;
20
+ }
21
+ //# sourceMappingURL=TSVSpliterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TSVSpliterator.d.ts","sourceRoot":"","sources":["../../../lib/formats/TSVSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;GAKG;AACH,8BAAsB,cAAe,SAAQ,cAAc;IAC1D;;;;OAIG;IACH,OAAuB,eAAe,EAAE,MAAM,CAAiB;CAC/D"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { Delimiters } from "../core/CharacterSequence.js";
7
+ import { CSVSpliterator } from "./CSVSpliterator.js";
8
+ /**
9
+ * A static class spliterator for tab-separated values.
10
+ *
11
+ * @see {@linkcode TSVSpliterator.from} for synchronous usage.
12
+ * @see {@linkcode TSVSpliterator.fromAsync} for asynchronous usage.
13
+ */
14
+ export class TSVSpliterator extends CSVSpliterator {
15
+ /**
16
+ * The column delimiter used by the spliterator.
17
+ *
18
+ * @default Delimiters.Tab
19
+ */
20
+ static ColumnDelimiter = Delimiters.Tab;
21
+ }
22
+ //# sourceMappingURL=TSVSpliterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TSVSpliterator.js","sourceRoot":"","sources":["../../../lib/formats/TSVSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,OAAgB,cAAe,SAAQ,cAAc;IAC1D;;;;OAIG;IACI,MAAM,CAAU,eAAe,GAAW,UAAU,CAAC,GAAG,CAAA;CAC/D"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license MIT
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { CharacterSequenceInput } from "../core/CharacterSequence.js";
7
+ import { type SpliteratorInit } from "../core/Spliterator.js";
8
+ import type { AsyncDataResource } from "../internal/shared.js";
9
+ import { type AdaptiveSourceInit } from "../io/adaptive-source.js";
10
+ import { AsyncSequence } from "../iterators/AsyncSequence.js";
11
+ export interface TextSpliteratorInit {
12
+ /**
13
+ * The encoding to use when decoding the data.
14
+ *
15
+ * @default "utf-8"
16
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/TextDecoder
17
+ */
18
+ encoding?: string;
19
+ /**
20
+ * Whether to throw an error when encountering invalid data, or to swap it with a replacement character.
21
+ */
22
+ fatal?: boolean;
23
+ /**
24
+ * Whether to ignore BOM characters.
25
+ */
26
+ ignoreBOM?: boolean;
27
+ }
28
+ export declare abstract class TextSpliterator {
29
+ constructor();
30
+ /**
31
+ * Synchronously yield delimited text from a byte array or string.
32
+ *
33
+ * @param source The source content to split.
34
+ * @param options The options to use when splitting the content.
35
+ *
36
+ * @yields Each slice of the source content.
37
+ * @see {@linkcode TextSpliterator.fromAsync} for asynchronous iteration with decoding.
38
+ * @see {@linkcode Spliterator.fromSync} for synchronous iteration without decoding.
39
+ */
40
+ static from(source: CharacterSequenceInput, { encoding, fatal, ignoreBOM, ...options }?: TextSpliteratorInit & SpliteratorInit): Generator<string>;
41
+ /**
42
+ * Asynchronously yield delimited text from a byte array or string.
43
+ *
44
+ * @param source The async data resource to split.
45
+ * @param options The options to use when splitting the content.
46
+ *
47
+ * @yields Each slice of the source content.
48
+ * @see {@linkcode TextSpliterator.from} for synchronous iteration with decoding.
49
+ * @see {@linkcode Spliterator.fromAsync} for asynchronous iteration without decoding.
50
+ */
51
+ static fromAsync(source: AsyncDataResource, { encoding, fatal, ignoreBOM, ...options }?: TextSpliteratorInit & AdaptiveSourceInit): AsyncSequence<string>;
52
+ }
53
+ //# sourceMappingURL=TextSpliterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextSpliterator.d.ts","sourceRoot":"","sources":["../../../lib/formats/TextSpliterator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAC1E,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,0BAA0B,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,8BAAsB,eAAe;IACpC,cAEC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAE,IAAI,CACX,MAAM,EAAE,sBAAsB,EAC9B,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,GAAE,mBAAmB,GAAG,eAAoB,GACpF,SAAS,CAAC,MAAM,CAAC,CAsBnB;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,SAAS,CACf,MAAM,EAAE,iBAAiB,EACzB,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,GAAE,mBAAmB,GAAG,kBAAuB,GACvF,aAAa,CAAC,MAAM,CAAC,CAevB;CACD"}