zena:fs

zena
import {…} from 'zena:fs';

File system access over WASI 0.3, for the component target.

Provides file reading and writing, directory listing and metadata, relative to the directories the host preopened, over wasi:filesystem@0.3.0 as the compiler synthesizes it from the vendored WIT.

The API is asynchronous, as the 0.3 filesystem is: every descriptor method is an async func on the wire, and a file's contents travel as a stream<u8>. Each convenience function here (readFile, writeFile, listDir, ...) also has a synchronous twin under a Sync suffix, which waits for the same call in blockOn. Only a task the host lifted async may wait that way, and the compiler exports main async for a program that reaches blockOn, so the Sync forms work inside main and inside test bodies; in a synchronous WIT export, a module initializer or test registration they trap, and the asynchronous forms are the ones to use. See docs/design/async-fs-cli.md.

Examples ​

zena
import { readFile, writeFile, listDir, readFileSync } from 'zena:fs';

let content = await readFile('config.json');
await writeFile('output.txt', 'Hello, World!');
for (let entry in await listDir('.')) {
  console.log(entry.name);
}
let synchronous = readFileSync('config.json');

Classes

FsError

zena
class FsError extends Error
Extends Error

A failed file operation: its code, and what was being done.

Constructors
zena
new(errno: i32, message: String)
#
Properties
zena
code: FsErrorCode
#
zena
errno: i32
#
2 inherited members
From Error
Properties
zena
message: String
#
Methods
zena
getStackTrace(): String | null
#

Descriptor

zena
resource class Descriptor extends Resource
Extends Resource

An open file or directory: a resource over the host's handle, held as Own<Descriptor> and released when that owner leaves scope. A use after the release is a compile error. Paths given to the *At methods are relative to a directory descriptor. Every operation is asynchronous; a synchronous caller waits with blockOn.

The preopened directories are Unmanaged<Descriptor>: they live as long as the program and are never released, and an unmanaged handle reaches every method here the way an owned one does.

Constructors
zena
new(inner: Own<WitDescriptor>)
#
Methods
zena
async readAllBytes(): Future<FixedArray<u8>>
#

The entire contents, as bytes.

zena
async readString(): Future<String>
#

The entire contents, as text.

zena
readStream(): Stream<u8>
#

The contents, as a stream the host fills: for handing on to another host interface — a response body, say — so that the bytes never pass through the program. Consumes this descriptor: it goes to a task that releases it once the stream has been read to the end.

zena
async writeBytes(data: FixedArray<u8>): Future<void>
#

Write data from the start of the file.

zena
async writeString(data: String): Future<void>
#

Write data from the start of the file.

zena
async openAt(path: String, flags: DescriptorFlags): Future<Own<Descriptor>>
#

Open a path under this directory, following symlinks.

zena
async createAt(path: String): Future<Own<Descriptor>>
#

Create a file under this directory, or truncate the one there, open for writing.

zena
async openDirAt(path: String): Future<Own<Descriptor>>
#

Open a directory under this one.

zena
async stat(): Future<FileStat>
#

This descriptor's metadata.

zena
async statAt(path: String): Future<FileStat>
#

The metadata of a path under this directory, following symlinks.

zena
async existsAt(path: String): Future<boolean>
#

Whether anything is at a path under this directory.

zena
async readDir(): Future<Array<DirEntry>>
#

The entries of this directory. . and .. are not among them.

zena
async mkdirAt(path: String): Future<void>
#

Create a directory under this one.

zena
async unlinkAt(path: String): Future<void>
#

Remove a file under this directory.

zena
async rmdirAt(path: String): Future<void>
#

Remove an empty directory under this one.

zena
async renameAt(from: String, to: Unmanaged<Descriptor>, toPath: String): Future<void>
#

Rename a path under this directory to a path under to, a directory the program does not own, which is what a preopen is. (An unmanaged handle does not pass where a borrow is expected, so a caller holding an owned target disowns it for the call.)

GlobOptions

zena
class GlobOptions

How glob searches.

Properties
zena
var cwd: String
#
zena
var onlyFiles: boolean
#
zena
var exclude
#

Enums

FsErrorCode

zena
enum FsErrorCode

The failures a file operation reports. The numbers are the WASI preview 1 errno values the codes were first modelled on, kept so FsError.errno stays what it was; a 0.3 error-code maps onto them.

