Skip to content

Instantly share code, notes, and snippets.

@baetheus
Last active June 19, 2019 15:49
Show Gist options
  • Select an option

  • Save baetheus/9605e8e75cdb6a4a0652a968cb79ac4e to your computer and use it in GitHub Desktop.

Select an option

Save baetheus/9605e8e75cdb6a4a0652a968cb79ac4e to your computer and use it in GitHub Desktop.
Quick and dirty wrapper for indexeddb using idb and io-ts
import { Either } from 'fp-ts/lib/Either';
import { openDB } from 'idb';
import { array, Type } from 'io-ts';
import { from, Observable, of, throwError } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
export const objectFactory = (
name: string,
keyPath: string,
option: 'readonly' | 'readwrite' | 'versionchange' = 'readonly',
db: string = 'MockDatabase',
version: number = 1
) =>
openDB(db, version, {
upgrade: db => {
if (!db.objectStoreNames.includes(name)) {
console.log('Got a thing');
db.createObjectStore(name, { keyPath });
}
},
}).then(db => db.transaction([name], option).objectStore(name));
export const decode = <A, O = A>(codec: Type<A, O>) => (t: unknown) =>
codec.decode(t);
export const fromPromiseEither = <E, T>(
p: Promise<Either<E, T>>
): Observable<T> =>
from(p).pipe(mergeMap(e => (e.isLeft() ? throwError(e.value) : of(e.value))));
interface StoreConfig<G> {
name: string;
codec: Type<G>;
keyPath: string;
db?: string;
version?: number;
options?: 'readonly' | 'readwrite' | 'versionchange';
}
export const objectStore = <T>(C: StoreConfig<T>) => {
const store = () =>
objectFactory(C.name, C.keyPath, C.options, C.db, C.version);
const allCodec = array(C.codec);
const decodeC = decode(C.codec);
const decodeAllC = decode(allCodec);
const get = (id: string | number) =>
store()
.then(os => os.get(id))
.then(decodeC);
const put = <T>(value: T, id?: string | number) =>
store()
.then(os => os.put(value, id))
.then(t => get(t.toString()))
.then(decodeC);
const patch = <T>(value: Partial<T>, id: string | number) =>
get(id)
.then(v => put({ ...v, ...value }, id))
.then(() => get(id))
.then(decodeC);
const remove = (id: string | number) => store().then(os => os.delete(id));
const getAll = () =>
store()
.then(os => os.getAll())
.then(decodeAllC);
return {
get,
put,
patch,
remove,
getAll,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment