or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asset-system.mdbuild-configuration.mdbundle-system.mdenvironment-system.mdfile-system.mdindex.mdplugin-system.md

file-system.mddocs/

0

# File System

1

2

Cross-platform file system abstraction with caching, watching, and invalidation support for build operations.

3

4

## Capabilities

5

6

### FileSystem Interface

7

8

Complete file system abstraction with async and sync operations.

9

10

```typescript { .api }

11

/**

12

* Cross-platform file system interface

13

*/

14

interface FileSystem {

15

/** Read file contents as Buffer */

16

readFile(filePath: FilePath): Promise<Buffer>;

17

/** Read file contents as string with encoding */

18

readFile(filePath: FilePath, encoding: Encoding): Promise<string>;

19

/** Read file contents synchronously as Buffer */

20

readFileSync(filePath: FilePath): Buffer;

21

/** Read file contents synchronously as string */

22

readFileSync(filePath: FilePath, encoding: Encoding): string;

23

24

/** Write file contents */

25

writeFile(filePath: FilePath, contents: Buffer | string, options?: ?FileOptions): Promise<void>;

26

/** Copy file from source to destination */

27

copyFile(source: FilePath, destination: FilePath, flags?: number): Promise<void>;

28

29

/** Get file statistics */

30

stat(filePath: FilePath): Promise<Stats>;

31

/** Get file statistics synchronously */

32

statSync(filePath: FilePath): Stats;

33

/** Get file statistics without following symlinks */

34

lstat(filePath: FilePath): Promise<Stats>;

35

/** Get file statistics synchronously without following symlinks */

36

lstatSync(filePath: FilePath): Stats;

37

38

/** Read directory contents */

39

readdir(path: FilePath): Promise<Array<string>>;

40

/** Read directory contents with file types */

41

readdir(path: FilePath, opts: {withFileTypes: true}): Promise<Array<Dirent>>;

42

/** Read directory contents synchronously */

43

readdirSync(path: FilePath): Array<string>;

44

/** Read directory contents synchronously with file types */

45

readdirSync(path: FilePath, opts: {withFileTypes: true}): Array<Dirent>;

46

47

/** Create symbolic link */

48

symlink(target: FilePath, path: FilePath): Promise<void>;

49

/** Delete file */

50

unlink(path: FilePath): Promise<void>;

51

/** Resolve real path of symlink */

52

realpath(path: FilePath): Promise<FilePath>;

53

/** Resolve real path of symlink synchronously */

54

realpathSync(path: FilePath): FilePath;

55

/** Read symbolic link target */

56

readlink(path: FilePath): Promise<FilePath>;

57

/** Read symbolic link target synchronously */

58

readlinkSync(path: FilePath): FilePath;

59

60

/** Check if file or directory exists */

61

exists(path: FilePath): Promise<boolean>;

62

/** Check if file or directory exists synchronously */

63

existsSync(path: FilePath): boolean;

64

65

/** Create directory recursively */

66

mkdirp(path: FilePath): Promise<void>;

67

/** Remove directory and contents recursively */

68

rimraf(path: FilePath): Promise<void>;

69

/** Copy directory recursively */

70

ncp(source: FilePath, destination: FilePath): Promise<void>;

71

72

/** Create readable stream */

73

createReadStream(path: FilePath, options?: ?FileOptions): Readable;

74

/** Create writable stream */

75

createWriteStream(path: FilePath, options?: ?FileOptions): Writable;

76

77

/** Get current working directory */

78

cwd(): FilePath;

79

/** Change current working directory */

80

chdir(dir: FilePath): void;

81

82

/** Watch directory for changes */

83

watch(

84

dir: FilePath,

85

fn: (err: ?Error, events: Array<Event>) => void,

86

opts: WatchOptions

87

): AsyncSubscription;

88

89

/** Get events since last call */

90

getEventsSince(

91

dir: FilePath,

92

snapshot: FilePath,

93

opts: WatchOptions

94

): Promise<Array<Event>>;

95

96

/** Write atomic snapshot of directory state */

97

writeSnapshot(

98

dir: FilePath,

99

snapshot: FilePath,

100

opts: WatchOptions

101

): Promise<void>;

102

103

/** Find first ancestor file matching name */

104

findAncestorFile(

105

filenames: Array<string>,

106

from: FilePath,

107

root: FilePath

108

): Promise<?FilePath>;

109

110

/** Find node_modules package */

111

findNodeModule(moduleName: string, from: FilePath): Promise<?FilePath>;

112

113

/** Find first file matching patterns */

114

findFirstFile(filePaths: Array<FilePath>): Promise<?FilePath>;

115

}

116

```

117

118

### File Statistics

119

120

File system statistics and metadata.

121

122

