or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

directory-operations.mdfile-descriptors.mdfile-operations.mdfile-watching.mdindex.mdstats-permissions.mdstreams.mdsymbolic-links.md

index.mddocs/

0

# Metro Memory FS

1

2

Metro Memory FS provides a complete in-memory filesystem implementation that mimics the Node.js `fs` module API for testing purposes. It offers a comprehensive drop-in replacement for the native filesystem API, supporting all standard file operations including reading, writing, creating, deleting files and directories, symbolic links, file descriptors, and file watchers.

3

4

## Package Information

5

6

- **Package Name**: metro-memory-fs

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install metro-memory-fs`

10

11

## Core Imports

12

13

```javascript

14

const MemoryFs = require("metro-memory-fs");

15

```

16

17

ES Modules:

18

19

```javascript

20

import MemoryFs from "metro-memory-fs";

21

```

22

23

## Basic Usage

24

25

```javascript

26

const MemoryFs = require("metro-memory-fs");

27

28

// Create a new memory filesystem instance

29

const fs = new MemoryFs({

30

cwd: () => "/current/working/dir",

31

platform: "posix" // or "win32"

32

});

33

34

// Write and read files

35

fs.writeFileSync("/hello.txt", "Hello, World!");

36

const content = fs.readFileSync("/hello.txt", "utf8");

37

console.log(content); // "Hello, World!"

38

39

// Create directories

40

fs.mkdirSync("/mydir", { recursive: true });

41

42

// List directory contents

43

const files = fs.readdirSync("/");

44

console.log(files); // ["hello.txt", "mydir"]

45

46

// Check if file exists

47

const exists = fs.existsSync("/hello.txt");

48

console.log(exists); // true

49

50

// Use async operations

51

fs.readFile("/hello.txt", "utf8", (err, data) => {

52

if (!err) {

53

console.log(data); // "Hello, World!"

54

}

55

});

56

57

// Use promises

58

const data = await fs.promises.readFile("/hello.txt", "utf8");

59

console.log(data); // "Hello, World!"

60

```

61

62

## Architecture

63

64

Metro Memory FS is built around several key components:

65

66

- **Memory Filesystem**: Complete in-memory representation of files and directories using Map-based storage

67

- **Path Resolution**: Cross-platform path handling supporting both POSIX and Windows path conventions

68

- **Node Compatibility**: Full API compatibility with Node.js fs module including sync, async, and promise variants

69

- **File Descriptors**: Low-level file descriptor support for fine-grained file operations

70

- **Streams**: Readable and writable stream implementations for large file handling

71

- **File Watching**: Event-based file system monitoring with recursive watching support

72

73

## Capabilities

74

75

### File Operations

76

77

Core file reading, writing, and manipulation operations supporting both synchronous and asynchronous patterns with full Node.js fs API compatibility.

78

79

```javascript { .api }

80

// Synchronous operations

81

writeFileSync(path: string | Buffer, data: string | Buffer, options?: WriteFileOptions): void;

82

readFileSync(path: string | Buffer, options?: ReadFileOptions): string | Buffer;

83

existsSync(path: string | Buffer): boolean;

84

unlinkSync(path: string | Buffer): void;

85

copyFileSync(src: string | Buffer, dest: string | Buffer, flags?: number): void;

86

accessSync(path: string | Buffer, mode?: number): void;

87

truncateSync(path: string | Buffer | number, len?: number): void;

88

89

// Asynchronous operations

90

writeFile(path: string | Buffer, data: string | Buffer, options?: WriteFileOptions, callback?: (err?: Error) => void): void;

91

readFile(path: string | Buffer, options?: ReadFileOptions, callback?: (err?: Error, data?: string | Buffer) => void): void;

92

unlink(path: string | Buffer, callback: (err?: Error) => void): void;

93

copyFile(src: string | Buffer, dest: string | Buffer, flags?: number, callback?: (err?: Error) => void): void;

94

access(path: string | Buffer, mode?: number, callback?: (err?: Error) => void): void;

95

truncate(path: string | Buffer, len?: number, callback?: (err?: Error) => void): void;

96

97

interface WriteFileOptions {

98

encoding?: string;

99

mode?: number;

100

flag?: string;

101

}

102

103

interface ReadFileOptions {

104

encoding?: string;

105

flag?: string;

106

}

107

```

108

109

[File Operations](./file-operations.md)

110

111

### Directory Operations

112

113

Directory creation, listing, and removal operations with support for recursive operations and various output formats.

114

115

```javascript { .api }

116

mkdirSync(path: string | Buffer, options?: MkdirOptions): void;

117

readdirSync(path: string | Buffer, options?: ReaddirOptions): string[] | Buffer[] | Dirent[];

118

rmdirSync(path: string | Buffer): void;

119

rmSync(path: string | Buffer, options?: RmOptions): void;

120

mkdtempSync(prefix: string, options?: MktempOptions): string;

121

122

mkdir(path: string | Buffer, options?: MkdirOptions, callback?: (err?: Error) => void): void;