Members
zena
Success
#
zena
Access
#
zena
BadDescriptor
#
zena
Exist
#
zena
NotFound
#
zena
IsDirectory
#
zena
NotDirectory
#
zena
NotEmpty
#
zena
ReadOnly
#
zena
InvalidSeek
#
zena
Io
#
zena
InvalidArgument
#
zena
NameTooLong
#
zena
NoSpace
#
zena
NotPermitted
#

FileType

zena
enum FileType

The kind of a directory entry or stat'd path.

Members
zena
Unknown
#
zena
BlockDevice
#
zena
CharacterDevice
#
zena
Directory
#
zena
RegularFile
#
zena
Socket
#

DescriptorFlags

zena
enum DescriptorFlags

How Descriptor.openAt opens a path.

Members
zena
Read
#
zena
Write
#
zena
ReadWrite
#
zena
MutateDirectory
#

Type aliases

FileStat

zena
type FileStat = {fileType: FileType, size: i64, modified: i64}

File metadata.

DirEntry

zena
type DirEntry = {name: String, fileType: FileType}

When the contents last changed, in nanoseconds since the Unix epoch. A directory entry.

Functions

getPreopens

zena
function getPreopens(): Array<(Unmanaged<Descriptor>, String)>

The directories the host preopened, each with the path it is known by. Synchronous: get-directories is a synchronous WIT function. The descriptors are unmanaged: they are the program's for its whole run, and nothing releases them.

getRootDir

zena
function getRootDir(): Unmanaged<Descriptor>

The first preopened directory.

resolvePreopen

zena
function resolvePreopen(path: String): (Unmanaged<Descriptor>, String)

The preopen a path falls under, and the path relative to it. A relative path is under the preopen named . (else the first); an absolute path is under the preopen whose name is its longest prefix at a segment boundary, so /tmpfiles is not under /tmp.

readFile

zena
async function readFile(path: String): Future<String>

The contents of a file, as text.

readFileBytes

zena
async function readFileBytes(path: String): Future<FixedArray<u8>>

The contents of a file, as bytes.

writeFile

zena
async function writeFile(path: String, content: String): Future<void>

Write text to a file, creating or truncating it.

writeFileBytes

zena
async function writeFileBytes(path: String, content: FixedArray<u8>): Future<void>

Write bytes to a file, creating or truncating it.

listDir

zena
async function listDir(path: String): Future<Array<DirEntry>>

The entries of a directory.

exists

zena
async function exists(path: String): Future<boolean>

Whether anything exists at a path.

isFile

zena
async function isFile(path: String): Future<boolean>

Whether a regular file exists at a path.

isDirectory

zena
async function isDirectory(path: String): Future<boolean>

Whether a directory exists at a path.

mkdir

zena
async function mkdir(path: String): Future<void>

Create a directory.

zena
async function unlink(path: String): Future<void>

Remove a file.

rename

zena
async function rename(from: String, to: String): Future<void>

Move a file or directory.

stat

zena
async function stat(path: String): Future<FileStat>

The metadata of a path.

rmdir

zena
async function rmdir(path: String): Future<void>

Remove an empty directory.

glob

zena
async function glob(pattern: String, options: GlobOptions | null = null): Future<Array<String>>

The paths under options.cwd matching a glob pattern, sorted. A pattern with no wildcard names one path, reported if it exists.

readFileSync

zena
function readFileSync(path: String): String

readFileBytesSync

zena
function readFileBytesSync(path: String): FixedArray<u8>

writeFileSync

zena
function writeFileSync(path: String, content: String): void

writeFileBytesSync

zena
function writeFileBytesSync(path: String, content: FixedArray<u8>): void

listDirSync

zena
function listDirSync(path: String): Array<DirEntry>

existsSync

zena
function existsSync(path: String): boolean

isFileSync

zena
function isFileSync(path: String): boolean

isDirectorySync

zena
function isDirectorySync(path: String): boolean

mkdirSync

zena
function mkdirSync(path: String): void

unlinkSync

zena
function unlinkSync(path: String): void

renameSync

zena
function renameSync(from: String, to: String): void

statSync

zena
function statSync(path: String): FileStat

rmdirSync

zena
function rmdirSync(path: String): void

globSync

zena
function globSync(pattern: String, options: GlobOptions | null = null): Array<String>