From e91208b98e2fbaf33aa4cd3b9f8b150bc79b93ab Mon Sep 17 00:00:00 2001 From: Matthew Huebert Date: Fri, 14 Oct 2022 10:59:32 +0200 Subject: [PATCH] with-d3-require returns wrap-callback fn for :ref error handling --- resources/viewer-js-hash | 2 +- src/nextjournal/clerk/sci_viewer.cljs | 29 ++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/resources/viewer-js-hash b/resources/viewer-js-hash index 86a98e437..5e455e49a 100644 --- a/resources/viewer-js-hash +++ b/resources/viewer-js-hash @@ -1 +1 @@ -4ZdAZwg7ydXGHHZcCH31qfLYEfKa \ No newline at end of file +4HD1mR7S3FQkZPw8nJSggBZeDPRi \ No newline at end of file diff --git a/src/nextjournal/clerk/sci_viewer.cljs b/src/nextjournal/clerk/sci_viewer.cljs index 1a3ca6d6d..a35c3aa16 100644 --- a/src/nextjournal/clerk/sci_viewer.cljs +++ b/src/nextjournal/clerk/sci_viewer.cljs @@ -618,6 +618,14 @@ (defn reagent-viewer [x] (r/as-element (cond-> x (fn? x) vector))) +(defn wrap-f-async + "Wraps f to catch all synchronous and asynchronous errors" + [f on-error] + (fn [& args] + (-> (try (apply f args) (catch js/Error e (on-error e))) + js/Promise.resolve + (.catch on-error)))) + (defn with-d3-require [{:keys [package then loading-view] :or {loading-view "Loading..." then identity}} f] (r/with-let [!package (r/atom {:loading loading-view}) @@ -625,7 +633,14 @@ (d3-require/require package) (apply d3-require/require package)) (.then then) - (.then f) + (.then + (fn wrap-callback [packages] + (f packages + (fn wrap-callback + ;; wraps callback function to display errors here, serving + ;; as an error boundary. + [callback] + (wrap-f-async callback #(reset! !package {:error %})))))) (.then #(reset! !package {:value %})) (.catch #(reset! !package {:error %})))] (let [{:keys [loading error value]} @!package] @@ -636,13 +651,13 @@ (defn vega-lite-viewer [value] (when value - (html ^{:key value} - [with-d3-require {:package ["vega-embed@6.11.1"] - :then (fn [embed] (.container embed (clj->js value)))} - (j/fn [vega-el] + (html [with-d3-require {:package ["vega-embed@6.11.1"] + :key value} ;; specify what value should trigger re-render + (fn [vega-embed wrap-callback] [:div {:style {:overflow-x "auto"}} - [:div.vega-lite {:ref #(when % - (.appendChild % vega-el))}]])]))) + [:div.vega-lite {:ref (wrap-callback + (fn [el] + (when el (.embed vega-embed el (clj->js value)))))}]])]))) (def mathjax-viewer (comp normalize-viewer-meta mathjax/viewer)) (def code-viewer (comp normalize-viewer-meta code/viewer))