Fork me on GitHub
#biff
<
2023-02-26
>
Danny Almeida02:02:39

Hi @foo, a noob question. How do i run the project in Cider REPL ? after jacking in, i'm not sure which namespace to load and what the starting point is. I've trying out the chatapp as an example. If I run start() in chatapp namespace, it errors out saying config.edn not found

Jacob O'Bryant05:02:14

I assume you've cloned the chat app repo? For that to work, you'll need to add a config.edn file, since that file isn't tracked by git. I should add a config.edn.TEMPLATE file that you can rename. this won't be a problem if you create a new project, since in that case the config.edn file will be created for you. start is the right function to call. however, instead of jacking in the usual way, I generally recommend starting up the app with bb dev, and then connect to the nrepl server that gets started by that command.

Jacob O'Bryant05:02:45

(if you did want to add a config.edn file to the cloned repo, easiest way is to start a new project and use com.eelchat as the main namespace, then copy over the config.edn file that gets generated)

Jacob O'Bryant05:02:28

also if you prefer to continue jacking in the usual way, that's fine as well--but you'll need to do a couple extra things that bb dev does for you, like setting the BIFF_ENV=dev environment variable.

Danny Almeida22:02:41

Hi @foo, thanks for the detailed explanation. I can live with starting the repl with bb dev and then connecting it with cider connect. I'll create a new project and copy the config.edn file from it. Thank you for responding so quickly, appreciate it. Cheers 🙂

👌 1
ag02:02:13

> I can live with starting the repl with bb dev and then connecting it with cider connect. create .dir-locals.el file with the following content:

((nil . ((cider-preferred-build-tool . babashka)
         (cider-babashka-parameters . "dev"))))
and jack-in as usual

Danny Almeida02:02:18

thanks 👍:skin-tone-3:

Danny Almeida02:02:58

I assume i would still have to run bb dev first

ag02:02:59

you may have to run hack-dir-local-variables, kill project buffers and re-open them for Emacs to pick up the directory local changes. Just check that those variables are being set to the values indicated before running jack-in. Or simply restart Emacs. When you open the project, Emacs will prompt you, asking if you want to store these values for future sessions in custom.el.

ag02:02:11

> I assume i would still have to run bb dev first No. That's the whole point of that file, so you don't have to

ag02:02:27

@foo btw, I wanted to submit a few sentences to the documentation about this thing, but I couldn't find the repo.

Danny Almeida02:02:52

