Skip to content

Commit

Permalink
Delay viewer fn eval to invoke (#712)
Browse files Browse the repository at this point in the history
Delay the evaluation of a ViewerFn to when it's invoked. This is a first step towards no longer doing eval on read. In follow-up, we should be able to implement ViewerEval on top of this delayed ViewerFn and unify sci and cherry under a single reader tag.
  • Loading branch information
mk authored Oct 19, 2024
1 parent 233541b commit 126ddaf
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/nextjournal/clerk/cherry_env.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
(catch js/Error e
(viewer/map->ViewerFn
{:form form
:f (fn [_]
[render/error-view (ex-info (str "error in render-fn: " (.-message e)) {:render-fn form} e)])}))))
:f (delay (fn [_]
[render/error-view (ex-info (str "error in render-fn: " (.-message e)) {:render-fn form} e)]))}))))

(defn ->viewer-eval-with-error [form]
(try (eval-form form)
Expand Down
6 changes: 3 additions & 3 deletions src/nextjournal/clerk/render.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,9 @@
;; each view function must be called in its own 'functional component' so that it gets its own hook state.
^{:key hash}
[:> ErrorBoundary {:hash hash}
[(:f (:render-fn viewer)) value (merge opts
(:nextjournal/render-opts x)
{:viewer viewer :path path})]]))))
[(:render-fn viewer) value (merge opts
(:nextjournal/render-opts x)
{:viewer viewer :path path})]]))))

(defn inspect [value]
(r/with-let [!state (r/atom nil)
Expand Down
10 changes: 5 additions & 5 deletions src/nextjournal/clerk/sci_env.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,18 @@
(sci/resolve (sci.ctx-store/get-ctx) (resolve-legacy-alias unresolved-sym)))
(viewer/map->ViewerFn
{:form form
:f (fn [] [render/error-view (ex-info (str "We now require `:render-fn`s to use fully-qualified symbols, and we have removed the old aliases from Clerk. "
"Please change `" unresolved-sym "` to `" (resolve-legacy-alias unresolved-sym) "` in your `:render-fn` to resolve this issue.")
{:render-fn form} e)])}))))
:f (delay (fn [] [render/error-view (ex-info (str "We now require `:render-fn`s to use fully-qualified symbols, and we have removed the old aliases from Clerk. "
"Please change `" unresolved-sym "` to `" (resolve-legacy-alias unresolved-sym) "` in your `:render-fn` to resolve this issue.")
{:render-fn form} e)]))}))))

(defn ->viewer-fn-with-error [form]
(try (viewer/->viewer-fn form)
(catch js/Error e
(or (maybe-handle-legacy-alias-error form e)
(viewer/map->ViewerFn
{:form form
:f (fn [_]
[render/error-view (ex-info (str "error in render-fn: " (.-message e)) {:render-fn form} e)])})))))
:f (delay (fn [_]
[render/error-view (ex-info (str "error in render-fn: " (.-message e)) {:render-fn form} e)]))})))))

(defn ->viewer-eval-with-error [form]
(try (*eval* form)
Expand Down
7 changes: 4 additions & 3 deletions src/nextjournal/clerk/viewer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@

(defrecord ViewerFn [form #?(:cljs f)]
#?@(:cljs [IFn
(-invoke [_ x] (f x))
(-invoke [_ x y] (f x y))]))
(-invoke [_ x] (@f x))
(-invoke [_ x y] (@f x y))]))

;; Make sure `ViewerFn` and `ViewerEval` is changed atomically
#?(:clj
Expand Down Expand Up @@ -67,7 +67,8 @@

(defn ->viewer-fn [form]
(map->ViewerFn {:form form
#?@(:cljs [:f (*eval* form)])}))
#?@(:cljs [:f (let [bound-eval *eval*]
(delay (bound-eval form)))])}))

(defn ->viewer-eval [form]
(map->ViewerEval {:form form}))
Expand Down

0 comments on commit 126ddaf

Please sign in to comment.