@zenfs/core 0.8.0 → 0.9.0

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.
@@ -4,8 +4,9 @@
4
4
  import type * as Node from 'fs';
5
5
  import type { FileContents } from '../filesystem.js';
6
6
  import { BigIntStats, type BigIntStatsFs, type Stats, type StatsFs } from '../stats.js';
7
- import type { Callback } from '../utils.js';
7
+ import { type Callback } from '../utils.js';
8
8
  import { Dirent, type Dir } from './dir.js';
9
+ import * as promises from './promises.js';
9
10
  import { PathLike } from './shared.js';
10
11
  import { ReadStream, WriteStream } from './streams.js';
11
12
  /**
@@ -375,25 +376,50 @@ export declare function watch(filename: PathLike, listener?: (event: string, fil
375
376
  export declare function watch(filename: PathLike, options: {
376
377
  persistent?: boolean;
377
378
  }, listener?: (event: string, filename: string) => any): Node.FSWatcher;
378
- /**
379
- * @todo Implement
380
- */
381
- export declare function createReadStream(path: PathLike, options?: {
379
+ interface StreamOptions {
382
380
  flags?: string;
383
- encoding?: string;
384
- fd?: number;
381
+ encoding?: BufferEncoding;
382
+ fd?: number | promises.FileHandle;
385
383
  mode?: number;
386
384
  autoClose?: boolean;
387
- }): ReadStream;
385
+ emitClose?: boolean;
386
+ start?: number;
387
+ signal?: AbortSignal;
388
+ highWaterMark?: number;
389
+ }
390
+ interface FSImplementation {
391
+ open?: (...args: any[]) => unknown;
392
+ close?: (...args: any[]) => unknown;
393
+ }
394
+ interface ReadStreamOptions extends StreamOptions {
395
+ fs?: FSImplementation & {
396
+ read: (...args: any[]) => unknown;
397
+ };
398
+ end?: number;
399
+ }
400
+ interface WriteStreamOptions extends StreamOptions {
401
+ fs?: FSImplementation & {
402
+ write: (...args: any[]) => unknown;
403
+ writev?: (...args: any[]) => unknown;
404
+ };
405
+ flush?: boolean;
406
+ }
407
+ /**
408
+ * Opens a file in read mode and creates a Node.js-like ReadStream.
409
+ *
410
+ * @param path The path to the file to be opened.
411
+ * @param options Options for the ReadStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
412
+ * @returns A ReadStream object for interacting with the file's contents.
413
+ */
414
+ export declare function createReadStream(path: PathLike, _options?: BufferEncoding | ReadStreamOptions): ReadStream;
388
415
  /**
389
- * @todo Implement
416
+ * Opens a file in write mode and creates a Node.js-like WriteStream.
417
+ *
418
+ * @param path The path to the file to be opened.
419
+ * @param options Options for the WriteStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
420
+ * @returns A WriteStream object for writing to the file.
390
421
  */
391
- export declare function createWriteStream(path: PathLike, options?: {
392
- flags?: string;
393
- encoding?: string;
394
- fd?: number;
395
- mode?: number;
396
- }): WriteStream;
422
+ export declare function createWriteStream(path: PathLike, _options?: BufferEncoding | WriteStreamOptions): WriteStream;
397
423
  export declare function rm(path: PathLike, callback: Callback): void;
398
424
  export declare function rm(path: PathLike, options: Node.RmOptions, callback: Callback): void;
