npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kaigejiabengle/safe-json-stream

v0.1.1

Published

Serialize arbitrarily large or deeply-nested JSON without RangeError / stack overflow, via streaming generators and Node streams.

Downloads

258

Readme

safe-json-stream

任意超大 / 超深嵌套的 JSON 对象序列化成字符串,不会抛出 RangeError: Invalid string lengthMaximum call stack size exceeded

JSON.stringify({}) 没问题,但在生产环境里你传入的往往不是 {}——而是一个 涨到几 MB 的响应、一个有几十万项的数组、或一个嵌套了几千层的对象。到那个 量级,JSON.stringify 要么试图构建一根比 V8 上限还长的字符串,要么递归深度 超过了 JS 调用栈,然后进程就挂了。

本包用增量方式序列化同样的数据:

  • jsonChunks(value) —— 生成器,把 JSON 拆成一串字符串片段逐个产出(绝 不会先攒成一根巨型字符串)。
  • createReadable(value) —— 基于该生成器的 Node Readable,自带背压 (back-pressure)。
  • streamify(value, writable) —— 直接管道接到文件 / HTTP 响应,返回一个 Promise
  • stringify(value) —— 便捷方法,返回一整根字符串(仅建议用于中等规模数据)。

它用的是显式栈而不是递归调用,所以嵌套深度不受限,且内存只占用"当前片段 + 打开中的帧",而不是整个序列化结果。

安装

npm install @kaigejiabengle/safe-json-stream

本地开发时也可指向本地构建产物:npm install /path/to/safe-json-stream

用法

流式写入文件(处理超大数据的推荐方式)

const fs = require('node:fs');
const { streamify } = require('@kaigejiabengle/safe-json-stream');

await streamify(hugeData, fs.createWriteStream('out.json'));

流式写回 HTTP 响应(Express / 原生 http)

const { createReadable } = require('@kaigejiabengle/safe-json-stream');

app.get('/export', (req, res) => {
  res.setHeader('Content-Type', 'application/json');
  createReadable(hugeData).pipe(res);
});

ESM

import { streamify } from '@kaigejiabengle/safe-json-stream';

await streamify(hugeData, fs.createWriteStream('out.json'));

自己逐片段迭代

const { jsonChunks } = require('@kaigejiabengle/safe-json-stream');

for (const chunk of jsonChunks(data)) {
  process.stdout.write(chunk);
}

API

| 导出 | 说明 | | --- | --- | | jsonChunks(value) | Generator<string>,逐段产出 JSON 片段。 | | createReadable(value, options?) | 产出字符串片段的 Readable(带背压)。 | | streamify(value, writable) | Promise<void>;完成时 resolve,出错时 reject。 | | stringify(value) | string;便捷方法,会完整物化整根字符串——极端规模时避免使用。 |

行为说明

在合理范围内与 JSON.stringify 语义保持一致:

  • undefined / 函数 / symbol → null;对象里的 undefined 属性会被省略 (和 JSON.stringify 完全一致)。
  • NaN / Infinitynull
  • Date 以及任何带 toJSON() 的对象,会走其 toJSON() 序列化。
  • 循环引用会被替换成字符串 "[Circular]",而不是崩溃,因此序列化总能终止。
  • BigInt 会抛 TypeError(和 JSON.stringify 一样)。

设计上的差异:

  • 字符串不会被进一步切小(你已确认字符串本身都是安全的);只有整体结构是 流式产出的。
  • 输出是完整数据——不做任何截断。需要保留每一层时使用它。

该选哪个

| 你的需求… | 用 | | --- | --- | | 把海量数据写入磁盘 / 网络而不崩溃 | streamify / createReadable | | 自己手动逐片段处理 | jsonChunks | | 要一根普通字符串,且数据量中等 | stringify | | 丢掉深层部分、只要小体积(日志 / 调试) | 改用带深度限制的 JSON.stringify replacer |

从源码构建

本包用 TypeScript(src/index.ts)编写,编译为发布用的 dist/ 产物。你只需 修改 src/index.ts 一处即可。

npm install        # devDependencies: typescript, @types/node
npm run build      # src/index.ts -> dist/cjs (CJS + d.ts) 与 dist/esm (ESM)
npm test           # 先 build,再运行 node:test 测试套件

发布产物(均在 dist/ 下,dist/ 为 gitignore 的构建产物):

  • dist/cjs/index.js —— CommonJS 入口(main / require
  • dist/esm/index.js —— ESM 入口(module / import),通过 dist/esm/package.json 标记为 ESM
  • dist/cjs/index.d.ts —— 类型声明(types

dist/ 由构建脚本生成、不纳入版本管理(见 .gitignore)。根目录 package.jsonfiles 字段只打包 dist/

许可证

MIT