Gunnery.js makes GUN easier to use. It is still under heavy construction.
yarn add gunnery
import gunnery from "gunnery"
const db = new gunnery({ peers: ["http://localhost:8765/gun"] })
// only one authenticated user per instance is possible
const pub = await db.auth("alias", "password")
// but you can use multiple instances at the same time
const db2 = new gunnery({ peers: ["http://localhost:8765/gun"] })
const pub2 = await db2.auth("alias2", "password2")
const data = { example: 1 }
// save data to authenticated user
await db.put(data, "key1", "key2")
const my_data = await db.get("key1", "key2")
// get data from non-authenticated user with a public key (u of uget = user)
const user_data = await db.uget(pub2, "key1", "key2")
// save data to a public path (g of gget = global)
await db.gput(data, "key1", "key2")
const public_data = await db.gget("key1", "key2")
// encrypt the data so only the currently authenticated user can read
await db.put(data, "key1", "key2", {enc: true})
const enc_data = await db.get("key1", "key2", {enc: true})
// encrypt the data so only a specified user can read
await db.gput(data, "key1", "key2", {enc: pub2})
const enc_data2 = await db2.gget("key1", "key2", {enc: pub})
// save frozen data with hash, hash will be appended to the last key
await db.gput(data, "#", "", {hash: true})
await db.gput(data, "#inbox", "2021/August#", {hash: true})
// map child nodes
await db.map("key1",(data)=>{
console.log(data)
})
// listen to data changes
await db.on("key1","key2", (data)=>{
console.log(data)
})
// pagination
const page = await db.page("key1")
await page.put("key2", data)
const p1 = await page.next()
const p2 = await page.next()
const p3 = await page.next()
A public key of a non-authenticated user. There is no writing (uput
) to other users' nodes.
const data = await db.uget(pub, "key1", "key2")
Most functions take an optional opt
object.
true
encrypt the data so only the currently authenticated user can readpublic key
encrypt the data so only the specified user can read
true
sign the data, so the data owner can be verified later
true
encrypt the data with AEC-GCM key
true
freeze the data with hash, this option has to be used with#
in the keys
You can freeze encrypted data by setting both options true
.
// save frozen data only you can read.
// the last key is empty but the hash will be appended here, so you still need it.
await db.gput(data, "#", "", { enc: true, hash: true })
In case of on
functions, cb
(callback function to receive the data) also receives a off
function to remove the listener. This appies to on
gon
uon
mapon
gmapon
umapon
.
await db.on("key1", "key2", (data, off)=>{ console.log(data) })
path
can be any length (depth).
await db.get("key1", "key2", "key3", "key4", opt })
true
save data in reverse order, only applicable to page instances.
millisecond
wait until there exists data, but returnundefined
whentimeout
has passed.
There can be only one authenticated user per instance, but you can use multiple instances at the same time.
const pub = await db.auth("alias", "password")
You can also authenticate a user with a pair
, the optional alias
is an arbitrary value.
const pub = await db.authPair(pair)
Put data to the authenticated user.
await db.put(data, "key1", "key2")
Put data to public.
await db.gput(data, "key1", "key2")
Share encrypted data with another user with pub
.
await db.share(pub, "key1", "key2")
Get data stored to the authenticated user.
const data = await db.get("key1", "key2")
Get data stored to a specified user.
const data = await db.uget(pub, "key1", "key2")
Get public data.
const data = await db.gget("key1", "key2")
Get shared data. pub
is the user who shared the data with you.
const data = await db.sget(pub, "key1", "key2")
Get and listen to changes of data stored to the authenticated user.
await db.on("key1", "key2", (data, off)=>{ console.log(data) })
Get and listen to changes of data stored to a specified user.
await db.uon(pub, "key1", "key2", (data, off)=>{ console.log(data) })
Get and listen to changes of public data.
await db.gon("key1", "key2", (data, off)=>{ console.log(data) })
Map child nodes stored to the currently authenticated user.
await db.map("list", (data)=>{ console.log(data) })
Map child nodes stored to a specified user.
await db.umap("list", (data)=>{ console.log(data) })
Map public child nodes.
await db.umap("list", (data)=>{ console.log(data) })
Map and listen to changes of child nodes stored to the currently authenticated user.
await db.mapon("list", (data, off)=>{ console.log(data) })
Map and listen to changes of child nodes stored to a specified user.
await db.umapon(pub, "list", (data, off)=>{ console.log(data) })
Map and listen to changes of public child nodes.
await db.gmapon("list", (data, off)=>{ console.log(data) })
Pagination is hard with graph database, but gunnery makes it simple.
const page = await db.page("articles")
await page.init()
const id = "testid"
const id2 = "testid2"
const id3 = "testid3"
const page.put(id, data)
const page1 = await page.next()
const page2 = await page.next()
// listen for new items (only effective with { desc: true })
page.on((data)=> console.log("new item", data))
// delete item
await page.del(id)
// blacklist items, so they won't show in the result of next()
page.blacklistIds([id,id2,id3])