Fork me on GitHub
#portal
<
2023-05-31
>
Sam Ritchie03:05:04

update: thanks to @djblue we are close to supporting all of the emmy viewers in portal, like this: this one should be dragging the plot around, and it will, soon! EDIT: it works great:

❤️ 8
💯 6
Sam Ritchie03:05:29

it should look like this:

djblue03:05:42

Can't get the inequality bit working, probably have the wrong version of the code, but the atoms are working for this example if you wrap the code in an fn

djblue03:05:58

Also default viewers can be specified at all levels so this viewer will compose will all the other viewers in portal clojure-spin

djblue03:05:31

For example:

(->
 [:<>
  [:portal.viewer/code "(+ 1 2 3)"]
  [:portal-present.viewer/mafs
   '(fn []
      (reagent.core/with-let
        [G__68160 (reagent.core/atom [0 0])]
        [:<>
         [:pre (clojure.core/pr-str @G__68160)]
         [mafs.core/Mafs
          [mafs.coordinates/Cartesian {}]
          (reagent.core/with-let
            [G__68161
             (js/Function.
              "[y0001]"
              "[p0002]"
              "  const _0006 = - p0002;\n  const _0008 = _0006 + y0001;\n  const _0013 = Math.sinh(_0008);\n  const _0014 = Math.cosh(_0008);\n  const _0015 = Math.pow(_0014, 4.0);\n  return (- 6.0 * Math.pow(_0013, 4.0) + 8.0 * Math.pow(_0013, 2.0) * Math.pow(_0014, 2.0) - 2.0 * _0015) / _0015;")]
            [mafs.plot/OfX
             {:y
              (let [G__68162 (mapv @G__68160 [0])] (fn [x] (G__68161 [x] G__68162)))}])
          (reagent.core/with-let
            [G__68163
             (js/Function.
              "[y0001]"
              "[p0002]"
              "  const _0006 = - p0002;\n  const _0008 = _0006 + y0001;\n  const _0013 = Math.sinh(_0008);\n  const _0014 = Math.cosh(_0008);\n  const _0015 = Math.pow(_0014, 4.0);\n  return (- 6.0 * Math.pow(_0013, 4.0) + 8.0 * Math.pow(_0013, 2.0) * Math.pow(_0014, 2.0) - 2.0 * _0015) / _0015;")
             G__68165
             (js/Function. "y0001" "  return Math.cos(y0001);")]
            #_[mafs.plot/Inequality
               {:y
                {:<=
                 (let [G__68164 (mapv @G__68160 [0])] (fn [x] (G__68163 [x] G__68164))),
                 :> G__68165},
                :color :blue}])
          [mafs.core/MovablePoint {:atom G__68160, :constrain "horizontal"}]]]))]]
 (with-meta {:portal.viewer/default :portal.viewer/hiccup}))

djblue04:05:22

In terms of downstream users resolving npm deps, not sure how you envisioned it, but the following might be a start:

In jvm land
(try
  (portal.api/eval-str "(js/require \"mafs\")")
  (catch Exception e <install deps for user or ask them to do so>))

djblue04:05:19

If you wanted to vendor your npm deps, portal can resolve js files from the classpath 👍

Sam Ritchie04:05:03

@djblue I do specify deps.cljs , could we pull them from there?

Sam Ritchie04:05:36

@djblue in clerk I have been building a custom JS bundle that includes everything, but this approach seems obviously easier to extend

Sam Ritchie04:05:05

