Fork me on GitHub

@roklenarcic Thanks. I’m kinda picky about getting started with what you actually need to get started 🙂


don’t mind bare-bones code, but it is just going to be a ton of work if you don’t have all of the builds and such ready to go. I appreciate testing as well, so CI out-of-the-box seems a requirement.


anyhow, it’s easy to delete stuff 🙂


@roklenarcic I am using hugsql for mysql on the backend. Really happy with it so far :)


@mitchelkuijpers so, as I’m playing with dynamic code loading, ModuleManager seems to be auto-retrying internally already. If I shut down my server and hit a dynamic route, it’ll keep retrying. Not sure for how long. I wrote code for retries…but not sure it is necessary.


oh, it does seem to give up after about 30 seconds.


Release: fulcro-1.0.0-beta10 See changelog for details.


I noticed all the talk about optimistic updates etc. Thought I might mention that in the good old days there was what Oracle called 'row level locking'. This was integrated with Oracle Forms. Here the server would inform the client when someone else had updated your row and tell you you needed to re-query. There also would have been a variation where the server tells the client that someone else has queried your row with the intention of updating it. Also you could think that when query a row for update you could be warned from the beginning that you were in a race (because someone else had also queried for update)!


The great advantage of this 'server informing the client' is that the programmer never needed to think about optimistic/pessimistic. In fact I was never aware of those terms at the time - that had to wait till the RAD revolution and Powerbuilder came along.


So, I’ve written a prototype using websockets so that the client could subscribe to queries (graph) for Datomic. It is relatively simple to make what you’re talking about, but instead of locking, it is just server pushes when something changes. In general, though, conflicts on write are usually fixable with minimal deltas (only send what you changed) and last-write-wins. That is, for things that are pure write (not based on old values). Other kinds of “write” should be abstract mutations. E.g. if I’m adding something to a field (write after read) then I should send a mutation saying (add 10), not (set-to 30). The former can be applied in any order, the latter cannot.


of course, then my comment about follow on reads applies (you should read anything that you care about the final server value of)


You can use polling rather than websockets maybe?


why bother? websockets is trivial, no?


or you mean to avoid subscriptions to queries


Yes, as long as not too much data ever.


I think you can do it without needing either, really. The implementation just has to take a few things into account.


as I described above


distributed systems also put a damper on schemes like Oracle’s…you often don’t know when your clients go away.


(unless, again, websockets or busy polling)


The thing that I liked is that the framework handled it all. It even handled the UI part for you. I'm not even sure if this was override-able.


It really was RAD!


how was it for users? Did you have “Sally leaving a screen up and going to lunch” problems?


Probably. Users were always in a transaction and they knew this. They had a commit button. There was like a mantra among users that they had to commit frequently. Perhaps there was a timeout for a user being in a transaction, for Sally going off to lunch.


"Do you want to stay in this transaction, you will be kicked out you've been in too long with no activity", would have been possible.


yeah, and long-running transactions are not really handled well in SQL databases mostly


Oracle may be an exception if you spend enough $$$$


Oracle Forms was what every corporate used at the time. Was such a productive environment. Gone now 😞


@U0D5RN0S1 Just also mentions oracle forms when talking about om-next 🙂


Thanks Claudiu. I must have missed that part on the first quick read a year and a half ago now. I don't really associate JUXT with Om Next these days.


Of course less users as this was pre-Internet. But in theory it could scale. Not sure. Just wanted to mention it.


@tony.kay how do you feel about this? And possibly having it in fulcro? I included it in my defui wrapper macro. Rum also uses it.


i've been blundering around trying to get one of the hiccup templaters working in fulcro, but haven't yet succeeded


working with server-side rendering in fulcro, that is


I have a scary issue with dynamic routes. I get warnings like this:

console.js:203  [  2.065s] [goog.module.ModuleLoader] Loaded incomplete code for module(s): contacts_overview
console.js:203  [  2.074s] [goog.module.ModuleLoader] Request failed for module(s): contacts_overview


