Fork me on GitHub
#fulcro
<
2019-05-20
>
roklenarcic13:05:02

I have generated Fulcro project from template and when I run npx shadow-cljs server and navigate to localhost:8023 to see workspaces, I get Not found. Missing index.html.

roklenarcic13:05:17

The app works otherwise at port 3000

wilkerlucio13:05:02

@roklenarcic you need to have an index.html in your resources root, there is a pre-made workspaces build with shadow, and I guess you access that using the server port (the shadow server, not your app) with /workspaces in the end

wilkerlucio13:05:35

this automatic one is cool, but somewhat limiting since its harder to add extra css and other html things you may need

tony.kay14:05:02

@roklenarcic Please see the README that was generated in your project. The index file is generated from the server to include CSRF protection so you can work on full-stack things with security via ws.

roklenarcic15:05:37

I just had the wrong url, had to add /workspaces

tony.kay16:05:46

General Note: Fulcro 3 is officially “in progress”. I’ve been working on it behind the scenes for a few weeks, and I’ve decided I can start putting it up in a new repo. I intend to have a “portability layer” to help porting 2 -> 3 (providing the old namespaces with wrappers that map over to the new). The README in the repo describes that basic status and goals. Fulcro 3 is going to be a significantly better library than 2. I finally got the time to rewrite the internals, which lets me get rid of a lot of the “impedance mismatch” between the old Om Next internals and the way I wanted Fulcro to work. There is very very little code left that predates F2. Some highlights of the progress: • Maintains the “code shape”. Even though the namespaces and implementation are different, the primary things you use (`defsc`, defmutation, etc.) are still there and look pretty much the same; however, both are significantly more capable (and extensible). • Rendering speed improvements: denormalization is roughly 6x faster, and the new rendering is targeted at components. My tests for far indicate that Fulcro will often use less CPU time than React on refresh. I have reasonable hopes that we can get full data-driven stateful components that store normalized state in the Fulro client database, but refresh nearly as fast as components that use component-local state. • Transaction semantics are rewritten which allows submission of new transactions from anywhere (e.g. within mutations (without setTimeout), network layer, etc., etc.). This mostly eliminates the need for things like ptransact! since you can chain safely (if you want). • Transaction “features” like optimistic and pessimistic eval are now more under your control. • Extensible defsc without writing new macros • Extensible defmutation features (no macros required, but writing wrappers could make your extensions look nicer). This one is particularly exciting: you’ll be able to interact with the network result directly at the mutation layer. This allows for much better (and more direct) control of how errors are handled. • Tunable merge logic. The merge (and normalization) layer of Fulcro has been largely static. Additions like pre-merge helped, but the new version will make it possible for you to tune merge logic much more flexibly. • The mutation generalizations make the API for loads extensible as well. The load API has always been a generalization of mutations. Fulcro 3 takes this a step further and allows you to easily design exactly how loads should work. Of course, the 2.x time-tested data fetch API will be available. This version is not really usable yet, but I expect it to reach a “semi-usable” state pretty quickly. https://github.com/fulcrologic/fulcro3

🎉 60
fulcro 56
aw_yeah 28
exit217:05:10

@tony.kay If I already have my data in the state (let’s say several [:person/by-id] entires 1, 2, 3). I have a [:root/person [:person/by-id "1"]] Should I not be able to set root/person to 2 and have the UI change the “selected” person? This only seems to work if I use df/load on click, and I’d rather not do a another server fetch since I have that data loaded in my app-state already. Or is there some other load function that doesn’t perform the network call and looks at the app-state first before doing so?

tony.kay17:05:32

@njj You can change the ident in app state to point to a different thing, of course…that is central to the entire system.

tony.kay17:05:08

But understand that you need to indicate what needs refreshed (e.g. in your mutation, or as a follow-on read) for the UI to know what to refresh.

exit217:05:46

ah was just looking at this section 🙂

phreed20:05:03

@tony.kay Yes, I am using shadow-cljs The critical thing I was missing was the following to be added to the shadow-cljs.edn

:js-options   {:js-provider :shadow
                                      :resolve {"cytoscape" {:target :npm
                                                             :require "cytoscape/dist/cytoscape.esm"}}}
Then the ...
(:require
    ...
    ["cytoscape" :default cytoscape]
   ...]))
...worked as I expected. Without that the incorrect `"cytoscape/dist/cytoscape.cljs.js" was being picked up.

thheller20:05:27

@phreed that is not incorrect that is intentional. commonjs interop with ESM is still sketchy and not all modules interop cleanly. so it is safer to stick with commonjs as the default for now.

thheller20:05:43

You could just require the esm version directly instead of overriding it on the config

thheller20:05:17

it is also possible to override the default and actually use ESM as the default via :js-options {:entry-keys ["module" "jsnext:main" "browser" "main"]}}

thheller20:05:52

which is the order of package.json keys that will be picked to select the main entry, defaults to ["browser" "main"] because of said sketchy CJS<->ESM interop

thheller20:05:15

if that story ever improves and more packages do the right thing the "module" key will become the default

thheller20:05:45

every time I tried changing this in the past it created more problems that it solved so be careful 😉

phreed21:05:36

While reading the documentation and I see that you, @thheller, recommend against using something like (js/ReactDOM.findDOMNode this). What would you recommend instead?

thheller21:05:42

(:require ["react-dom" :as rdom]) then (rdom/findDOMNode this)

phreed21:05:10

@thheller ok, let me give that a try. Right, that is what I tried so the documentation makes sense. I get an error shadow-cljs - failed to load module$react_dom . I suppose there is a dependency I am missing?

thheller21:05:25

why did it fail to load? there should be an actual stacktrace of sorts but the error itself already looks suspicious

phreed21:05:56

Uncaught ReferenceError: ReactDOM is not defined at Object.shadow$provide.module$react_dom (global$module$react_dom.js:2)

thheller21:05:30

do you have :resolve config for react-dom?

phreed21:05:23

:js-options   {:js-provider :shadow
                                      :resolve {"cytoscape" {:target :npm
                                                             :require "cytoscape/dist/cytoscape.esm"}
                                                "react-dom" {:target :global
                                                             :global "ReactDOM"}}}

thheller21:05:31

you don't need that

thheller21:05:12

that is telling the compiler that instead of using the actual npm react-dom package it should use the JS ReactDOM global

thheller21:05:23

which is only ok if you imported it by other means

thheller21:05:36

so just take it out and the compiler will do the right thing

phreed21:05:02

Ok, that works. Ah, I see. I misunderstood the point you were making here...