mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
93 lines
7.3 KiB
Plaintext
93 lines
7.3 KiB
Plaintext
HOOKS:
|
|
- TRANSPORT:
|
|
Has to basically re-implement set/load/key over some transport.
|
|
REMEMBER that you have to subscribe on all set/load/key (especially key).
|
|
|
|
|
|
Notes:
|
|
|
|
Messaging
|
|
Every message has who/what/when/where/why/how metadata.
|
|
Who is information that identifies the potential keys or locations a reply should be made to, such that a user can receive it no matter where they are
|
|
What is the message/delta itself
|
|
When is when the message was sent, this may have no relation to a timestamp on a delta transmission
|
|
Where is the destination that the message is trying to get to, and the paths it has taken to get there
|
|
Why is any arbitrary comment
|
|
How is the transformation that caused the message, and potentially the expected transformation to happen
|
|
|
|
Data
|
|
Because data can be in more than one place at a time, its identifier should not be mixed with any whereabouts even if you are planning on only using it within your walled garden.
|
|
Instead, the data itself should express its particular locality - information about a statue in Rome should not be identified a being Roman, but express it is Roman.
|
|
Therefore, preferrably the identifier for a thing should be globally unique, in case it is ever shared by multiple services - that way conflict won't happen.
|
|
This is important because that way any service is forced to do a scan on its own dataset to match with this service's own identifier and link them together - or start fresh if no match exists.
|
|
Information is not deleted, mostly just dereferenced - which may eventually cause cold storage, and loss of data as every system has physical limitations.
|
|
Arrays cannot be supported because cardinality is actually an expression of the data, not an identifier - for if it were, it would cause concurrency problems resulting in divergence.
|
|
|
|
Identifiers
|
|
Reality seems to be lacking any true identifiers because we perceive things in incredibly mutable states.
|
|
Often times attributes that may appear to be static are in fact not - take for instance the color of a car.
|
|
One generally assumes that the color will not change, since it is not observed much - however the lifetime of a program may outlive the developer. Even the sun will go dark one day.
|
|
This is the power of graphs, particularly in a functional setting - they are searchable, potentially timelessly.
|
|
As such identifiers should only be created in response to an attempt to match incoming unfound data with data stored.
|
|
If successful, the service is free and should make as many extra identifiers to reference and link that data again as to avoid doing slow scans again.
|
|
The most likely candidate for that identifier is the identifier that was given to the service, as there is high probability that the requester will make such requests again.
|
|
Throught his means, an identifier can spread like a virus through multiple services, where if it exists it can be retrieved immediately.
|
|
Thus, no one identifier should potentially conflict with any other identifier, as that would produce an erroneous lookup and a faulty response.
|
|
|
|
Do identifiers point to subsets or nodes, or both? Where do identifiers live? Ever in the graph itself? A developer of course would want an identifier to point to both.
|
|
However this is a little tricky, because a single node by itself is fairly useless (hermeneutics) because it has no context, especially if it is composed of many parts.
|
|
So an identifier referencing a "single node" should technically pull in its relations as well, into the subset. But what then do we return to the developer? The subset or the node?
|
|
If you assume the node, then identifiers "point" to different types of data - unless we allow the node the same methods as the subset, where map returns itself.
|
|
If we return the subset, it is inconvenient that you then have to scan for the thing you were already identifying, unless the map method also accepts traversal strings.
|
|
Identifiers are suppose to intentionally allow humans to think in a document based perspective, however there is no guarantee that the pieces in their system will remain that way.
|
|
Take for example a car, you'd assume that the wheel is part of the car and should be referenced as such. But what happens when the tire pops? It is removed and then used as a swing.
|
|
Now tell me, the "belongingness" of the tire is now in the hierarchy of the tree that it was hung on. Hierarchy is imposed by directional relations, not as static structures.
|
|
So there must be a way to evolve the system, for if we assume the identifier now references the subset, giving context to the original node, we need all of them to be uniquely referenced.
|
|
The unique references are the system's internal IDs, not the human friendly identifiers, these must be system-wide guaranteed to be unique.
|
|
But if everything has one, no matter how small, then that increases the odds quite substantially of conflicts. Meaning larger IDs need to be generated, which is never pretty.
|
|
This also then causes scanning issues, cause now countless tiny nodes are floating around in the system that will get mapped over, that is unpleasant for the developer.
|
|
Unless of course there are really good tools that allow them to map with string traversals (known paths) and value traversal (matching structures), in addition to the callback.
|
|
Meaning everything should be its own object, but really good search tools should be available to make this easy.
|
|
If this is the case, enforce the many-solution, that you alway have a subset and never a single node - a single node is just a subset of one.
|
|
Or is it? Or is it the subset of the things that compose the node? Do you hide these from the developer? Expose them?
|
|
It seems like subset of one works fine when you already have the larger subset, but not when you are using the initial identifier.
|
|
So can we mitigate that by providing really good priority loading tools?
|
|
|
|
Special Characters
|
|
These are reserved for gun, to include meta-data on the data itself.
|
|
/ is used as a delimiter in service specific identifiers
|
|
# is used to define the transition from a graph identifier, into the nodes themselves
|
|
. represents walking the path through a node's scope
|
|
_ represents non-human data in the graph that the amnesia machine uses to process stuff
|
|
> and < are dedicated to comparing timestamp states, timelessly to avoid malicious abuse (this should always come last, because requests will be rejected without it)
|
|
|
|
{
|
|
who: {}
|
|
,what: {'#": 'email/hi@example.com'}
|
|
,when: {'>': 1406184438192 }
|
|
,where: {}
|
|
,how: '*'
|
|
}
|
|
{
|
|
_: {
|
|
#: 'email/hi@example.com'
|
|
>: 1406184438192
|
|
}
|
|
}
|
|
|
|
Stream
|
|
If we receive a message with data at a symbolic scope that doesn't exist we should still save it.
|
|
However if we attempt to read it, we should be unable to access it because the symbols haven't been connected.
|
|
That way idempotently, when the symbols are connected, it'll then be readable if they haven't already been overwritten.
|
|
Grouping of symbols always inherit and merge, if all of them need to be dereferenced you must explicitly dereference it.
|
|
How do we do memory management / clean up then of old dead bad data?
|
|
|
|
Init
|
|
You initialize with a node(s) you want to connect to.
|
|
|
|
Evolution
|
|
var node = gun.create('person/joe', {}); // this creates a 'new' node with an identifier to this node
|
|
node('name', 'joe'); // changes properties
|
|
node('age', 24);
|
|
node('eyes', {}); // this internally creates a new node within the same subset as joe,
|
|
node('eyes.color', 'blue'); |