Skip to content

Commit

Permalink
Updated Storage backend to support all Storages
Browse files Browse the repository at this point in the history
  • Loading branch information
james-pre committed Sep 24, 2023
1 parent fd145f2 commit d922c74
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 106 deletions.
100 changes: 0 additions & 100 deletions src/backends/LocalStorage.ts

This file was deleted.

93 changes: 93 additions & 0 deletions src/backends/Storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { SyncKeyValueStore, SimpleSyncStore, SyncKeyValueFileSystem, SimpleSyncRWTransaction, SyncKeyValueRWTransaction } from '../generic/key_value_filesystem';
import { ApiError, ErrorCode } from '../ApiError';
import { Buffer } from 'buffer';
import { CreateBackend, type BackendOptions } from './backend';

/**
* A synchronous key-value store backed by Storage.
*/
export class StorageStore implements SyncKeyValueStore, SimpleSyncStore {
public name(): string {
return StorageFileSystem.Name;
}

constructor(protected _storage) {}

public clear(): void {
this._storage.clear();
}

public beginTransaction(type: string): SyncKeyValueRWTransaction {
// No need to differentiate.
return new SimpleSyncRWTransaction(this);
}

public get(key: string): Buffer | undefined {
const data = this._storage.getItem(key);
if (typeof data != 'string') {
return;
}

return Buffer.from(data);
}

public put(key: string, data: Buffer, overwrite: boolean): boolean {
try {
if (!overwrite && this._storage.getItem(key) !== null) {
// Don't want to overwrite the key!
return false;
}
this._storage.setItem(key, data.toString());
return true;
} catch (e) {
throw new ApiError(ErrorCode.ENOSPC, 'Storage is full.');
}
}

public del(key: string): void {
try {
this._storage.removeItem(key);
} catch (e) {
throw new ApiError(ErrorCode.EIO, 'Unable to delete key ' + key + ': ' + e);
}
}
}

export namespace StorageFileSystem {
/**
* Options to pass to the StorageFileSystem
*/
export interface Options {
/**
* The Storage to use. Defaults to globalThis.localStorage.
*/
storage: Storage;
}
}

/**
* A synchronous file system backed by a `Storage` (e.g. localStorage).
*/
export class StorageFileSystem extends SyncKeyValueFileSystem {
public static readonly Name = 'Storage';

public static Create = CreateBackend.bind(this);

public static readonly Options: BackendOptions = {
storage: {
type: 'object',
optional: true,
description: 'The Storage to use. Defaults to globalThis.localStorage.',
},
};

public static isAvailable(storage: Storage = globalThis.localStorage): boolean {
return storage instanceof Storage;
}
/**
* Creates a new Storage file system using the contents of `Storage`.
*/
constructor({ storage = globalThis.localStorage }: StorageFileSystem.Options) {
super({ store: new StorageStore(storage) });
}
}
6 changes: 3 additions & 3 deletions src/backends/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FileSystemAccessFileSystem as FileSystemAccess } from './FileSystemAcce
import { FolderAdapter } from './FolderAdapter';
import { InMemoryFileSystem as InMemory } from './InMemory';
import { IndexedDBFileSystem as IndexedDB } from './IndexedDB';
import { LocalStorageFileSystem as LocalStorage } from './LocalStorage';
import { StorageFileSystem as Storage } from './Storage';
import { OverlayFS } from './OverlayFS';
import { WorkerFS } from './WorkerFS';
import { HTTPRequest } from './HTTPRequest';
Expand All @@ -22,7 +22,7 @@ export const backends: { [backend: string]: BackendConstructor } = {
InMemory,
IndexedDB,
IsoFS,
LocalStorage,
Storage,
OverlayFS,
WorkerFS,
HTTPRequest,
Expand All @@ -39,7 +39,7 @@ export {
InMemory,
IndexedDB,
IsoFS,
LocalStorage,
Storage,
OverlayFS,
WorkerFS,
HTTPRequest,
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@ export function configure(config: Configuration, cb?: BFSOneArgCallback): Promis
* Individual options can recursively contain FileSystemConfiguration objects for
* option values that require file systems.
*
* For example, to mirror Dropbox to LocalStorage with AsyncMirror, use the following
* For example, to mirror Dropbox to Storage with AsyncMirror, use the following
* object:
*
* ```javascript
* var config = {
* fs: "AsyncMirror",
* options: {
* sync: {fs: "LocalStorage"},
* sync: {fs: "Storage"},
* async: {fs: "Dropbox", options: {client: anAuthenticatedDropboxSDKClient }}
* }
* };
Expand Down
2 changes: 1 addition & 1 deletion test/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const tests /*: { [B in keyof typeof Backends]: Parameters<typeof Backends[B]['C
InMemory: {},
//IndexedDB: {},
//IsoFS: {},
//LocalStorage: {},
//Storage: {},
OverlayFS: { readable: { fs: 'InMemory' }, writable: { fs: 'InMemory' } },
//WorkerFS: {},
//HTTPRequest: {},
Expand Down

0 comments on commit d922c74

Please sign in to comment.