psusfs
v1.1.4
Published
**Pretty Solid User Space File System** is a custom virtual file system for use with **Node.js**
Readme
PSUSFS
Pretty Solid User Space File System is a custom virtual file system for use with Node.js
It allows packing multiple files into a single binary blob and load them either via ESM imports, such
as import data from "vfs/somefile.xyz", or use the supplied VFS-API
Core features
- Binary filesystem representation
- ESM loader with
import-support for contained files - TypeScript support
- Node.Js-like calls for
open,close,read,stat, andreadFile - No directory tree, only a flat file system because I personally did not think it necessary
Structure
[.HEDR] (Header section)
MAGIC "PSUFS" (6 bytes)
VERSION 8-bit uint (1 byte)
FLAGS 8-bit uint (1 byte)
FILE_COUNT 32-bit uint (4 bytes)
[.FTAB] (File table. 1 entry per file)
FILENAME string (64 bytes, zero-padded, utf-8)
OFFSET 32-bit uint (4 bytes)
LENGTH 32-bit uint (4 bytes)
[.DATA] (Binary file data, files are stored back-to-back)Usage
1. Via API
Use-Case: Bundling a folder into a PSUSFS-VFS blob
import {FromPath} from "psusfs";
const vfs_blob = await FromPath("./assets");Use-Case: Load a PSUSFS-VFS blob and work with its contents
import {Mount} from "psusfs"
const vfs = await Mount("./vfs.Bin");
const fd = vfs.open("logo.webp");
const buf = Buffer.alloc(1024 * 10);
const bytes_read = vfs.read(fd, buf, 0, buf.length);
vfs.close(fd);2. Via ESM-Loader
The ESM-Loader allows resolution of virtual imports from a given PSUSFS-VFS blob.
If you want to use this feature, please add the following into your tsconfig.json
"paths": {
"vfs/*": ["./node_modules/psusfs/types/loader.d.ts"]
}Then in your code, you can do the following
import img from "vfs/logo.png"
//img is resolved to a Uint8Array read directly from the supplied PSUSFS-VFS blob
console.log(img);You'll need to run node with like this
node --import psusfs/register-loader ./your_file.jsFile resolution table
The loader converts some files into different types depending on the file format
| Format | Resvoles to | |--------|------------------------------------------------------------------| | json | utf-8 string | | wasm | Buffer | | js | not resolved (see Incompatibilities) | | mjs | not resolved (see Incompatibilities) | | other | Uint8Array |
ESM-Loader options
- Environment variable:
PSUSFS_VFS(absolute or relative path to a PSUSFS-VFS blob) - Fallback default:
vfs.bin(in current working directory)
Public API
The following API functions are available to use:
/*
* Mounts the PSUSFS, specified by `source`.
*
* If source is a `string`, it will be interpreted as a path and read from disk.
*
* If it is a `Buffer`, it will be used directly.
* */
function Mount(source: string | Buffer): Promise<VFS>;
/*
* Generates a PSUSFS-VFS binary from the given `base_path`.
*
* It will recursively scan the subfolders and files of `base_path`
* and flatten them into a list, keeping only the file names.
*
* Using `options`, you can enable gzip and aes-256-gcm encryption
* */
function FromPath(base_path: string, options?: CommonOptions): Promise<Buffer>;The Mount function returns a VFS object.
VFS API
The following API functions are available to use on the VFS object.
(Excerpt from 'index.d.ts')
/*
* Opens the file specified by `name`
*
* @param name The file to open
*
* @returns A file descriptor
* */
function open(name: string): number;
/*
* Closes the file specified by `file_descriptor`
*
* @param file_descriptor The file descriptor to close
* */
function close(file_descriptor: number): void;
/**
* Read data from the file specified by `file_descriptor`.
*
* @param file_descriptor The file descriptor to read data from
* @param buf_out The buffer that the data will be written to.
* @param offset The position in `buffer` to write the data to.
* @param length The number of bytes to read.
* @param position Specifies where to begin reading from in the file. If `position` is `undefined` or `-1 `, data will be read from the current file position, and the file position will be updated. If
* `position` is an integer, the file position will be unchanged.
*
* @returns The number of bytes read
*/
function read(file_descriptor: number, buf_out: Buffer, offset: number, length: number, position?: number): number;
/**
* Get file statistics
*
* @param name The file to get statistics on
*
* @returns A vfs_stat object, see {@link vfs_stat}
* */
function stat(name: string): vfs_stat;
/**
* Read a file specified by `filename` entirely
*
* @param name The name of the file to read
* @param [utf8=false] If the file should be read as a UTF-8 string
*
* @returns The file contents, either as Buffer or UTF-8 string
* */
function readFile(name: string, utf8: true): string;
function readFile(name: string, utf8?: false): Buffer;
function readFile(name: string, utf8: boolean = false): string | Buffer;
/**
* Creates a readable stream from a file in the VFS
* @param name The file name to create a stream for
*
* @returns a readable stream
* */
function createReadStream(name: string): Readable;
/*
* Enumerate all files in the VFS
*
* @returns An array of strings, containing all file names in the VFS
* */
function enumerate(): string[];Incompatibilities
- Any
.mjsor.jsfiles loaded by the ESM-Loader may not containimportorexportstatements
Status
- Stable blob file format ✅
- ESM loader ✅
- Integration with Node.js-Readable interface ✅
- Gzip support via
node:zlib✅ - Encryption support via
aes-256-gcm✅
