@claudewerk/envelope-codec

中文文档
0.2.1发布于 2026/10/27MITTypeScriptES Module零依赖近 30 天下载 1862

{env, body?} 纯编码/解码码码 。 信封为通道编码(JSON或CBOR);正文为不透明的octets通过字节来表示字节.

中文使用文档
文档目录13 节
  1. 它所支持的东西
  2. 安装
  3. 使用量
  4. 编码接口
  5. 线条格式
  6. JSON频道(强制性基线)
  7. CBOR频道(RFC 8949,可选)
  8. 二元框架歧视者(1字节)
  9. 硬化解码( 不信任输入)
  10. 通过模式
  11. 谈判
  12. 日志
  13. 许可证

信封编码c

形状信件的独立、无依赖的编码器 { env, body? }。 。 。 .

整个问题:信息是 信封 (结构路由/控制) 元数据)加一 任择机构 (opaque octets) (英语). 编码器只编码 频道编码中的信封 身体通过字节表示 从未解码或检查这就是让尸体成为编码的原因,或者 已封存/ 加密, 编码器费用为零 .

它对WebSockets,队列,或运输一无所知. 这是纯洁的 encode编号 :decode 双人 这个 Codec 形状是鸭子类型,与什么兼容 可靠连接的运输预期—— 但这里没有输入这样的库.

  • 运行时间道克:0. cbor-x 财务报告和审定财务报表 pino 是可选的同伴依赖关系, 懒得说 软件包完全没有安装(只有JSON).
  • 阿宝 (单位:千美元)bun test, (中文(简体) ), bun 运行时间).

它所支持的东西

执行和涵盖以下所有项目: bun test (51个测试):

  • 信封的两个信道编码 - JSON(强制基线,UTF-8) JSON文本)和CBOR(RFC 8949,通过 cbor-x) (中文(简体) ).
  • 不透明体,字节取出. JSON携带一具小身体作为基座64或, 带外模式,作为长度/contentType 仅标出文字. CBOR 载有 作为二进制正体 本地未标记的字节字符串 - 无 base64 税解码 返回每个模式中的确切输入八分点;解码器从不剖析正文.
  • 1字节二进制歧视者 (单位:千美元)0x01 信封数 / 0x02 原始块, ,在任何登记册之前解决 解码后接收器就不再试镜了.
  • 通过模式 - 将一个任意的不透明框架包裹为下体 默认信封,因此解码器可以备份原始字节的传输.
  • 未信任输入的硬化解码 -- 解码前的大小盖,最大巢穴 深度、 最大收藏大小、 重复键拒绝和 (CBOR) 拒绝 无限期长度和标记(无标记->类即时). 每一次失败都是 类型 CodecError从不漏出一掷一绞.
  • 编码谈判 优先排序和版本意识;对等者 当地不同的订单仍然一致,没有往返.
  • 可注入式记录 - 默认沉默; console 或可选 pino。 。 。 .

安装

bun add @claudewerk/envelope-codec
bun add cbor-x   # optional: enables the CBOR channel
bun add pino     # optional: structured logging

使用量

import { jsonCodec, cborCodec, negotiate, codecFor } from '@claudewerk/envelope-codec';

const enc = negotiate(['cbor', 'json'], theirAdvertised); // 'cbor' | 'json'
const codec = codecFor(enc);

const wire = codec.encode({
  env: { to: 'node-7', kind: 'sync', seq: 9 },
  body: new Uint8Array([0xde, 0xad, 0xbe, 0xef]), // opaque octets
  contentType: 'application/octet-stream',
});

const msg = codec.decode(wire);
// msg.env  -> { to: 'node-7', kind: 'sync', seq: 9 }   (opaque object, not interpreted)
// msg.body -> Uint8Array [0xde,0xad,0xbe,0xef]          (exact input bytes, untouched)
// msg.contentType -> 'application/octet-stream'

编码接口

interface Codec {
  encoding: 'json' | 'cbor';
  encode(msg: { env: object; body?: Uint8Array; contentType?: string }): Uint8Array | string;
  decode(data: Uint8Array | string): { env: object; body?: Uint8Array; contentType?: string; bodyBytes?: number };
}

