Documentation Index
Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
Use this file to discover all available pages before exploring further.
Bun 内置支持解析 JSONL(换行分隔的 JSON),每一行都是一个独立的 JSON 值。该解析器使用 JavaScriptCore 优化的 JSON 解析器在 C++ 中实现,支持流式场景。
const results = Bun.JSONL.parse('{"name":"Alice"}\n{"name":"Bob"}\n');
// [{ name: "Alice" }, { name: "Bob" }]
Bun.JSONL.parse()
解析完整的 JSONL 输入并返回所有解析值的数组。
import { JSONL } from "bun";
const input = '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n{"id":3,"name":"Charlie"}\n';
const records = JSONL.parse(input);
console.log(records);
// [
// { id: 1, name: "Alice" },
// { id: 2, name: "Bob" },
// { id: 3, name: "Charlie" }
// ]
输入可以是字符串或 Uint8Array:
const buffer = new TextEncoder().encode('{"a":1}\n{"b":2}\n');
const results = Bun.JSONL.parse(buffer);
// [{ a: 1 }, { b: 2 }]
当传入 Uint8Array 时,缓冲区开头的 UTF-8 BOM 会被自动跳过。
错误处理
如果输入包含无效 JSON,Bun.JSONL.parse() 会抛出 SyntaxError:
try {
Bun.JSONL.parse('{"valid":true}\n{invalid}\n');
} catch (error) {
console.error(error); // SyntaxError: Failed to parse JSONL
}
Bun.JSONL.parseChunk()
对于流式场景,parseChunk 尽可能从输入中解析完整值并报告解析进度。当数据逐步接收(例如网络流)时,知道从何处继续解析很有用。
const chunk = '{"id":1}\n{"id":2}\n{"id":3';
const result = Bun.JSONL.parseChunk(chunk);
console.log(result.values); // [{ id: 1 }, { id: 2 }]
console.log(result.read); // 17 — 已消费字符数
console.log(result.done); // false — 仍有不完整的值
console.log(result.error); // null — 无解析错误
返回值
parseChunk 返回一个包含四个属性的对象:
| 属性 | 类型 | 说明 |
|---|
values | any[] | 成功解析的 JSON 值数组 |
read | number | 消耗的字节数(Uint8Array)或字符数(字符串) |
done | boolean | 如果整个输入被完全消费且无剩余数据,值为 true |
error | SyntaxError | null | 解析错误,若无错误则为 null |
流式示例
使用 read 截取已消耗输入,剩余部分继续传递:
let buffer = "";
async function processStream(stream: ReadableStream<string>) {
for await (const chunk of stream) {
buffer += chunk;
const result = Bun.JSONL.parseChunk(buffer);
for (const value of result.values) {
handleRecord(value);
}
// 保留未消费部分
buffer = buffer.slice(result.read);
}
// 处理剩余数据
if (buffer.length > 0) {
const final = Bun.JSONL.parseChunk(buffer);
for (const value of final.values) {
handleRecord(value);
}
if (final.error) {
console.error("最终数据块解析错误:", final.error.message);
}
}
}
使用 Uint8Array 的字节偏移
当输入为 Uint8Array 时,可以传入可选的起始和结束字节偏移:
const buf = new TextEncoder().encode('{"a":1}\n{"b":2}\n{"c":3}\n');
// 从字节 8 开始解析
const result = Bun.JSONL.parseChunk(buf, 8);
console.log(result.values); // [{ b: 2 }, { c: 3 }]
console.log(result.read); // 24
// 解析特定范围
const partial = Bun.JSONL.parseChunk(buf, 0, 8);
console.log(partial.values); // [{ a: 1 }]
The read value is always a byte offset into the original buffer. Use it with TypedArray.subarray() for zero-copy streaming:
let buf = new Uint8Array(0);
async function processBinaryStream(stream: ReadableStream<Uint8Array>) {
for await (const chunk of stream) {
// 追加 chunk 到缓冲区
const newBuf = new Uint8Array(buf.length + chunk.length);
newBuf.set(buf);
newBuf.set(chunk, buf.length);
buf = newBuf;
const result = Bun.JSONL.parseChunk(buf);
for (const value of result.values) {
handleRecord(value);
}
// 保留未消费的字节
buf = buf.slice(result.read);
}
}
错误恢复
与 parse() 不同,parseChunk() 遇到无效 JSON 不抛出异常,而是通过返回的 error 属性提供错误信息,同时返回错误前成功解析的所有值:
const input = '{"a":1}\n{invalid}\n{"b":2}\n';
const result = Bun.JSONL.parseChunk(input);
console.log(result.values); // [{ a: 1 }] — 错误前解析的值
console.log(result.error); // SyntaxError
console.log(result.read); // 7 — 最后成功解析的位置
支持的值类型
每一行可以是任意有效的 JSON 值,而不仅限于对象:
const input = '42\n"hello"\ntrue\nnull\n[1,2,3]\n{"key":"value"}\n';
const values = Bun.JSONL.parse(input);
// [42, "hello", true, null, [1, 2, 3], { key: "value" }]
性能说明
- ASCII 快速通道:纯 ASCII 输入直接解析,无需复制,使用零分配的
StringView。
- UTF-8 支持:非 ASCII 的
Uint8Array 输入通过 SIMD 加速转换为 UTF-16。
- BOM 处理:
Uint8Array 开头的 UTF-8 BOM(0xEF 0xBB 0xBF)自动跳过。
- 预构建对象形状:
parseChunk 返回的结果对象使用缓存结构,提高属性访问速度。