Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ffc49a7
fs: add virtual file system support
mcollina Jan 22, 2026
8038e5d
vfs: add Windows path compatibility
mcollina Jan 23, 2026
74941b0
sea: support VFS in embedderRequire
mcollina Jan 23, 2026
be747df
test: add tmpdir.refresh() to SEA VFS test
mcollina Jan 24, 2026
0f01bc8
test: update SEA VFS test for new buildSEA API
mcollina Jan 25, 2026
eda0afa
vfs: add provider-based architecture and node:vfs module
mcollina Jan 27, 2026
52f5bce
vfs: remove backward compat methods, use standard fs API
mcollina Jan 27, 2026
d987894
vfs: address review comments
mcollina Jan 27, 2026
4d8fdec
vfs: fix lint errors
mcollina Jan 28, 2026
7f885c4
vfs: fix lint errors
mcollina Jan 28, 2026
6d46594
vfs: remove public createSEA()
mcollina Jan 28, 2026
19230d5
vfs: address review comments
mcollina Jan 28, 2026
694d92a
doc: address review comments on VFS documentation
mcollina Jan 28, 2026
6392f49
doc: clarify virtualCwd behavior in Worker threads
mcollina Jan 28, 2026
a92c4c6
vfs: add RealFSProvider for mounting real directories
mcollina Jan 28, 2026
76001b4
tools: add VFS types to doc type-parser
mcollina Jan 28, 2026
3634173
doc: use REPLACEME for version placeholders in vfs.md
mcollina Jan 29, 2026
3ebd8c2
doc: add security warnings and symlink documentation to vfs.md
mcollina Jan 29, 2026
3f79b7b
vfs: address code review feedback from @jasnell
mcollina Jan 29, 2026
5fa1ca9
vfs: add overlay mode for selective file interception
mcollina Jan 29, 2026
a14ad6d
vfs: add tests and fix appendFile, add readonly checks
mcollina Jan 30, 2026
21225d6
fs: remove createVirtual, use node:vfs instead
mcollina Jan 31, 2026
f9e4797
vfs: add watch and watchFile support
mcollina Jan 31, 2026
6969624
vfs: improve test coverage for watch implementation
mcollina Jan 31, 2026
736b664
vfs: remove unused utility functions from module_hooks
mcollina Jan 31, 2026
b2460e3
vfs: add test for symlink target creation after symlink
mcollina Feb 1, 2026
988fa73
doc: add worker thread limitations to VFS documentation
mcollina Feb 1, 2026
50e3bfe
doc: clarify VFS accepts same types as fs module
mcollina Feb 1, 2026
225b536
vfs: remove unused entries.js, add error tests
mcollina Feb 1, 2026
c46d8fd
vfs: remove unused exports from fd.js and stats.js
mcollina Feb 1, 2026
564b4a8
vfs: remove unused VirtualFD methods
mcollina Feb 1, 2026
9b1c617
vfs: remove more unused VirtualFD code
mcollina Feb 1, 2026
b7738b0
vfs: address Aviv's review comments
mcollina Feb 2, 2026
8dac8f0
test: improve VFS code coverage
mcollina Feb 2, 2026
99399ce
Update lib/internal/vfs/module_hooks.js
mcollina Feb 2, 2026
0d5c6a4
Update lib/internal/vfs/module_hooks.js
mcollina Feb 2, 2026
74133e8
vfs: address aduh95 review comments
mcollina Feb 2, 2026
3d48b95
vfs: remove SEAProvider export and hasSeaAssets
mcollina Feb 3, 2026
aa19193
vfs: remove addFile and addDirectory methods
mcollina Feb 3, 2026
4726b7f
doc: alphabetize VirtualFileSystem members in vfs.md
mcollina Feb 3, 2026
b1416b8
Update single-executable-applications.md
mcollina Feb 3, 2026
d5217e7
sea: remove getVfs from public API
mcollina Feb 3, 2026
c083f03
doc: explain symlink behavior in overlay mode
mcollina Feb 3, 2026
b437e54
doc: document overlay mode behavior for fs operations
mcollina Feb 3, 2026
0453725
vfs: add Symbol.dispose support for automatic unmount
mcollina Feb 3, 2026
0feeed4
vfs: add missing JSDoc @returns for mount()
mcollina Feb 3, 2026
1300143
vfs: only initialize SEA VFS when assets exist
mcollina Feb 3, 2026
36ec459
vfs: use path.posix methods instead of custom implementations
mcollina Feb 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
* [URL](url.md)
* [Utilities](util.md)
* [V8](v8.md)
* [Virtual File System](vfs.md)
* [VM](vm.md)
* [WASI](wasi.md)
* [Web Crypto API](webcrypto.md)
Expand Down
51 changes: 51 additions & 0 deletions doc/api/single-executable-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,57 @@ const raw = getRawAsset('a.jpg');
See documentation of the [`sea.getAsset()`][], [`sea.getAssetAsBlob()`][],
[`sea.getRawAsset()`][] and [`sea.getAssetKeys()`][] APIs for more information.