jsonCodec(opts?): Codec;
cborCodec(opts?): Codec;   // throws CodecError('CBOR_UNAVAILABLE') if cbor-x is absent
negotiate(ours: string[], theirs: string[]): 'json' | 'cbor';
codecFor(encoding, opts?): Codec;

选项( 双解码器 ) : { maxBytes, limits: { maxDepth, maxItems }, log, passthrough }。 。 。 . jsonCodec 还要 { oob } (出带正文下.

单位 通过模式 (单位:千美元)passthrough: true(中文(简体) ) encode() 也接受原始数据 Uint8Array。见 通过模式。 。 。 .

线条格式

这个 env 是不透明的 -- 解码器从不读取其字段。 两个频道串行 同一个带密钥的逻辑线对象 env选项 contentType,则 每个频道携带的可选身体不同.

JSON频道(强制性基线)

信封是UTF-8 JSON文本:

{
  "env": { "...": "..." },
  "contentType": "application/octet-stream",
  "body": "<base64 of the opaque body>"
}

二进制车身内置为 基础64 下级 body基数64 绕行 精确的octets,所以解码还原它们不变;字节从不解析.

带外模式 (单位:千美元)jsonCodec({ oob: true }): 无字节被内嵌; 只有 a 描述器被放出,身体在侧道上行走.

{ "env": { "...": "..." }, "contentType": "video/mp4", "bodyBytes": 1048576 }

解码后返回 { env, contentType, bodyBytes } 没有 body。 。 。 .

CBOR频道(RFC 8949,可选)

这个信封是CBOR 地图二进制是 本地 CBOR 字节字符串 (主要类型2)- 无基数64税数字 :

map(2) {
  "env"  => map(...)      ; the opaque envelope
  "body" => bytes(N)      ; major type 2, untagged -- the opaque body
}
; "contentType" => text   ; present when set

字节字符串未标记( 标题) 0x40 | len),所以是一个平地字节 字符串,不是标记/类型阵列值.

二元框架歧视者(1字节)

在二进制模式( CBOR) 中, 调用者可以将信封信息与原始不透明连接开 块(如批量转移)。 单人 首字节 区分它们和它们 在任何解码前都解决了,所以接收者从来不是试验方:

歧视登记 (由此软件包所拥有; 编组协议必须 )),在其中停留. 此编码器只释放和消耗 0x01编号 :0x02;其余为: 保留这样高的地层可以添加帧而无需再重新指派这两个.

字节类含义
0x00保留永远不要发射
0x01信封编码 { env, body? }
0x02块原始/不公开字节,从未解码
0x03..0x0f控制为协议控制框架保留
0x10..0xff应用程序应用程序定义

frameType(bytes) 路径中只有此编码器拥有的两个字节( 返回) 'envelope'编号 :'chunk'掷出 BAD_FRAME (否则). frameClass(byte) 对照登记册对任意字节进行分类(reserved编号 :envelope编号 :chunk编号 : control编号 :application)为高层自有路由.

import { framed, frameType, encodeChunk, decodeChunk } from '@claudewerk/envelope-codec';

const codec = framed(cborCodec());     // encode() now prepends 0x01
const wire = codec.encode({ env, body });

// receiver: route on the discriminator, THEN decode -- no trial parse
switch (frameType(wire)) {
  case 'envelope': return codec.decode(wire);
  case 'chunk':    return handleRaw(decodeChunk(wire));
}

设计说明:Spec说"把它作为选择". frameType() + 键 framed() 是一个刻意的改进 -- -- 歧视者必须解决 解码前的接收器,解码时间选项无法做到这一点 已经承诺进行剖析。 因此,跑步是一个单独的,预解码步骤.

硬化解码( 不信任输入)

每条解码路径都会执行限制,并将任何失败变为已键入 CodecError (从不漏出一掷一吊):

