All files / src/node-to-fsa NodeFileSystemSyncAccessHandle.ts

88.88% Statements 32/36
80% Branches 16/20
100% Functions 7/7
94.11% Lines 32/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 1047x 7x             7x       22x 22x 22x   22x 22x             13x 13x 13x             1x 1x             2x             4x 4x 4x 3x   1x 1x 1x   1x                         1x 1x                             4x 4x 4x 4x   1x 1x 1x   1x                
import { assertCanWrite } from './util';
import { Buffer } from '../vendor/node/internal/buffer';
import type { FileSystemReadWriteOptions, IFileSystemSyncAccessHandle } from '../fsa/types';
import type { NodeFsaContext, NodeFsaFs } from './types';
 
/**
 * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle
 */
export class NodeFileSystemSyncAccessHandle implements IFileSystemSyncAccessHandle {
  protected readonly fd: number;
 
  constructor(
    protected readonly fs: NodeFsaFs,
    protected readonly path: string,
    protected readonly ctx: NodeFsaContext,
  ) {
    this.fd = fs.openSync(path, 'r+');
    this.ctx.locks.acquireLock(this.path);
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/close
   */
  public async close(): Promise<void> {
    assertCanWrite(this.ctx.mode);
    this.fs.closeSync(this.fd);
    this.ctx.locks.releaseLock(this.path);
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/flush
   */
  public async flush(): Promise<void> {
    assertCanWrite(this.ctx.mode);
    this.fs.fsyncSync(this.fd);
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/getSize
   */
  public async getSize(): Promise<number> {
    return this.fs.statSync(this.path).size;
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/read
   */
  public async read(buffer: ArrayBuffer | ArrayBufferView, options: FileSystemReadWriteOptions = {}): Promise<number> {
    const buf: Buffer | ArrayBufferView = buffer instanceof ArrayBuffer ? Buffer.from(buffer) : buffer;
    try {
      const size = this.fs.readSync(this.fd, buf, 0, buffer.byteLength, options.at ?? 0);
      return size;
    } catch (error) {
      Iif (error instanceof DOMException) throw error;
      if (error && typeof error === 'object') {
        switch (error.code) {
          case 'EBADF': {
            throw new DOMException('File handle already closed.', 'InvalidStateError');
          }
        }
      }
      throw error;
    }
  }
 
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/truncate
   * @param newSize The number of bytes to resize the file to.
   */
  public async truncate(newSize: number): Promise<void> {
    assertCanWrite(this.ctx.mode);
    this.fs.truncateSync(this.fd, newSize);
  }
 
  /**
   * Writes the content of a specified buffer to the file associated with the
   * handle, optionally at a given offset.
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/API/FileSystemSyncAccessHandle/write
   * @param buffer
   * @param options
   */
  public async write(
    buffer: ArrayBuffer | ArrayBufferView | DataView,
    options: FileSystemReadWriteOptions = {},
  ): Promise<number> {
    assertCanWrite(this.ctx.mode);
    const buf: Buffer | ArrayBufferView = buffer instanceof ArrayBuffer ? Buffer.from(buffer) : buffer;
    try {
      return this.fs.writeSync(this.fd, buf, 0, buffer.byteLength, options.at ?? 0);
    } catch (error) {
      Iif (error instanceof DOMException) throw error;
      if (error && typeof error === 'object') {
        switch (error.code) {
          case 'EBADF': {
            throw new DOMException('File handle already closed.', 'InvalidStateError');
          }
        }
      }
      throw error;
    }
  }
}