Fork me on GitHub
#hyperfiddle
<
2023-04-21
>
braai engineer08:04:30

How can I tell Hyperfiddle how to serialize things like Dates so I don’t get this INFO log? I have time-literals installed on front & back, so it should know how to serialize #time/date "2018-10-09" (just like that).

: Unserializable reference transfer: java.time.LocalDate 2018-10-09

xificurC09:04:17

data is transferred with transit, so you need to install the transit handlers in the app. Here's a https://github.com/hyperfiddle/electric/blob/0bc5f4bcd96b632f4522de328af66b44f1220fe4/src-docs/wip/demo_custom_types.cljcshowing how you can do that today

braai engineer12:04:22

hmm, the following does not seem to work:

(ns xtx.transit
  "Connect time-literals to transit.

  Sourced and edited from:
  

  "
  (:require
    [time-literals.read-write]
    [cognitect.transit :as transit]
    #?(:cljs [java.time :refer [Period
                                LocalDate
                                LocalDateTime
                                ZonedDateTime
                                Instant
                                ZoneId
                                DayOfWeek
                                LocalTime
                                Month
                                Duration
                                Year
                                YearMonth]]))
  #?(:clj (:import
            (java.time Period
                       LocalDate
                       LocalDateTime
                       ZonedDateTime
                       Instant
                       ZoneId
                       DayOfWeek
                       LocalTime
                       Month
                       Duration
                       Year
                       YearMonth))))

;; uhmm I think these have to be fully namespaces
(def time-classes
  {'period          Period
   'time/date            LocalDate
   'date-time       LocalDateTime
   'zoned-date-time ZonedDateTime
   'instant         Instant
   'time            LocalTime
   'duration        Duration
   'year            Year
   'year-month      YearMonth
   'zone            ZoneId
   'day-of-week     DayOfWeek
   'month           Month})

(def write-handlers
  (into {}
    (for [[tick-class host-class] time-classes]
      [host-class (transit/write-handler (constantly (name tick-class)) str)])))

(def read-handlers
  (into {} (for [[sym fun] time-literals.read-write/tags]
             [(name sym) (transit/read-handler fun)])))


;; Demo shows how to serialize custom types in Electric

;; Todo cleanup, there are better ways to do this
#?(:clj (alter-var-root #'
          merge write-handlers)) ; server: write only
#?(:cljs (set! 
           (merge  read-handlers))) ; client: read only
maybe because tags not fully-namespaced? cc @U09FL65DK

xificurC13:04:00

I'd suggest taking a single class, e.g. Period, use it manually and get that working. Then you can expand to subsume above. Any chance you're failing to transfer a date/time type from client to server? The config only sets up server->client

braai engineer13:04:41

Hmm, even this complains if I try to send a LocalDate (from server to client only):

(def write-handler (transit/write-handler
                     (fn [_] 'time/date) ; this tag must be namespaced!
                     str))

(def read-handler (transit/read-handler 12345.67)) ;; just overriding it for now to see if it can send from server to client

#?(:clj (alter-var-root #'
          assoc LocalDate write-handler)) ; server: write only
#?(:cljs (set! 
           (assoc 
             "time/date" read-handler))) ; client: read only
Do I need to call alter-var-root from somewhere specific? Error:
INFO  : Unserializable reference transfer: java.time.LocalDate 2000-01-01
Tried with string tag vs symbol tag.

👀 2
xificurC13:04:09

Here's a minimal working example where a JVM LocalDate is represented as a string "LOCALDATE: <date-here>" on the client

Dustin Getz14:04:10

lets change the tutorial to this

Dustin Getz14:04:18

also tutorial should provide both directions imo

Dustin Getz14:04:41

and also link to any supporting documentation/examples for transit

braai engineer17:04:13

I have to re-eval the transit handler namespace on server to get changes to show up, which I find unexpected given that my “app” namespace :require’s my transit handler namespace. The auto-builder does not seem to pick up changes to that namespace, which is confusing when trying to debug why handlers aren’t working.

👀 2
braai engineer17:04:18

Hmm, maybe because alter-var-root is in #?(:clj …) directive?

braai engineer09:04:19

Hmm, can’t seem to use Specter in Electric functions, which kind of makes sense with all it’s crazy macros:

(->> (:entry/_tx tx)
     (S/transform [S/ALL :entry/amount] float)) ;; because  (sort-by :entry/amount ...) chokes on bigdec [TaggedValue f...] some or other.

