@freqhole/midden

中文文档
0.3.27发布于 2026/11/10TypeScriptES Module零依赖构建来源已验证近 30 天下载 2699

WASM bindings for freqhole P2P client (iroh-based)

原始使用文档
文档目录5 节
  1. architecture
  2. structure
  3. getting started
  4. developer quick start
  5. protocol

midden

the unified wasm iroh node for the freqhole world of apps: a MiddenNode class that lets browsers talk to freqhole peers over iroh p2p - api requests, verified blob streaming, opfs-backed persistent blob storage, chunked import sessions, radio, and raw bidirectional streams for app protocols. rust crate built with wasm-bindgen/wasm-pack; npm package @freqhole/midden.

architecture

graph LR
    subgraph browser
        APP[your app / worker]
        MN[MiddenNode wasm]
        OPFS[(opfs blob store)]
    end
    subgraph peers
        P1[always-on peer<br/>grimoire / tumulus / any]
        P2[another browser]
    end
    APP --> MN
    MN --- OPFS
    MN <-- "iroh p2p (relay discovery + direct)" --> P1 & P2

the default registered ALPN set is the app-neutral base (freqhole/1, automerge sync, friendz, admin, events, iroh-blobs). app-specific ALPNs are passed via extra_alpns - never hardcoded here.

structure

src/
  lib.rs           MiddenNode + options, bi-streams, blob transfer, import sessions
  opfs_store/      persistent browser blob store (storage-generic core, native tests)
  radio.rs         radio streaming
pkg/               committed wasm-pack output - consumers file:-dep straight at it
Makefile           build targets

pkg/ is checked into git: rebuild it whenever src/ changes or consumers won't see the change.

getting started

import { MiddenNode, MiddenNodeOptions } from "@freqhole/midden";

const options = new MiddenNodeOptions();
options.set_secret_key(mySecretKeyBytes); // omit to generate fresh
options.set_opfs_store_dir("myapp-blobs"); // persistent blob store
options.set_extra_alpns(["myapp/1"]); // app protocol ALPNs
const node = await MiddenNode.create_with_options(options);
console.log("node id:", node.node_id());

// request/response to a peer (json over iroh; same dispatch shape as http)
const resp = await node.api_request(peerAddr, "GET", "/api/hello", null);

// verified blob download with progress
const bytes = await node.download_verified_with_ensure_progress(
  peerAddr,
  blake3Hash,
  totalSize,
  (fraction) => {},
  downloadId,
);

// raw bidirectional stream for your own protocol
const stream = await node.open_bi(peerAddr, "myapp/1");
await stream.write_raw_and_finish(encodedRequest);
const reply = await stream.read_to_end(64 * 1024);

peer_addr accepts a bare 64-hex node id (relay discovery) or a full endpoint json ({"id":"...","addrs":[...]} with relay/ip hints).

other surface: import_blob/release_blob (stage bytes for peers), ImportSession (chunked streaming import with incremental blake3), Blake3Hasher, CancelToken + download_cancel (pause/resume), protect_blob/unprotect_blob (gc pins), has_complete_blob, opfs selftests, radio.

developer quick start

cargo install wasm-pack
brew install llvm          # macos: wasm toolchain needs it

make build                 # dev build -> pkg/
make build-release         # optimized
cargo test                 # native tests (opfs_store core runs without a browser)

consumers today: tomb/spume + rathole, skein/loam, playlistz - all via file: deps at pkg/ (e.g. file:../../midden/pkg). vite consumers bundling this inside a worker need the resolveId-plugin pattern (see @freqhole/reliquary's README).

protocol

same wire protocol as grimoire's federation transport: ALPN freqhole/1, messages ApiRequest/ApiResponse, EnsureBlobRequest/EnsureBlobResponse, blob streaming as a length-prefixed header + raw bytes. see grimoire/src/federation/transport/protocol.rs.


made with 💖 in NYC

版本与发布记录

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

版本发布日期距今
0.3.27latest2026/11/105 天前
0.3.262026/11/078 天前
0.3.252026/11/0510 天前
0.3.242026/11/0510 天前
0.3.232026/11/0313 天前
0.3.222026/10/2818 天前

关于 @freqhole/midden 的常见问题

@freqhole/midden 是什么?

WASM bindings for freqhole P2P client (iroh-based)

如何安装 @freqhole/midden?

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

@freqhole/midden 支持 TypeScript 吗?

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

@freqhole/midden 支持 ESM 还是 CommonJS?

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

@freqhole/midden 可以商用吗?

@freqhole/midden 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@freqhole/midden 的下载量有多少?

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

@freqhole/midden 还在维护吗?

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