警卫贾森边境保护局CodecError.code
解码前的大小封顶✓✓TOO_LARGE
最大筑巢深度✓✓TOO_DEEP
每集最大项✓✓TOO_MANY_ITEMS
重复密钥被拒绝✓✓DUP_KEY
无限期拒绝- 说吧✓INDEFINITE_LENGTH
标记被拒绝( 无类 )- 说吧✓UNSUPPORTED
输入格式错误✓✓MALFORMED

CBOR输入在结构上被手写通行证所扫描(cbor-scan.js在此之前 cbor-x 所以任何攻击者控制的形状 都不会被瞬间改变 标记地图到类。 JSON是扫描之前 JSON.parse 捕捉深度和 复制密钥, 哪个 JSON.parse 一个人不能.

默认 : maxBytes = 16 MiB, (中文(简体) ), maxDepth = 64, (中文(简体) ), maxItems = 100000通过 页:1 limits 编号 : maxBytes 选项.

通过模式

支持框架为 ARBIRARY 字节的运输( 尚未) { env, body }),启用 passthrough。 。 。 . encode() 并接受一个原始的 Uint8Array 把它包成一个默认的封口,所以不要 每个相框必须是一个信封才能流出解码器.

const codec = cborCodec({ passthrough: true });        // or an env object: { passthrough: { src: 'transport' } }

codec.encode(new Uint8Array([1, 2, 3]));               // -> encodes { env: {}, body: <those bytes> }
codec.encode({ env: { k: 1 }, body });                 // normal messages still work

const { env, body } = codec.decode(wire);              // body is the exact opaque frame back

无 passthrough,将原始字节输入 encode() 是一个 CodecError (单位:千美元)MALFORMED() -- 需要发送信息.

谈判

优先排序和版本意识,所以两个对等者与 不同当地 订单仍然同意 不往返。 。 。 .

negotiate(ours, theirs) // -> 'json' | 'cbor'
  • 光学 PREFERENCE = ['cbor', 'json'] (最受欢迎的先) 此软件包并导出.
  • 广告编码是道具 name[/version] (例如:. 'cbor/1'; 匹配为 以 名称。 。 。 .
  • 结果 = 首名 PREFERENCE 双方广告, 提供量cbor 只有在 cbor-x 这里有 oper dep .
  • JSON是永远可以利用的后退.
negotiate(['json', 'cbor'], ['cbor', 'json']) // -> 'cbor'  (order-independent)
negotiate(['cbor/1'],       ['cbor/2'])       // -> 'cbor'  (version-agnostic match)
negotiate(['cbor'],         ['json'])         // -> 'json'

日志

可注射 Logger (单位:千美元)debug/info/warn/error;默认沉默. consoleLogger 财务报告和审定财务报表 pinoLogger() (懒惰,可选) pino页:1 将任何对象与 四种方法为: { log }。 。 。 .

许可证

麻省理工学院

版本与发布记录

@claudewerk/envelope-codec 共发布 3 个版本,首次发布于 2026/09/28;过去 12 个月发布了 3 个版本。

版本发布日期距今
0.2.1latest2026/10/2713 天前
0.2.02026/09/281 个月前
0.1.02026/09/281 个月前

关于 @claudewerk/envelope-codec 的常见问题

@claudewerk/envelope-codec 是什么?

{env, body?} 纯编码/解码码码 。 信封为通道编码(JSON或CBOR);正文为不透明的octets通过字节来表示字节.

如何安装 @claudewerk/envelope-codec?

在项目目录运行 npm install @claudewerk/envelope-codec,或使用 pnpm add / yarn add / bun add。

@claudewerk/envelope-codec 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@claudewerk/envelope-codec 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@claudewerk/envelope-codec 可以商用吗?

@claudewerk/envelope-codec 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@claudewerk/envelope-codec 的下载量有多少?

根据 npm 官方下载统计,@claudewerk/envelope-codec 在 2026/10/10 – 2026/11/08 这 30 天内被下载 1,862 次,日均约 62 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@claudewerk/envelope-codec 还在维护吗?

最新版本 0.2.1 发布于 2026/10/27(13 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/09/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。