Fork me on GitHub
Pepijn de Vos13:08:37

Is there a reasonable way to round-trip sets and tagged elements through json?


I think that’s one of the problems transit was designed to solve.


• Switch to transit+json (i.e. transit would be valid json, but you'd still have to use transit encoder/decoder) • Use something like spec-tools.core/coerce with spec-tools.core/json-transformer and with a correctly defined schema:

Pepijn de Vos13:08:52

Ah interesting. I was just looking over the spec guide and thinking about coll-of to get sets back.


You might be able to pull it off without spec-tools because coll-of has :into argument. But it requires conforming, and that might lead to other data transformations, like s/or returning vectors instead of values.

Pepijn de Vos13:08:02

Yea I could look into transit but I'm not sure how "invasive" it is. I'm using it with couchdb so if it turns the id and rev into BS that's not going to work either.


Depends on how you structured your app, I suppose. I haven't worked with couchdb, but I imagine you could go this route: • Prepare your data • Serialize it with Transit and get not a string but a JSON-ready data as an output (I think it's a possibility) • Assoc _id and _rev into that data • Store it Do the same but in reverse upon retrieving the data.

Pepijn de Vos14:08:22

Hmmm does transit have an API to start from a JS object rather than stringified json?

Pepijn de Vos14:08:34

Seems no, so that's a bit of a showstopper.


The CLJ interface is rather generic - if you provide your own writer that's not JSON writer, it should be possible.


package com.cognitect.transit;

 * Interface for writing values in transit format.
public interface Writer<T> {
     * Writes a single value to an output stream
     * @param o the value to write
    void write(T o);

Pepijn de Vos14:08:06

Mjeh I think I'll try the coercion method


I don't have much experience with clojurescript yet but wanted to start a small project and use to handle my auth and db needs (it's basically an opensource Firebase alternative.) They only have a javascript client currently. Do you think this would be much of a problem? I assume with the interop story I just need to take whatever JS function the docs describe and convert it over to cljs. So if using reagent I should be able to just convert all the functions and such on this doc page: to cljs pretty easily?


Would I also be able to use clojure/script db tools like honey sql to access the postgres db?


> I just need to take whatever JS function the docs describe and convert it over to cljs Not the function itself, but they way it's called. If something like queryData is already implemented, you don't need to reimplement it - you just call it from CLJS via JS interop. > Would I also be able to use clojure/script db tools like honey sql to access the postgres db? Is it related to Supabase? Because by itself the answer is "absolutely" since HoneySQL explicitly supports PostgreSQL.


Ok, awesome. Supabase's db is postgres so you query it as if it was a db on your local machine (I think? I'm new to such things) so that sounds like it would work with HoneySQL


So something like this for the auth portion:

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

const supabaseUrl = process.env.REACT_APP_SUPABASE_URL
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)


for cljs, that createClient function call would be something like

