feat: add origin private file system service

This commit is contained in:
2026-02-03 22:28:21 -03:00
parent 1bf0b71ca7
commit 1502418cfa
2 changed files with 98 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { TestBed } from '@angular/core/testing';
import { vi } from 'vitest';
import { OPFS } from './opfs';
describe('OPFS', () => {
let service: OPFS;
let dirHandleMock: Partial<FileSystemDirectoryHandle>
let fileHandleMock: Partial<FileSystemFileHandle>;
let writeable: Partial<FileSystemWritableFileStream>
let FILENAME_MOCK: string;
let DIR_MOCK: string;
beforeEach(() => {
FILENAME_MOCK = 'FILENAME_MOCK';
DIR_MOCK = 'DIR_MOCK';
writeable = {
write: vi.fn().mockResolvedValue(undefined),
close: vi.fn().mockResolvedValue(undefined)
};
fileHandleMock = {
createWritable: vi.fn().mockResolvedValue(writeable),
getFile: vi.fn().mockResolvedValue({arrayBuffer: vi.fn()}),
};
dirHandleMock = {
getDirectoryHandle: vi.fn().mockResolvedValue(dirHandleMock),
getFileHandle: vi.fn().mockResolvedValue(fileHandleMock),
removeEntry: vi.fn()
};
(<any>globalThis.navigator).storage = {
getDirectory: vi.fn().mockResolvedValue(dirHandleMock),
persist: vi.fn().mockResolvedValue(true),
persisted: vi.fn().mockResolvedValue(true),
estimate: vi.fn().mockResolvedValue({ usage: 100, quota: 1000 }),
};
TestBed.configureTestingModule({});
service = TestBed.inject(OPFS);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should get a dir handle to write a file to storage', async() => {
const getDirHandlerSpy = vi.spyOn<OPFS, any>(service, 'getDirHandle');
const BUFFER_MOCK = new ArrayBuffer();
await service.writeTo(FILENAME_MOCK, DIR_MOCK, BUFFER_MOCK)
expect(getDirHandlerSpy).toHaveBeenCalledOnce();
});
it('should get a dir handle to read a file from storage', async () => {
const getDirHandlerSpy = vi.spyOn<OPFS, any>(service, 'getDirHandle');
await service.readFrom(FILENAME_MOCK, DIR_MOCK);
expect(getDirHandlerSpy).toHaveBeenCalledOnce();
});
it('should get a dir handle to delete a file in storage', async () => {
const getDirHandlerSpy = vi.spyOn<OPFS, any>(service, 'getDirHandle');
await service.delete(FILENAME_MOCK, DIR_MOCK);
expect(getDirHandlerSpy).toHaveBeenCalledOnce();
});
});

32
src/app/services/opfs.ts Normal file
View File

@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class OPFS {
async writeTo(filename: string, dir: string, data: ArrayBuffer) {
const dirHandler = await this.getDirHandle(dir);
const file = await dirHandler.getFileHandle(filename, { create: true });
const writable = await file.createWritable();
await writable.write(data);
await writable.close();
}
async readFrom(filename: string, dir: string) {
const dirHandler = await this.getDirHandle(dir);
const file = await dirHandler.getFileHandle(filename);
const fileData = await file.getFile();
return await fileData.arrayBuffer();
}
async delete(filename: string, dir: string) {
const dirHandler = await this.getDirHandle(dir);
await dirHandler.removeEntry(filename);
}
private async getDirHandle(dir: string) {
const root = await navigator.storage.getDirectory();
return await root.getDirectoryHandle(dir, { create: true });
}
}