```typescript { .api }

123

/**

124

* File statistics interface

125

*/

126

interface Stats {

127

/** File size in bytes */

128

size: number;

129

/** Last access time */

130

atime: Date;

131

/** Last modified time */

132

mtime: Date;

133

/** Creation time */

134

ctime: Date;

135

/** Birth time (creation on some systems) */

136

birthtime: Date;

137

/** Device ID */

138

dev: number;

139

/** Inode number */

140

ino: number;

141

/** File mode */

142

mode: number;

143

/** Number of hard links */

144

nlink: number;

145

/** User ID */

146

uid: number;

147

/** Group ID */

148

gid: number;

149

/** Device ID for special files */

150

rdev: number;

151

/** Block size for I/O */

152

blksize: number;

153

/** Number of blocks allocated */

154

blocks: number;

155

156

/** Check if this is a file */

157

isFile(): boolean;

158

/** Check if this is a directory */

159

isDirectory(): boolean;

160

/** Check if this is a symbolic link */

161

isSymbolicLink(): boolean;

162

/** Check if this is a block device */

163

isBlockDevice(): boolean;

164

/** Check if this is a character device */

165

isCharacterDevice(): boolean;

166

/** Check if this is a FIFO */

167

isFIFO(): boolean;

168

/** Check if this is a socket */

169

isSocket(): boolean;

170

}

171

```

172

173

### Directory Entries

174

175

Directory entry information with file types.

176

177

```typescript { .api }

178

/**

179

* Directory entry with file type information

180

*/

181

interface Dirent {

182

/** Entry name */

183

name: string;

184

185

/** Check if this is a file */

186

isFile(): boolean;

187

/** Check if this is a directory */

188

isDirectory(): boolean;

189

/** Check if this is a symbolic link */

190

isSymbolicLink(): boolean;

191

/** Check if this is a block device */

192

isBlockDevice(): boolean;

193

/** Check if this is a character device */

194

isCharacterDevice(): boolean;

195

/** Check if this is a FIFO */

196

isFIFO(): boolean;

197

/** Check if this is a socket */

198

isSocket(): boolean;

199

}

200

```

201

202

### File Options

203

204

Configuration options for file operations.

205

206

```typescript { .api }

207

/**

208

* File operation options

209

*/

210

interface FileOptions {

211

/** File mode permissions */

212

mode?: number;

213

/** File encoding */

214

encoding?: Encoding;

215

/** File flags */

216

flag?: string;

217

}

218

219

/**

220

* Directory reading options

221

*/

222

interface ReaddirOptions {

223

/** Include file type information */

224

withFileTypes?: boolean;

225

/** Encoding for file names */

226

encoding?: Encoding;

227

}

228

229

/**

230

* File encoding types

231

*/

232

type Encoding =

233

| 'ascii'

234

| 'utf8'

235

| 'utf-8'

236

| 'utf16le'

237

| 'ucs2'

238

| 'ucs-2'

239

| 'base64'

240

| 'base64url'

241

| 'latin1'

242

| 'binary'

243

| 'hex';

244

```

245

246

### File Watching

247

248

File system watching and change detection.

249

250

```typescript { .api }

251

/**

252

* File watching options

253

*/

254

interface WatchOptions {

255

/** Ignore patterns */

256

ignore?: Array<FilePath>;

257

/** Include patterns */

258

include?: Array<FilePath>;

259

}

260

261

/**

262

* File system event

263

*/

264

interface Event {

265

/** Event type */

266

type: 'create' | 'update' | 'delete';

267

/** File path that changed */

268

path: FilePath;

269

}

270

271

/**

272

* Async subscription for cleanup

273

*/

274

interface AsyncSubscription {

275

/** Unsubscribe from events */

276

unsubscribe(): Promise<void>;

277

}

278

```

279

280

### Cache Interface

281

282

Build cache abstraction for storing and retrieving build artifacts.

283

284

```typescript { .api }

285

/**

286

* Build cache interface

287

*/

288

interface Cache {

289

/** Ensure cache is ready */

290

ensure(): Promise<void>;

291

292

/** Check if key exists in cache */

293

has(key: string): Promise<boolean>;

294

/** Get cached value */

295

get<T>(key: string): Promise<?T>;

296

/** Set cached value */

297

set(key: string, value: mixed): Promise<void>;

298

299

/** Get cached value as stream */

300

getStream(key: string): Readable;

301

/** Set cached value from stream */

302

setStream(key: string, stream: Readable): Promise<void>;

303

304

/** Get cached blob */

305

getBlob(key: string): Promise<Buffer>;

306

/** Set cached blob */

307

setBlob(key: string, contents: Buffer | string): Promise<void>;

308

309

/** Check if large blob exists */

310

hasLargeBlob(key: string): Promise<boolean>;

311

/** Get large cached blob */

312

getLargeBlob(key: string): Promise<Buffer>;

313

/** Set large cached blob */

314

setLargeBlob(

315

key: string,

316

contents: Buffer | string,

317

options?: {signal?: AbortSignal}

318

): Promise<void>;

319

/** Delete large cached blob */

320

deleteLargeBlob(key: string): Promise<void>;

321

322

/** Get cached buffer (legacy) */

323

getBuffer(key: string): Promise<?Buffer>;

324

325

/** Refresh cache state */

326

refresh(): void;

327

}

328

```

