- Notifications
You must be signed in to change notification settings - Fork6
Lightweight key-value storage library for Browser, Node.js, and In-Memory.
License
azu/kvs
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Key Value storage for Browser, Node.js, and In-Memory.
It is a monorepo for key-value storage.
I want to get universal storage library that works on Browser and Node.js.
Previously, I've createdlocalstorage-ponyfill for this purpose.However,Window.localStorage does not work onWeb Workers orService Worker
@kvs/*
packages provide async storage API usingIndexedDB etc and resolve this issue.
KVS libraries provide following common features.
- Key-Value Storage
- Async Read, and Write API
- provide
get
,set
,has
,delete
, andclear
API
- provide
- Migration API
- Upgrade storage data via
version
andupgrade
method
- Upgrade storage data via
- Tiny packages
- Almost package size is1kb(gzip)
- TypeScript
- All packages are written by TypeScript
- A browser that supportAsyncIterator
- It requires ES2018+ supports
- Chromium-based(Google Chrome and MSEdge), Firefox, and macOS Safari
- Universal
- @kvs/env: Use suitable storage for platform
- Use IndexedDB for Browser, and Use node-localstorage for Node.js
- @kvs/env: Use suitable storage for platform
- Browser
- @kvs/indexeddb: UseIndexedDB
- For WebWorker and ServiceWorker
- @kvs/localstorage: UselocalStorage
- For Browser
- @kvs/indexeddb: UseIndexedDB
- Node.js
- @kvs/node-localstorage: Usenode-localstorage
- For Node.js
- @kvs/node-localstorage: Usenode-localstorage
- In-Memory
- @kvs/memorystorage: In-Memory Storage
- For debugging and testing
- @kvs/memorystorage: In-Memory Storage
- Sync Version
- @kvs/storage-sync: Sync version of@kvs/localstorage
If you want to custom implementation, please see@kvs/storage and test it with@kvs/common-test-case.
@kvs/env support Browser and Node.js.In fact, browser use@kvs/indexeddb and Node.js use@kvs/node-localstorage.
import{KVSIndexedDB,kvsIndexedDB}from"@kvs/env";(async()=>{conststorage=awaitkvsEnvStorage({name:"database-name",version:1});awaitstorage.set("a1","string");consta1=awaitstorage.get("a1");console.log(a1);// => "string"})();
@kvs/types define common interface.
Each constructor function likekvsEnvStorage
returnKVS
object that has following methods.Also,KVS
object defineSymbol.asyncIterator, and you can iterate the storage byfor await...of.
exporttypeKVS<SchemaextendsStorageSchema>={/** * Returns the value associated to the key. * If the key does not exist, returns `undefined`. */get<KextendsStoreNames<Schema>>(key:K):Promise<StoreValue<Schema,K>|undefined>;/** * Sets the value for the key in the storage. Returns the storage. */set<KextendsStoreNames<Schema>>(key:K,value:StoreValue<Schema,K>|undefined):Promise<KVS<Schema>>;/** * Returns a boolean asserting whether a value has been associated to the key in the storage. */has(key:StoreNames<Schema>):Promise<boolean>;/** * Returns true if an key in the storage existed and has been removed. * Returns false if the key does not exist. */delete(key:StoreNames<Schema>):Promise<boolean>;/** * Removes all key-value pairs from the storage. * Note: clear method does not delete the storage. * In other words, after clear(), the storage still has internal metadata like version. */clear():Promise<void>;/** * Drop the storage. * It delete all data that includes metadata completely. */dropInstance():Promise<void>;/* * Close the KVS connection * DB-like KVS close the connection via this method * Of course, localStorage-like KVS implement do nothing. It is just noop function */close():Promise<void>;}&AsyncIterable<[StoreNames<Schema>,StoreValue<Schema,StoreNames<Schema>>]>;
importassertfrom"assert";import{kvsEnvStorage}from"@kvs/env";(async()=>{typeStorageSchema={a1:string;b2:number;c3:boolean;};// open database and initialize itconststorage=awaitkvsEnvStorage<StorageSchema>({name:"database-name",version:1});// setawaitstorage.set("a1","string");// type checkawaitstorage.set("b2",42);awaitstorage.set("c3",false);// hasconsole.log(awaitstorage.has("a1"));// => true// getconsta1=awaitstorage.get("a1");// a1 will be string typeconstb2=awaitstorage.get("b2");constc3=awaitstorage.get("c3");assert.strictEqual(a1,"string");assert.strictEqual(b2,42);assert.strictEqual(c3,false);// iterateforawait(const[key,value]ofstorage){console.log([key,value]);}// deleteawaitstorage.delete("a1");// clear all dataawaitstorage.clear();})();
KVS support migration feature.You can defineupgrade
and use it as migration function.
import{kvsEnvStorage}from"@kvs/env";(async()=>{// Defaut version: 1// when update version 1 → 2, call upgrace functionconststorage=awaitkvsEnvStorage({name:"database-name",version:2,asyncupgrade({ kvs, oldVersion}){if(oldVersion<2){awaitkvs.set("v1","v1-migrated-value");// modify storage as migration}return;}});assert.strictEqual(awaitstorage.get("v1"),"v1-migrated-value");})();
When open database at first time, this library also callupgrade
function with{ oldVersion: 0, newVersion: 1 }
.So, You can implement0
to1
migration as initializing database.
import{KVSIndexedDB,kvsIndexedDB}from"@kvs/env";(async()=>{conststorage=awaitkvsEnvStorage({name:"database-name",version:1,asyncupgrade({ kvs, oldVersion, newVersion}){console.log(oldVersion);// => 0console.log(newVersion);// => 1}});})();
KVS packages supportSchema
type.It helps you to define a schema of the storage.
import{KVSIndexedDB,kvsIndexedDB}from"@kvs/env";(async()=>{typeStorageSchema={a1:string;b2:number;c3:boolean;};conststorage=awaitkvsEnvStorage<StorageSchema>({name:"database-name",version:1});awaitstorage.set("a1","string");// type checkawaitstorage.set("b2",42);awaitstorage.set("c3",false);consta1=awaitstorage.get("a1");// a1 will be string typeconstb2=awaitstorage.get("b2");constc3=awaitstorage.get("c3");assert.strictEqual(a1,"string");assert.strictEqual(b2,42);assert.strictEqual(c3,false);})();
You can also set up initial data usingupgrade
function.This approach help you to improveScheme
typing.
(async()=>{typeUnixTimeStamp=number;typeScheme={timeStamp:UnixTimeStamp};conststorage=awaitkvsEnvStorage<Scheme>({name:"test-data",version:1,asyncupgrade({ kvs, oldVersion, newVersion}){// Initialize data// oldVersion is 0 and newVersion is 1 at first timeif(oldVersion<1){awaitkvs.set("timeStamp",Date.now());}}});consttimeStamp=awaitstorage.get("timeStamp");console.log(timeStamp);// => timestamp})()
- azu/localstorage-ponyfill
- It provides storage API based on localStorage API
- KV Storage
- This proposal aims to create "async local storage", but it is suspended
- @kvs project aims to be similar one
- localForage
- It has same concept and similar API.
- However,localForage size is large
~8.8kB
(gzipped)
- Unstorage
- Unstorage has various cloud storage support
- However, Unstorage API is too rich for me
- IndexedDB is not supported yet - Issue:unjs/unstorage#10
- idb
- @kvs type interface inspired by idb
- If you want to use only IndexedDB directly, I recommend to use idb
- It has low level API for IndexedDB
SeeReleases page.
This repository useYarn.You need to build before editing each packages.
# install and linkyarn install# build all packageyarn run build
Running test viayarn test
command.
yarn test
Pull requests and stars are always welcome.
For bugs and feature requests,please create an issue.
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
MIT © azu
About
Lightweight key-value storage library for Browser, Node.js, and In-Memory.