@effect-vfs/core

中文文档
0.11.0发布于 2026/11/14MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 2034

A runtime-neutral virtual filesystem core for Effect.

原始使用文档
文档目录5 节
  1. Install
  2. Create an isolated workspace
  3. Confine a caller to a directory
  4. Guides and reference
  5. Limits

@effect-vfs/core

@effect-vfs/core manages in-memory volumes with byte-preserving paths, callers with explicit permissions, quotas, watches, fixtures, and portable snapshots. It does not access the host filesystem.

Use core when you need direct control over a shared volume or byte-oriented paths. For Effect's standard FileSystem service, use @effect-vfs/memory.

The package implements a documented subset of POSIX behavior. It does not claim full POSIX conformance. See the implemented profile for the exact permission, path, timestamp, quota, and atomicity rules.

Install

npm install @effect-vfs/core@latest

The package declares its exact Effect version as a peer dependency. Volume constructors and snapshot delta functions require Effect's Crypto service. On Node, install the matching provider and supply NodeCrypto.layer when running these effects:

npm install "@effect/platform-node-shared@$(npm view @effect-vfs/core peerDependencies.effect)"

Create an isolated workspace

A volume owns the files. A caller supplies identity, permissions, and a working directory. Scoped handles close when their Effect scope ends. This example gives an unprivileged caller access to one directory in a bounded volume.

import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto"
import { ByteSize, Effect } from "effect"

const utf8 = new TextEncoder()

const program = Effect.scoped(Effect.gen(function*() {
  const volume = yield* Vfs.make({
    maxEntries: 100,
    maxBytes: ByteSize.megabytes(1),
    maxFileBytes: ByteSize.kilobytes(100)
  })

  const admin = yield* volume.caller()
  yield* admin.mkdir("/workspace", { mode: 0o770 })
  yield* admin.chown("/workspace", { uid: 1000, gid: 1000 })

  const developer = yield* volume.caller({
    identity: { uid: 1000, gid: 1000, groups: [], privileged: false },
    umask: 0o027
  })

  yield* developer.writeFile(
    "/workspace/config.json",
    utf8.encode(JSON.stringify({ feature: "preview" })),
    { access: "write", create: "exclusive", mode: 0o666 }
  )

  const file = yield* developer.open("/workspace/config.json", { access: "read" })
  const contents = yield* file.read(100_000)
  const metadata = yield* file.stat

  return {
    config: JSON.parse(new TextDecoder().decode(contents)),
    mode: metadata.mode.toString(8)
  }
}))

const result = await Effect.runPromise(program.pipe(Effect.provide(NodeCrypto.layer)))
console.log(result) // { config: { feature: "preview" }, mode: "640" }

The root caller is privileged by default. Privilege is explicit: setting uid to 0 does not grant it. New root callers default to umask 0o022; the developer's 0o027 mask turns the requested file mode 0o666 into 0o640.

The root package exports VirtualFileSystem as a namespace. The equivalent direct module import is import * as Vfs from "@effect-vfs/core/VirtualFileSystem".

Confine a caller to a directory

caller.withRoot(path) creates a scoped caller whose / is that directory. Absolute symlinks and .. stay inside the root. Renaming the root preserves access; deleting it permanently invalidates the caller.

Keep the caller's scope open and pass only the capabilities the consumer needs. Existing hard links can share file contents across roots. See Confine a workspace for a complete example with Effect's FileSystem service and the confinement limits.

Guides and reference

Limits

The package is experimental. Public APIs may change between minor releases.

Paths preserve arbitrary non-NUL bytes. Components are limited to 255 bytes, and symlink traversal to 40 links. Volume options bound entries, file sizes, pending operations, and watch queues. In-memory volumes provide no host or crash durability. See compatibility and limits for the complete contract.

版本与发布记录

@effect-vfs/core 共发布 14 个版本,首次发布于 2026/09/09;过去 12 个月发布了 14 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.11.0latest2026/11/14今天
0.10.02026/11/104 天前
0.9.02026/10/051 个月前
0.8.02026/10/031 个月前
0.7.12026/10/011 个月前
0.7.02026/09/271 个月前

关于 @effect-vfs/core 的常见问题

@effect-vfs/core 是什么?

A runtime-neutral virtual filesystem core for Effect.

如何安装 @effect-vfs/core?

在项目目录运行 npm install @effect-vfs/core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(~4.1.4)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effect-vfs/core 支持 TypeScript 吗?

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

@effect-vfs/core 支持 ESM 还是 CommonJS?

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

@effect-vfs/core 可以商用吗?

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

@effect-vfs/core 的下载量有多少?

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

@effect-vfs/core 还在维护吗?

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