:clojure.main/message "Execution error (IllegalArgumentException) at java.util.Base64$Decoder/decode0 (Base64.java:746).\nIllegal base64 character 5f\n", :clojure.main/triage {:clojure.error/class java.lang.IllegalArgumentException, :clojure.error/line 746, :clojure.error/cause "Illegal base64 character 5f", :clojure.error/symbol java.util.Base64$Decoder/decode0, :clojure.error/source "Base64.java", :clojure.error/phase :execution}, :clojure.main/trace {:via [{:type java.lang.IllegalArgumentException, :message "Illegal base64 character 5f", :at [java.util.Base64$Decoder decode0 "Base64.java" 746]}], :trace [[java.util.Base64$Decoder decode0 "Base64.java" 746] [java.util.Base64$Decoder decode "Base64.java" 538] [java.util.Base64$Decoder decode "Base64.java" 561] [jdk.internal.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2] [jdk.internal.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.java" 62] [jdk.internal.reflect.DelegatingMethodAccessorImpl invoke "DelegatingMethodAccessorImpl.java" 43] [java.lang.reflect.Method invoke "Method.java" 566] [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 167] [clojure.lang.Reflector invokeInstanceMethod "Reflector.java" 102] [com.biffweb.impl.util$base64_decode invokeStatic "util.clj" 57] [com.biffweb.impl.util$base64_decode invoke "util.clj" 56] [com.biffweb.impl.middleware$wrap_ring_defaults invokeStatic "middleware.clj" 88] [com.biffweb.impl.middleware$wrap_ring_defaults invoke "middleware.clj" 80] [com.biffweb.impl.middleware$wrap_outer_defaults invokeStatic "middleware.clj" 125] [com.biffweb.impl.middleware$wrap_outer_defaults invoke "middleware.clj" 123] [clojure.core$update invokeStatic "core.clj" 6233] [clojure.core$update invoke "core.clj" 6223] [com.biffweb$use_outer_default_middleware invokeStatic "biffweb.clj" 333] [com.biffweb$use_outer_default_middleware invoke "biffweb.clj" 328] [com.biffweb.impl.util$start_system invokeStatic "util.clj" 28] [com.biffweb.impl.util$start_system invoke "util.clj" 23] [com.biffweb$start_system invokeStatic "biffweb.clj" 30] [com.biffweb$start_system invoke "biffweb.clj" 24] [com.technolunatic.chatapp$start invokeStatic "chatapp.clj" 57] [com.technolunatic.chatapp$start invoke "chatapp.clj" 56] [com.technolunatic.chatapp$_main invokeStatic "chatapp.clj" 71] [com.technolunatic.chatapp$_main doInvoke "chatapp.clj" 70] [clojure.lang.RestFn applyTo "RestFn.java" 137] [clojure.lang.Var applyTo "Var.java" 705] [clojure.core$apply invokeStatic "core.clj" 667] [clojure.main$main_opt invokeStatic "main.clj" 514] [clojure.main$main_opt invoke "main.clj" 510] [clojure.main$main invokeStatic "main.clj" 664] [clojure.main$main doInvoke "main.clj" 616] [clojure.lang.RestFn applyTo "RestFn.java" 137] [clojure.lang.Var applyTo "Var.java" 705] [clojure.main main "main.java" 40]], :cause "Illegal base64 character 5f"}}

Danny Almeida03:02:24

that's the error message i get when i try to invoke cider jack-in

Danny Almeida03:02:30

not sure what's going on

Danny Almeida03:02:50

i guess i'll start with a fresh project instead of trying to use an existing one

ag03:02:55

make sure that the vars are properly set. run M-x describe-variable (while you're in the directory). the logs in *nrepl-server* buffer, should be pretty much the same as when you run bb dev in the terminal

Danny Almeida03:02:22

thanks. It works with a new project.

Danny Almeida03:02:09

how do i restart the system ? there is no reset or stop command

Jacob O'Bryant03:02:40

oh, just remembered that a config.edn file from a new project won't be backwards compatible with the eelchat project (specifically, the way secrets are stored has changed). on the first or second page of the tutorial it has you run the new project script with an additional argument that'll base the project off the same biff version that I used for the tutorial. you would need to make a new project with that command and copy the config.edn file from there. (or just stick with a new project). call (biff/refresh) to restart. in most cases (e.g. updating routes or schema) it isn't necessary, but it is needed sometimes of course docs are in a separate repo. bit of a mess currently. I'll post a link in a minute

2
Danny Almeida03:02:45

thanks @foo, you are doing an amazing job with this project

Danny Almeida03:02:09

i am just trying to learn and see if I can use biff for a couple of starter projects

Danny Almeida03:02:45

i appreciate your quick responses here.. always a pleasure when developer responds to quickly 😄

Danny Almeida03:02:57

cause i'm a total noob

Jacob O'Bryant03:02:07

thanks, and you're welcome :)

metal 2
Danny Almeida03:02:15

Hi @foo, the docs mention Rum. but I also saw htmx on the webpage. Which one is being used for the UI part right now ?

Jacob O'Bryant04:02:30

both. rum renders the html on the server, and htmx swaps it into the dom client-side

Danny Almeida04:02:11

i was wondering why Rum on the server instead of something like Selmer ?

Danny Almeida04:02:25

coming from CMS background, i like the templating capability of Selmer

Jacob O'Bryant04:02:05

I use rum in Biff since I personally prefer hiccup syntax, as do a lot of Clojure developers I believe. I like the succinctness, and being able to use plain Clojure instead of a custom templating language. But biff isn't tied to rum; you can use Selmer instead if you like. you'd just need to write your own version of biff/base-html, and replace the biff/wrap-render-rum (I think that's what it's called anyway...)middleware with a Selmer version (or just have all your html-returning routes call Selmer explicitly)

Danny Almeida04:02:56

ah I see. thanks for the explanation. Good to know that things can be swapped out if required

Jacob O'Bryant04:02:16

yep! being able to swap stuff out is one of the main design goals

❤️ 2
m.q.warnock16:02:36

I just encountered a bug which I caused by using the req passed into a ws-handlers function in the on-text callback; old database reference leading to previously updated data not appearing. I'm fixing it by calling get-sys in the callback, but I wonder if there might be a cleaner way - maybe biff could wrap the ws callbacks and provide a current system value? I know it would essentially be the same thing, but might be less 'surprising'

Jacob O'Bryant17:02:26

actually I'm not sure if there is a good way for biff to do that for you unless I do some restructuring, since I think on-text is a closure over the req value--we'd need to have on-text receive req as a parameter so that it can be passed in by biff an each new websocket message. re: get-sys: it is unclean (more specifically, it's a matter of style/system organization/dependency injection. using get-sys will get the job done and honestly you may never have any problems doing that. but as your app grows, there's a danger it might lead to spaghetti. if you always pass the system object to functions via a parameter, then it's clear what functions are actually depending on the system map. it also means you can easily pass in a modified version of the system map e.g. for testing, if you're into that sort of thing)

m.q.warnock17:02:03

oh, I definitely avoid get-sys within functions wherever possible; it's just this particular case of a stale req, because, as you say, it's closed over. passing it in to on-text as a param is what I was suggesting

👍 1
Jacob O'Bryant17:02:00

👍 yeah, the staleness thing is solved by merge-context--only reason get-sys returns an up-to-date db is because it calls merge-context

👍 1