123

readdir(path: string | Buffer, options?: ReaddirOptions, callback?: (err?: Error, files?: string[] | Buffer[] | Dirent[]) => void): void;

124

125

interface MkdirOptions {

126

recursive?: boolean;

127

mode?: number;

128

}

129

130

interface ReaddirOptions {

131

encoding?: string;

132

withFileTypes?: boolean;

133

}

134

135

interface RmOptions {

136

recursive?: boolean;

137

force?: boolean;

138

}

139

```

140

141

[Directory Operations](./directory-operations.md)

142

143

### File Descriptors

144

145

Low-level file descriptor operations for fine-grained control over file access, positioning, and data manipulation.

146

147

```javascript { .api }

148

openSync(path: string | Buffer, flags: string | number, mode?: number): number;

149

closeSync(fd: number): void;

150

readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number;

151

writeSync(fd: number, buffer: Buffer | string, offset?: number, length?: number | string, position?: number): number;

152

fstatSync(fd: number): Stats;

153

fchmodSync(fd: number, mode: number | string): void;

154

fsyncSync(fd: number): void;

155

fdatasyncSync(fd: number): void;

156

157

open(path: string | Buffer, flags: string | number, mode?: number, callback?: (err?: Error, fd?: number) => void): void;

158

close(fd: number, callback: (err?: Error) => void): void;

159

read(fd: number, buffer: Buffer, offset: number, length: number, position?: number, callback?: (err?: Error, bytesRead?: number) => void): void;

160

write(fd: number, buffer: Buffer | string, offset?: number, length?: number, position?: number, callback?: (err?: Error, bytesWritten?: number) => void): void;

161

```

162

163

[File Descriptors](./file-descriptors.md)

164

165

### Symbolic Links

166

167

Symbolic link and hard link creation, reading, and path resolution with cross-platform support.

168

169

```javascript { .api }

170

symlinkSync(target: string | Buffer, path: string | Buffer, type?: string): void;

171

readlinkSync(path: string | Buffer, options?: ReadlinkOptions): string | Buffer;

172

linkSync(existingPath: string | Buffer, newPath: string | Buffer): void;

173

realpathSync(path: string | Buffer): string;

174

175

symlink(target: string | Buffer, path: string | Buffer, type?: string, callback?: (err?: Error) => void): void;

176

readlink(path: string | Buffer, options?: ReadlinkOptions, callback?: (err?: Error, linkString?: string | Buffer) => void): void;

177

realpath(path: string | Buffer, callback: (err?: Error, resolvedPath?: string) => void): void;

178

179

interface ReadlinkOptions {

180

encoding?: string;

181

}

182

```

183

184

[Symbolic Links](./symbolic-links.md)

185

186

### Streams

187

188

Readable and writable stream implementations for efficient handling of large files with position control and event handling.

189

190

```javascript { .api }

191

createReadStream(path: string | Buffer, options?: ReadStreamOptions): ReadStream;

192

createWriteStream(path: string | Buffer, options?: WriteStreamOptions): WriteStream;

193

194

interface ReadStreamOptions {

195

flags?: string;

196

encoding?: string;

197

fd?: number;

198

mode?: number;

199

autoClose?: boolean;

200

start?: number;

201

end?: number;

202

highWaterMark?: number;

203

}

204

205

interface WriteStreamOptions {

206

flags?: string;

207

encoding?: string;

208

fd?: number;

209

mode?: number;

210

autoClose?: boolean;

211

start?: number;

212

emitClose?: boolean;

213

}

214

```

215

216

[Streams](./streams.md)

217

218

### File Watching

219

220

File system monitoring capabilities with event-driven notifications for file and directory changes, supporting recursive watching.

221

222

```javascript { .api }

223

watch(filename: string | Buffer, options?: WatchOptions, listener?: WatchListener): FSWatcher;

224

225

interface WatchOptions {

226

encoding?: string;

227

persistent?: boolean;

228

recursive?: boolean;

229

}

230

231

type WatchListener = (eventType: 'rename' | 'change', filename?: string | Buffer) => void;

232

233

interface FSWatcher {

234

close(): void;

235

on(event: 'change', listener: WatchListener): this;

236

on(event: 'error', listener: (error: Error) => void): this;

237

on(event: 'close', listener: () => void): this;

238

}

239

```

240

241

[File Watching](./file-watching.md)

242

243

### Stats and Permissions

244

245

File statistics, permission checking, and metadata operations with full compatibility for Node.js Stats objects.

246

247

```javascript { .api }

248

statSync(path: string | Buffer): Stats;

249

lstatSync(path: string | Buffer): Stats;

250

chmodSync(path: string | Buffer, mode: number | string): void;

251

lchmodSync(path: string | Buffer, mode: number | string): void;

252

renameSync(oldPath: string | Buffer, newPath: string | Buffer): void;

253

254

stat(path: string | Buffer, callback: (err?: Error, stats?: Stats) => void): void;

