This is an abstract-level
implementation of AsyncStorage
for React Native using TypeScript.
It was tested with Expo SDK 48 for iOS & Android.
Powered by Hyphen.
AsyncStorage
has to be installed, and development builds have to be created:
yarn add @react-native-async-storage/async-storage
yarn expo run:ios
yarn expo run:android
yarn add @hyphen-id/rn-async-storage-level
import { LevelFactory, RNAsyncStorageLevel } from '@hyphen-id/rn-async-storage-level'
import AsyncStorage from '@react-native-async-storage/async-storage'
async function withAsync() {
try {
// create a new db
const db = LevelFactory.createAbstractLevel(RNAsyncStorageLevel, 'my-db-1')
if (db instanceof RNAsyncStorageLevel) {
db.setStorage(AsyncStorage)
}
// listen for 'put' events
db.on('put', (key, value) => {
console.log('event: put', key, value)
})
// listen for 'del' events
db.on('del', (key) => {
console.log('event: del', key)
})
// listen for 'clear' events
db.on('clear', () => {
console.log('event: clear')
})
// write some data
await db.put('key1', 'value1')
await db.put('key2', 'value2')
// get the value of one key
console.log(await db.get('key1'))
// get the values of multiple keys
console.log(await db.getMany(['key1', 'key2']))
// get all keys
console.log(await db.keys().all())
// get all values
console.log(await db.values().all())
// get all entries
console.log(await db.iterator().all())
// delete a key
await db.del('key1')
// clear db
await db.clear()
} catch (error) {
console.error(error)
}
}
import { LevelFactory, RNAsyncStorageLevel } from '@hyphen-id/rn-async-storage-level'
import AsyncStorage from '@react-native-async-storage/async-storage'
async function withCallbacks() {
// create a new db
const db = LevelFactory.createAbstractLevel(RNAsyncStorageLevel, 'my-db-1')
if (db instanceof RNAsyncStorageLevel) {
db.setStorage(AsyncStorage)
}
// listen for 'put' events
db.on('put', (key, value) => {
console.log('event: put', key, value)
})
// listen for 'del' events
db.on('del', (key) => {
console.log('event: del', key)
})
// listen for 'clear' events
db.on('clear', () => {
console.log('event: clear')
})
// write some data
db.put('key1', 'value1', (err) => {
if (err) console.error(err)
console.log('put callback')
})
db.put('key2', 'value2', (err) => {
if (err) console.error(err)
console.log('put callback')
})
// get the value of one key
db.get('key1', (err, result) => {
if (err) console.error(err)
console.log('get callback', result)
})
// get the values of multiple keys
db.getMany(['key1', 'key2'], (err, result) => {
if (err) console.error(err)
console.log('getMany callback', result)
})
// get all keys
db.keys().all((err, result) => {
if (err) console.error(err)
console.log('keys callback', result)
})
// get all values
db.values().all((err, result) => {
if (err) console.error(err)
console.log('values callback', result)
})
// get all entries
db.iterator().all((err, result) => {
if (err) console.error(err)
console.log('iterator callback', result)
})
// delete a key
db.del('key1', (err) => {
if (err) console.error(err)
console.log('del callback')
})
// clear db
db.clear((err) => {
if (err) console.error(err)
console.log('clear callback')
})
}
There was no modern and actively maintained abstract-level
compatible storage for React Native.
abstract-level
uses NodeJS native functions which won't work in a browser (or in the Hermes JS engine for React Native). At build time, parcel
pollyfills some of the native functions, but misses text-encoding
. This is injected by build.sh
, then browserify
bundles everything together into a 100% browser compatible module.
Apart from bundling, it is important to have AsyncStorage
module installed in the consumer app, for it to referece the correct bindings. This is why it needs to be refereced from the app:
const db = new RNAsyncStorageLevel(AsyncStorage, 'my-db-1')
- Known storage limits
- a value's type is limited to
string | number | boolean | null | undefined
- no support for
snapshots, keyIterator, valueIterator, iteratorNextv, streams, seek, batch
- without support for snapshots, isolation of transactions is instead guaranteed by using await/promises (as they are sequential), as opposed to callbacks that use
queueMicrotask
- support for
keyIterator, valueIterator, iteratorNextv, batch
operations - Remove buffer from bundle, use react-native-buffer instead
- Fix encodings: use view, json, buffer
- Fix Accepted value types
- Fix iterator: don't return a new instance every time, use * generators
- Implement other errors
- Find a way to implement snapshots / locks
- Implement simple caching
- Pass options for all _methods
- add tests
To TBD for powering the next wave of private & decentralised apps.
git clone https://github.com/pax-k/rn-async-storage-level && cd rn-async-storage-level
yarn
cd expo-demo && yarn && yarn expo start:ios
cd ../ && yarn watch