From 0f4d359fe6de58c2f132f622baee8a293808406d Mon Sep 17 00:00:00 2001 From: Matthew Huebert Date: Tue, 1 Nov 2022 21:59:30 +0100 Subject: [PATCH 1/3] ErrorBoundary using shadow.cljs.modern defclass --- resources/viewer-js-hash | 2 +- src/nextjournal/clerk/render.cljs | 32 ++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/resources/viewer-js-hash b/resources/viewer-js-hash index 624e0cbe0..905e445ec 100644 --- a/resources/viewer-js-hash +++ b/resources/viewer-js-hash @@ -1 +1 @@ -3G8qHYpeyRtTiivLb5mGgdo6VrZM \ No newline at end of file +oMbRqh4yRmtcrxeBr7Dt3LutfiH \ No newline at end of file diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index 3b7fd5b18..013ed2c8a 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -20,6 +20,7 @@ [reagent.core :as r] [reagent.dom :as rdom] [reagent.ratom :as ratom] + [shadow.cljs.modern :refer [defclass]] [sci.core :as sci])) ;; a type for wrapping react/useState to support reset! and swap! @@ -284,8 +285,32 @@ (when-some [data (.-data error)] [:div.mt-2 [inspect data]])]) - - +(def ErrorProvider (j/get (view-context/get-context :!error) :Provider)) + +(defclass ErrorBoundary + (extends react/Component) + (field !error) + (constructor [this ^js props] + + (super props) + (set! !error (j/get props :!error)) + (set! (.-state this) #js{:error @!error})) + Object + (componentDidMount [this] + (add-watch !error this + (fn [_ _ _ new-val] + (j/call this :setState #js{:error new-val})))) + (componentWillUnmount [this] (remove-watch !error this)) + (render [^js this props] + (j/let [^js {{:keys [error]} :state + {:keys [children]} :props} this] + (if error + (r/as-element [error-view error]) + (.apply react/createElement nil + (.concat #js[ErrorProvider #js{:value !error}] children)))))) + +(j/!set ErrorBoundary + :getDerivedStateFromError (fn [error] #js{:error error})) (defn error-boundary [!error & _] (r/create-class @@ -356,7 +381,8 @@ (reset! !desc (read-result result !error)) (reset! !error nil)) [view-context/provide {:fetch-fn fetch-fn} - [error-boundary !error + [#_#_error-boundary !error + :> ErrorBoundary {:!error !error} [:div.relative [:div.overflow-y-hidden {:ref ref-fn} From 9a5201356767815b796fb4a4259c380203b884cb Mon Sep 17 00:00:00 2001 From: Martin Kavalar Date: Tue, 1 Nov 2022 21:26:13 +0000 Subject: [PATCH 2/3] Update errors notebook --- notebooks/viewers/errrors.clj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/notebooks/viewers/errrors.clj b/notebooks/viewers/errrors.clj index e21ea5306..f3ae5e980 100644 --- a/notebooks/viewers/errrors.clj +++ b/notebooks/viewers/errrors.clj @@ -11,16 +11,12 @@ (clerk/with-viewer {:render-fn '(fn [x] (throw (ex-info "I blow up when called" {})))} :boom) -(clerk/with-viewer {:render-fn '(fn [x] x)} +(clerk/with-viewer {:render-fn '(fn [_] (v/inspect-presented :crash))} 42) -(clerk/with-viewer {:render-fn '(fn [_] (v/inspect :crash))} - 42) - -(clerk/with-viewer {:render-fn '(fn [_] (v/html (v/inspect :crash)))} +(clerk/with-viewer {:render-fn '(fn [_] (v/html (v/inspect-presented :crash)))} 42) (clerk/with-viewer {:render-fn '(fn [_] (v/html [1 2 3]))} 42) - From 8175c8fac22def46ee432f5cd16b5b025557cec6 Mon Sep 17 00:00:00 2001 From: Martin Kavalar Date: Tue, 1 Nov 2022 21:29:36 +0000 Subject: [PATCH 3/3] Activate functional components for SSR, cleanup --- src/nextjournal/clerk/render.cljs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/nextjournal/clerk/render.cljs b/src/nextjournal/clerk/render.cljs index 013ed2c8a..17775c164 100644 --- a/src/nextjournal/clerk/render.cljs +++ b/src/nextjournal/clerk/render.cljs @@ -101,10 +101,7 @@ #js[x]) #(binding [reagent.ratom/*ratom-context* nil] @x)))) -(when (exists? js/window) - ;; conditionalized currently because this throws in node - ;; TypeError: Cannot assign to read only property 'reagentRender' of object '#' - (r/set-default-compiler! (r/create-compiler {:function-components true}))) +(r/set-default-compiler! (r/create-compiler {:function-components true})) (declare inspect inspect-presented reagent-viewer html html-viewer) @@ -312,17 +309,6 @@ (j/!set ErrorBoundary :getDerivedStateFromError (fn [error] #js{:error error})) -(defn error-boundary [!error & _] - (r/create-class - {:constructor (fn [_ _]) - :component-did-catch (fn [_ e _info] (reset! !error e)) - :get-derived-state-from-error (fn [e] (reset! !error e) #js {}) - :reagent-render (fn [_error & children] - (if-let [error @!error] - (error-view error) - [view-context/provide {:!error !error} - (into [:<>] children)]))})) - (def default-loading-view "Loading...") (defn use-handle-error [] @@ -381,8 +367,7 @@ (reset! !desc (read-result result !error)) (reset! !error nil)) [view-context/provide {:fetch-fn fetch-fn} - [#_#_error-boundary !error - :> ErrorBoundary {:!error !error} + [:> ErrorBoundary {:!error !error} [:div.relative [:div.overflow-y-hidden {:ref ref-fn}