### Virtual File System (VFS) for assets

> Stability: 1 - Experimental

Instead of using the `node:sea` API to access individual assets, you can use
the Virtual File System (VFS) to access bundled assets through standard `fs`
APIs. When running as a Single Executable Application, the VFS is automatically
initialized and mounted at `/sea`. All assets defined in the SEA configuration
are accessible through this virtual path.

```cjs
const fs = require('node:fs');

// Assets are automatically available at /sea when running as SEA
const config = JSON.parse(fs.readFileSync('/sea/config.json', 'utf8'));
const data = fs.readFileSync('/sea/data/file.txt');

// Directory operations work too
const files = fs.readdirSync('/sea/assets');

// Check if a bundled file exists
if (fs.existsSync('/sea/optional.json')) {
// ...
}
```

The VFS supports the following `fs` operations on bundled assets:

* `readFileSync()` / `readFile()` / `promises.readFile()`
* `statSync()` / `stat()` / `promises.stat()`
* `lstatSync()` / `lstat()` / `promises.lstat()`
* `readdirSync()` / `readdir()` / `promises.readdir()`
* `existsSync()`
* `realpathSync()` / `realpath()` / `promises.realpath()`
* `accessSync()` / `access()` / `promises.access()`
* `openSync()` / `open()` - for reading
* `createReadStream()`

#### Loading modules from VFS in SEA

You can use `require()` directly with absolute VFS paths:

```cjs
// Require bundled modules directly
const myModule = require('/sea/lib/mymodule.js');
const utils = require('/sea/utils/helpers.js');
```

The SEA's `require()` function automatically detects VFS paths (paths starting
with `/sea/`) and loads modules from the virtual file system.

### Startup snapshot support

The `useSnapshot` field can be used to enable startup snapshot support. In this
Expand Down
88 changes: 88 additions & 0 deletions doc/api/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,94 @@ test('mocks a counting function', (t) => {
});
```

### `mock.fs([options])`

<!-- YAML
added: REPLACEME
-->

> Stability: 1.0 - Early development

* `options` {Object} Optional configuration options for the mock file system.
The following properties are supported:
* `prefix` {string} The mount point prefix for the virtual file system.
**Default:** `'/mock'`.
* `files` {Object} An optional object where keys are file paths (relative to
the VFS root) and values are the file contents. Contents can be strings,
Buffers, or functions that return strings/Buffers.
* Returns: {MockFSContext} An object that can be used to manage the mock file
system.

This function creates a mock file system using the Virtual File System (VFS).
The mock file system is automatically cleaned up when the test completes.

## Class: `MockFSContext`

The `MockFSContext` object is returned by `mock.fs()` and provides the
following methods and properties:

* `vfs` {VirtualFileSystem} The underlying VFS instance.
* `prefix` {string} The mount prefix.
* `addFile(path, content)` Adds a file to the mock file system.
* `addDirectory(path[, populate])` Adds a directory to the mock file system.
* `existsSync(path)` Checks if a path exists (path is relative to prefix).
* `restore()` Manually restores the file system to its original state.

The following example demonstrates how to create a mock file system for testing:

```js
const { test } = require('node:test');
const assert = require('node:assert');
const fs = require('node:fs');

test('reads configuration from mock file', (t) => {
const mockFs = t.mock.fs({
prefix: '/app',
files: {
'/config.json': JSON.stringify({ debug: true }),
'/data/users.txt': 'user1\nuser2\nuser3',
},
});

// Files are accessible via standard fs APIs
const config = JSON.parse(fs.readFileSync('/app/config.json', 'utf8'));
assert.strictEqual(config.debug, true);

// Check file existence
assert.strictEqual(fs.existsSync('/app/config.json'), true);
assert.strictEqual(fs.existsSync('/app/missing.txt'), false);

// Use mockFs.existsSync for paths relative to prefix
assert.strictEqual(mockFs.existsSync('/config.json'), true);
});

test('supports dynamic file content', (t) => {
let counter = 0;
const mockFs = t.mock.fs({ prefix: '/dynamic' });

mockFs.addFile('/counter.txt', () => {
counter++;
return String(counter);
});

// Each read calls the function
assert.strictEqual(fs.readFileSync('/dynamic/counter.txt', 'utf8'), '1');
assert.strictEqual(fs.readFileSync('/dynamic/counter.txt', 'utf8'), '2');
});

test('supports require from mock files', (t) => {
t.mock.fs({
prefix: '/modules',
files: {
'/math.js': 'module.exports = { add: (a, b) => a + b };',
},
});

const math = require('/modules/math.js');
assert.strictEqual(math.add(2, 3), 5);
});
```

### `mock.getter(object, methodName[, implementation][, options])`

<!-- YAML
Expand Down
Loading