silverbulletmd / silverbullet

The knowledge tinkerer's notebook
https://silverbullet.md
MIT License
2.5k stars 182 forks source link

Explore the viability of two-way binding as a first-class query/template feature #181

Closed pm64 closed 1 year ago

pm64 commented 1 year ago

It's common for extensions to PKM systems to implement bidirectional integration with data sources, allowing the user to do things like mark items completed or change the indentation level of items on a remote todo list that has materialized within a document.

On the current trajectory, it's easy to envision a future where plugs provide SB's query engine with a vast array of data sources from which to pull different kinds of information. But I wonder if we can take this further, minimizing friction for developers and users not only when it comes to pulling data (as SB's query engine has been designed to do brilliantly), but when pushing it as well.

I think any approach to this would necessarily involve both SB's query engine and template system, and I've put some thought into how a solution might look. Is this worth exploring? If so, now might be the time to do it, with all of this in its infancy.

yorrd commented 1 year ago

I'm so into this idea! Loving it. My biggest pain with any PKM so far has always been the lacking integrations with task management / file storage / meeting notes / documentation tools / etc.

+1 on this

zefhemel commented 1 year ago

I’m definitely interested in exploring this further and I also put some thought into this. Here are some:

I think in the general case this is theoretically (and thus practically) impossible, simply because neither queries nor templates are not reversible functions. Queries maybe are for now, but as soon as we’d add ways to manipulate the results a bit more, e.g. by adding aggregations, it becomes impossible to map values in the output back to the inputs, if that makes sense. For instance, if we’d allow to do a “select count(*) as cnt” type of thing like SQL allows, it’s hard to map a manually changed “cnt” value back to the original query.

If queries could only render as e.g. markdown tables, it would be feasible to pick up changes in this table and try to map them back to their attributes, and try to hand that back to the query provider. However, with the “render” clause allowing arbitrary Handlebars templates, this becomes impossible again. Handlebar templates are not reversible in the general case either, e.g. {{first_name}} {{last_name}} given attributes first_name “Peter” and last_name “Johnson” could be mapped back when edited to be “John Johnson”, but what about “John Hank Johnson”? Just one trivial example.

The more pragmatic solution, is to indeed leave this up to plugs completely. I’m doing this for tasks now for instance, if you render a task in a query and include a [[pageref@123] reference, and the check or uncheck the task, it will look up pageref and look at position 123, if there’s a task tickbox there, it will apply the change there too, thereby propagating the change back: https://github.com/silverbulletmd/silverbullet/blob/main/plugs/tasks/task.ts#L116

This example task template template/task uses this mechanism.