Fork me on GitHub
#clojurescript
<
2022-07-19
>
geraldodev11:07:08

I'm using useSyncExternalStore to tap into an atom. I was curious how it re-renders and I forced a not stable snapshot of data with merge (the commented version) and got multiple renders error. So: Can I conclude that a deref on the atom that is backed by a map is a stable reference? It appears so and that is cool, and the consequence of it: exposing it to react appears to be simple. Can you share your thoughts on this ?

(def ^:private cache (atom {}))

(def ^:private notifiers (atom #{}))
(add-watch cache :logger
          (fn [_key _atom _old-state _new-state]
            (doseq [notify @notifiers]
              (notify))))

(defn ^:private subscribe
  [notify]
  (swap! notifiers conj notify)
  (fn [] (swap! notifiers disj notify)))

(defn use-paginated-query-cache
  [query-name ]
  (useSyncExternalStore subscribe (fn [] (get @cache query-name)))
  ; (useSyncExternalStore
  ;   subscribe
  ;   (fn []
  ;    (merge {} (get @cache query-name))))
  )

Roman Liutikov11:07:16

Here's a complete implementation of React Hooks <-> atom gluing code https://github.com/pitch-io/uix/blob/master/docs/interop-with-reagent.md#syncing-with-ratoms-and-re-frame We use it at Pitch, works well for us

💯 1
Ovidiu Stoica19:07:51

Hei guys, I’m trying to integrate Supabase (firebase competitor) but I get stuck trying to call a nested object function signUp (https://supabase.com/docs/reference/javascript/auth-signup) From the docs: Create client:

import { createClient } from '@supabase/supabase-js'

// Create a single supabase client for interacting with your database 
const supabase = createClient('', 'public-anon-key')
Sign up:
const { user, session, error } = await supabase.auth.signUp({
  email: '',
  password: 'example-password',
})
My cljs:
(defonce ^SupabaseClient supabase-client (create-client supabase-url supabase-key))


(defn sign-up
  [email password]
  (let [sign-up-fn (-> supabase-client .-auth .-signUp)]
    (sign-up-fn (clj->js {:email email :password password}))))

(comment
  (-> (sign-up "" "pass123omg_crazy")
      (.then js/console.log)))
In the shadow cljs repl I get:
------ WARNING #1 - :infer-warning ---------------------------------------------
 File: /Users/ovistoica/workspace/invoice-dev/src/invoice_dev/core.cljs:21:20
--------------------------------------------------------------------------------
  18 | 
  19 | (defn sign-up
  20 |   [email password]
  21 |   (let [sign-up-fn (-> supabase-client .-auth .-signUp)]
--------------------------^-----------------------------------------------------
 Cannot infer target type in expression (. (.-auth supabase-client) -signUp)
--------------------------------------------------------------------------------
  22 |     (sign-up-fn (clj->js {:email email :password password}))))
  23 | 
  24 | (comment
  25 |   (-> (sign-up "" "pass123omg_crazy")
--------------------------------------------------------------------------------
In the console I get
"TypeError: Cannot read properties of null (reading '_removeSession')
    at eval ()
    at Generator.next (<anonymous>)
    at eval ()
    at new Promise (<anonymous>)
    at __awaiter ()
    at signUp ()
    at invoice_dev$core$sign_up ()
    at eval (eval at shadow$cljs$devtools$client$browser$global_eval (), <anonymous>:1:26)
    at eval (<anonymous>)
    at Object.shadow$cljs$devtools$client$browser$global_eval [as global_eval] ()"
I saw this documented in the cljs docs, but I thought that declaring the ^Supabase type would handle it. I think the supabase object is a class implementation. Anyway this should have worked. Any opinions?

p-himik19:07:10

Three things: • There's a password in your CLJS code that you posted - not sure whether it's something sensitive • No need to annotate with ^Supabase in CLJS, you can just use ^js whenever shadow-cljs complains with "Cannot infer target type" • Don't extract JS functions under separate bindings without using >bind, otherwise they lose their this, which is I'm pretty sure the root cause of the issue you're seeing

Ovidiu Stoica19:07:38

The pass is a mock pass, but you scared me for a sec lol. Yes, I think that is the issue! I’ll check back, thank you

geraldodev19:07:51

@U2FRKM4TW nice thing about shadow is that it warns us when we does not use ^js and it thinks its needed . Do you have any information about that ?

Ovidiu Stoica19:07:49

@U2FRKM4TW I still get the same error even if I do ((-> client .-auth .-signUp) email pass) What is the correct way to do it without losing the bind to this?

p-himik19:07:22

Also note that there can be false negatives - you might need ^js where you haven't received any warning. Like in this expression: (let [x (first #js [#js {:a 1}])] ...).

thheller19:07:30

(defonce ^js supabase-client (create-client supabase-url supabase-key)) should be enough

p-himik19:07:52

@U01JA0VU7P0 (.. client -auth (signUp email pass)).

p-himik19:07:18

Even without the binding in your variant, you're still extracting a function and then calling it. In my variant, you're calling it without extracting.

Ovidiu Stoica19:07:38

I see. I had no idea about that notation. Thank you