Created
October 10, 2019 12:51
-
-
Save hugomrdias/2027b6a065c5d71831116604bd0be8bc to your computer and use it in GitHub Desktop.
Simple ipfs datastore for browsers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Store, set, get, del } = require('idb-keyval') | |
function isStrictTypedArray (arr) { | |
return ( | |
arr instanceof Int8Array || | |
arr instanceof Int16Array || | |
arr instanceof Int32Array || | |
arr instanceof Uint8Array || | |
arr instanceof Uint8ClampedArray || | |
arr instanceof Uint16Array || | |
arr instanceof Uint32Array || | |
arr instanceof Float32Array || | |
arr instanceof Float64Array | |
) | |
} | |
function typedarrayToBuffer (arr) { | |
if (isStrictTypedArray(arr)) { | |
// To avoid a copy, use the typed array's underlying ArrayBuffer to back new Buffer | |
var buf = Buffer.from(arr.buffer) | |
if (arr.byteLength !== arr.buffer.byteLength) { | |
// Respect the "view", i.e. byteOffset and byteLength, without doing a copy | |
buf = buf.slice(arr.byteOffset, arr.byteOffset + arr.byteLength) | |
} | |
return buf | |
} else { | |
// Pass through all other types to `Buffer.from` | |
return Buffer.from(arr) | |
} | |
} | |
class IdbDatastore { | |
constructor (location) { | |
this.store = new Store(location, location) | |
} | |
open () { | |
} | |
put (key, val) { | |
return set(key.toBuffer(), val, this.store) | |
} | |
async get (key, callback) { | |
const value = await get(key.toBuffer(), this.store) | |
if (!value) { | |
return callback(new Error('No value')) | |
} | |
return typedarrayToBuffer(value) | |
} | |
async has (key) { | |
const v = await get(key.toBuffer(), this.store) | |
if (v) { | |
return true | |
} | |
return false | |
} | |
delete (key) { | |
return del(key.toBuffer(), this.store) | |
} | |
batch () { | |
const puts = [] | |
const dels = [] | |
return { | |
put (key, value) { | |
puts.push([key.toBuffer(), value]) | |
}, | |
delete (key) { | |
dels.push(key.toBuffer()) | |
}, | |
commit: () => { | |
return Promise.all(puts.map(p => this.put(p[0], p[1]))) | |
} | |
} | |
} | |
query (q) { | |
return null | |
} | |
close () { | |
} | |
} | |
class IdbDatastoreBatch { | |
constructor (location) { | |
this.location = location | |
} | |
open () { | |
const location = this.location | |
return openDB(this.location, 1, { | |
upgrade (db) { | |
db.createObjectStore(location) | |
} | |
}) | |
} | |
async put (key, val) { | |
const db = await this.open() | |
return db.put(this.location, val, key.toBuffer()) | |
} | |
async get (key) { | |
const db = await this.open() | |
const value = await db.get(this.location, key.toBuffer()) | |
if (!value) { | |
throw new Error('No value') | |
} | |
return typedarrayToBuffer(value) | |
} | |
async has (key) { | |
const db = await this.open() | |
return Boolean(await db.get(this.location, key.toBuffer())) | |
} | |
async delete (key) { | |
const db = await this.open() | |
return db.del(this.location, key.toBuffer()) | |
} | |
batch () { | |
const puts = [] | |
const dels = [] | |
return { | |
put (key, value) { | |
puts.push([key.toBuffer(), value]) | |
}, | |
delete (key) { | |
dels.push(key.toBuffer()) | |
}, | |
commit: async () => { | |
const db = await this.open() | |
const tx = db.transaction(this.location, 'readwrite') | |
const store = tx.store | |
await Promise.all(puts.map(p => store.put(p[1], p[0]))) | |
await Promise.all(dels.map(p => store.del(p))) | |
await tx.done | |
} | |
} | |
} | |
query (q) { | |
return null | |
} | |
close () { | |
this.store.close() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment