其他
需要对大型 JSON 形态数据做随机读取和免解析查询时,用…
把 JSON 形态数据编码为 RX 文本或 Uint8Array,之后原地随机访问,减少解析和 GC 开销。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 58/100 ×0.15
适用场景
需要对大型 JSON 形态数据做随机读取特定
解决思路
- 安装 RX 库:`npm install @creationix/rx`。
- 全局安装 RX CLI:`npm install -g @creationix/rx`。
- 一次性运行 CLI:`npx @creationix/rx data.rx`。
- 使用字符串 API 编码:`import { stringify, parse } from '@creationix/rx'`;`const rx = stringify({ users: ['alice', 'bob'], version: 3 })`;返回字符串,可存到任何存 JSON 文本的地方。
- 使用字符串 API 解码与读取:`const data = parse(rx) as any`;`data.users[0]` 得到 `'alice'`;`data.version` 得到 `3`;`Object.keys(data)` 得到 `['users', 'version']`;`JSON.stringify(data)` 可用,支持完整 JS 互操作。
- 使用 Uint8Array API:`import { encode, open } from '@creationix/rx'`;`const buf = encode({ path: '/api/users', status: 200 })`;`const data = open(buf) as any`;`data.path` 得到 `'/api/users'`;`data.status` 得到 `200`。
- 使用 Inspect API 惰性 AST:`import { encode, inspect } from '@creationix/rx'`;`const buf = encode({ name: 'alice', scores: [10, 20, 30] })`;`const root = inspect(buf)`;读取 `root.tag`、`root[0].tag`、`root[0].value`、`root.length`(key、value、key、value 共 4)。
- Inspect API 遍历子节点:`for (const child of root) { console.log(child.tag, child.b64); }`。
- Inspect API 对象辅助遍历:`for (const [key, val] of root.entries()) { /* ... */ }`。
- Inspect API 查找节点:`const node = root.index('name')` 按键查找;`const elem = root.index(2)` 按数组索引查找。
- Inspect API 过滤键搜索:`for (const [key, val] of root.filteredKeys('/api/')) { /* ... */ }`;在已索引对象上为 O(log n + m)。
- 使用底层 buffer 逃生口:`import { handle } from '@creationix/rx'`;`const h = handle(data.nested)`;`h.data` 是 `Uint8Array`;`h.right` 是字节偏移。
- 编码选项 indexes:`stringify(data, { indexes: 10 })` 或 `encode(data, { indexes: 10 })`;为 >= N 个条目的容器添加排序索引以启用 O(log n) 查找;`0` 表示所有容器,`false` 表示完全禁用。
- 编码选项 refs:`stringify(data, { refs: { R: ['/api/users', '/api/teams'] } })` 或 `encode(data, { refs: { R: ['/api/users', '/api/teams'] } })`;提供已知值共享字典,用于跨文档去重。
- 编码选项 onChunk:`stringify(data, { onChunk: (chunk: string, offset: number) => process.stdout.write(chunk) })`;对 `encode` 用 `onChunk: (chunk: Uint8Array, offset: number) => { /* ... */ }`;在产生数据时接收分块。
- 解码时匹配外部 refs:如果编码器用了外部 refs,则 `const data = parse(payload, { refs: { R: ['/api/users', '/api/teams'] } })` 或 `const data = open(buf, { refs: { R: ['/api/users', '/api/teams'] } })`;必须传入相同字典。
- CLI 默认树状打印:`rx data.rx`(TTY 默认按树状输出)。
- CLI 转 JSON:`rx data.rx -j`。
- CLI 转 RX:`rx data.json -r`。
- CLI 从 stdin 读取:`cat data.rx | rx`;自动检测格式。
- CLI 选择子值:`rx data.rx -s key 0 sub`,等价于 `data['key'][0]['sub']`。
- CLI 写入文件:`rx data.rx -o out.json`。
- CLI 输出编码结构:`rx data.rx --ast`。
- CLI 写回转换文件:`rx data.rx -w`(.json↔.rx)。
- CLI flag `<file>`:输入文件,格式自动检测。
- CLI flag `-`:显式从 stdin 读取。
- CLI flag `-j`/`--json`:输出为 JSON。
- CLI flag `-r`/`--rexc`:输出为 RX。
- CLI flag `-t`/`--tree`:输出为树。
- CLI flag `-a`/`--ast`:输出编码结构。
- CLI flag `-s`/`--select <seg>...`:按路径段选择子值。
- CLI flag `-w`/`--write`:写入转换后的文件。
- CLI flag `-o`/`--out <path>`:写入指定文件而非 stdout。
- CLI flag `-c`/`--color` 或 `--no-color`:强制或禁用 ANSI 颜色。
- CLI flag `--index-threshold <n>`:索引超过 n 个值的容器,默认 16。
- CLI flag `--string-chain-threshold <n>`:拆分长于 n 的字符串,默认 64。
- CLI flag `--string-chain-delimiter <s>`:字符串链分隔符,默认 `/`。
- CLI flag `--key-complexity-threshold <n>`:去重键允许的最大对象复杂度,默认 100。
- 配置 shell 补全:`rx --completions setup zsh` 或 `rx --completions setup bash`。
- 分页彩色查看提示:定义 `p() { rx "$1" -t -c | less -RFX; }`,然后用它查看。
- 理解 Proxy 只读行为:`obj.newKey = 1` 会抛 TypeError;`delete obj.key` 会抛 TypeError;`'key' in obj` 可用且零分配键搜索;`obj.nested === obj.nested` 为 true,因为容器 Proxy 有记忆化。
- 使用 Proxy 支持的操作:属性访问 `data.key`、`data[0]`;`Object.keys()`、`Object.entries()`、`Object.values()`;`for...of`、`for...in`;`Array.isArray()`;`.map()`、`.filter()`、`.find()`、`.reduce()`;展开与解构;`JSON.stringify()`。
- 构建期模式:把 JSON 产物转成 RX:`import { readFileSync, writeFileSync } from 'fs'`;`import { stringify } from '@creationix/rx'`;`const json = JSON.parse(readFileSync('manifest.json', 'utf-8'))`;`const rx = stringify(json, { indexes: 10 })`;`writeFileSync('manifest.rx', rx, 'utf-8')`。
- 运行期模式:从大 RX 文件稀疏读取:`import { readFileSync } from 'fs'`;`import { parse } from '@creationix/rx'`;`const manifest = parse(readFileSync('manifest.rx', 'utf-8')) as any`;`const route = manifest.routes['/dashboard/projects']`;`console.log(route.title, route.component, route.auth)`;只解码被访问的值,其他内容跳过。
- 流式编码到 stdout:`import { stringify } from '@creationix/rx'`;`stringify(largeData, { onChunk: (chunk, offset) => process.stdout.write(chunk) })`。
- 用外部 refs 做跨文档去重:`const sharedRefs = { R: ['/api/users', '/api/teams', '/api/projects'] }`;`const doc1 = stringify(data1, { refs: sharedRefs })`;`const doc2 = stringify(data2, { refs: sharedRefs })`;`const val1 = parse(doc1, { refs: sharedRefs }) as any`;`const val2 = parse(doc2, { refs: sharedRefs }) as any`。
- 低层 inspect 零分配遍历:`import { encode, inspect } from '@creationix/rx'`;`const buf = encode(routes)`;`const root = inspect(buf)`;当 `root.tag === ':'` 时,`for (const [key, val] of root.entries())`;若 `key.value === '/dashboard'`,用 `val.index('title').value` 读取并 `break`。
- 类型安全用法:定义 `interface Route { title: string; component: string; auth: boolean }` 与 `interface Manifest { routes: Record<string, Route>; version: number }`;`const manifest = parse(rxString) as unknown as Manifest`;然后访问 `manifest.routes['/dashboard']`。
- 理解 RX 文本编码:每个值从右向左读取;解析器向左扫描过 base64 数字以找到 tag 字符,格式为 `[body][tag][b64 varint]`;标签包括 `+` integer、`*` decimal、`,` string、`'` ref/literal、`:` object、`;` array、`^` pointer、`.` chain、`#` index。
- 排查只读 Proxy 报错:若解码值上出现 `TypeError: Cannot set property`,先展开为普通对象:`const mutable = { ...parse(rx) }`;然后 `mutable.newKey = 'value'`。
- 排查数组判断:若解码值看起来正确但 `instanceof Array` 失败,改用 `Array.isArray(val)`,Proxy 会正确拦截。
- 排查外部 refs:若 refs 不匹配或解码值错误,确保 `stringify`/`encode` 与 `parse`/`open` 传入完全相同的 `refs` 字典(相同键、相同数组、相同顺序)。
- 排查 CLI 找不到:全局安装 `npm install -g @creationix/rx`;若仍找不到,检查 npm 全局 bin 路径 `npm bin -g`。
- 检查编码字节:`rx data.rx --ast` 查看带标签和偏移的编码结构;或使用 rx.run 在线查看器直接粘贴 RX 或 JSON。
- 性能排查:若查找比预期慢,确保编码时 `indexes` 阈值合适;对大对象(例如 35k 个键)用 `indexes: 0` 索引所有容器:`stringify(data, { indexes: 0 })`。
- 参考资源:rx.run 在线查看器;`docs/rx-format.md` 完整格式规范;`docs/cursor-api.md` 低层零分配 cursor API;`samples/` 示例数据集(route manifest、RPG state、emoji metadata、sensor telemetry)。
适用边界 · 注意事项
- 小型配置文件或人类手写配置:用 JSON/YAML。
- 写入频繁或需要可变数据:用真正的数据库。
- 固定 schema 且要最小 wire size:用 Protobuf;关系型/表格数据:用 SQLite;只需最小化压缩传输:用 gzip/zstd + JSON。