csv-stream-lite 0.1.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/EXAMPLES.md +197 -0
- package/LICENSE +21 -0
- package/README.md +273 -0
- package/dist/byte-buffer.d.ts +112 -0
- package/dist/byte-buffer.js +282 -0
- package/dist/defaults.d.ts +8 -0
- package/dist/defaults.js +8 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.js +30 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/parser.d.ts +293 -0
- package/dist/parser.js +596 -0
- package/dist/stringify.d.ts +91 -0
- package/dist/stringify.js +186 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.js +20 -0
- package/package.json +69 -0
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# csv-stream-Lite Examples
|
|
2
|
+
|
|
3
|
+
This directory contains example scripts demonstrating how to use the csv-stream-Lite library.
|
|
4
|
+
|
|
5
|
+
## Basic CSV streaming example
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Csv } from 'csv-stream-lite'
|
|
9
|
+
|
|
10
|
+
const csvData = `name,age,city
|
|
11
|
+
Alice,30,New York
|
|
12
|
+
Bob,25,Los Angeles
|
|
13
|
+
Charlie,35,Chicago`
|
|
14
|
+
|
|
15
|
+
for await (const row of new Csv(csvData).streamObjectsAsync()) {
|
|
16
|
+
console.log(row)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Output:
|
|
20
|
+
// { name: 'Alice', age: '30', city: 'New York' }
|
|
21
|
+
// { name: 'Bob', age: '25', city: 'Los Angeles' }
|
|
22
|
+
// { name: 'Charlie', age: '35', city: 'Chicago' }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Low-level CSV streaming example
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Csv } from 'csv-stream-lite'
|
|
29
|
+
|
|
30
|
+
const csvData = `name,age,city
|
|
31
|
+
Alice,30,New York
|
|
32
|
+
Bob,25,Los Angeles
|
|
33
|
+
Charlie,35,Chicago`
|
|
34
|
+
|
|
35
|
+
let i = 0
|
|
36
|
+
|
|
37
|
+
const csvStream = new Csv(csvData)
|
|
38
|
+
for await (const row of csvStream) {
|
|
39
|
+
for await (const cell of row) {
|
|
40
|
+
if (i++ % 2 === 0) {
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
for await (const char of cell) {
|
|
44
|
+
// Write each character to stdout as we read it
|
|
45
|
+
process.stdout.write(char)
|
|
46
|
+
}
|
|
47
|
+
process.stdout.write('\n')
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Output:
|
|
52
|
+
// age
|
|
53
|
+
// Alice
|
|
54
|
+
// New York
|
|
55
|
+
// 25
|
|
56
|
+
// Charlie
|
|
57
|
+
// Chicago
|
|
58
|
+
|
|
59
|
+
// Note: There are no delimiters or newlines in the output because we are
|
|
60
|
+
// writing each cell directly as we read it.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Type Coercion Example
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Csv } from 'csv-stream-lite'
|
|
67
|
+
|
|
68
|
+
const csvData = `name,age,city
|
|
69
|
+
Alice,30,New York
|
|
70
|
+
Bob,25,Los Angeles
|
|
71
|
+
Charlie,35,Chicago`
|
|
72
|
+
|
|
73
|
+
// Define a schema for type coercion
|
|
74
|
+
const schema = {
|
|
75
|
+
name: String,
|
|
76
|
+
age: Number,
|
|
77
|
+
city: String,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for await (const row of new Csv(csvData, {
|
|
81
|
+
shape: schema,
|
|
82
|
+
}).streamObjectsAsync()) {
|
|
83
|
+
console.log(row)
|
|
84
|
+
// TypeScript infers the type of `row` as:
|
|
85
|
+
// {
|
|
86
|
+
// name: string;
|
|
87
|
+
// age: number;
|
|
88
|
+
// city: string;
|
|
89
|
+
// }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Output:
|
|
93
|
+
// { name: 'Alice', age: 30, city: 'New York' }
|
|
94
|
+
// { name: 'Bob', age: 25, city: 'Los Angeles' }
|
|
95
|
+
// { name: 'Charlie', age: 35, city: 'Chicago' }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Object to CSV stringification example
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { Csv } from 'csv-stream-lite'
|
|
102
|
+
|
|
103
|
+
const data = [
|
|
104
|
+
{ name: 'Alice', age: 30, city: 'New York' },
|
|
105
|
+
{ name: 'Bob', age: 25, city: 'Los Angeles' },
|
|
106
|
+
{ name: 'Charlie', age: 35, city: 'Chicago' },
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
const csvString = Csv.stringifier(data).toString()
|
|
110
|
+
console.log(csvString)
|
|
111
|
+
|
|
112
|
+
// Output:
|
|
113
|
+
// name,age,city
|
|
114
|
+
// Alice,30,New York
|
|
115
|
+
// Bob,25,Los Angeles
|
|
116
|
+
// Charlie,35,Chicago
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Object to CSV stringification streaming example
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { Csv } from 'csv-stream-lite'
|
|
123
|
+
|
|
124
|
+
const data = [
|
|
125
|
+
{ name: 'Alice', age: 30, city: 'New York' },
|
|
126
|
+
{ name: 'Bob', age: 25, city: 'Los Angeles' },
|
|
127
|
+
{ name: 'Charlie', age: 35, city: 'Chicago' },
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
const csvStream = Csv.stringify(data)
|
|
131
|
+
for (const chunk of csvStream) {
|
|
132
|
+
process.stdout.write(chunk)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
process.stdout.write('\n')
|
|
136
|
+
|
|
137
|
+
// Output:
|
|
138
|
+
// name,age,city
|
|
139
|
+
// Alice,30,New York
|
|
140
|
+
// Bob,25,Los Angeles
|
|
141
|
+
// Charlie,35,Chicago
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Transforming parsed CSV data before further processing
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { Csv } from 'csv-stream-lite'
|
|
148
|
+
|
|
149
|
+
const csvData = `first_name,last_name,age
|
|
150
|
+
Alice,Smith,30
|
|
151
|
+
Bob,Johnson,25`
|
|
152
|
+
|
|
153
|
+
const csvStream = new Csv(csvData, {
|
|
154
|
+
transform: (record: {
|
|
155
|
+
first_name: string
|
|
156
|
+
last_name: string
|
|
157
|
+
age: string
|
|
158
|
+
}) => ({
|
|
159
|
+
fullName: `${record.first_name} ${record.last_name}`,
|
|
160
|
+
age: Number(record.age),
|
|
161
|
+
}),
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
for await (const row of csvStream.streamObjectsAsync()) {
|
|
165
|
+
console.log(row)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Output:
|
|
169
|
+
// { fullName: 'Alice Smith', age: 30 }
|
|
170
|
+
// { fullName: 'Bob Johnson', age: 25 }
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Transform CSV data during stringification
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { Csv } from 'csv-stream-lite'
|
|
177
|
+
|
|
178
|
+
const data = [
|
|
179
|
+
{ name: 'Alice', age: 30, city: 'New York' },
|
|
180
|
+
{ name: 'Bob', age: 25, city: 'Los Angeles' },
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
const csvStringifier = Csv.stringifier(data, {
|
|
184
|
+
transform: (row) => ({
|
|
185
|
+
fullName: row.name.toUpperCase(),
|
|
186
|
+
ageInFiveYears: row.age + 5,
|
|
187
|
+
city: row.city,
|
|
188
|
+
cityWithCountry: `${row.city}, USA`,
|
|
189
|
+
}),
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
console.log(csvStringifier.toString())
|
|
193
|
+
// Expected output:
|
|
194
|
+
// fullName,ageInFiveYears,city,cityWithCountry
|
|
195
|
+
// ALICE,35,New York,"New York, USA"
|
|
196
|
+
// BOB,30,Los Angeles,"Los Angeles, USA"
|
|
197
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jacob Shirley
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
**[Examples](./EXAMPLES.md)** | **[Documentation](https://jacobshirley.github.io/csv-stream-lite/v1)**
|
|
2
|
+
|
|
3
|
+
# csv-stream-lite
|
|
4
|
+
|
|
5
|
+
A lightweight, memory-efficient, zero-dependency streaming CSV parser and stringifier written in TypeScript. Process large CSV files without loading them entirely into memory.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/csv-stream-lite)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- 🚀 **Zero Dependencies** - No external dependencies
|
|
13
|
+
- 💪 **TypeScript First** - Written in TypeScript with full type safety
|
|
14
|
+
- 🌊 **Streaming Support** - Process large CSV files without loading them into memory
|
|
15
|
+
- ⚡ **High Performance** - Efficient byte-level parsing
|
|
16
|
+
- 🔄 **Dual Mode** - Both synchronous and asynchronous APIs
|
|
17
|
+
- 🌐 **Universal** - Works in Node.js and browser environments
|
|
18
|
+
- 📝 **Flexible** - Support for custom delimiters, escape characters, and transformers
|
|
19
|
+
- ✅ **Well Tested** - Comprehensive test coverage
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install csv-stream-lite
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add csv-stream-lite
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpm add csv-stream-lite
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### Parsing CSV
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { Csv } from 'csv-stream-lite'
|
|
41
|
+
|
|
42
|
+
// Parse CSV string
|
|
43
|
+
const csvData = `name,age,city
|
|
44
|
+
Alice,30,New York
|
|
45
|
+
Bob,25,Los Angeles`
|
|
46
|
+
|
|
47
|
+
const csv = new Csv(csvData, { readHeaders: true })
|
|
48
|
+
|
|
49
|
+
// Sync streaming
|
|
50
|
+
for (const row of csv.streamObjects()) {
|
|
51
|
+
console.log(row) // { name: 'Alice', age: '30', city: 'New York' }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Async streaming (for large files)
|
|
55
|
+
for await (const row of csv.streamObjectsAsync()) {
|
|
56
|
+
console.log(row)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Parsing with Type Transformers
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { Csv, CsvObjectShape } from 'csv-stream-lite'
|
|
64
|
+
|
|
65
|
+
interface User {
|
|
66
|
+
name: string
|
|
67
|
+
age: number
|
|
68
|
+
active: boolean
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const shape: CsvObjectShape<User> = {
|
|
72
|
+
name: String,
|
|
73
|
+
age: Number,
|
|
74
|
+
active: Boolean,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const csv = new Csv<User>(fileStream, { shape })
|
|
78
|
+
|
|
79
|
+
for await (const user of csv.streamObjectsAsync()) {
|
|
80
|
+
console.log(user.age) // Typed as number
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Stringifying to CSV
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Csv } from 'csv-stream-lite'
|
|
88
|
+
|
|
89
|
+
const data = [
|
|
90
|
+
{ name: 'Alice', age: 30, city: 'New York' },
|
|
91
|
+
{ name: 'Bob', age: 25, city: 'Los Angeles' },
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
// Sync
|
|
95
|
+
for (const chunk of Csv.stringify(data, { headers: ['name', 'age', 'city'] })) {
|
|
96
|
+
process.stdout.write(chunk)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Async
|
|
100
|
+
for await (const chunk of Csv.stringifyAsync(data)) {
|
|
101
|
+
process.stdout.write(chunk)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Or get complete string
|
|
105
|
+
const csvString = new CsvStringify(data).toString()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## API Documentation
|
|
109
|
+
|
|
110
|
+
Full API documentation is available at [https://jacobshirley.github.io/csv-stream-lite/v1](https://jacobshirley.github.io/csv-stream-lite/v1)
|
|
111
|
+
|
|
112
|
+
## Advanced Usage
|
|
113
|
+
|
|
114
|
+
### Reading from File Stream (Node.js)
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { createReadStream } from 'fs'
|
|
118
|
+
import { Csv } from 'csv-stream-lite'
|
|
119
|
+
|
|
120
|
+
const fileStream = createReadStream('large-file.csv')
|
|
121
|
+
|
|
122
|
+
const csv = new Csv(fileStream, { readHeaders: true })
|
|
123
|
+
|
|
124
|
+
for await (const row of csv.streamObjectsAsync()) {
|
|
125
|
+
// Process each row without loading entire file into memory
|
|
126
|
+
console.log(row)
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Custom Delimiters
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// Tab-separated values
|
|
134
|
+
const csv = new Csv(tsvData, {
|
|
135
|
+
separator: '\t',
|
|
136
|
+
readHeaders: true,
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// Semicolon-separated values
|
|
140
|
+
const csv = new Csv(csvData, {
|
|
141
|
+
separator: ';',
|
|
142
|
+
readHeaders: true,
|
|
143
|
+
})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Strict Column Validation
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { Csv, TooManyColumnsError, TooFewColumnsError } from 'csv-stream-lite'
|
|
150
|
+
|
|
151
|
+
const csvData = `name,age,city
|
|
152
|
+
Alice,30,New York
|
|
153
|
+
Bob,25,Los Angeles,ExtraColumn`
|
|
154
|
+
|
|
155
|
+
const csv = new Csv(csvData, {
|
|
156
|
+
headers: ['name', 'age', 'city'],
|
|
157
|
+
strictColumns: true, // Throws error if column count doesn't match
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
for await (const row of csv.streamObjectsAsync()) {
|
|
162
|
+
console.log(row)
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if (error instanceof TooManyColumnsError) {
|
|
166
|
+
console.error('Row has too many columns')
|
|
167
|
+
} else if (error instanceof TooFewColumnsError) {
|
|
168
|
+
console.error('Row has too few columns')
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Row Transformation
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const csv = new Csv(csvData, {
|
|
177
|
+
readHeaders: true,
|
|
178
|
+
transform: (row) => ({
|
|
179
|
+
...row,
|
|
180
|
+
fullName: `${row.firstName} ${row.lastName}`,
|
|
181
|
+
age: Number(row.age),
|
|
182
|
+
}),
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Writing to File Stream (Node.js)
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { createWriteStream } from 'fs'
|
|
190
|
+
import { CsvStringify } from 'csv-stream-lite'
|
|
191
|
+
|
|
192
|
+
const writeStream = createWriteStream('output.csv')
|
|
193
|
+
|
|
194
|
+
const data = [
|
|
195
|
+
{ name: 'Alice', age: 30 },
|
|
196
|
+
{ name: 'Bob', age: 25 },
|
|
197
|
+
]
|
|
198
|
+
|
|
199
|
+
const stringifier = new CsvStringify(data, {
|
|
200
|
+
headers: ['name', 'age'],
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
for await (const chunk of stringifier) {
|
|
204
|
+
writeStream.write(chunk)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
writeStream.end()
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Error Handling
|
|
211
|
+
|
|
212
|
+
The library provides specific error types for different scenarios:
|
|
213
|
+
|
|
214
|
+
- `CsvStreamLiteError` - Base error class
|
|
215
|
+
- `NoMoreTokensError` - Buffer is empty and more input is needed
|
|
216
|
+
- `EofReachedError` - End of file reached
|
|
217
|
+
- `BufferSizeExceededError` - Buffer size limit exceeded
|
|
218
|
+
- `TooManyColumnsError` - Row has more columns than expected (when `strictColumns: true`)
|
|
219
|
+
- `TooFewColumnsError` - Row has fewer columns than expected (when `strictColumns: true`)
|
|
220
|
+
|
|
221
|
+
## Performance
|
|
222
|
+
|
|
223
|
+
csv-stream-lite is designed for memory efficiency and high performance:
|
|
224
|
+
|
|
225
|
+
- **Streaming Architecture**: Process files of any size with constant memory usage
|
|
226
|
+
- **Lazy Evaluation**: Data is only parsed as it's consumed
|
|
227
|
+
- **Byte-Level Parsing**: Efficient low-level parsing without intermediate string allocations
|
|
228
|
+
- **Chunked Processing**: Configurable chunk sizes for optimal performance
|
|
229
|
+
|
|
230
|
+
## TypeScript Support
|
|
231
|
+
|
|
232
|
+
Full TypeScript support with comprehensive type definitions:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { Csv, CsvObjectShape } from 'csv-stream-lite'
|
|
236
|
+
|
|
237
|
+
interface User {
|
|
238
|
+
id: number
|
|
239
|
+
name: string
|
|
240
|
+
email: string
|
|
241
|
+
active: boolean
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const shape: CsvObjectShape<User> = {
|
|
245
|
+
id: Number,
|
|
246
|
+
name: String,
|
|
247
|
+
email: String,
|
|
248
|
+
active: Boolean,
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const csv = new Csv<User>(data, { shape })
|
|
252
|
+
|
|
253
|
+
// Type-safe iteration
|
|
254
|
+
for await (const user of csv.streamObjectsAsync()) {
|
|
255
|
+
console.log(user.id) // TypeScript knows this is a number
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Browser Support
|
|
260
|
+
|
|
261
|
+
csv-stream-lite works in modern browsers with support for:
|
|
262
|
+
|
|
263
|
+
- `ReadableStream` API
|
|
264
|
+
- `AsyncIterable` protocol
|
|
265
|
+
- ES2018+ features
|
|
266
|
+
|
|
267
|
+
## Contributing
|
|
268
|
+
|
|
269
|
+
Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT © [Jacob Shirley](https://github.com/jacobshirley)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { ByteStream, StreamInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A buffer for managing byte-level input with support for async streams.
|
|
4
|
+
* Provides lookahead, consumption tracking, and buffer compaction capabilities.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ByteBuffer {
|
|
7
|
+
/** Maximum size of the buffer before compaction */
|
|
8
|
+
maxBufferSize: number;
|
|
9
|
+
/** Whether end of file has been signaled */
|
|
10
|
+
eof: boolean;
|
|
11
|
+
/** Current position in the buffer */
|
|
12
|
+
bufferIndex: number;
|
|
13
|
+
/** Whether the buffer is locked against compaction */
|
|
14
|
+
locked: boolean;
|
|
15
|
+
/** Whether to allow exceeding the buffer size temporarily */
|
|
16
|
+
allowBufferToBeExceeded: boolean;
|
|
17
|
+
/** Current position in the input stream */
|
|
18
|
+
protected inputOffset: number;
|
|
19
|
+
/** Number of outputs generated */
|
|
20
|
+
protected outputOffset: number;
|
|
21
|
+
/** Buffer holding input items */
|
|
22
|
+
protected buffer: number[];
|
|
23
|
+
/** Optional async iterable input source */
|
|
24
|
+
protected asyncIterable?: ByteStream;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new ByteBuffer instance.
|
|
27
|
+
*
|
|
28
|
+
* @param asyncIterable - Optional async iterable source for streaming input
|
|
29
|
+
*/
|
|
30
|
+
constructor(asyncIterable?: ByteStream);
|
|
31
|
+
/**
|
|
32
|
+
* Reads data from the stream into the buffer.
|
|
33
|
+
* Reads up to maxBufferSize bytes at a time.
|
|
34
|
+
*/
|
|
35
|
+
readStream(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Reads data from the sync or async stream into the buffer.
|
|
38
|
+
* Reads up to maxBufferSize bytes at a time.
|
|
39
|
+
*/
|
|
40
|
+
readStreamAsync(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the current length of the buffer.
|
|
43
|
+
*
|
|
44
|
+
* @returns The number of bytes in the buffer
|
|
45
|
+
*/
|
|
46
|
+
get length(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Feeds input items into the parser buffer.
|
|
49
|
+
*
|
|
50
|
+
* @param input - Input items to add to the buffer
|
|
51
|
+
*/
|
|
52
|
+
feed(...input: StreamInput[]): void;
|
|
53
|
+
push(byte: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Checks if end of file has been reached and buffer is exhausted.
|
|
56
|
+
*
|
|
57
|
+
* @returns True if no more input is available
|
|
58
|
+
*/
|
|
59
|
+
atEof(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Peeks at an item in the buffer without consuming it.
|
|
62
|
+
*
|
|
63
|
+
* @param ahead - Number of positions to look ahead (default: 0)
|
|
64
|
+
* @returns The item at the peek position, or null if at EOF
|
|
65
|
+
* @throws NoMoreTokensError if more input is needed and EOF not signaled
|
|
66
|
+
*/
|
|
67
|
+
peek(ahead?: number): number | null;
|
|
68
|
+
/**
|
|
69
|
+
* Consumes and returns the next item from the buffer.
|
|
70
|
+
*
|
|
71
|
+
* @returns The next item
|
|
72
|
+
* @throws NoMoreTokensError if more input is needed and EOF not signaled
|
|
73
|
+
* @throws EofReachedError if at EOF and no more items available
|
|
74
|
+
*/
|
|
75
|
+
next(): number;
|
|
76
|
+
/**
|
|
77
|
+
* Consumes and validates the next item against an expected type or value.
|
|
78
|
+
*
|
|
79
|
+
* @typeParam T - The expected item type
|
|
80
|
+
* @param itemType - Constructor or value to match against
|
|
81
|
+
* @returns The consumed item cast to the expected type
|
|
82
|
+
* @throws Error if the item doesn't match the expected type/value
|
|
83
|
+
*/
|
|
84
|
+
expect<T extends number>(itemType: T): T;
|
|
85
|
+
/**
|
|
86
|
+
* Compacts the buffer by removing consumed items
|
|
87
|
+
*/
|
|
88
|
+
compact(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Override to customize when to compact the buffer
|
|
91
|
+
* By default, compacts when more than maxBufferSize bytes have been consumed
|
|
92
|
+
*
|
|
93
|
+
* @returns boolean indicating whether to compact the buffer
|
|
94
|
+
*/
|
|
95
|
+
canCompact(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Attempts to execute a function, resetting buffer position on failure.
|
|
98
|
+
* Useful for speculative parsing attempts that may need to be retried.
|
|
99
|
+
*
|
|
100
|
+
* @typeParam T - The return type of the try function
|
|
101
|
+
* @param tryFn - Function to attempt execution
|
|
102
|
+
* @param onFail - Optional callback invoked on failure
|
|
103
|
+
* @returns The result of tryFn if successful, undefined if NoMoreTokensError thrown
|
|
104
|
+
*/
|
|
105
|
+
resetOnFail<T>(tryFn: () => T, onFail?: (e: Error) => void): T | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Returns a string representation of the buffer state for debugging.
|
|
108
|
+
*
|
|
109
|
+
* @returns A formatted string showing buffer contents and state
|
|
110
|
+
*/
|
|
111
|
+
toString(): string;
|
|
112
|
+
}
|