@bitplane/rars

中文文档
0.12.4发布于 2026/11/06Apache-2.0TypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 3340

Read, write and repair RAR archives in the browser and in Node, with no native dependency.

原始使用文档
文档目录5 节
  1. Read
  2. Write
  3. Loading
  4. Development validation
  5. Development coverage

@bitplane/rars

Read, write and repair RAR archives in browsers and Node.

npm install @bitplane/rars

Read

import { RarArchive } from "@bitplane/rars";

const archive = await RarArchive.open(file, { password: "optional" });

for (const entry of archive.entries) {
  console.log(entry.name, entry.size, entry.isEncrypted);
}

const bytes = await archive.get("docs/readme.txt").bytes();
await archive.test();
archive.close(); // optional; releases retained input eagerly

open() accepts a Blob, ArrayBuffer or typed array. Pass an ordered array to open a volume set. Entry objects use archive-order indices internally, so duplicate names and non-UTF-8 names remain unambiguous; nameBytes contains the exact header bytes.

get(name) selects the last matching entry; getAll(name) returns every match in archive order. Each returned entry reads its own payload by index.

Node also accepts paths and file URLs. Passing the first path of a conventional volume set discovers its siblings automatically.

For legacy byte names, pass legacyNameEncoding: "cp850" to open(). Supported encodings are cp437, cp850, cp852, cp866, windows-1251, windows-1252 and utf-8 (cp1251, cp1252 and utf8 are aliases). Names are case insensitive. Unicode names take precedence; unspecified legacy encodings are never guessed. Invalid or undefined input fails conversion. entry.name is the selected view and entry.nameBytes retains its original identity. Reopen to select another encoding. get() refuses ambiguous decoded names with AMBIGUOUS_ENTRY; use getAll() or archive-order entry indices. This setting does not affect comments, passwords, payloads or writer names.

open(), entry.bytes(), readMany(), test() and readComment() accept ReadOptions:

const limits = { maxHeaderCount: 10000, maxMemberOutputBytes: 256 * 1024 * 1024 };
const archive = await RarArchive.open(file, limits);
const bytes = await archive.entries[0].bytes(limits);
const selected = await archive.readMany([archive.entries[1], archive.entries[0]], limits);
const comment = await archive.readComment(limits); // undefined if absent

The optional fields are maxHeaderCount, maxHeaderBytes, maxMemberOutputBytes, maxTotalOutputBytes, maxReaderWorkspaceBytes, rar50DictionarySizeLimit and rar50BufferedDecodeLimit. Values must be nonnegative safe integer numbers or bigint values through 2n ** 64n - 1n. Zero is a real limit. Omission retains the library default. Resource options apply to one call and are not retained by open(). Each operation reparses its input; header limits apply per archive/volume. readMany() accepts an iterable of entries or names and performs one parse and decoder traversal for the batch. Results retain request order and duplicates; prefer entry objects for duplicate identity and direct index selection. Entries from another archive are rejected. Solid predecessors are decoded once, and output limits apply to the whole batch. Repeated results have independent byte buffers but do not consume logical decode quota again. Failures return no partial list. Directories are rejected; RAR5 redirections have no readable file payload. The cached archive.comment is decoded under the options passed to open(); readComment() decodes it again with fresh options and an optional password.

Output limits count logical decoded bytes, including discarded solid-prefix output. Reading a volume entry currently decodes the whole volume set, so its total-output limit includes other members. Limits are not an aggregate RAM ceiling: inputs and returned outputs are materialised, and decoder workspace has separate costs. RAR5/7 dictionary and buffered-decoding limits affect those formats only. Filesystem scratch decoding is unavailable in the WASM backend. Unknown-size RAR5 members are refused under a member-output limit; decode-to-end support remains separate work.

maxReaderWorkspaceBytes limits aggregate reader allocation capacity per call, including decoder state and queued parallel payloads. Source buffers, JavaScript objects and returned bytes are outside the quota. Capacity replacement overlap counts; this is not a process RAM limit. Refusals retain the resource error code and byte details.

Write

import { RarWriter } from "@bitplane/rars";

const writer = new RarWriter({ format: "rar50", level: 5 });
writer
  .add("hello.txt", "hello")
  .add("data.bin", payload, { mode: 0o644, modifiedAt: new Date() });

const bytes = await writer.bytes();
const parts = await writer.volumes(5 * 1024 * 1024);