But when I start loading the other dynamic module after a 500ms delay it works.. But I am thinking that maybe I should pre-load the module because this is only a problem on initial load


I'm using sablono with fulcro


@roklenarcic do you have ssr ?


@currentoor Not interested. It is usable as-is if you want it. I don’t want to add dependencies that others may not want. I personally like the function calls.


If you’re dying to have a macro that leverages it, copy the source of defsc or defui and munge it. 🙂


or write a macro on top of them…that would be simpler, I think


@mitchelkuijpers almost certainly a misunderstanding of Closure. The cljs stuff is a very thin wrapper over Closure’s module system.


@currentoor I’m constantly struggling with the balance. Too many deps and you become cumbersome. It’s a good idea to use lightly coupled libraries, and that’s why the Clojure community tends to prefer that. I want Fulcro to be easy to get started with, but I don’t want it to get Spring + Hibernate heavy….or even close


One of my goals is to further prune the dependencies. For example, set up dynamic loading of things like Ring iff you use Ring. If you use the module system and plug it into a Servlet, you shouldn’t need the ring deps.


I probably won’t be able to prune out ring request/response, but I can prune out things like ring-gzip, etc. Document that you have to add them if you use easy-server. That kind of thing.


I think we can actually become quite lightweight. There is already a (mis)perception that Fulcro is heavy. Most of the code is front-end, and Closure will prune that to what you use. So I’m hoping to be able to sell it to the community at large as a lightweight library rich in functionality.


I also need to re-evaluate the deps in fulcro itself. Some of the ones that are there are dev-time only, but are not listed that way (e.g. are only used in a demo)


i understand, and i agree that approach would probably make fulcro better in the simple vs easy sense


but IMO some ease of use (not necessarily soblano) is needed for adoption


well, the whole library is a response to ease of use of Om Next


just a thought, maybe another approach could be a way to opt out of dependencies rather than having to opt in?


In some sense, a lot of the “easy” needs to be provided by a larger demo app (or more demos) that models more complex scenarios for people to follow.


Personally, I find the stuff that is already there to make things easier than anything I’ve ever used for a similar level of features/interactivity. Definitely areas where improvements is possible. Forms could use more work.


the error handling story needs a touch more API (and a big demo)


There is no helping server-side rendering of js components from external libraries that I can think of…so more companion libraries in cljc would be nice.


A sablono recipe could be a nice addition. Seems similar to hiccup & reagent, and could smooth the transition for people that are familiar with it & like it, are thinking of switching to fulcro.


Last time I tried had some issues with ssr, not exactly sure how the performance is compared to om/dom (the #js part), and if there are any hidden downsides.


again, exercise for the reader. Glad to have a contribution to demos if anyone wants to make one


The SSR for js might be fixable. It sounds like there has been some work to get React (render to string) working in Nashorn.


React rendered with noshorn sounds awesome. Doing my own "material like" inputs now to have ssr working, dropping in something like react-toolbox and have it work on the java backend would be really awesome :)


I think leveraging these comments/results might make it work.


Definitely worth exploring


The key is that currently Om Next ssr relies on hand-written to-string code for Om Next DOM. It does not run in JS at all. It is a clj implmentation of react’s render-to-string. If you can get the js to just run (without a DOM) to generate the string, then everything would “just work”. All the server would have to do is generate the initial app state.


Hm... after generating fulcro project from lein template, I'm running into a bit of a snafu. The client is served by figwheel on port 3449, but the server runs on port 3000. And the client side makes requests to localhost:3449, which isn't where the server is


And I've found a possible mistake in the template: server_main.clj passes a string to build-server fn, but the fn expect a map {:config .... }


@claudiu i had been trying and failing at SSR with sablono 0.8.0, but it looks like 0.8.1-SNAPSHOT might have taken care of my issue. which makes sense, given that it includes an extremely relevant PR 🙂


Cool 🙂 Will give it a try and rewrite some components and see how they compare.