I've just pushed a pretty big update to Holster, it now has an API that sits on top of the wire spec. This allows you to run nice queries similar to the original Gun API, such as:
holster.get("hello").put({
things: "I want to add",
which: {
can: "also have nested objects",
},
}, console.log)
It then resolves the query and puts objects on the graph, resolving nested objects as it goes, making extra calls to the wire API as it needs to. The webpack build exposes Holster as a single library, so the previous wire API is now available via holster.wire. I've also added a root node to the graph, so it's also possible to put non-object properties at the root level:
holster.get("key").put("value", console.log)
Check out the tests for more examples! There's also a lot more tests including using mock-socket to add more test coverage to what is now wire.js.
Test driven development
test("write and read a soul relation with state is ok", (t, done) => {
radisk("key", [{"#": "soul"}, 1234])
setTimeout(() => {
assert.deepEqual(puts, {
"!": '\x1F+0\x1F#\x1F"key\x1F=\x1F#soul\x031234\x1F\n',
})
done()
}, 10)
})
I noticed some typos after my first commit to Holster and wondered how they didn't get picked up. A lot of the current code is copied over from Porting Gun, so I'm still working out how it all works and was genuinely curious why it hadn't caused errors.
The typo was in a utility function that checks if an object is a soul relation (fixed version):
// Check if an object is a soul relation, ie {'#': 'UUID'}
const rel = {
is: value => {
if (value && value["#"] && !value._ && obj.is(value)) {
let o = {}
obj.map(value, map_soul, o)
if (o.id) return o.id
}
return false
},
// Convert a soul into a relation and return it.
ify: soul => obj.put({}, "#", soul),
}
But why hadn't it caused any errors? Turns out it was called in Radisk.encode(), but only if it was passed an object, and it wasn't. Radisk is called by store, but it was using JSON.stringify to store a value and it's state as an array, so Radisk was only receiving strings! So now besides the original typo, I'm wondering why I can't just store the array and not use JSON in store.js. That led to updating the file format to include state, which explains the test at the start of this post!
Holster API
It then resolves the query and puts objects on the graph, resolving nested objects as it goes, making extra calls to the wire API as it needs to. The webpack build exposes Holster as a single library, so the previous wire API is now available via
holster.wire
. I've also added a root node to the graph, so it's also possible to put non-object properties at the root level: Check out the tests for more examples! There's also a lot more tests including using mock-socket to add more test coverage to what is now wire.js.Test driven development
I noticed some typos after my first commit to Holster and wondered how they didn't get picked up. A lot of the current code is copied over from Porting Gun, so I'm still working out how it all works and was genuinely curious why it hadn't caused errors.
The typo was in a utility function that checks if an object is a soul relation (fixed version):
But why hadn't it caused any errors? Turns out it was called in Radisk.encode(), but only if it was passed an object, and it wasn't. Radisk is called by store, but it was using JSON.stringify to store a value and it's state as an array, so Radisk was only receiving strings! So now besides the original typo, I'm wondering why I can't just store the array and not use JSON in store.js. That led to updating the file format to include state, which explains the test at the start of this post!