Coder Social home page Coder Social logo

fulcrologic / fulcro Goto Github PK

View Code? Open in Web Editor NEW
1.5K 1.5K 137.0 17.88 MB

A library for development of single-page full-stack web applications in clj/cljs

Home Page: http://fulcro.fulcrologic.com

License: MIT License

Makefile 0.02% Clojure 99.32% HTML 0.13% CSS 0.50% JavaScript 0.03%
clojurescript data-driven full-stack react reactjs web-application-development

fulcro's People

Contributors

abhi18av avatar anmonteiro avatar awkay avatar barisa avatar claudiu-apetrei avatar currentoor avatar dvingo avatar egracer avatar felipethome avatar fjolne avatar gardnervickers avatar grzm avatar holyjak avatar j1mr10rd4n avatar jdslavin avatar jj-atkinson avatar kenbier avatar livtanong avatar mahinshaw avatar markusalbertgraf avatar mitchelkuijpers avatar mrebbinghaus avatar pancia avatar souenzzo avatar swannodette avatar thheller avatar thosmos avatar timovanderkamp avatar wilkerlucio avatar yenda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fulcro's Issues

Fulcro server modular docs

When combining libraries I seemed to have lost the server docs. I need to make sure those are integrated, and proofread them and improve them. Should also make sure the template shows how to do it...@Pancia, where is that code for template...all I see is some untangled-server stuff. Have you pushed it?

Make a demo of defrouter for heterogeneous editor

List of different kinds of things on the left that all share some same basic props (like label and type) so they can be rendered by one kind of UI thing, but detail screen on right uses router to show the right kind of edit screen.

Dynamic routing code loses query changes in state

The dynamic routing code, as written, needed to set a component query. This involves Om Next updating the application state with the new query. Unfortunately, the new update-routing-links for composition puts you inside of a swap that has already saved the state of the world for funcitonal update, so we're causing a nested swap that will be un-done after the code has completed. Thus, the queries that are supposed to be stored in app state never get stored there, which will lead to UI issues on refresh.

":onChange is not a function"

In forms.cljc:

`(log/warn ":onChange is not a function")`

Slight problem that this message is emitted when onChange is not supplied. We should only emit the message if it is not nil. Something like this:

`(and onChange (log/warn ":onChange is not a function"))`

Refine forms

Normalize form state
write bigger examples with custom commits

Make logging able to be app specific

Things like fulcro-inspector cause log message to intermingle with app logging. It would be useful to be able to target logging by app so that the logs could be better controlled. Need to investigate possibilities.

FEATURE: Improve general error handling paths

After some discussion in #28 it became apparent that there are a couple of tweaks that would allow us to handle general errors in much more useful and advanced ways. See the comment stream in that issue for background, and add comments here to extend that conversation.

2.0: follow-on reads might be broken

In the quick tour the grand total sum is supposed to update immediately due to a follow-on read, but it lags until the network request returns, indicating that it got queued with the network refresh instead of the optimistic update.

Create new history system

  • Add history storage, configurable with number of steps
  • Support transactions that are compressible (e.g. more than one in a row cause only the last to appear)
  • Include metadata about the transition edge (mutation, or server return).
  • DEFERRED Allow history tagging (e.g. checkpoint for return)
  • Add first-class public functions for manipulating and viewing history
  • Fix up support viewer to support it all

2.0: Consider supporting `returning` on queries without an ident

Merging into the root node of the graph is possible, so perhaps we should allow queries that have no top-level ident to be the target of m/returning.

Pros: you could define an arbitrary query that could update multiple things in the root, which are easy to query via link queries.
Cons: You can easily pollute/overwrite things in the root node, where accidental collisions are too easy

Push fulcro-app as PR to devcards

I need to finish making the devcards stuff work with state maintenance, and push it as a PR to devcards, so we can remove the hard dependency on devcards.

Feature: Polish forms support

  • Add complex example to template
  • Improve file upload
    • Add/Fix CSS on file upload for devguide or demos or template
    • Add submit processing to example
  • Add docs to cover custom form submission

Fulcro 2.0: Drop ILocalState

