Open joeltg opened 4 years ago
As of this commit, Styx has replaced its HTTP API with a use-as-a-library Cursor
interface, with the idea that pkgs will bundle a StyxIndex
adapter that wraps a styx.Cursor
as an Index
in some way.
Playing around with possible Index
interfaces led me to something like this:
type Index interface {
Add(pathname []string, resource Resource)
Remove(pathname []string, resource Resource)
Signatures() []Signature
}
type Signature interface {
Head() []*ld.Quad
Domain() []string
}
// Resource is interface type for resources (packages, messages, and files)
type Resource interface {
ETag() (cid.Cid, string)
URI() string
}
It feels like unifying query-style access to indices (the "output interface") is just as important as unifying the add/remove functions (the "input interface"), so that's what Signatures()
is - a set of query signatures, where each signature is a subgraph (with some blank nodes) and a domain (the subset of the blank nodes in the subgraph that are required to be ground for the signature to match).
For example, an index that lets you look up an ID from a schema.org name (but not the other way around) would have a signature with a head of
_:id <http://schema.org/name> _:name .
and a domain of
[]string{"_:name"}
... but an index that lets you look up a name from an ID would have the same head, but a domain of
[]string{"_:id"}
This still is only an interface for selecting which indices match a query, and not actually querying them (we could potentially re-use the Cursor interface from Styx), but it's a start.
--- More thoughts --- I think embracing a Cursor interface (or something like it) all the way to end usage might be the best thing to do for queries. I had previously assumed that we'd wrap Cursors in some declarative HTTP API, but maybe it's best to actually expose an interactive websocket/libp2p stream-based interface where actual end users of queries - like javascript frontends etc - actually open a transaction and can page through results interactively before closing it.
This would mean a JavaScript library to expose like
const { Cursor } = require("styx-client")
const pattern = {
"@context": "ipfs://Qm...",
"name": "...",
"properties": { ... }
}
const cursor = new Cursor(pattern, "http://localhost:8086")
cursor.graph // returns the current value as an N3Store or JSON-LD object or something
cursor.next() // advances to next solution
cursor.seek(cursor.domain[3]) // ...
cursor.close()
--- More thoughts --- I think I have a neat idea of what package servers could be. They should expose two APIs, both over libp2p:
Cursor
interface (which now lives in pkgs/query; styx imports from it)Both of these get exposed as libp2p protocols
Joel's Current Grand Vision is to unify styx and pkgs so that pkgs has a plugin architecture that can integrate any index (i.e. database index) that satisfies some interface.
In my mind right now this interface is just
... which styx can be refactored to implement.
For now each index would be responsible for providing its own usage endpoint (i.e. styx would still attach an API handler to some other port) but that is also something that should be unified under pkgs in the future.