255

lstat(path: string | Buffer, callback: (err?: Error, stats?: Stats) => void): void;

256

chmod(path: string | Buffer, mode: number | string, callback?: (err?: Error) => void): void;

257

rename(oldPath: string | Buffer, newPath: string | Buffer, callback?: (err?: Error) => void): void;

258

259

interface Stats {

260

isFile(): boolean;

261

isDirectory(): boolean;

262

isSymbolicLink(): boolean;

263

isBlockDevice(): boolean;

264

isCharacterDevice(): boolean;

265

isFIFO(): boolean;

266

isSocket(): boolean;

267

size: number;

268

mode: number;

269

uid: number;

270

gid: number;

271

// ... other stat properties

272

}

273

```

274

275

[Stats and Permissions](./stats-permissions.md)

276

277

## Promise API

278

279

```javascript { .api }

280

interface MemoryFs {

281

promises: {

282

writeFile(path: string | Buffer, data: string | Buffer, options?: WriteFileOptions): Promise<void>;

283

readFile(path: string | Buffer, options?: ReadFileOptions): Promise<string | Buffer>;

284

mkdir(path: string | Buffer, options?: MkdirOptions): Promise<void>;

285

readdir(path: string | Buffer, options?: ReaddirOptions): Promise<string[] | Buffer[] | Dirent[]>;

286

stat(path: string | Buffer): Promise<Stats>;

287

lstat(path: string | Buffer): Promise<Stats>;

288

access(path: string | Buffer, mode?: number): Promise<void>;

289

unlink(path: string | Buffer): Promise<void>;

290

copyFile(src: string | Buffer, dest: string | Buffer, flags?: number): Promise<void>;

291

symlink(target: string | Buffer, path: string | Buffer, type?: string): Promise<void>;

292

readlink(path: string | Buffer, options?: ReadlinkOptions): Promise<string | Buffer>;

293

realpath(path: string | Buffer): Promise<string>;

294

truncate(path: string | Buffer, len?: number): Promise<void>;

295

chmod(path: string | Buffer, mode: number | string): Promise<void>;

296

lchmod(path: string | Buffer, mode: number | string): Promise<void>;

297

rename(oldPath: string | Buffer, newPath: string | Buffer): Promise<void>;

298

open(path: string | Buffer, flags: string | number, mode?: number): Promise<number>;

299

rmdir(path: string | Buffer): Promise<void>;

300

utimes(path: string | Buffer, atime: number | Date, mtime: number | Date): Promise<void>;

301

// ... other promise methods

302

};

303

}

304

```

305

306

## Constructor Options

307

308

```javascript { .api }

309

interface MemoryFsOptions {

310

/** Platform type for path handling */

311

platform?: 'posix' | 'win32';

312

/** Function to get current working directory for relative path resolution */

313

cwd?: () => string;

314

}

315

316

class MemoryFs {

317

constructor(options?: MemoryFsOptions);

318

319

/** Reset filesystem to initial empty state */

320

reset(): void;

321

322

/** Node.js filesystem constants */

323

constants: typeof constants;

324

325

/** Dirent class for directory entries */

326

Dirent: typeof Dirent;

327

}

328

```

329

330

## Constants

331

332

```javascript { .api }

333

interface FsConstants {

334

// File access constants

335

F_OK: number; // File existence

336

R_OK: number; // Read permission

337

W_OK: number; // Write permission

338

X_OK: number; // Execute permission

339

340

// Copy file constants

341

COPYFILE_EXCL: number; // Exclusive copy (fail if destination exists)

342

COPYFILE_FICLONE: number; // Clone file

343

344

// File mode constants

345

S_IRUSR: number; // User read permission

346

S_IWUSR: number; // User write permission

347

S_IXUSR: number; // User execute permission

348

S_IRGRP: number; // Group read permission

349

S_IWGRP: number; // Group write permission

350

S_IXGRP: number; // Group execute permission

351

S_IROTH: number; // Other read permission

352

S_IWOTH: number; // Other write permission

353

S_IXOTH: number; // Other execute permission

354

355

// File type constants

356

S_IFMT: number; // File type mask

357

S_IFREG: number; // Regular file

358

S_IFDIR: number; // Directory

359

S_IFLNK: number; // Symbolic link

360

// ... other constants

361

}

362

```

363

364

## Error Handling

365

366

Metro Memory FS throws standard Node.js filesystem errors with appropriate error codes:

367

368

- `ENOENT` - File or directory not found

369

- `EEXIST` - File or directory already exists

370

- `EISDIR` - Is a directory (when file expected)

371

- `ENOTDIR` - Not a directory (when directory expected)

372

- `EPERM` - Operation not permitted

373

- `EBADF` - Bad file descriptor

374

- `EMFILE` - Too many open files

375

- `ELOOP` - Too many symbolic links

376

- `EINVAL` - Invalid argument

377

- `ENOTEMPTY` - Directory not empty

378

- `ENAMETOOLONG` - Filename too long