Unable to resolve symbol: pathcache83102
{:file "xtx/electric.cljc", :cljs.analyzer/no-resolve true, :no-doc true, :private true, :in [pathcache83102]}
ExceptionInfo: Unable to resolve symbol: pathcache83102
	hyperfiddle.electric.impl.compiler/analyze-form (compiler.clj:643)
	hyperfiddle.electric.impl.compiler/analyze-form 

leonoel09:04:31

I suspect the problem to be specter macroexpanding to inline defs, which in turn confuse electric compiler because the symbol doesn't refer to a top-level var

xificurC09:04:31

[TaggedValue f...] seems like a type you didn't expect, maybe the serialization returns something else than you expect? • I think specter will work if you call it in a clojure context, not electric. As a first step try to push the specter code in a toplevel cc/defn

Dustin Getz11:04:20

we have a bug related to certain things that should be float coming across as TaggedValue ratio

braai engineer10:05:44

Is there a quickfix for TaggedValue? I’m seeing decimals come over the wire as e.g. [TaggedValue: f, -2402.97] or should I coerce to float or string before sending from server to client?

vincent19:04:36

I have a crazy idea- I'm gonna use my cloud box to do the heavy lifting for me, and code via SSH 😄 probably lots of fellows already doing this i bet

vincent19:04:08

I think I found an issue w/ electric-examples-app a fresh clone gives. me

cloning: 
Checking out:  at 447810b9401d66d6f6d5a7bf3da685f406efa7a5
Cloning: 
Downloading: com/google/guava/guava/31.1-jre/guava-31.1-jre.pom from central
Downloading: com/google/guava/guava-parent/31.1-jre/guava-parent-31.1-jre.pom from central
Downloading: thheller/shadow-cljs/2.22.10/shadow-cljs-2.22.10.pom from clojars
Downloading: markdown-clj/markdown-clj/1.11.4/markdown-clj-1.11.4.pom from clojars
Checking out:  at ac038ebf6e5da09dd2b8a31609e9ff4a65e36852
Error building classpath. Failed to read artifact descriptor for com.datomic:dev-local:jar:1.0.243
org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for com.datomic:dev-local:jar:1.0.243
	... 21 more

vincent19:04:11

which is `Could not transfer artifact com.datomic:dev-local:pom:1.0.243 from/to cognitect-dev-tools (): status code: 401, reason phrase: Unauthorized (401)

Dustin Getz19:04:00

datomic dev-local requires registration and out of band maven configuration, you can remove the datomic from deps.edn and comment out any references to the datomic example

vincent19:04:06

I replaced it :deps {com.datomic/datomic-free {:mvn/version "0.9.5697"} in deps.edn and seems to be working

vincent19:04:17

Now I get The required JS dependency "@codemirror/language" is not available, it was required by "contrib/electric_codemirror.cljc". maybe npm dep?

vincent19:04:31

I do want to use datomic, just not sure how to accommodate the codemirror thang, but i'm looking into it 😅

Dustin Getz19:04:05

or, npm install

Dustin Getz19:04:19

datomic free is not a drop in replacement i don’t think

vincent19:04:27

confirmed it is not 😅

vincent19:04:19

So ideally there would be a super simple app with:z

vincent19:04:51

datomic free, jetty server w/ session, and electric chat app

vincent19:04:11

trying to carve a useful starting block of marble out of the example app 😅

vincent19:04:28

Maybe I can just add datomic to the starter-app and be good to go, I just require sessions, eventually, and figure it better to work with them from the outset

Dustin Getz19:04:28

yes i recommend that, use the starter todos app and port datascript to datomic free

vincent19:04:07

thanks for the rec

vincent19:04:18

add sesh later?

Daniel Jomphe11:04:04

this little story above is a great example of how it might be great for Datomic to loosen up on the maven config requirements for dev-local tutorial-level users and tutorial-level creators (if possible)! @U1QJACBUM

vincent23:04:07

uh yeah i don't want to touch maven with a ten foot pole 😅

vincent23:04:25

what year is it 😅 😅 robin williams full of beard

vincent21:04:54

I think my remote box ran out of JVM RAM 😅 I set the stack size to 3g is that too much ? o_O 2g was not enough

vincent21:04:14

2777mb seems to do it x)