> ## Documentation Index
> Fetch the complete documentation index at: https://bun.ll1025.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# JSONL

> 使用 Bun 内置的流式解析器解析换行符分隔的 JSON（JSONL）

Bun 内置了对解析 [JSONL](https://jsonlines.org/)（换行符分隔的 JSON）的支持，其中每行是一个独立的 JSON 值。解析器使用 C++ 实现，利用了 JavaScriptCore 优化的 JSON 解析器，并支持流式处理。

```ts theme={null}
const results = Bun.JSONL.parse('{"name":"Alice"}\n{"name":"Bob"}\n');
// [{ name: "Alice" }, { name: "Bob" }]
```

***

## `Bun.JSONL.parse()`

解析完整的 JSONL 输入并返回所有解析值的数组。

```ts theme={null}
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`：

```ts theme={null}
const buffer = new TextEncoder().encode('{"a":1}\n{"b":2}\n');
const results = Bun.JSONL.parse(buffer);
// [{ a: 1 }, { b: 2 }]
```

对于 `Uint8Array` 输入，Bun 会跳过缓冲区开头的 UTF-8 BOM。

### 错误处理

如果输入包含无效 JSON 且没有成功解析任何值，`Bun.JSONL.parse()` 会抛出 `SyntaxError`。如果在错误发生前至少解析了一个值，则返回已解析的值而不抛出异常。

```ts theme={null}
try {
  Bun.JSONL.parse("{invalid}\n");
} catch (error) {
  console.error(error); // SyntaxError: Failed to parse JSONL
}
```

***

## `Bun.JSONL.parseChunk()`

对于流式处理，`parseChunk` 解析输入中尽可能多的完整值，并报告已处理的位置，因此当数据增量到达时（例如，来自网络流），您可以知道从哪里继续处理。

```ts theme={null}
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` 切掉已消耗的输入并保留剩余部分：

```ts theme={null}
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("Parse error in final chunk:", final.error.message);
    }
  }
}
```

### 使用 `Uint8Array` 的字节偏移量

当输入是 `Uint8Array` 时，您可以传递可选的 `start` 和 `end` 字节偏移量：

```ts theme={null}
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); // 23

// 解析特定范围
const partial = Bun.JSONL.parseChunk(buf, 0, 8);
console.log(partial.values); // [{ a: 1 }]
```

`read` 值始终是原始缓冲区中的字节偏移量。结合 `TypedArray.subarray()` 使用可实现零拷贝流式处理：

```ts theme={null}
let buf = new Uint8Array(0);

async function processBinaryStream(stream: ReadableStream<Uint8Array>) {
  for await (const chunk of stream) {
    // 将块追加到缓冲区
    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` 属性中返回错误，同时返回错误之前成功解析的任何值：

```ts theme={null}
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 值，而不仅仅是对象：

```ts theme={null}
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` 的结果对象使用缓存结构以实现快速属性访问。