399
425
  /**
@@ -406,11 +432,11 @@ export declare function mkdtemp(prefix: string, options: Node.BufferEncodingOpti
406
432
  export declare function copyFile(src: PathLike, dest: PathLike, callback: Callback): void;
407
433
  export declare function copyFile(src: PathLike, dest: PathLike, flags: number, callback: Callback): void;
408
434
  type readvCb = Callback<[number, NodeJS.ArrayBufferView[]]>;
409
- export declare function readv(fd: number, buffers: readonly NodeJS.ArrayBufferView[], cb: readvCb): void;
410
- export declare function readv(fd: number, buffers: readonly NodeJS.ArrayBufferView[], position: number, cb: readvCb): void;
435
+ export declare function readv(fd: number, buffers: NodeJS.ArrayBufferView[], cb: readvCb): void;
436
+ export declare function readv(fd: number, buffers: NodeJS.ArrayBufferView[], position: number, cb: readvCb): void;
411
437
  type writevCb = Callback<[number, NodeJS.ArrayBufferView[]]>;
412
- export declare function writev(fd: number, buffers: NodeJS.ArrayBufferView[], cb: writevCb): void;
413
- export declare function writev(fd: number, buffers: NodeJS.ArrayBufferView[], position: number, cb: writevCb): void;
438
+ export declare function writev(fd: number, buffers: Uint8Array[], cb: writevCb): void;
439
+ export declare function writev(fd: number, buffers: Uint8Array[], position: number, cb: writevCb): void;
414
440
  export declare function opendir(path: PathLike, cb: Callback<[Dir]>): void;
415
441
  export declare function opendir(path: PathLike, options: Node.OpenDirOptions, cb: Callback<[Dir]>): void;
416
442
  export declare function cp(source: PathLike, destination: PathLike, callback: Callback): void;
@@ -422,5 +448,4 @@ export declare function statfs(path: PathLike, options: Node.StatFsOptions & {
422
448
  export declare function statfs(path: PathLike, options: Node.StatFsOptions & {
423
449
  bigint: true;
424
450
  }, callback: Callback<[BigIntStatsFs]>): void;
425
- export declare function openAsBlob(path: PathLike, options?: Node.OpenAsBlobOptions): Promise<Blob>;
426
451
  export {};
@@ -1,8 +1,10 @@
1
1
  import { ApiError, ErrorCode } from '../ApiError.js';
2
2
  import { BigIntStats } from '../stats.js';
3
+ import { nop, normalizeMode } from '../utils.js';
3
4
  import { R_OK } from './constants.js';
4
5
  import * as promises from './promises.js';
5
- import { fd2file, nop, normalizeMode } from './shared.js';
6
+ import { fd2file } from './shared.js';
7
+ import { ReadStream, WriteStream } from './streams.js';
6
8
  /**
7
9
  * Asynchronous rename. No arguments other than a possible exception are given
8
10
  * to the completion callback.
@@ -429,32 +431,98 @@ export function access(path, cbMode, cb = nop) {
429
431
  }
430
432
  access;
431
433
  export function watchFile(filename, optsListener, listener = nop) {
432
- throw ApiError.With('ENOTSUP', filename, 'watchFile');
434
+ throw ApiError.With('ENOSYS', filename, 'watchFile');
433
435
  }
434
436
  watchFile;
435
437
  /**
436
438
  * @todo Implement
437
439
  */
438
440
  export function unwatchFile(filename, listener = nop) {
439
- throw ApiError.With('ENOTSUP', filename, 'unwatchFile');
441
+ throw ApiError.With('ENOSYS', filename, 'unwatchFile');
440
442
  }
441
443
  unwatchFile;
442
444
  export function watch(filename, options, listener = nop) {
443
- throw ApiError.With('ENOTSUP', filename, 'watch');
445
+ throw ApiError.With('ENOSYS', filename, 'watch');
444
446
  }
445
447
  watch;
446
448
  /**
447
- * @todo Implement
449
+ * Opens a file in read mode and creates a Node.js-like ReadStream.
450
+ *
451
+ * @param path The path to the file to be opened.
452
+ * @param options Options for the ReadStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
453
+ * @returns A ReadStream object for interacting with the file's contents.
448
454
  */
