I am not familiar with this topic even not under the context of cljs. I am writing a react-native app with clojurescript. I wonder how to support sync data between the server so that when the mobile goes offline and later online again it will sync data (either upload to the server or retrieve data from the server as another device might have updated it).
This is a very broad topic which I’ve been interested in for a long time. It’s a rabbit hole 🙂 . There’s also CRDTs which are a formal way to do this but the automatic, formally correct resolution of CRDT conflicts does not always match what the average person would expect to be the “correct” or “expected” end state. TLDR, conflict resolution is application-specific, in most cases. There’s no “one size fits all”.
If you want to dig deep on this topic, everything by https://martin.kleppmann.com is really good. Warning: you might spend a lot of time exploring this 🙂
Thanks for the tip, I'll dive in. I've looked into this topic many years ago and kept my ears open from then on but the solution/answers (summed up above) I came across never satisfied me. I hope that will change
If you want to know more about this search for the term "offline first"
But the big spoiler is that in the end you just have to pick a strategy on how to deal with merge conflicts.
There are 3 options when it comes to dealing with merge conflicts when syncing the 2 databases. Server is always right over the client, client is always right over the server or give the user some way to pick one of the 2 options
So I’m using cljs-node-io
, it’s supposed to make <http://java.io|java.io>
-like abstractions node.js file operations.
I’m getting the same warnings while shadow compiles. This is one of 4 of the same warnings.
The warning all happen when I use dot-methods from the library.
For my intents and purposes this is no problem, just a bit noisy.
------ WARNING #1 - :infer-warning ---------------------------------------------
File: /Users/main/Code/clojure/uniorg-util/src/uniorg_util/core.cljs:94:17
--------------------------------------------------------------------------------
91 | (let [d (io/file path)]
92 | (for [f (.listFiles d)]
93 | (when (.isFile f)
94 | (.getName f))))))
-----------------------^--------------------------------------------------------
Cannot infer target type in expression (. f getName)
--------------------------------------------------------------------------------
95 |
96 | (defn create-files [in-path out-path json?]
97 | (create-out-dir out-path)
98 | (let [input (filter #(-> % io/file .getExt (= ".org"))
--------------------------------------------------------------------------------
I decided to use cljs-node-io.fs
instead of the methods of the type File
.
No more warnings.
Edit: looks a lot cleaner as well
For future reference: https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html
tl;dr: add ^js
in front of the definition of f
. Just in case - make sure that it still works under advanced compilation with that addition.
Got it.
and also don't use a wrapper that tries to make it look like java. use the node methods directly. IMHO 😛
how do I get the namespace where a macro is called (instead of where the macro is defined)? We have *ns*
in clj but not in cljs
you have *ns*
in CLJS macros (given that they are written in CLJ)
but that's the ns of where the macro is defined? I am asking about where it's called
let me give an example
it is where the macro is called, not defined. *ns*
is a runtime binding, which is bound to the current ns when expanding macros in the CLJS compiler. same as CLJ really.
thanks, let me try again
(ns <http://foo.app|foo.app>
(:require [foo.macro-lib :as lib]))
(lib/mymacro foo)
=> how to implement mymacro so that the above expands to `<http://foo.app/foo|foo.app/foo>`?
(defmacro mymacro [the-sym]
(symbol (str *ns*) (name the-sym)))
I've tested, *ns*
always return nil
at run time.
at CLJS runtime yes, and macro-expansion time no (so CLJ compile time, there it is bound).
it works, thanks a lot
I think I’ll still use it for slurp
and spit
lol
FWIW (:require ["fs" :as fs])
and (fs/readFileSync path)
or (fs/writeFileSync path content)
would be slurp/spit equiv
I see! I’ll have to remember that for the next thing I build.
Has anybody used https://github.com/clojure/tools.cli/ for their projects? I’m considering using it for my node script here, I just need a little help with configuring some of the options. Maybe I could take a look at your project? https://github.com/wildwestrom/uniorg-util
Ok, I’m using it and I’m a bit confused as to why my tests are failing.
args
will be a seq of strings, so not one string but many. so ["-e" "-m"]
instead of "-e -m"
don't know why you are checking true?
. that doesn't seem to be the expected result?
I wanted this option to return true
or false
that’s why I check it that way.
But that makes sense, no wonder it won’t work.
shadow-cljs uses it https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/cljs/devtools/cli_opts.cljc#L57