Fork me on GitHub
#clojurescript
<
2022-09-22
>
seepel01:09:50

Has anyone used https://github.com/smothers/cause? In particular I am trying to figure out how I would serialize and deserialize a CausalList.

seepel01:09:24

Here is how I expected it to work

(def root-uuid (random-uuid))

;; Helper to set uuid and site-id
(defn base [uuid site-id]
  (->  (cause/base)
       (cause/set-uuid uuid)
       (cause/set-site-id site-id)))

;; Create a CausalList for site-id "foo"
(def cb1 (atom (base root-uuid "foo")))
(def starting-data '(1 2 3))
(swap! cb1 cause/transact [[nil nil starting-data]])

;; Get the backing nodes for site-id "foo"
(def cl (cause/get-collection @cb1))
(def nodes (seq cl))

;; Load CausalList from site-id "foo" at site-id "bar"
(def cb2 (atom (base root-uuid "bar")))
(swap! cb2 cause/transact nodes)

; Execution error (ExceptionInfo) at (<cljs repl>:1).
Please transact a root collection first by setting uuid and cause to nil
:repl/exception!

Dane Filipczak19:09:23

I don’t know the answer to your question but thanks for bringing this to my attention, I didn’t know there was a good clojure CRDT ❤️

seepel23:09:27

I have a sinking suspicion that you can't do it 😞 https://github.com/smothers/cause/issues/10

e16:09:15

I have a website that I want to automatically close or redirect if the user tabs away. I have an event listener that listens for visibility and redirects if the tab is inactive. On desktop, everything works as expected on both Chrome and Safari... that is, if I open up the webpage on my laptop and then open up another tab, this works as expected. However, on mobile, Chrome behaves as expected, but Safari does not. The event listener doesn’t appear to fire at all if I open up the site and then open up a different tab on my phone. Is there a nuance to Safari on mobile re visibility? (I suppose this might as well be answered by hitting up a JS forum, but I don’t really feel like translating all of my cljs code to js 🙂 )

e16:09:27

(ns foo.common.events.visibility
  (:require
   [re-frame.core :as rf]
   [foo.chat.queries.visibility :as visibility-q]
   [foo.entry.queries.authentication :as auth-q]
   [foo.common.funcs :as f-utils]))


(rf/reg-event-db
 ::set-hidden-value
 (fn [db [_ value]]
   (visibility-q/set-hidden-value db value)))

(defn is-hidden? []
  (or (.-hidden js/document)
      (.-msHidden js/document)
      (.-webkitHidden js/document)
      (.-onblur js/document)))

(defn visibility-type []
  (cond
    (exists? (.-hidden js/document))  "visibilitychange"
    (exists? (.-msHidden js/document)) "msvisibilitychange"
    (exists? (.-webkitHidden js/document)) "webkitvisibilitychange"
    :else nil))

;; just a hobby project, so don't care that it doesn't check for android
(defn is-mobile []
  (f-utils/not-nil? (.match (.-userAgent js/navigator) #"(?i)iPhone")))

(defn handle-visibility-change []
  (.log js/console (is-hidden?))
  (rf/dispatch [::set-hidden-value (is-hidden?)])
   (rf/dispatch [::quit-if-visible]))

(rf/reg-event-fx
 ::quit-if-visible
 (fn [cofx]
   (let [db (:db cofx)
         admin? (auth-q/get-admin-status db)]
     (when (and
            (is-hidden?)
            (not admin?)
            (is-mobile))
       (.replace (.-location js/window) "")
     {}))))


(defn set-visibility-listener []
  (.addEventListener js/document
                     (visibility-type)
                     handle-visibility-change
                     false))

(defn remove-visibility-listener []
  (.removeEventListener js/document
                     (visibility-type)
                     handle-visibility-change
                     false))

leif16:09:05

Is there any way to make code like this in clojurescript?:

(ns test.core)

(defmacro foo [a]
  `[~a :b])

(defmacro alet [a body]
 (let [exp (macroexpand `(foo ~a))]
  `(let ~exp ~body)))

phronmophobic16:09:35

Would you be able to do something like?

(defn foo* [a]
  `[~a :b])

(defmacro foo [a]
  (foo* a))

(defmacro alet [a body]
 (let [exp (foo* a)]
  `(let ~exp ~body)))

leif16:09:07

Interesting

leif16:09:59

Actually, yes, I think that would work here.

leif16:09:20

I forgot about ClojureScripts phase mixing. 🙂

phronmophobic16:09:37

I often write my macros using that pattern regardless since it's easier to work with functions than macros

leif16:09:46

Ya, that I have noticed.

leif16:09:56

I'm used to Racket's more powerful macro system.

leif16:09:01

Anyway, thanks.

👍 1
leif16:09:34

(Including bootstrapped/self-hosted clojurescript)

leif16:09:50

In clojure it seems fine, but clojurescript seems unhappy with macroexpand.