@componentor/fs 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,544 @@
1
+ /**
2
+ * File system constants matching Node.js fs.constants
3
+ */
4
+ interface FSConstants {
5
+ F_OK: number;
6
+ R_OK: number;
7
+ W_OK: number;
8
+ X_OK: number;
9
+ COPYFILE_EXCL: number;
10
+ COPYFILE_FICLONE: number;
11
+ COPYFILE_FICLONE_FORCE: number;
12
+ O_RDONLY: number;
13
+ O_WRONLY: number;
14
+ O_RDWR: number;
15
+ O_CREAT: number;
16
+ O_EXCL: number;
17
+ O_TRUNC: number;
18
+ O_APPEND: number;
19
+ S_IFMT: number;
20
+ S_IFREG: number;
21
+ S_IFDIR: number;
22
+ S_IFLNK: number;
23
+ }
24
+ /**
25
+ * Configuration options for OPFS instance
26
+ */
27
+ interface OPFSOptions {
28
+ /** Use synchronous access handles when available (default: true) */
29
+ useSync?: boolean;
30
+ /** Enable verbose logging (default: false) */
31
+ verbose?: boolean;
32
+ }
33
+ /**
34
+ * Options for readFile operation
35
+ */
36
+ interface ReadFileOptions {
37
+ /** Text encoding (e.g., 'utf-8'). If not provided, returns Uint8Array */
38
+ encoding?: string;
39
+ }
40
+ /**
41
+ * Options for writeFile operation
42
+ */
43
+ interface WriteFileOptions {
44
+ /** Text encoding for string data */
45
+ encoding?: string;
46
+ }
47
+ /**
48
+ * Entry for batch file write operation
49
+ */
50
+ interface BatchWriteEntry {
51
+ /** File path to write */
52
+ path: string;
53
+ /** Data to write (string or binary) */
54
+ data: string | Uint8Array;
55
+ }
56
+ /**
57
+ * Result entry for batch file read operation
58
+ */
59
+ interface BatchReadResult {
60
+ /** File path */
61
+ path: string;
62
+ /** File data (null if file doesn't exist or error occurred) */
63
+ data: Uint8Array | null;
64
+ /** Error if read failed */
65
+ error?: Error;
66
+ }
67
+ /**
68
+ * Options for readdir operation
69
+ */
70
+ interface ReaddirOptions {
71
+ /** Return Dirent objects instead of strings */
72
+ withFileTypes?: boolean;
73
+ }
74
+ /**
75
+ * Directory entry (Dirent-like object)
76
+ */
77
+ interface Dirent {
78
+ name: string;
79
+ isFile(): boolean;
80
+ isDirectory(): boolean;
81
+ isSymbolicLink(): boolean;
82
+ }
83
+ /**
84
+ * File statistics
85
+ */
86
+ interface Stats {
87
+ type: 'file' | 'dir' | 'symlink';
88
+ size: number;
89
+ mode: number;
90
+ ctime: Date;
91
+ ctimeMs: number;
92
+ mtime: Date;
93
+ mtimeMs: number;
94
+ target?: string;
95
+ isFile(): boolean;
96
+ isDirectory(): boolean;
97
+ isSymbolicLink(): boolean;
98
+ }
99
+ /**
100
+ * Options for rm operation
101
+ */
102
+ interface RmOptions {
103
+ /** Remove directories and their contents recursively */
104
+ recursive?: boolean;
105
+ /** Ignore if path doesn't exist */
106
+ force?: boolean;
107
+ }
108
+ /**
109
+ * Options for cp operation
110
+ */
111
+ interface CpOptions {
112
+ /** Copy directories recursively */
113
+ recursive?: boolean;
114
+ /** Overwrite existing files */
115
+ force?: boolean;
116
+ /** Throw if destination exists */
117
+ errorOnExist?: boolean;
118
+ }
119
+ /**
120
+ * Options for watch operation
121
+ */
122
+ interface WatchOptions {
123
+ /** Keep the process running while watching (default: true) */
124
+ persistent?: boolean;
125
+ /** Watch subdirectories recursively */
126
+ recursive?: boolean;
127
+ /** Abort signal to stop watching */
128
+ signal?: AbortSignal;
129
+ /** Encoding for filename (default: 'utf8') */
130
+ encoding?: string;
131
+ }
132
+ /**
133
+ * Watch event
134
+ */
135
+ interface WatchEvent {
136
+ eventType: 'rename' | 'change';
137
+ filename: string;
138
+ }
139
+ /**
140
+ * File watcher
141
+ */
142
+ interface FSWatcher {
143
+ close(): void;
144
+ ref(): FSWatcher;
145
+ unref(): FSWatcher;
146
+ [Symbol.asyncIterator](): AsyncIterator<WatchEvent>;
147
+ }
148
+ /**
149
+ * Read stream options
150
+ */
151
+ interface ReadStreamOptions {
152
+ /** Start reading from this byte position */
153
+ start?: number;
154
+ /** Stop reading at this byte position */
155
+ end?: number;
156
+ /** Chunk size for reading (default: 64KB) */
157
+ highWaterMark?: number;
158
+ }
159
+ /**
160
+ * Write stream options
161
+ */
162
+ interface WriteStreamOptions {
163
+ /** File open flags (default: 'w') */
164
+ flags?: string;
165
+ /** Start writing at this byte position */
166
+ start?: number;
167
+ }
168
+ /**
169
+ * Symlink definition for batch operations
170
+ */
171
+ interface SymlinkDefinition {
172
+ target: string;
173
+ path: string;
174
+ }
175
+ /**
176
+ * Result of read operation on FileHandle
177
+ */
178
+ interface ReadResult {
179
+ bytesRead: number;
180
+ buffer: Uint8Array;
181
+ }
182
+ /**
183
+ * Result of write operation on FileHandle
184
+ */
185
+ interface WriteResult {
186
+ bytesWritten: number;
187
+ buffer: Uint8Array;
188
+ }
189
+ /**
190
+ * FileHandle interface (returned by open())
191
+ */
192
+ interface FileHandle {
193
+ fd: number;
194
+ read(buffer: Uint8Array, offset?: number, length?: number, position?: number | null): Promise<ReadResult>;
195
+ write(buffer: Uint8Array, offset?: number, length?: number, position?: number | null): Promise<WriteResult>;
196
+ close(): Promise<void>;
197
+ stat(): Promise<Stats>;
198
+ truncate(len?: number): Promise<void>;
199
+ sync(): Promise<void>;
200
+ datasync(): Promise<void>;
201
+ readFile(options?: ReadFileOptions): Promise<string | Uint8Array>;
202
+ writeFile(data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
203
+ appendFile(data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
204
+ [Symbol.asyncDispose](): Promise<void>;
205
+ }
206
+ /**
207
+ * Directory handle (returned by opendir())
208
+ */
209
+ interface Dir {
210
+ path: string;
211
+ read(): Promise<Dirent | null>;
212
+ close(): Promise<void>;
213
+ [Symbol.asyncIterator](): AsyncIterableIterator<Dirent>;
214
+ }
215
+ /**
216
+ * Disk usage result
217
+ */
218
+ interface DiskUsage {
219
+ path: string;
220
+ size: number;
221
+ }
222
+ /**
223
+ * Filesystem statistics (similar to Node.js fs.statfs)
224
+ */
225
+ interface StatFs {
226
+ /** Filesystem type (always 0 for OPFS) */
227
+ type: number;
228
+ /** Optimal transfer block size (simulated as 4096) */
229
+ bsize: number;
230
+ /** Total blocks in filesystem */
231
+ blocks: number;
232
+ /** Free blocks in filesystem */
233
+ bfree: number;
234
+ /** Available blocks for unprivileged users */
235
+ bavail: number;
236
+ /** Total file nodes (0 - not available in browser) */
237
+ files: number;
238
+ /** Free file nodes (0 - not available in browser) */
239
+ ffree: number;
240
+ /** Bytes used by origin (from Storage API) */
241
+ usage: number;
242
+ /** Total bytes available to origin (from Storage API) */
243
+ quota: number;
244
+ }
245
+ /**
246
+ * Internal symlink cache structure
247
+ */
248
+ type SymlinkCache = Record<string, string>;
249
+ /**
250
+ * Watch callback function
251
+ */
252
+ type WatchCallback = (eventType: string, filename: string) => void;
253
+ /**
254
+ * Internal watch registration
255
+ */
256
+ interface WatchRegistration {
257
+ path: string;
258
+ callbacks: Set<WatchCallback>;
259
+ recursive: boolean;
260
+ }
261
+
262
+ /**
263
+ * File system constants matching Node.js fs.constants
264
+ */
265
+ declare const constants: FSConstants;
266
+
267
+ type Backend = 'main' | 'worker';
268
+ interface OPFSHybridOptions {
269
+ /** Backend for read operations (default: 'main') */
270
+ read?: Backend;
271
+ /** Backend for write operations (default: 'worker') */
272
+ write?: Backend;
273
+ /** Worker URL (required if using worker backend) */
274
+ workerUrl?: URL | string;
275
+ /** Enable verbose logging */
276
+ verbose?: boolean;
277
+ }
278
+ /**
279
+ * Hybrid OPFS implementation that routes operations to optimal backends
280
+ */
281
+ declare class OPFSHybrid {
282
+ private mainFs;
283
+ private workerFs;
284
+ private readBackend;
285
+ private writeBackend;
286
+ private workerUrl?;
287
+ private workerReady;
288
+ private verbose;
289
+ constructor(options?: OPFSHybridOptions);
290
+ /**
291
+ * Wait for all backends to be ready
292
+ */
293
+ ready(): Promise<void>;
294
+ /**
295
+ * Terminate worker if active
296
+ */
297
+ terminate(): void;
298
+ private getReadFs;
299
+ private getWriteFs;
300
+ readFile(path: string, options?: ReadFileOptions): Promise<Uint8Array | string>;
301
+ readFileBatch(paths: string[]): Promise<BatchReadResult[]>;
302
+ readdir(path: string, options?: ReaddirOptions): Promise<string[] | Dirent[]>;
303
+ stat(path: string): Promise<Stats>;
304
+ lstat(path: string): Promise<Stats>;
305
+ exists(path: string): Promise<boolean>;
306
+ access(path: string, mode?: number): Promise<void>;
307
+ readlink(path: string): Promise<string>;
308
+ realpath(path: string): Promise<string>;
309
+ statfs(path?: string): Promise<StatFs>;
310
+ du(path: string): Promise<DiskUsage>;
311
+ writeFile(path: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
312
+ writeFileBatch(entries: BatchWriteEntry[]): Promise<void>;
313
+ appendFile(path: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
314
+ mkdir(path: string): Promise<void>;
315
+ rmdir(path: string): Promise<void>;
316
+ unlink(path: string): Promise<void>;
317
+ truncate(path: string, len?: number): Promise<void>;
318
+ symlink(target: string, path: string): Promise<void>;
319
+ symlinkBatch(symlinks: SymlinkDefinition[]): Promise<void>;
320
+ rename(oldPath: string, newPath: string): Promise<void>;
321
+ copyFile(src: string, dest: string, mode?: number): Promise<void>;
322
+ cp(src: string, dest: string, options?: CpOptions): Promise<void>;
323
+ rm(path: string, options?: RmOptions): Promise<void>;
324
+ chmod(path: string, mode: number): Promise<void>;
325
+ chown(path: string, uid: number, gid: number): Promise<void>;
326
+ utimes(path: string, atime: Date | number, mtime: Date | number): Promise<void>;
327
+ lutimes(path: string, atime: Date | number, mtime: Date | number): Promise<void>;
328
+ mkdtemp(prefix: string): Promise<string>;
329
+ /**
330
+ * Reset internal caches on both backends
331
+ */
332
+ resetCache(): Promise<void>;
333
+ /**
334
+ * Force full garbage collection on both backends
335
+ * More aggressive than resetCache() - reinitializes the worker's OPFS instance
336
+ */
337
+ gc(): Promise<void>;
338
+ }
339
+
340
+ /** Extended options that include hybrid mode support */
341
+ interface OPFSExtendedOptions extends OPFSOptions {
342
+ /** Worker script URL - when provided, enables hybrid mode (reads on main, writes on worker) */
343
+ workerUrl?: URL | string;
344
+ /** Override read backend when using hybrid mode (default: 'main') */
345
+ read?: Backend;
346
+ /** Override write backend when using hybrid mode (default: 'worker') */
347
+ write?: Backend;
348
+ }
349
+ /**
350
+ * OPFS-based filesystem implementation compatible with Node.js fs/promises API
351
+ *
352
+ * When `workerUrl` is provided, automatically uses hybrid mode for optimal performance:
353
+ * - Reads on main thread (no message passing overhead)
354
+ * - Writes on worker (sync access handles are faster)
355
+ */
356
+ declare class OPFS {
357
+ private useSync;
358
+ private verbose;
359
+ private handleManager;
360
+ private symlinkManager;
361
+ private packedStorage;
362
+ private watchCallbacks;
363
+ private tmpCounter;
364
+ /** Hybrid instance when workerUrl is provided */
365
+ private hybrid;
366
+ /** File system constants */
367
+ readonly constants: FSConstants;
368
+ constructor(options?: OPFSExtendedOptions);
369
+ /**
370
+ * Wait for the filesystem to be ready (only needed for hybrid mode)
371
+ */
372
+ ready(): Promise<void>;
373
+ /**
374
+ * Terminate any background workers (only needed for hybrid mode)
375
+ */
376
+ terminate(): void;
377
+ private log;
378
+ private logError;
379
+ /**
380
+ * Execute tasks with limited concurrency to avoid overwhelming the system
381
+ * @param items - Array of items to process
382
+ * @param maxConcurrent - Maximum number of concurrent operations (default: 10)
383
+ * @param taskFn - Function to execute for each item
384
+ */
385
+ private limitConcurrency;
386
+ /**
387
+ * Read file contents
388
+ */
389
+ readFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array>;
390
+ /**
391
+ * Read multiple files efficiently in a batch operation
392
+ * Uses packed storage batch read (single index load), falls back to individual files
393
+ * Returns results in the same order as input paths
394
+ */
395
+ readFileBatch(paths: string[]): Promise<BatchReadResult[]>;
396
+ /**
397
+ * Write data to a file
398
+ */
399
+ writeFile(path: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
400
+ /**
401
+ * Write multiple files efficiently in a batch operation
402
+ * Uses packed storage (single file) for maximum performance
403
+ */
404
+ writeFileBatch(entries: BatchWriteEntry[]): Promise<void>;
405
+ /**
406
+ * Create a directory
407
+ */
408
+ mkdir(path: string): Promise<void>;
409
+ /**
410
+ * Remove a directory
411
+ */
412
+ rmdir(path: string): Promise<void>;
413
+ /**
414
+ * Remove a file or symlink
415
+ */
416
+ unlink(path: string): Promise<void>;
417
+ /**
418
+ * Read directory contents
419
+ */
420
+ readdir(path: string, options?: ReaddirOptions): Promise<string[] | Dirent[]>;
421
+ /**
422
+ * Get file/directory statistics (follows symlinks)
423
+ */
424
+ stat(path: string): Promise<Stats>;
425
+ /**
426
+ * Get file/directory statistics (does not follow symlinks)
427
+ */
428
+ lstat(path: string): Promise<Stats>;
429
+ /**
430
+ * Rename a file or directory
431
+ */
432
+ rename(oldPath: string, newPath: string): Promise<void>;
433
+ /**
434
+ * Create a symbolic link
435
+ */
436
+ symlink(target: string, path: string): Promise<void>;
437
+ /**
438
+ * Read symlink target
439
+ */
440
+ readlink(path: string): Promise<string>;
441
+ /**
442
+ * Create multiple symlinks efficiently
443
+ */
444
+ symlinkBatch(links: SymlinkDefinition[]): Promise<void>;
445
+ /**
446
+ * Check file accessibility
447
+ */
448
+ access(path: string, mode?: number): Promise<void>;
449
+ /**
450
+ * Append data to a file
451
+ */
452
+ appendFile(path: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>;
453
+ /**
454
+ * Copy a file
455
+ */
456
+ copyFile(src: string, dest: string, mode?: number): Promise<void>;
457
+ /**
458
+ * Copy files/directories recursively
459
+ */
460
+ cp(src: string, dest: string, options?: CpOptions): Promise<void>;
461
+ /**
462
+ * Check if path exists
463
+ */
464
+ exists(path: string): Promise<boolean>;
465
+ /**
466
+ * Resolve symlinks to get real path
467
+ */
468
+ realpath(path: string): Promise<string>;
469
+ /**
470
+ * Remove files and directories
471
+ */
472
+ rm(path: string, options?: RmOptions): Promise<void>;
473
+ /**
474
+ * Truncate file to specified length
475
+ */
476
+ truncate(path: string, len?: number): Promise<void>;
477
+ /**
478
+ * Create a unique temporary directory
479
+ */
480
+ mkdtemp(prefix: string): Promise<string>;
481
+ /**
482
+ * Change file mode (no-op for OPFS compatibility)
483
+ */
484
+ chmod(path: string, mode: number): Promise<void>;
485
+ /**
486
+ * Change file owner (no-op for OPFS compatibility)
487
+ */
488
+ chown(path: string, uid: number, gid: number): Promise<void>;
489
+ /**
490
+ * Update file timestamps (no-op for OPFS compatibility)
491
+ */
492
+ utimes(path: string, atime: Date | number, mtime: Date | number): Promise<void>;
493
+ /**
494
+ * Update symlink timestamps (no-op)
495
+ */
496
+ lutimes(path: string, atime: Date | number, mtime: Date | number): Promise<void>;
497
+ /**
498
+ * Open file and return FileHandle
499
+ */
500
+ open(path: string, flags?: string | number, mode?: number): Promise<FileHandle>;
501
+ /**
502
+ * Open directory for iteration
503
+ */
504
+ opendir(path: string): Promise<Dir>;
505
+ /**
506
+ * Watch for file changes
507
+ */
508
+ watch(path: string, options?: WatchOptions): FSWatcher;
509
+ /**
510
+ * Create read stream
511
+ */
512
+ createReadStream(path: string, options?: ReadStreamOptions): ReadableStream<Uint8Array>;
513
+ /**
514
+ * Create write stream
515
+ */
516
+ createWriteStream(path: string, options?: WriteStreamOptions): WritableStream<Uint8Array>;
517
+ /**
518
+ * Get file statistics (alias for stat)
519
+ */
520
+ backFile(path: string): Promise<Stats>;
521
+ /**
522
+ * Get disk usage for a path
523
+ */
524
+ du(path: string): Promise<DiskUsage>;
525
+ /**
526
+ * Get filesystem statistics (similar to Node.js fs.statfs)
527
+ * Uses the Storage API to get quota and usage information
528
+ * Note: Values are estimates for the entire origin, not per-path
529
+ */
530
+ statfs(path?: string): Promise<StatFs>;
531
+ /**
532
+ * Reset internal caches
533
+ * Useful when external processes modify the filesystem
534
+ */
535
+ resetCache(): void;
536
+ /**
537
+ * Force full garbage collection
538
+ * Releases all handles and caches, reinitializes the worker in hybrid mode
539
+ * Use this for long-running operations to prevent memory leaks
540
+ */
541
+ gc(): Promise<void>;
542
+ }
543
+
544
+ export { type Backend, type BatchReadResult, type BatchWriteEntry, type CpOptions, type Dir, type Dirent, type DiskUsage, type FSConstants, type FSWatcher, type FileHandle, type OPFSExtendedOptions, OPFSHybrid, type OPFSHybridOptions, type OPFSOptions, type ReadFileOptions, type ReadResult, type ReadStreamOptions, type ReaddirOptions, type RmOptions, type StatFs, type Stats, type SymlinkCache, type SymlinkDefinition, type WatchCallback, type WatchEvent, type WatchOptions, type WatchRegistration, type WriteFileOptions, type WriteResult, type WriteStreamOptions, constants, OPFS as default };