Fork me on GitHub
#portal
<
2024-01-18
>
Lukas Domagala17:01:01

@djblue In your london clojurians presentation you mentioned that it’s “easy” to handle infinite values somehow. Is there anywhere I can read up on it? We’re now using datascript internally. The d/entity api returns a deftype that pretends to be a map/sequence. If there are cycles in there, it seems to break protal serialization (although it might also be related to the size).

Lukas Domagala22:01:09

I got it working. Not sure if it’s the best way. Turns out that datascript does have a datafy implementation, it just doesn’t get required by default. Requiring it partially solves the problem. Next I have the portal middleware, which means all my evals get wrapped in a map. That doesn’t work with the portal datafy example submit code. Manually tapping or datafying switching the code for something like (update value :result datafy/datafy) makes that work. Now everything kind of works, but it isn’t enjoyable to use. That’s because in the default datascript implementation every nav returns an object that still needs to be datafied. Changing the implementation of datascripts datafy to call datafy on all the result of nav feels dirty but makes it much easier to use in practice.

djblue02:01:22

Interesting :thinking_face: btw you can do something like:

(cond-> value
  (:portal.nrepl/eval (meta value))
  (update :result datafy/datafy))
to ensure you only update portal.nrepl values.

djblue02:01:36

In term of datafy-ing nav'd values, I'm not sure what is a good default behavior. For those who want objects, calling datafy would be an issues, for those who want data, not calling datafy would be an issue.

Lukas Domagala02:01:28

Ah that nrepl code looks a lot less accident prone, thanks 🙂 For me, I can't return them as is from nav, since they'd be infinite again. So the only way to be save is for nav to also datafy. nav+datafy command in portal would also do the trick I guess, but it would be a bit annoying while we can't set hotkeys for custom coomands

djblue02:01:12

Maybe it's time to add that feature 😂

Lukas Domagala02:01:56

Should have let clojurists together sponsor it 😛

😆 1
djblue02:01:52

I'm thinking of an api like:

(defn command-name
  "Docs"
  {:portal.shortcut/default #{:control :enter}
   :portal.shortcut/osx     #{:meta :enter}}
  [& args]
  ...)

djblue02:01:05

There would also be a programmatic shortcut api, not 100% sure what that would look like yet :thinking_face:

djblue02:01:29

Might be nice to start by passing it into the open fn

Lukas Domagala02:01:52

The static one seems completely reasonable as a start. And passing it in will also solve most of the use cases 👍 I'm always pro simple MVP anyways 🙂

djblue02:01:54

Well it sounds like you are volunteering to put up a PR 😏

Lukas Domagala02:01:46

Somewhat related question: when I doubleclick a value, it currently runs nav on that, right? You probably don't plan on making those kinds of behaviors easily customizable? So if I wanted nav + datafy on double click I'd have to fork the viewer?

Lukas Domagala02:01:37

(fork = take your code and create a custom viewer from it 🙂 )

djblue02:01:38

I think the handler is currently inlined, but I don't see a reason why it couldn't be lifted out and dispatched into

🙏 1
djblue02:01:59

Then all events (mouse + keyboard) can be handled in a centralized place which would make it easy to make user customizable.

Lukas Domagala02:01:01

Although I'm not certain why I'm even thinking about having an extra command + replacing the handler. Running datafy inside nav feels ugly but it's working perfectly, so there's no actual practical reason to complicate everything 😉

Lukas Domagala02:01:28

Having it customizable might be nice for other situations though 🤷

djblue02:01:27

I'll see how hard it is to accomplish 👌

Lukas Domagala02:01:59

Nice. Your presentation inspired me to get back into doing more of this type of thing, so it's nice to see you also get back into it 😛

awesome 1
Lukas Domagala02:01:43

One thing that would be interesting, but might also be too much work:

{
 :a [{:datafy :object}]
 }
When this whole thing is a nested datafyable structure, you have to open/nav the vector first before you can nav the {:datafy :object} since nav only takes a single key. It would be a lot nicer if the viewer was able to do the nav chain by itself so that it's possible to directly go to the object. I guess custom handlers would be able to solve that. A different and possibly even nicer way of solve it is to be able to call nav on expanding in the inspector. That way the whole thing would be totally transparent and you could just stay in the original view without drilling down.

djblue03:01:26

I do think it's up to nav implementations to include that metadata on children values, kinda like I did here https://github.com/djblue/portal/blob/master/src/examples/hacker_news.cljc#L84-L91

djblue03:01:10

Especially because that type of implementation is more likely to be better supported across different tools.

Lukas Domagala03:01:32

I guess you're right I should look into adding the nav data immediately and not only when you go into the seq. On the other hand I still like my nav on expanding the inspector idea. Having to leave the parent to be able to see the deeper value isn't as nice as seeing the whole thing for a while.

djblue03:01:45

Yeah, although I'm not sure about coupling it to expand. I feel like Portal should have a fn/transform viewer. Where you can run any fn on any value and the result get's inlined. Kinda like how all the parsing viewers work.

Lukas Domagala03:01:05

Huh, that sounds even nicer, more general and more composable 👏

Lukas Domagala03:01:01

We'd have to have some way of saying which values should have which version of that viewer, but at least for datafy that's not that difficult. Harder for other cases. Might be a good place to look at the kindly integration we talked about a long time ago 🙂

👍 1
Lukas Domagala03:01:43

Looks good. Do you intend to expose mouse keys as well?

djblue03:01:54

Eventually, not there yet.

djblue04:01:48

I still want to play with how keyboard shortcuts are specified. My hope is that mouse events can be specified in a similar way 👌

👍 1