(ns app.auth 
 (:import [supabase/supabase-js :refer [createClient])

(def supabaseUrl ...)
(def supabaseAnonKey ...)

(def supabase (.createClient supabaseUrl supabaseAnonKey)


Without the dot. Dots are used when that function is a property of some object.


Ok, cool. Thanks!


Side question if I decide to go with firebase instead: I am seeing a few different wrapper libraries. Which one are any of you folks currently using?


Awesome! Cool timing. Thanks


Just to follow up on figuring out node vs browser execution contexts inside of cljs - I'm going to go with :closure-defines to define a compile-time constant that says which context I'm in. Turns out some node libraries are pretty chunky and GCC can get rid of them if it knows that they're never called (i.e. because we're in the browser context).

👍 1
Thomas Gebert22:08:14

Hi all! I need a bit of help. I'm not sure what I did, but something is broken. I'm trying to run this app (based on a template) ( Shadowcljs seems to compile it ok with shadow-cljs watch main renderer, but upon trying to run it, I get this error

Thomas Gebert22:08:41

(base) ➜  sp2 git:(master) ✗ ELECTRON_ENABLE_LOGGING=1 electron .
shadow-cljs - #4 ready!
[39655:0830/184112.665391:INFO:CONSOLE(15)] "SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021. See 
red-array-buffer/ for more details.", source: js/cljs-runtime/module$node_modules$scheduler$cjs$scheduler_development.js (15)
[39655:0830/184112.668933:INFO:CONSOLE(796)] "%cDownload the React DevTools for a better development experience: 
You might need to use a local HTTP server (instead of file://):  font-weight:bold", source: js/cljs-runtime/module$node_modules$react_dom$cjs$reac
t_dom_development.js (796)
[39655:0830/184112.670735:INFO:CONSOLE(36)] "shadow-cljs - failed to load module$node_modules$electron$index", source: js/cljs-runtime/shadow.js.js (36)
[39655:0830/184112.674968:INFO:CONSOLE(1551)] "An error occurred when loading app.renderer.core.js", source: file:///Users/tombert/sp2/resources/public/js/renderer.js (1551)
[39655:0830/184112.675045:INFO:CONSOLE(1552)] "TypeError: exports.existsSync is not a function
    at Object.shadow$provide.module$node_modules$electron$index (js/cljs-runtime/module$node_modules$electron$index.js:1:291)
    at Object.shadow.js.jsRequire (js/cljs-runtime/shadow.js.js:34:18)
    at Object.shadow.js.require (js/cljs-runtime/shadow.js.js:59:20)
    at eval (js/cljs-runtime/app.renderer.core.js:2:50)
    at eval (<anonymous>)
    at (file:///Users/tombert/sp2/resources/public/js/renderer.js:486:12)
    at Object.env.evalLoad (file:///Users/tombert/sp2/resources/public/js/renderer.js:1549:12)
    at file:///Users/tombert/sp2/resources/public/js/renderer.js:1704:12", source: file:///Users/tombert/sp2/resources/public/js/renderer.js (1552)
[39655:0830/184112.675198:INFO:CONSOLE(4)] "An error occurred when calling (app.renderer.core/start!)", source: js/cljs-runtime/shadow.module.renderer.append.js (4)
[39655:0830/184112.675260:INFO:CONSOLE(1551)] "An error occurred when loading shadow.module.renderer.append.js", source: file:///Users/tombert/sp2/resources/public/js/renderer.js
[39655:0830/184112.675303:INFO:CONSOLE(1552)] "TypeError: app.renderer.core.start_BANG_ is not a function

Thomas Gebert22:08:28

to a lay person it looks like it cannot find the node modules folder, but the folder is definitely there

Thomas Gebert22:08:43

For perspective, my node version:

$ node -v

Thomas Gebert22:08:38

and my current package.json config:

  "name": "shadow-electron-starter",
  "version": "1.0.0",
  "description": "shadow-cljs electron starter",
  "main": "resources/main.js",
  "scripts": {
    "dev": "shadow-cljs watch main renderer",
    "build": "shadow-cljs compile main renderer",
    "clean": "rm -rf resources/public/js/* && rm -rf target"
  "keywords": [
  "author": "Ahonn Jiang <[email protected]>",
  "license": "MIT",
  "devDependencies": {
    "electron": "^8.5.5",
    "shadow-cljs": "^2.15.6"
  "dependencies": {
    "electron": "^8.5.5",
    "react": "16.13.0",
    "react-dom": "16.13.0"

Thomas Gebert22:08:30

I am not terribly deep into this project so I'm fairly happy to abandon and start from scratch

Thomas Gebert22:08:15

;; shadow-cljs configuration
{:source-paths ["src"]

 :dependencies [[reagent "0.10.0"]]

 :dev-http {8080 "resources/public/"}

 :builds {:main {:target :node-script
                 :output-to "resources/main.js"
                 :compiler-options {:output-feature-set :es2020}
                 :main app.main.core/main}

          :renderer {:target :browser
                     :compiler-options {:output-feature-set :es6}
                     :js-options {:ignore-asset-requires true}
                     :output-dir "resources/public/js"
                     :asset-path "js"
                     :modules {:renderer {:init-fn app.renderer.core/start!}}}}}