key-value-file-system
v1.1.0
Published
Turn any key-value store into a file system for hierarchical object storage
Downloads
6
Maintainers
Readme
key-value-file-system
KVFS (key-value-file-system) mimics a basic "file system" of Javascript objects on top of a key value store (e.g. AsyncStorage
). You end up doing things like:
await store.write("/home/stuff", { rock: "me", amadeus: true});
const filenames = await store.ls("/ho*/*tu*");
filenames.forEach(async name => {
const obj = await store.read(name);
console.log("Who to rock?", obj.rock, "And is it Mozart?", obj.amadeus);
});
Here are the benefits over using the key-value store directly:
- Direct object support. KVFS reads and writes objects instead of strings. No more
JSON.stringify
andJSON.parse
all over the place. - "Hierarchy" support. KVFS defaults to supporting filepaths and the concept of path hierarchies.
- Wildcard support. KVFS has commands like
ls
andrm
that support wildcards (e.g.ls(/base*ll/dia*n*
).
Install
npm install key-value-file-system
or
yarn add key-value-file-system
API
First create a key value file system, passing it a key/value read/write store:
import AsyncStorage from "@react-native-async-storage/async-storage";
import KVFS from "key-value-file-system";
const store = new KVFS(AsyncStorage);
By default, KVFS prepends all your filenames with "/kvfs"
, so that you can use the same storage for other things unrelated to KVFS. If you want to use a different prefix for all KVFS keys, you can create it this way:
const store = new KVFS(AsyncStorage, "/ILikeThisPrefixBetter");
KVFS supports AsyncStorage
APIs out of the box. But if you're using another type of key-value store, it just needs to conform to this spec:
export interface KeyValueStore {
getAllKeys(): Promise<readonly string[]>;
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
multiGet(
keys: readonly string[]
): Promise<readonly [string, string | null][]>;
multiSet(keyValuePairs: Array<[string, string]>): Promise<void>;
multiRemove(keys: readonly string[]): Promise<void>;
}
async ls(spec?: string): Promise<readonly string[]>
Lists all filenames if you pass undefined
, ""
, or "*"
. Supports wildcards in multiple places (e.g. ls("/stats/*bowl*/*ing")
).
async read<T>(path: string): Promise<T | null>
Gives you back the object stored at path
, or null
if path doesn't exist.
async readMulti<T>(spec: string): Promise<readonly PathValue<T | null>[]>
Takes a wildcarded string and gives you back all objects that match.
/* key-value-file-system defines the following:
export interface PathValue<T> {
path: string;
value: T;
}
*/
const stuff = await store.readMulti("*69");
stuff.forEach(item => console.log(`At path ${item.path} I found ${path.value}`));
async write<T>(path: string, value: T): Promise<void>
Does what it says on the tin.
async rm(spec: string): Promise<void>
Takes a wildcard-capable path spec and deletes all objects that match. Note that unlike ls
, rm
won't let you just pass nothing. In order to delete everything, you'll either need to rm("*")
so KVFS knows you're serious, or you can call rmAllForce
.
async rmMulti(paths: string[]): Promise<void>
For those times when one regex won't do for all the files you want to remove.
rmAllForce(): Promise<void>
The rm -fr
of KVFS. Removes all KVFS objects. Note that this does NOT delete other keys of yours in the same store — KVFS never messes with keys written by other parts of your app.