Fork me on GitHub
#biff
<
2023-08-29
>
Bhougland11:08:08

Can anyone else go to the docs section on the Biff website on a mobile device (in my case iPhone)? I am having the same problem in my desktop browser

Epidiah Ravachol14:08:35

I'm having trouble clicking on the links on the front page, but I can get to the docs directly: https://biffweb.com/docs/get-started/intro/

Jacob O'Bryant15:08:31

oh, looks like the fix I made for that other issue broke the links in that top section... I'll fix that in a bit

Jacob O'Bryant15:08:11

it seems my fancy scroll thingy is starting to be more trouble than it's worth

Jacob O'Bryant16:08:04

It's fixed now.

👍 4
Bhougland16:08:39

I don't know if anyone will have an answer to this, but what would be some approaches to creating an app with ClojureDart and sync with a Biff backend? I would like the ability to use the app offline and then sync when the internet is available. I am not expecting the exact Dart/Flutter library/db, more of "it would be ideal if it could....". Btw Jacob, I can't wait for the "admin panel" example that you listed on the Biff website, I would love to use Biff as a Firebase alternative.

Jacob O'Bryant16:08:45

Hm, you'll for sure need to replace htmx with some sort of SPA solution, like re-frame or fulcro. In any case, the main question is what to do for the frontend--I assume there's a dart channel, perhaps ask there what people do for offline apps? And then regardless of what you end up doing for the frontend, you'll be able to use biff for the backend. Good to know about the admin panel! Could you clarify what aspects of Firebase you're interested in? I usually associate Firebase with its realtime DB, which seems unrelated to having an admin panel (?). For the latter I'm mainly envisioning showing how to set up some tables and charts for usage data (like # of new users, # of active users, etc), and then also show how to put in controls for any admin actions you'd like to expose through the web app (though I for actions I also often just use the repl).

Bhougland16:08:57

Hi Jacob, I am also just thinking about statistic type information, charts, etc. As far as Firebase, I probably only need a subset, but definitely manage OAuth, user, security, storage, ease of deployment.

👍 2
Bhougland17:08:16

oh, and payments (Stripe?) and email reminders/communication.

mqw20:08:58

I'm currently building a clojuredart app w/ biff backend (and htmx pages for admin stuff). For the client, I'm using a middleware stack that's api-routes + session, which I add an anon-id to if it doesn't exist. I store the cookies in shared-preferences and send them with my requests. That's good enough authentication for me right now, but I'll be solving some of the same problems as you longer term, assuming my project gets that far. Feel free to @ me with questions specific to our chosen stack, and I hope you'll write up any conclusions you come to where I can find them. Good luck!

🙌 2
vonadz19:08:32

@U7YNGKDHA I'd be curious to hear how you plan to do the tables / charts on a high level (what libs, etc). I was planning on setting some up on my site as well further down the line.

Jacob O'Bryant21:08:30

For Yakread's dashboard I use plain html tables and chart.js for charts. I also have a bunch of custom code for calculating various business metrics like retention that would might be valuable to put in a lib somewhere.

❤️ 2
Bhougland12:08:59

I would love to have a good Clojure alternative to the Realm -> https://www.mongodb.com/cloud/atlas front end to backend sync but using xtdb. I like the way Objectbox and realm are local first with sync and not the other way around. With ClojureDart making app development "easier" we don't have a good persistent local db that can be used across ios, android, desktop, and web that can sync with a Atlas/Firebase type service. I would like the service to be something just like Biff, where it isn't a complete black box. I don't mind paying for the service (heck I might just pay for the Atlas service, but I feel it is going to lock me in...).

Jacob O'Bryant21:08:00

I likely won't be working on any local-first stuff myself for the foreseeable future since for the sake of development simplicity I like focusing on thin-client architectures. I think a lot of people in the clj community are interested in this type of stuff though!

ianjones20:08:30

if I want to query records in a date range, whats the best way to do this?

ianjones20:08:06

it seems I have to pass a java.util.Date but Im seeing around the internet that java.time.LocalDate is preferred now

ianjones20:08:13

(let [{:keys [biff/db]} (get-context)]
    (biff/q db '{:find  (pull r [*])
                 :in [[start end]]
                 :where [[r :result/date d]
                         [(>= d start)]
                         [(<= d end)]]}
            [#inst "2023-08-31T00:00:00.000-00:00" #inst "2023-09-02T00:00:00.000-00:00"]))

ianjones20:08:39

this works however, passing a java.time.Instant doesnt work

Jacob O'Bryant23:08:25

I'm guessing it just depends on what the value of :result/date is--e.g. if I set :result/date to a java.time.Instant, I'm able to query using other Instant s as parameters:

(let [t (java.time.Instant/now)]
    (with-open [node (test-node [{:xt/id :foo
                                  :result/date t}])]
      (biff/q (xt/db node)
              '{:find (pull r [*])
                :in [start end]
                :where [[r :result/date t]
                        [(< start t)]
                        [(< t end)]]}
              (.plusSeconds t -1)
              (.plusSeconds t 1))))
(https://github.com/jacobobryant/biff/blob/master/test/com/biffweb/impl/xtdb_test.clj#L31 is a helper fn that starts an in-memory node and inserts the given documents)

Jacob O'Bryant23:08:27

java.util.Date vs java.time.Instant is one of those things I need to familiarize myself more with--I think it's not necessarily a huge deal in clojureland because if I understand correctly the main problem with java.util.Date is that it's mutable, and we generally don't mutate dates anyway 🤷 But I suppose it's still probably worth going with java.time.Instant since that's where the ecosystem is going... I mainly like java.util.Date because it has the built-in #inst reader macro ha ha

ianjones15:08:02

they both pass the inst? test but it seems like xtdb doesnt want to compare them with their operators

ianjones15:08:23

I also like java.util.Date for the reader macro

ianjones15:08:24

just created this utility function to help with the conversion… easy enough

(defmulti ->instant
  (fn [x] (type x)))

(defmethod ->instant java.time.LocalDate
  [local-date]
  (.toInstant (.atStartOfDay local-date (jt/zone-id))))

(defmethod ->instant java.time.ZonedDateTime
  [zdt]
  (.toInstant zdt))

(defmethod ->instant java.time.Instant
  [instant]
  instant)

(defn ->date
  [d]
  (jt/java-date (->instant d)))

👍 2