329

330

### File Invalidation

331

332

File change invalidation tracking for cache management.

333

334

```typescript { .api }

335

/**

336

* File creation invalidation types

337

*/

338

type FileCreateInvalidation =

339

| GlobInvalidation

340

| FileInvalidation

341

| FileAboveInvalidation;

342

343

/**

344

* Glob pattern invalidation

345

*/

346

interface GlobInvalidation {

347

type: 'glob';

348

glob: Glob;

349

}

350

351

/**

352

* Specific file invalidation

353

*/

354

interface FileInvalidation {

355

type: 'file';

356

filePath: FilePath;

357

}

358

359

/**

360

* Ancestor file invalidation

361

*/

362

interface FileAboveInvalidation {

363

type: 'file-above';

364

fileName: string;

365

aboveFilePath: FilePath;

366

}

367

```

368

369

**Usage Examples:**

370

371

```typescript

372

import type { FileSystem, Cache, WatchOptions } from '@parcel/types';

373

374

// Basic file operations

375

async function processFiles(fs: FileSystem) {

376

// Read file contents

377

const buffer = await fs.readFile('/path/to/file.js');

378

const text = await fs.readFile('/path/to/file.js', 'utf8');

379

380

// Write processed contents

381

const processed = transformCode(text);

382

await fs.writeFile('/path/to/output.js', processed);

383

384

// Check file existence

385

if (await fs.exists('/path/to/config.json')) {

386

const config = await fs.readFile('/path/to/config.json', 'utf8');

387

console.log('Config:', JSON.parse(config));

388

}

389

390

// Get file statistics

391

const stats = await fs.stat('/path/to/file.js');

392

console.log(`File size: ${stats.size} bytes`);

393

console.log(`Modified: ${stats.mtime}`);

394

}

395

396

// Directory operations

397

async function processDirectory(fs: FileSystem) {

398

// Create directory

399

await fs.mkdirp('/path/to/new/dir');

400

401

// Read directory contents

402

const files = await fs.readdir('/path/to/dir');

403

console.log('Files:', files);

404

405

// Read with file types

406

const entries = await fs.readdir('/path/to/dir', { withFileTypes: true });

407

for (const entry of entries) {

408

if (entry.isFile()) {

409

console.log(`File: ${entry.name}`);

410

} else if (entry.isDirectory()) {

411

console.log(`Directory: ${entry.name}`);

412

}

413

}

414

415

// Copy directory

416

await fs.ncp('/source/dir', '/dest/dir');

417

}

418

419

// File watching

420

async function watchFiles(fs: FileSystem) {

421

const watchOptions: WatchOptions = {

422

ignore: ['node_modules/**', '*.log'],

423

include: ['src/**/*.{js,ts,jsx,tsx}']

424

};

425

426

const subscription = fs.watch('/project/root', (err, events) => {

427

if (err) {

428

console.error('Watch error:', err);

429

return;

430

}

431

432

for (const event of events) {

433

console.log(`${event.type}: ${event.path}`);

434

435

if (event.type === 'create' && event.path.endsWith('.js')) {

436

console.log('New JavaScript file created');

437

}

438

}

439

}, watchOptions);

440

441

// Later: cleanup

442

await subscription.unsubscribe();

443

}

444

445

// Cache operations

446

async function useCache(cache: Cache) {

447

const cacheKey = 'processed-file-hash123';

448

449

// Check if cached

450

if (await cache.has(cacheKey)) {

451

const cached = await cache.get(cacheKey);

452

console.log('Using cached result:', cached);

453

return cached;

454

}

455

456

// Process and cache

457

const result = await expensiveProcessing();

458

await cache.set(cacheKey, result);

459

460

// Cache large blobs

461

const largeBuffer = generateLargeAsset();

462

await cache.setLargeBlob('large-asset-key', largeBuffer);

463

464

return result;

465

}

466

467

// File utilities

468

async function findProjectFiles(fs: FileSystem) {

469

// Find package.json

470

const packageJson = await fs.findAncestorFile(

471

['package.json'],

472

'/project/src/components',

473

'/project'

474

);

475

476

if (packageJson) {

477

console.log('Found package.json at:', packageJson);

478

}

479

480

// Find node_modules package

481

const lodashPath = await fs.findNodeModule('lodash', '/project/src');

482

if (lodashPath) {

483

console.log('Found lodash at:', lodashPath);

484

}

485

486

// Find first existing config file

487

const configFile = await fs.findFirstFile([

488

'/project/.parcelrc',

489

'/project/parcel.config.js',

490

'/project/parcel.config.json'

491

]);

492

493

if (configFile) {

494

console.log('Using config:', configFile);

495

}

496

}

497

```