gun
gun copied to clipboard
Add a function to perform an asynchronous "gun.get()" + tests
Asynchronous "gun.get()"
DISCLAIMER: this functionnality is optional meaning that I have not added it to the
/src
folder which bundles gun itself. The source code is instead in/lib
meaning that it can be imported if the user wants.
The goal of this PR is to introduce a way to quicly query the database asynchronously. I also included a inject
function to allow the user to use its Gun configuration (eg. const gun = Gun({ peers: ["https://gunpoint.herokuapp.com/gun"] })
. In order to use it you must just pass it to the function and it'll be automatically used.
Example
This function allows you to write:
let data = await get(`this is a test`);
console.log(data);
/*
{
_: {
'#': 'this is a test',
'>': {
l4pqkx1ihbPFwyN: 1655910875718.001,
l4pqkx1jHgZS44c: 1655910875719.001,
l4pqkx1j02jUyiCK6R: 1655910875719.003,
l4pqkx1j05JBa74d2: 1655910875719.0051,
l4pqkx1j08cv7cc14: 1655910875719.007,
l4pqkba002j9uQhSOn: 1655910847513,
l4pqkba07557SmB: 1655910847512.001,
l4pqkba101a31UNqzR: 1655910847513.002,
l4pqkba103tKkEIL5s: 1655910847513.004,
l4pqkba106nVTfaeAD: 1655910847513.006
}
},
l4pqkx1ihbPFwyN: 'Hello, 0',
l4pqkx1jHgZS44c: 'Hello, 1',
l4pqkx1j02jUyiCK6R: 'Hello, 2',
l4pqkx1j05JBa74d2: 'Hello, 3',
l4pqkx1j08cv7cc14: 'Hello, 4',
l4pqkba002j9uQhSOn: 'Hello, 1',
l4pqkba07557SmB: 'Hello, 0',
l4pqkba101a31UNqzR: 'Hello, 2',
l4pqkba103tKkEIL5s: 'Hello, 3',
l4pqkba106nVTfaeAD: 'Hello, 4'
}
*/
console.log(data.list());
/*
[
'Hello, 0', 'Hello, 1',
'Hello, 2', 'Hello, 3',
'Hello, 4', 'Hello, 1',
'Hello, 0', 'Hello, 2',
'Hello, 3', 'Hello, 4'
]
*/
I'll be writing the documentation if the community thinks this PR can be merged. Looking forward to read what you all think !
you have a global. used
and will break apps if use multiple times.
you are prototyping off the Object Global class.. 'we need to stay away from that'
the core of this code is
await gun.get(what).once(data => {
result = data;
})
and is already a standard way of using gun.
Hi @bmatusiak ! Why will it break app? Also... why would it be bad to have a short-hand to quickly the database ? It is useful, isn't it ?
Thank you for your contribution, please elaborate.
if a app uses multiple gun instances
my setup
const gunA = Gun({ peers:["https://gunpoint.herokuapp.com/gun"] });
inject(gunA);
let dataA = await get("this is a test");
console.log(dataA.list())
const gunV = Gun({ peers:["https://privatehost:845/gun?auth=8as76df98a7s6d"] , localStorage : false });
inject(gunV);
let dataV = await get("this is a test");
later trying to get data again
let dataA = await get("this is a test");
is now dataA is broken unless you call inject(gunA);
again
Ok. I see. However... isn't it a problem to use 2 instances of gun in the same file?
Also, we can work this out?
Guys. I think it's still a good idea but as @bmatusiak said... maybe it is not very interesting. I'll be closing the PR for now. You can re-open it later ok?
@noctisatrae no no no! I just got here to look at it (had a busy week)
I think contributions like this should be encouraged.
This is a better PR than most that I see (for instances, that try to change semicolons or tabs, or some arbitrary thing).
It is voluntary, it doesn't force anyone into using or not using something, its small & does something, it has a test, etc.
While @bmatusiak is correct maybe need to fix a thing/race condition, or whatever, that doesn't mean the PR should be closed.
There is a lot of people who like/want promises and your energy & enthusiasm at documenting that is much needed!
@noctisatrae no no no! I just got here to look at it (had a busy week)
I think contributions like this should be encouraged.
This is a better PR than most that I see (for instances, that try to change semicolons or tabs, or some arbitrary thing).
It is voluntary, it doesn't force anyone into using or not using something, its small & does something, it has a test, etc.
While @bmatusiak is correct maybe need to fix a thing/race condition, or whatever, that doesn't mean the PR should be closed.
There is a lot of people who like/want promises and your energy & enthusiasm at documenting that is much needed!
What's next for asynchronous gun?
I. Rethinking its implementation
The inject
, if I'm being honest is a ~way~ to correct a design flaw. We could at this point either rethink it or get rid of it completely by directely putting the functions into gun chaining.
Here are a few points yet to be discussed:
- How do you handle big graphs? The loading time with asynchronous programming could create issues in a P2P system.
- How do you flawlessly implement this feature into gun's chaining?
Let me know if you think of something.
II. "OK. I see your point, but what is more likely to happen between this two choices?"
Gun as its core is extensible ; meaning it is predicated on modules. Wouldn't it make more sense to keep on doing that ? It is harder, will require testing, a bit of mathematics and a lot of effort to do it right. Hopefully, it'll be amazing!
i have dwelled on promise logic issues,
1 idea i had was maybe we can make a chain called promise(action)
like promise("on")
or even a called async
like await gun.get(something).async("on")
it would be easy to add this in, and i may have time to work on it, in the next few days
also there is a lib called promise.js
, i only viewd the code, never used it, but looks like some extra logic is useful in that
Hey @bmatusiak! Hey @amark ! Going back to you. I've been working on prototype. It's quite hard messing with gun source code because it is complex.
@bmatusiak, the idea that you proposed didn't sound appealing to me as I find that it is very verbose. Why not just do something like that:
let data = await gun.aget(<key>);
// or
let data = await gun.async("get", <key>);
However, if you really think it's the right thing then... let's go! But I wanted something more... elegant.
EDIT: could someone explain to me how gun.get() and gun.get().once work? I'd like to refactor/adapt/reproduce the code.
on
and once
are emitters,
on
will fire every time it changes and give you a stream of data from other peers,
once
will grab the current value, and only fires one time
and the reason why i think promise(action)
is a good direction is because it sets us up for future and current chains to wrap anything in a promise
if later someone creates fun
chain then we can do await promise("fun")
I just read what you've written and I think it's very cool to develop the feature to be not only useful but also allowing extensibility by making it flexible !
When I was prototyping I came up with something that could maybe help us do what you said:
// Imagine it's the gun chain here.
let gun = {
some_func: () => {
// do stuff here
}
// some_func2, some_func3...
}
const exec_async = async (what) => {
// return asynchronously the value of the executed function!
return await gun[what]();
}
// later...
await exec_async("on");