feat: add origin private file system service
This commit is contained in:
66
src/app/services/opfs.spec.ts
Normal file
66
src/app/services/opfs.spec.ts
Normal 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
32
src/app/services/opfs.ts
Normal 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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user