Skip to content

Architechture

James Prevett edited this page Nov 25, 2024 · 8 revisions

Note

This article is still being worked on and is not finished.

Layers

ZenFS is organized into a system of "layers". These are the primary concepts that work together.

Emulation

The emulation layer converts Node.js API calls into method calls on backends. It handles path translation (including symlinks) and permissions.

Backends

Backends sits behind the emulation layer and handles configuration of a FileSystem. A backend is just an object that implements Backend, and creates a new FileSystem instance.

FileSystem

FileSystem provides the functionality of backends. Put simply, FileSystem is an abstraction of any arbitrary storage medium.

Contexts

Contexts are a way you can completely isolate different parts of your file system tree. They are analogous to a sub-set of a process, and could be used as a basis for processes.

You can get access to a context in a few ways. The most straight forward is using chroot, which also exists on contexts:

import { fs } from '@zenfs/core';

// You need to make sure the directory exists
fs.mkdirSync('/new_root', { recursive: true });
const sub = fs.chroot('/new_root');

// notice the absolute path
sub.mkdirSync('/another/level', { recursive: true });

fs.readdirSync('/new_root'); // ['another']

// Setting `inPlace` to true modifies the exiting context instead of creating a new one
// It has no effect if called on `fs` since `fs` is not a context
sub.chroot('/another', true);

sub.readdirSync('/'); // ['level']

For more control you can use bindContext, which allows you to change much more than just the root.

import { fs, bindContext } from '@zenfs/core';

// You still need to make sure the directory exists
fs.mkdirSync('/context', { recursive: true });

// You can change permissions as well
const ctx = bindContext('/context', { uid: 1000, gid: 1000 });

ctx.writeFileSync('example.txt', 'Cool!');

fs.readFileSync('/context/example.txt', 'utf8'); // 'Cool!'

fs.statSync('/context/example.txt').uid // 1000

If credentials are not provided to bindContext, they are deep copied from the default credentials object.

Clone this wiki locally