Verify that this is an unused feature...pretty sure it is. Love to hear from people on their thoughts about it. I'm leaning towards deleting it from the system altogether. I just don't see it fitting in the picture very well.

Feature 2.0: add `ptransact!`

So, I've advocate that people use load to take advantage of post-mutations in order to do blocking UI on full-stack mutations. This is wasteful in that it requires at least a server ping in order to see the result...it is needlessly chatty.

My hesitation to add something akin to a callback is that it throws async into the UI, and Om Next went to great lengths to get it out of there.

I've already let post-mutations in, which are a break with the model, though they are limited to data transforms. This prevents chains of callbacks, but sorta has the flavor of a callback.

I've been trying to figure out how to modify mutations so that one can actually do something on the successful completion of a remote mutation operation.

Fallbacks are fine for errors (though I don't believe they are practical).

In fact, I don't really think callbacks on mutations are really as practical either; however, some people would like to code blocking full-stack operations, and the only clear way to do that is to provide some mechanism where we have a sequential operation list that is full-stack aware:

Do f, wait for a result, then do g.

For loads, this is post-mutation. A callback-feeling thing that I only accept because it is aimed at data manipulation of the loaded result. The only reason it is a mutation is I don't want to store functions in app state. This seems a perfect exception, even though it looks a bit callback-y

In mutations, we've not had a way of saying anything about sequence of full-stack interaction, even though there are queues that we can leverage to enforce it.

So, I'm exploring ways in which we can add this, as it would be useful.

FormatJS Custom Formats

In the Fulcro devcards it's mentioned how FormatJS is extensible; however, I don't see any way to pass a formats object to MessageFormat. As I understand it, the MessageFormat constructor can take the formats object as the third parameter, but fulcro.i18n/trf is hardcoded to only pass two. Could we get an option in new-fulcro-client or an atom in fulcro.i18n where we can set custom formats?

Forms: No way to ask for refresh in on-form-change

The mutation supported from on-form-change can modify anything in app state, but it cannot specify the data that has changed so that components outside of the form can refresh. This might be fixed in 2.0 with mutations that mark their reads, but for 1.0 it needs a parameter

Advanced optimization problem

Something is causing Om's statics to not get properly marked during adv optimization. This issue is to track hints as I discover things.

Any interest to try shadow-cljs as the build tool

shadow-cljs is another tool for developing and bundling ClojureScript. There are several features related to the GettingStarted document:

  • compile the code
  • hot code swapping
  • serving HTML and assets files
  • REPL to connect to the running environment

To define a compilation like https://github.com/fulcrologic/fulcro/blob/develop/GettingStarted.adoc#11-project-file , it's uses a file called shadow-cljs.edn:

{:source-paths #{"src/main" "src/dev"}
 :dependencies [[org.clojure/clojure "1.9.0-alpha17"]
                 [org.clojure/clojurescript "1.9.908"]
                 [org.omcljs/om "1.0.0-beta1"]
                 [fulcrologic/fulcro "1.0.0-beta10"]]
 :builds {:dev {:target :browser
                :output-to "resources/app/js/app.js"
                :output-dir "resources/app/js/app"
                :main cljs.user
                :asset-path "js/app"
                :devtools {:after-load cljs.user/refresh
                           :preloads [devtools.preloads]}}}}

Fields look similar to the one in Lein. But it's shorter to write since it's designed for compiling ClojureScript only. Many of the dependencies have already been built into shadow-cljs.

To start running shadow-cljs, you will need Node.js :

yarn add --dev shadow-cljs
yarn shadow-cljs watch dev # watch for development, dev for :build-id

It's started with a command line, so no need to add another script. As the watch server started, you get hot code swapping from :devtools configs.

If you need a REPL for connected environment, try:

yarn shadow-cljs cljs-repl dev

After you got an HTML, to serve the files, it's built in shadow-cljs. Just add configs in :devtools configs:

:http-root "public"
:http-port 8020

and you will get an HTTP server serving public/ at http://localhost:8020.

I guess shadow-cljs can be faster, since it's designed for ClojureScript specifically. But it may be used together with lein too.

Besides, shadow-cljs brings some improvements to cljs development too, like CommonJS support, more work on externs, filename hashing, dynamic loading, etc. It brought me a lot of useful features. I hope it may help in your scenarios too.

Eliminate the need for ^:once on defui for hot code reload

The ^:once notation on defui is necessary for hot code reload to work properly. I could make it the default, but that would technically change the behavior of it (and the ui macro). I personally have not used either in a way where I would need the reevaluation to happen.

Several users have indicated a desire for it to be the default, but I'm always leery of changing something like this in a global way without considering other possible courses. One would be that we could use a JVM property instead, so it would be the default, say, if the -Dhot-reload property was set on the JVM. That would eliminate the need for it in code, but would possibly confuse users where it didn't work because they forgot the JVM option.

So, while I see a way around changing the default (use a JVM option), and this would also maintain 100% source compatibility, I am tempted to just make the ^:once behavior the default.

Thoughts anyone?

Fulcro 2.0: Make dynamic queries arbitrarily composable with static queries

Not sure if this works or not, but it is definitely critical that nesting dynamic queries inside of static query components should work, and vice-versa. Composition breaks otherwise.

I think the requirement might be: If you use dynamic queries, you have to compose them to the root...but I think it is possible to use static queries within the tree as static branches.

If I can figure out a way for them to compose seamlessly in either direction, that would be ideal.

Feature: autocomplete widget

After talking to Mitchel, he recommended a good pre-written controllable lib component. I think it is a better idea for me to show how to integrate that into the template instead, since re-use from a library is a primary concern, and I don't need to fiddle around writing something that already has a good solution.

Fulcro 2.0: Update documentation

  • Developer's Guide
  • Reference Guide
  • Websites
  • Readmes
  • Demos
  • Docstrings
  • New load marker implementation
  • New declarative refresh
  • New mutation joins

Enhancement: Debugging Tools

I've been wanting to build something for a long time that would give you a debug overlay in develop mode. It really would not be that hard to make. Basically a Fulcro app that is pre-packaged in the Fulcro resources that you can embed in your development HTML and link to your running app. All sorts of cool stuff possible. Table browser, state watches, etc.

Compiler Hacks break Advanced Optimization if you refresh namespaces (relatively easy fix identified)

The workaround is to make sure tools-namespace is around when you're doing advanced compilation.

The fix is to figure out how to keep Closure from removing the static methods on the generated React classes.

Some possibilities:

  1. Figure out an alternate way of implementing static...perhaps it should just be metadata in cljs and clj, but that means some internal API changes that could break existing programs (anything that has been trying to call those statically against the classes)
  2. Figure out why it breaks with respect to Closure and submit a patch there?

FEATURE: Improve error support for dynamic code in dynamic routing

Add some kind of hook for cases where we know things are possibly not recoverable: E.g. a network error caused dynamic routing code loading to fail. Basically allow the program to transact, or js/alert, or something that let's the user know things are hosed, and what can be done.

Fulcro 2.0: Support auto-error handling for recoverable network errors

The new history system will enable a cool kind of error handling that will simplify apps. It will be opt-in, since there are server requirements you must agree that you meet:

  • Add code to network layer for auto-retry
  • Add a way for the application to see the back-log depth
  • Add code to traverse history and affect retries

Feature: Support mutation joins

Currently mutations can return a value, but that value is ignored. The latest query syntax supports a mutation join like this:

[ { (do-something)  (get-query Thing) } ]

which is a mutation joined to a subquery. This enables (syntactically) the possibility of having the client known how to merge the return value of the mutation.

The assumption for this is that the returned data from the mutation looks like props for the given Thing (which must have an ident). The query itself will be annotated with metadata so that the ident can be generated from the combination of Thing and the returned mutation value, meaning that we can merge/normalize the result.

I've talked a bit to @wilkerlucio about how to support this syntactically, and there are some things to think carefully about before we implement it:

  1. If you use the mutation join syntax at the UI-level, should the return value of the optimistic update be merged? I vote no. In fact, I'd prefer we not expose this at the UI layer at all.
  2. If you don't use the join syntax at the UI level: How should we support this in the mutation remotes? The AST route is a little messy, and I'm leaning towards making the AST something you rarely directly mess with on the client.

Some ideas:

(defmutation do-thing [params]
   (remote [env]
      (returning env Thing)))

and perhaps one or two other helpers against env, like:

(with-params env params) - alter the outgoing remote mutation to use the given params
(returning env Component) - alter the outgoing remote mutation to accept the given kind of component's data as a return value

and let them thread:

(-> env (with-params {:x 1}) (returning Thing))

Some other ideas that deserve consideration:

  • We could technically join to anything. Does it make sense to limit the join query to a component? Might a mutation want to return something to the root of your app state?

My current proposal is:

  • You may (but discouraged) use the mutation join on the UI or behind the scenes (it's just AST manipulation)
  • Add sugar helpers to augment remote (with-params/returning)
  • Subquery on mutation join must come from a component with Ident

Feature: complete server-side rendering

  • Initial state tools for the server to populate the client
  • Make merge-alternate-unions support doing so on the server
  • Add SSR to template to show how to do it for both global and logged-in pages
  • Write documentation/comments

Support declarative follow-on read notation in defmutation

Fulcro 2.0 is no longer tied to the internals of Om Next, and can now add support for mutations that can list what keys they are changing so that follow-on reads will largely be a thing of the past at the UI layer. They will still be allowed, but will no longer technically be required.

As far as I can tell this was an optimization based on the idea that a mutation might be changing things that the UI currently doesn't care about, and that triggering reads for extra stuff caused extra overhead.

The thing is: there are indexes, you don't change that many things, and if they changed, you want to queue the follow-on reads for correctness. If the index lookup comes up empty it really didn't cost you that much.

I think we can do this with some special key on the mutation return. Om Next allowed an unused (for documentation only) key called :keys on a mutation to advertise what it changes, but I've never really seen anyone use it because it was kind of obscure, poorly documented, and didn't actually do anything.

(defmutation do-thing [{:keys [id] :as params}]
   (action [env] ...)
   (refresh [env] [:person/name [:person/by-id id]]))

Change loading marker implementation

The current implementation causes a number of problems with Fulcro. The real design should be this:

Put the load markers in a table, with the marker name as the key. Then the query becomes [:prop-of-parent [:fulcro/load-markers :my-marker] :other-props], and the destructuring can just be (let [{:keys [my-marker]} (om/props)] ...)

Now we can do a defui for the LoadMarker, supply a query (and ident) function…perhaps even use a multi-method in render with a default. Now you have an easy way to customize the rendering of the marker. The query becomes [:prop-of-parent {[:fulcro/load-markers :my-marker] (om/get-query fulcro/LoadMarker)} :other-props] and you get a factory like ui-load-marker

FEATURE: post and fallback mutations should have a more complete env

The post mutation and fallback environment is insufficient for some tasks, and should include:

  • :ref of original component that triggered load (if available)
  • :reconciler
  • :load-request that contains all of the significant portions of the original load request (e.g. server-query (as focused/composed to send to the server, with params), keyword-or-ident, component-query, post-mutation, post-mutation-params)
  • POSSIBLY: :triggering-component and :query-component. These could be passed via metadata internally. I'm on the fence about this, because the temptation for abuse that can cause issues is high.

Devguide problems

  • Server topics and exercises got corrupted and generally broken.
  • Need to check sections J and above, proofread, and fix
  • Finish checking that all networking interactions work

i18n Polishing

The old lein plugin for extracting strings and generating modules for translations is out of date.

  • Fix i18n namespace to work well for client and server
  • Add the extract/gen functionality to fulcro itself as functions
    • Fix generated source to not explicitly use module manager
    • Fix generated translations to have "msgid" as "msgkey" and issue warnings if missing xlation
    • Fix bug: when msgid contains escaped ", it omits it
    • Emit CLJC!
  • Add scripts that run the functionality to template script/
  • Add documentation
  • Make sure SSR can work with translations

Feature: Add Dynamic Router

The new code splitting support makes it relatively easy to make a dynamic routing system that can be hooked into the existing router infrastructure to facilitate breaking apart large applications. I've written a demo for how to basically structure the router for this dynamic addition, but it needs to be codified into the library itself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.