449
- export function createReadStream(path, options) {
450
- throw ApiError.With('ENOTSUP', path, 'createReadStream');
455
+ export function createReadStream(path, _options) {
456
+ const options = typeof _options == 'object' ? _options : { encoding: _options };
457
+ let handle;
458
+ const stream = new ReadStream({
459
+ highWaterMark: options.highWaterMark || 64 * 1024,
460
+ encoding: options.encoding || 'utf8',
461
+ async read(size) {
462
+ try {
463
+ handle || (handle = await promises.open(path, 'r', options?.mode));
464
+ const result = await handle.read(new Uint8Array(size), 0, size, handle.file.position);
465
+ stream.push(!result.bytesRead ? null : result.buffer.slice(0, result.bytesRead));
466
+ handle.file.position += result.bytesRead;
467
+ if (!result.bytesRead) {
468
+ await handle.close();
469
+ }
470
+ }
471
+ catch (error) {
472
+ await handle?.close();
473
+ stream.destroy(error);
474
+ }
475
+ },
476
+ destroy(error, callback) {
477
+ handle
478
+ ?.close()
479
+ .then(() => callback(error))
480
+ .catch(callback);
481
+ },
482
+ });
483
+ stream.path = path;
484
+ return stream;
451
485
  }
452
486
  createReadStream;
453
487
  /**
454
- * @todo Implement
488
+ * Opens a file in write mode and creates a Node.js-like WriteStream.
489
+ *
490
+ * @param path The path to the file to be opened.
491
+ * @param options Options for the WriteStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
492
+ * @returns A WriteStream object for writing to the file.
455
493
  */
456
- export function createWriteStream(path, options) {
457
- throw ApiError.With('ENOTSUP', path, 'createWriteStream');
494
+ export function createWriteStream(path, _options) {
495
+ const options = typeof _options == 'object' ? _options : { encoding: _options };
496
+ let handle;
497
+ const stream = new WriteStream({
498
+ highWaterMark: options?.highWaterMark,
499
+ async write(chunk, encoding, callback) {
500
+ try {
501
+ handle || (handle = await promises.open(path, 'w', options?.mode || 0o666));
502
+ await handle.write(chunk, null, encoding);
503
+ callback(null);
504
+ }
505
+ catch (error) {
506
+ await handle?.close();
507
+ callback(error);
508
+ }
509
+ },
510
+ destroy(error, callback) {
511
+ callback(error);
512
+ handle
513
+ ?.close()
514
+ .then(() => callback(error))
515
+ .catch(callback);
516
+ },
517
+ final(callback) {
518
+ handle
519
+ ?.close()
520
+ .then(() => callback())
521
+ .catch(callback);
522
+ },
523
+ });
524
+ stream.path = path;
525
+ return stream;
458
526
  }
459
527
  createWriteStream;
460
528
  export function rm(path, options, callback = nop) {
@@ -521,9 +589,3 @@ export function statfs(path, options, callback = nop) {
521
589
  .catch(callback);
522
590
  }
523
591
  statfs;
524
- /* eslint-disable @typescript-eslint/no-unused-vars */
525
- export function openAsBlob(path, options) {
526
- throw ApiError.With('ENOTSUP', path, 'openAsBlob');
527
- }
528
- openAsBlob;
529
- /* eslint-enable @typescript-eslint/no-unused-vars */
@@ -4,5 +4,5 @@ export * as promises from './promises.js';
4
4
  export * as constants from './constants.js';
5
5
  export * from './streams.js';
6
6
  export * from './dir.js';
7
- export { mountMapping, mounts, mount, umount, _toUnixTimestamp } from './shared.js';
7
+ export { mountMapping, mounts, mount, umount } from './shared.js';
8
8
  export { Stats, BigIntStats, StatsFs } from '../stats.js';
@@ -4,5 +4,5 @@ export * as promises from './promises.js';
4
4
  export * as constants from './constants.js';
5
5
  export * from './streams.js';
6
6
  export * from './dir.js';
7
- export { mountMapping, mounts, mount, umount, _toUnixTimestamp } from './shared.js';
7
+ export { mountMapping, mounts, mount, umount } from './shared.js';
8
8
  export { Stats, BigIntStats, StatsFs } from '../stats.js';
@@ -8,14 +8,18 @@ import { Buffer } from 'buffer';
8
8
  import type * as Node from 'node:fs';
9
9
  import type * as promises from 'node:fs/promises';
10
10
  import type { CreateReadStreamOptions, CreateWriteStreamOptions, FileChangeInfo, FileReadResult, FlagAndOpenMode } from 'node:fs/promises';
11
- import type { ReadableStream } from 'node:stream/web';
11
+ import type { ReadableStream as TReadableStream } from 'node:stream/web';
12
12
  import type { Interface as ReadlineInterface } from 'readline';
13
+ import { File } from '../file.js';
13
14
  import { FileContents } from '../filesystem.js';
14
15
  import { BigIntStats, type BigIntStatsFs, type Stats, type StatsFs } from '../stats.js';
15
- import { Dirent, type Dir } from './dir.js';
16
+ import { Dir, Dirent } from './dir.js';
16
17
  import type { PathLike } from './shared.js';
17
18
  import { ReadStream, WriteStream } from './streams.js';
18
19
  export * as constants from './constants.js';
20
+ declare global {
21
+ const ReadableStream: typeof TReadableStream;
22
+ }
19
23
  export declare class FileHandle implements promises.FileHandle {
20
24
  /**
21
25
  * Gets the file descriptor for this file handle.
@@ -26,8 +30,10 @@ export declare class FileHandle implements promises.FileHandle {
26
30
  * Gets the file descriptor for this file handle.
27
31
  */
28
32
  fd: number);
29
- private get file();
30
- private get path();
33
+ /**
34
+ * @internal
35
+ */
36
+ get file(): File;
31
37
  /**
32
38
  * Asynchronous fchown(2) - Change ownership of a file.
33
39
  */
@@ -97,7 +103,7 @@ export declare class FileHandle implements promises.FileHandle {
97
103
  * @since v17.0.0
98
104
  * @experimental
99
105
  */
100
- readableWebStream(options?: promises.ReadableWebStreamOptions): ReadableStream;
106
+ readableWebStream(options?: promises.ReadableWebStreamOptions): TReadableStream<Uint8Array>;
101
107
  readLines(options?: promises.CreateReadStreamOptions): ReadlineInterface;
102
108
  [Symbol.asyncDispose](): Promise<void>;
103
109
  /**
@@ -153,16 +159,32 @@ export declare class FileHandle implements promises.FileHandle {
153
159
  */
154
160
  close(): Promise<void>;
155
161
  /**
156
- * See `fs.writev` promisified version.
157
- * @todo Implement
162
+ * Asynchronous `writev`. Writes from multiple buffers.
163
+ * @param buffers An array of Uint8Array buffers.
164
+ * @param position The position in the file where to begin writing.
165
+ * @returns The number of bytes written.
166
+ */
167
+ writev(buffers: Uint8Array[], position?: number): Promise<Node.WriteVResult>;
168
+ /**
169
+ * Asynchronous `readv`. Reads into multiple buffers.
170
+ * @param buffers An array of Uint8Array buffers.
171
+ * @param position The position in the file where to begin reading.
172
+ * @returns The number of bytes read.
158
173
  */
159
- writev(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<Node.WriteVResult>;
174
+ readv(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<Node.ReadVResult>;
160
175
  /**
161
- * See `fs.readv` promisified version.
162
- * @todo Implement
176
+ * Creates a `ReadStream` for reading from the file.
177
+ *
178
+ * @param options Options for the readable stream
179
+ * @returns A `ReadStream` object.
163
180
  */
164
- readv(buffers: readonly NodeJS.ArrayBufferView[], position?: number): Promise<Node.ReadVResult>;
165
181
  createReadStream(options?: CreateReadStreamOptions): ReadStream;
182
+ /**
183
+ * Creates a `WriteStream` for writing to the file.
184
+ *
185
+ * @param options Options for the writeable stream.
186
+ * @returns A `WriteStream` object
187
+ */
166
188
  createWriteStream(options?: CreateWriteStreamOptions): WriteStream;
167
189
  }
168
190
  /**
@@ -237,7 +259,7 @@ export declare function readFile(filename: PathLike, options: (Node.EncodingOpti
237
259
  flag?: Node.OpenMode;
238
260
  }) | BufferEncoding): Promise<string>;
239
261
  /**
240
- * Synchronously writes data to a file, replacing the file if it already exists.
262
+ * Asynchronously writes data to a file, replacing the file if it already exists.
241
263
  *
242
264
  * The encoding option is ignored if data is a buffer.
243
265
  * @param filename
@@ -373,22 +395,45 @@ export declare function watch(filename: PathLike, options?: Node.WatchOptions |
373
395
  */
374
396
  export declare function access(path: PathLike, mode?: number): Promise<void>;
375
397
  /**
376
- * @todo Implement
398
+ * Asynchronous `rm`. Removes files or directories (recursively).
399
+ * @param path The path to the file or directory to remove.
377
400
  */
378
401
  export declare function rm(path: PathLike, options?: Node.RmOptions): Promise<void>;
379
402
  /**
380
- * @todo Implement
403
+ * Asynchronous `mkdtemp`. Creates a unique temporary directory.
404
+ * @param prefix The directory prefix.
405
+ * @param options The encoding (or an object including `encoding`).
406
+ * @returns The path to the created temporary directory, encoded as a string or buffer.
381
407
  */
382
408
  export declare function mkdtemp(prefix: string, options?: Node.EncodingOption): Promise<string>;
383
409
  export declare function mkdtemp(prefix: string, options?: Node.BufferEncodingOption): Promise<Buffer>;
384
410
  /**
385
- * @todo Implement
411
+ * Asynchronous `copyFile`. Copies a file.
412
+ * @param src The source file.
413
+ * @param dest The destination file.
414
+ * @param mode Optional flags for the copy operation. Currently supports these flags:
415
+ * * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
386
416
  */
387
417
  export declare function copyFile(src: PathLike, dest: PathLike, mode?: number): Promise<void>;
388
418
  /**
389
- * @todo Implement
419
+ * Asynchronous `opendir`. Opens a directory.
420
+ * @param path The path to the directory.
421
+ * @param options Options for opening the directory.
422
+ * @returns A `Dir` object representing the opened directory.
390
423
  */
391
424
  export declare function opendir(path: PathLike, options?: Node.OpenDirOptions): Promise<Dir>;
425
+ /**
426
+ * Asynchronous `cp`. Recursively copies a file or directory.
427
+ * @param source The source file or directory.
428
+ * @param destination The destination file or directory.
429
+ * @param opts Options for the copy operation. Currently supports these options from Node.js 'fs.await cp':
430
+ * * `dereference`: Dereference symbolic links.
431
+ * * `errorOnExist`: Throw an error if the destination file or directory already exists.
432
+ * * `filter`: A function that takes a source and destination path and returns a boolean, indicating whether to copy the given source element.
433
+ * * `force`: Overwrite the destination if it exists, and overwrite existing readonly destination files.
434
+ * * `preserveTimestamps`: Preserve file timestamps.
435
+ * * `recursive`: If `true`, copies directories recursively.
436
+ */
392
437
  export declare function cp(source: PathLike, destination: PathLike, opts?: Node.CopyOptions): Promise<void>;
393
438
  /**
394
439
  * @since v18.15.0
@@ -401,3 +446,4 @@ export declare function statfs(path: PathLike, opts: Node.StatFsOptions & {
401
446
  bigint: true;
402
447
  }): Promise<BigIntStatsFs>;
403
448
  export declare function statfs(path: PathLike, opts?: Node.StatFsOptions): Promise<StatsFs | BigIntStatsFs>;
449
+ export declare function openAsBlob(path: PathLike, options?: Node.OpenAsBlobOptions): Promise<Blob>;