native-file-system-adapter-ts
Version:
Native File System API
122 lines • 4.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileHandleMemory = exports.SinkMemory = void 0;
const errors_1 = require("../errors");
const { INVALID, GONE, SYNTAX, DISALLOWED } = errors_1.errors;
class SinkMemory {
constructor(fileHandle, file) {
this.fileHandle = fileHandle;
this.file = file;
this.size = file.size;
this.position = 0;
}
write(chunk) {
let file = this.file;
if (this.isWriteParams(chunk)) {
if (chunk.type === 'write') {
if (chunk.position !== undefined && Number.isInteger(chunk.position) && chunk.position >= 0) {
this.position = chunk.position;
if (this.size < chunk.position) {
this.file = new File([this.file, new ArrayBuffer(chunk.position - this.size)], this.file.name, this.file);
}
}
if (!('data' in chunk)) {
throw new Error(...SYNTAX('write requires a data argument'));
}
chunk = chunk.data;
}
else if (chunk.type === 'seek') {
if (Number.isInteger(chunk.position) && chunk.position >= 0) {
if (this.size < chunk.position) {
throw new Error(...INVALID);
}
this.position = chunk.position;
return;
}
else {
throw new Error(...SYNTAX('seek requires a position argument'));
}
}
else if (chunk.type === 'truncate') {
if (Number.isInteger(chunk.size) && chunk.size >= 0) {
file =
chunk.size < this.size
? new File([file.slice(0, chunk.size)], file.name, file)
: new File([file, new Uint8Array(chunk.size - this.size)], file.name);
this.size = file.size;
if (this.position > file.size) {
this.position = file.size;
}
this.file = file;
return;
}
else {
throw new Error(...SYNTAX('truncate requires a size argument'));
}
}
}
chunk = new Blob([chunk]);
let blob = this.file;
// Calc the head and tail fragments
const head = blob.slice(0, this.position);
const tail = blob.slice(this.position + chunk.size);
// Calc the padding
let padding = this.position - head.size;
if (padding < 0) {
padding = 0;
}
blob = new File([head, new Uint8Array(padding), chunk, tail], blob.name);
this.size = blob.size;
this.position += chunk.size;
this.file = blob;
}
close() {
if (this.fileHandle._deleted)
throw new Error(...GONE);
this.fileHandle._file = this.file;
this.file = null;
this.position = this.size = 0;
if (this.fileHandle.onclose) {
this.fileHandle.onclose(this.fileHandle);
}
}
isWriteParams(chunk) {
return chunk.type !== undefined;
}
}
exports.SinkMemory = SinkMemory;
class FileHandleMemory {
constructor(name = '', file = new File([], name), writable = true) {
this._file = file;
this.name = name;
this.kind = 'file';
this._deleted = false;
this.writable = writable;
this.readable = true;
}
async getFile() {
if (this._deleted)
throw new Error(...GONE);
return this._file;
}
async createWritable(opts) {
if (!this.writable)
throw new Error(...DISALLOWED);
if (this._deleted)
throw new Error(...GONE);
const file = opts.keepExistingData ? await this.getFile() : new File([], this.name);
return new SinkMemory(this, file);
}
async isSameEntry(other) {
return this === other;
}
async remove() {
this._destroy();
}
async _destroy() {
this._deleted = true;
this._file = null;
}
}
exports.FileHandleMemory = FileHandleMemory;
//# sourceMappingURL=memory.js.map