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