Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side db.query() alternatives #89

Open
staltz opened this issue Dec 15, 2020 · 1 comment
Open

Client-side db.query() alternatives #89

staltz opened this issue Dec 15, 2020 · 1 comment
Labels
enhancement 🌱 New feature or request

Comments

@staltz
Copy link
Member

staltz commented Dec 15, 2020

db.query is a bit difficult to support over a muxrpc stream, but it should be possible.

ssb.db.query(
  and( // this produces a function
    type('post') // this produces an object
  ),
  toPullStream() // this produces a function
)

ssb.db.query "in the same thread" (thread being either another Electron renderer, or a React Native rn-bridge thread, etc) is a synchronous function that will call all those chained functions (note that internally ssb.db.query will inject fromDB(jitdb) at the start!) and then will return a pull stream.

"In another thread", there are only async muxrpc calls, so we would have to do something like

ssb.db.query(
  and(type('post')
  toPullStream(),
  (err, ps) => {
     // ps is the pull stream
  })
)

But i'm not even sure if that would work, because toPullStream is a function, and you can't pass functions over the muxrpc stream, I guess.

There's one way to side step all of this, and that's to only use ssb.db.query "on the same thread" as sbot, and if you want to make queries from another thread, you'd have to create a custom muxrpc method on the "server side" such as ssb.extra.getPullStreamOfAllPosts which will do the snippet above, and that's what the client side calls.

But I'm quite sure someone will eventually ask for support for ssb.db.query on the client side, so we could begin thinking how to do that.

One way is that maybe on the client side we could have a custom ssb.db.query that creates objects (after all operations will be encoded as objects) and we can pass the objects from client to server, no problem. Just requires some careful thought because upon receiving such object on the server side, we have to prepend it with fromDB(jitdb) and the waitForDrain deferred thing. Also things like toPullStream could be converted to an object like {type: 'RESULT', data: 'pull-stream'}. But there's also the question of how does muxrpc know to dynamically return either "source" or "async" depending on our input, and I don't think it can do that. Maybe then we'd have ssb.db.queryAsAsync and ssb.db.queryAsSource which are "async" and "source", respectively?

Hmmm! Idea: we keep ssb.db.query as is (implicitly available, not declared on the manifest), then we add ssb.db.queryAsAsync and ssb.db.queryAsSource and those are declared in the manifest. And then maybe we should have another package, ssb-db2-client that doesn't drag in all these heavy dependencies like async-flumelog and jitdb (which are certain to not be needed on the client), and ssb-db2-client basically just has operators, and it would have one special function pipe(...args) which bundles all the arguments and spits out one single ops object, e.g.

// client side
const {pipe, and, type} = require('ssb-db2-client')

pull(
  ssb.db.queryAsSource(
    pipe(
      and(type('post'), author(me)),
      live()
      // no need to do toPullStream because that's done server side
      // in the implementation of queryAsSource()
    )
  ),
  pull.drain(console.log)
)
@staltz staltz changed the title db.query over muxrpc Client-side db.query alternatives: queryAsSource / queryAsAsync Dec 16, 2020
@staltz staltz changed the title Client-side db.query alternatives: queryAsSource / queryAsAsync Client-side db.query alternatives Dec 16, 2020
@staltz staltz changed the title Client-side db.query alternatives Client-side db.query() alternatives Dec 16, 2020
@staltz staltz added the enhancement 🌱 New feature or request label Feb 16, 2021
@staltz
Copy link
Member Author

staltz commented Oct 6, 2021

Improved API proposal, removing pipe:

// client side
const {and, type} = require('ssb-db2-client')

pull(
  ssb.db.queryAsSource(
    and(type('post'), author(me)),
    live()
    // no need to do toPullStream because that's done server side
    // in the implementation of queryAsSource()
  ),
  pull.drain(console.log)
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 🌱 New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant