Liking cljdoc? Tell your friends :D

Fulcro Rapid Application Development Tools

This library is currently in an experimental phase. It should not be used in any kind of production system unless you feel ok about forking it and maintaining the fork. Once the ideas have stabilized then I may do an official release with stable documentation and APIs.

See the YouTube Video for a demonstration of a working prototype.

HELP WANTED: This project is more ambitious than my time will allow. If you have Clojure chops and are interested in helping, please let me know.

Goals

Here are the goals:

  • Build applications quickly, without serious compromises:

    • Minimal Boilerplate

    • Easily (and gradually) escape to custom code when your needs outgrow the system’s abilities.

The facets that this library are intended to address:

  • OPEN model (via namespaced keywords and maps)

    • All declarative constructs use open maps in CLJC so that library extensions can easily add capabilities.

  • Declarative data model to facilitate:

    • Generated database schema (if desired) with migration management.

      • Database adapter makes it possible to use any database.

    • Generated demand-driven server APIs

    • Declarative (extensible) permissions model.

  • Authentication

    • Extensible system for obtaining and managing client authentication.

    • Demand-driven authentication (login pops if a screen needs to work with data that requires auth)

  • Forms

    • Declarative and extensible in all aspects: validation, rendering, permissions, etc.

    • Support for graph-based forms (nested forms with relations)

    • Automatic logic for complete data management Create/Update/Delete.

    • Integration with permissions (authorization)

    • Ability to generate UI with ability to incrementally override.

    • Pluggable UI generation system: Support web, native, etc., from a single declaration.

  • Reports

    • Input parameters

    • Pretty much everything from "Forms", but for read-only display.

    • Completely generated output, with ability to incrementally override.

Ideas

  • A state machine to manage auth context. For example, you have auth in a google domain, a facebook domain, and your company’s domain. Perhaps SSO gives you that, or perhaps you have to auth against each in some way. The idea is that the system can send events to the auth state machine to verify (before running a full-stack query or making a mutation button visible) that there is sufficient context for the request to succeed. The query and mutation can both imply what is being manipulated (the graph query could cross all three for example). So, the UI routing and visibility could be tied to sending an event to the auth context machine with a request to send back an event to the calling context when the auth is complete. The auth systems then run in parallel with the application logic.

  • A given cluster of UI, using the co-located query, establishes a top-level context (e.g. :account/id), and subqueries are joined via the graph query itself. Pathom is used to traverse this for data needs, but it is also traversed to derive the auth needs.

  • A cluster of UI also establishes path-based contexts (e.g. [account-id, mailbox, message-id]) where a component rendering the message is able to know the mailbox and account (accumulate identities along a UI path). This means the composition of components can be used to easily establish what is reachable from a given location in the UI. For example: say you’re in an email with a message ID, and you know that a message ID has a sender email, and you know there is a resolver that can take an email address and turn that that into a starting context for youtube videos posted by that person. This is already a feature of Pathom, but it could be used at development time to do things like error checking, code completion, etc., and at runtime to do things like mentioned in the prior point (resolve auth necessary to do something like use the GitHub API).

The dynamic routing support allows us to make it possible to assemble most of a CRUD app with HTML5 routing, dynamic code loading (splitting), and arbitrary linkage of navigation with very little code. Customizing the "chrome" of autogenerated things could also be declarative/pluggable, so that UI could even be emitted (and customized) for web + native from the same declarations.

Development

These steps are not authoritative across time. This project is in dynamic flux.

Basically you will generally need to do something along the lines of:

npm install
shadow-cljs server  # follow instructions to get to URL of browser-based control panel to start builds

# in another terminal
clj -A:dev          # to get a REPL for running server stuff

See the current example source middleware for additional instructions. The development.clj ns will typically have startup helpers, and the config generally has the app at http://localhost:3000 after a server is started.

Setup

For any contributors wanting to run this, please see: Datomic SQL database to provision a postgres database for Datomic. If you don’t want to use postgres, you can pass a custom Datomic url atop the Makefile. Then follow these steps:

  • Install datomic

  • Supply the necessary variables at the top of the Makefile

  • Set the matching datomic peer dependency in deps.edn

  • Install foreman

gem install foreman

Startup

  • Start up all the necessary proceses:

foreman start Procfile.dev
  • Connect to the nrepl server using your repl client, Emacs Cider is supported.

  • From the repl, load in the dev code.

This is done so that any compilation exceptions are thrown at runtime, instead of startup time which would make the repl crash.

If some code won’t compile, you can fix the issue and just try running (dev) again.

user=> (dev)
  • If all code is loaded, run (go).

development=> (go)
  • The system is started, visit localhost:3000/index.html

  • If you make any changes to the clj side or in the configs, refresh the namesaces and reset the system:

development=> (reset)
  • Some dir-locals are configured for emacs. The system will also reset when running M-x cider-ns-refresh

Can you improve this documentation? These fine people already did:
Yann Vanhalewyn & Tony Kay
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close