(ev/with-let [!phase [0 0]]
  (let [shifted (ev/with-params {:atom !phase :params [0]}
                  (fn [shift]
                    (((cube D) tanh) (- identity shift))))]
    [:<>
     [:pre `(pr-str @~!phase)]
     (mafs/mafs
      (mafs/cartesian)
      (mafs/of-x shifted)
      (mafs/inequality
       {:y {:<= shifted :> cos} :color :blue})
      (mafs/movable-point
       {:atom !phase :constrain "horizontal"}))]))

Sam Ritchie04:05:47

the fn trick worked great:

(p/register-viewer!
 {:name      ::mafs
  :predicate (constantly true)
  :component (fn [form]
               (eval (list 'fn [] form)))})

💯 2
djblue04:05:37

Currently Portal doesn't look for deps.cljs, it could but I'm not sure how that would play with how shadow treats it

djblue04:05:17

If you already have the code vendor'd:

;; in cljs land
(def mafs
  (try
    (js/require "./vendor.js")
    (catch :default e (js/reauire "mafs"))))

djblue04:05:56

Or perhaps fallback to the vendor if the npm version isn't available

djblue04:05:21

What are your expectations for the deps.cljs file?

Sam Ritchie04:05:34

my expectation was that any consumer of mafs.cljs will build a bundle with shadow, and that this file would trigger shadow into running npm install mafs with the correct version; https://github.com/mentat-collective/Mafs.cljs/blob/main/src/deps.cljs

2
Sam Ritchie04:05:43

and save the user from having to do it manually

Sam Ritchie04:05:57

same with mathbox.cljs, leva.cljs etc

djblue04:05:45

Interesting, so with Portal you get the convenience of no bundles but the inconvenience of resolving npm deps 😆

Sam Ritchie04:05:17

(clicking to interact seems to also “begin filtering” always, not sure if that matters enough to figure out a way around! doesn’t seem to impact the animation at all)

djblue04:05:18

Interesting, might need to stop some events from propagating :thinking_face:

djblue04:05:42

Not sure if you are interested, but you have access to portal.ui.theme, which will automatically work with editor based themes

djblue04:05:11

Also, would getting this working in calva notebooks be something you want? https://cljdoc.org/d/djblue/portal/0.40.0/doc/editors/vs-code/clojure-notebooks

Sam Ritchie04:05:44

yes, absolutely

Sam Ritchie04:05:55

that looks very powerful, and absolutely fits in with my goals here, of having these viewers come to the user wherever they are

djblue05:05:28

It looks like it should be able to work as long as people have the portal.nrepl/wrap-notebook nrepl middleware setup 🔥

metal 2
clojure-spin 2
djblue05:05:46

And some slight tweaks that I'm about to merge 😆

djblue06:05:42

https://github.com/djblue/portal/releases/tag/0.41.0 has all the changes so far to get things working 🎉

djblue06:05:55

Also, not sure if this is important to you but Portal also works for the #C060SFCPR and it looks like emmy is a lot of cljc :thinking_face:

seancorfield06:05:30

Tell me about this portal.nrepl/wrap-notebook middleware?!?

djblue06:05:44

By default, calva notebooks pass along edn from nrepl to the portal viewer so all the rich runtime data is gone (no datafy/nav, etc...). With this middleware, portal can detect if you are in a notebook, intercept the runtime value and pass along an id, then in the notebook viewer it can hookup portal to your runtime and everything works as a normal runtime connected portal.

🤯 2
💯 2
djblue06:05:34

The following bits are enabled with the middleware: • https://cljdoc.org/d/djblue/portal/0.40.0/doc/datafy-nav • First class object support • Runtime registered commands • Larger values which are harder for edn to serialize and parse • Better error rendering

djblue06:05:43

I think once calva notebooks support clojure-lsp, they are gonna be a top tier development environment

djblue07:05:26

I may have done a thing 😆

djblue07:05:48

(def ^:private theme-mapping
  {:fg         ::c/text
   :bg         ::background
   :line-color ::c/border
   :red        ::c/exception
   :orange     ::c/uri
   :green      ::c/string
   :blue       ::c/namespace
   :indigo     ::c/boolean
   :violet     ::c/package
   :pink       ::c/number
   :yellow     ::c/tag})

(defn- ->style [theme]
  (str
   ".MafsView {"
   (str/join
    ";"
    (reduce-kv
     (fn [out mafs portal]
       (conj out (str "--mafs-" (name mafs) ": " (get theme portal))))
     []
     theme-mapping))
   "}"))

🎉 2
Sam Ritchie13:05:36

I really love this

seancorfield17:05:26

Added the wrap-notebook middleware and I'm trying out the Clojure Notebook thing... very cool! Seems it selects Portal rendering by default? (good) One downside seems to be that if you have RCFs -- (comment ...) blocks -- in your file and you tell the Notebook to "Run All", it evaluates the contents of those RCFs as well as all the top-level forms... which is kinda dangerous (given some of the code I have in RCFs!). It doesn't look like there's even a way to visually distinguish regular top-level forms from the contents of RCFs?

seancorfield17:05:34

Is the Notebook format just fundamentally incompatible with the RCF-based approach?

seancorfield17:05:56

(and is there a better channel to ask about this?)

djblue17:05:06

The Calva integration was mostly handled by @U02EMBDU2JU so he probably knows more about the details / limitations

djblue17:05:39

I think the #CBE668G4R channel might be a good place to have this convo but I'm also cool if we continue it here 👌

seancorfield17:05:31

Cool, thanks. I remember seeing some discussions about it but couldn't remember where...

djblue17:05:22

I feel like https://github.com/BetterThanTomorrow/calva/blob/published/src/NotebookProvider.ts#L171-L173 could be updated to ignore forms from comments :thinking_face:

djblue17:05:47

I think when the parser splits apart the comment form into multiple cells, it might be able to mark them as special to filter them out in this for loop. Then, the only method of evaluation would be eval'ing the cell alone.

metal 2
Lukas Domagala18:05:42

I'm not at home right now so I can't link to it but there should be a github discussion on this in the calva repo

pez19:05:35

The parser already marks comment forms as special, so we can do the filtering. I’ll go ahead and do it, @U02EMBDU2JU. Holler if you see a reason not to do this.

awesome 2
seancorfield19:05:37

Having refreshed my memory -- since I participated quite a bit in that thread -- it seems that the restrictions with RCFs are known about but unsolved, which certainly makes it dangerous for me to use at present 🙂 Issue 2210 needs to also skip RCFs in the run cells above and run cell & below commands. I'll add that note to the issue.

pez19:05:16

This VSIX should fix it https://output.circle-artifacts.com/output/job/7f57b12b-206f-444d-bbea-b622700cd2b4/artifacts/0/tmp/artifacts/calva-2.0.365-2210-rich-comment-notebook-run-all-9710d2c3.vsix Do you have time to test it, @U04V70XH6? Otherwise, I’ll just release it and we can fix any remaining issues later. The run cells above and below cases should be covered the way I did the filtering.

seancorfield19:05:30

Sure, I can try it...

pez19:05:18

@djblue found a bug. 😃 New VSIX building.

pez19:05:53

The bug was that evaluation of cells below a comment cell would not happen either. Now they do (unless they are comment cells).

seancorfield19:05:53

I installed that but there still seems to be a bug in Cell and Below...

pez19:05:04

Can you describe? It seems to work when I try it.

seancorfield19:05:25

Trying to repro...

seancorfield19:05:04

Ah, my bad, I had a defn- inside a long RCF and couldn't tell in notebook view -- and it wasn't getting evaluated, but when I scrolled down I found real top-level forms were evaluated! So it does seem correct. Thank you!

seancorfield19:05:35

I wish there was a way to visually tell that a cell is part of an RCF 😐

pez19:05:08

Yeah, that would be nice. Dunno how possible.

seancorfield19:05:24

And ;; line comments don't appear in notebook cells (which would have clued me into this being in an RCF).

seancorfield19:05:05

It's got a ways to go... but it's certainly a lot safer to use now! 🙂

pez19:05:00

Calva’s feature for creating an RCF tucks an :rcf at the closing bracket. That’s retained as a cell in the notebook.

seancorfield20:05:11

Hmm, I don't see that:

djblue20:05:43

I wonder if comment cells can be styled with a border or something :thinking_face:

seancorfield20:05:47

Oh, @U0ETXRFEW You mean some specific feature in Calva that inserts an RCF actually inserts this?

(comment
  
  :rcf)
I have never used that (since it's so easy to just type (comm and tab-complete to accept the RCF suggestion)!

pez20:05:08

Yeah, it’s a bit of a silly feature. More for people to discover RCFs as such. But it does work well if you’re inside some function and want to create (or jump to) an RCF below it.

Lukas Domagala23:05:04

Yeah I’d love to style them somehow. The best I’ve come up with is to show the (comment and ) as cells but that seems weird as well 😞

Lukas Domagala23:05:24

And thanks @U0ETXRFEW for quickly implementing this. At some point, we might want to make run-all for RCF optional but off by default seems like a good safety feature.