level runs from 0 (stored) to 5. Other options are solid, password, encryptHeaders, comment and recoveryPercent. Node additionally provides addFile(), writeTo() and writeVolumesTo(). For legacy formats, writeVolumesTo() keeps the first path and names later volumes .r00 through .r99 in the same directory. Sets exceeding 101 volumes or containing overlapping output paths are rejected before any file is written.

Long operations accept an AbortSignal and progress callback:

const bytes = await writer.bytes({
  signal: controller.signal,
  onProgress: ({ phase, completed, total }) => {
    console.log(phase, completed, total);
  },
});

Errors are RarError instances with a stable code; client AbortSignal cancellation uses the standard AbortError. Core errors carry their code through WASM and the worker without parsing message text. details.contexts retains entry names as raw byte arrays, operations, archive offsets and volume numbers. Resource-limit details use decimal strings for byte counts, preserving values beyond JavaScript’s exact integer range. Node filesystem errors use IO with the original system code, errno and syscall in details.

Aborting queued work rejects it immediately without interrupting the active operation. Aborting active work terminates its worker; later operations start a fresh worker. This is worker termination, so it does not run cooperative Rust cleanup or undo completed filesystem writes. Interrupted Node writes may leave staged temporary files. No separate cancellation-token object is needed in JS.

RarWriter accepts maxMemoryBytes as a nonnegative safe integer or a bigint through 2n ** 64n - 1n. It caps managed RAR5/7 execution allocation capacity, including retained WASM spools, archive/volume output and the final JavaScript payload copy. The default is unlimited; zero admits no managed allocation. A refusal has code RESOURCE_LIMIT; legacy formats reject the requested policy with UNSUPPORTED_FEATURE. Caller inputs, returned caller-owned bytes, JavaScript runtime objects, allocator overhead, stacks and OS memory are excluded. This is not a process-memory ceiling and does not bound reading or rewrite staging.

Loading

ES modules, Node require, Vite, webpack, Rollup and direct browser imports use the same API and require no explicit Wasm initialisation:

<script type="module">
  import { RarArchive } from "https://esm.sh/@bitplane/rars";
</script>

Direct cross-origin imports use a small blob worker bootstrap. A restrictive Content Security Policy must therefore allow blob: in worker-src, or the package assets should be bundled or served from the page's origin.

The current API materialises input and output bytes. True backpressured stream input/output will be added separately rather than presenting a stream that secretly buffers an entire archive.

The same library is available as a Rust crate, Python package and command-line tool.

Development validation

Run CARGO_BUILD_JOBS=1 scripts/build-npm.sh --debug and then node scripts/test-npm-package.js for focused engine and worker checks. The debug build skips LTO and wasm-opt. Build release artifacts with scripts/build-npm.sh without --debug. Both modes require a wasm-bindgen CLI matching Cargo.lock.

Development coverage

From the repository root, run python3 scripts/coverage-wasm.py to measure Rust engine coverage under Node. It requires Node, wasm-bindgen matching Cargo.lock, and a Rust nightly using LLVM 23 with wasm32-unknown-unknown and llvm-tools-preview installed. The command uses one build job and at most two available CPUs, and saves reports under the ignored target/coverage-wasm-focused directory.

An independent two-branch probe checks the measurement before testing the engine. Private error conversion tests are compiled with cfg(test); their exports and the profiling runtime stub are absent from release builds. This measures Rust WASM source, separately from JavaScript facade coverage.

版本与发布记录

@bitplane/rars 共发布 16 个版本,首次发布于 2026/08/18;过去 12 个月发布了 16 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.12.4latest2026/11/062 天前
0.12.32026/10/2612 天前
0.12.22026/10/2514 天前
0.12.12026/10/2415 天前
0.12.02026/10/2316 天前
0.11.02026/10/1623 天前

关于 @bitplane/rars 的常见问题

@bitplane/rars 是什么?

Read, write and repair RAR archives in the browser and in Node, with no native dependency.

如何安装 @bitplane/rars?

在项目目录运行 npm install @bitplane/rars,或使用 pnpm add / yarn add / bun add。

@bitplane/rars 支持 TypeScript 吗?

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

@bitplane/rars 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@bitplane/rars 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@bitplane/rars 可以商用吗?

@bitplane/rars 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@bitplane/rars 的下载量有多少?

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

@bitplane/rars 还在维护吗?

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