Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.algorithms.denormalize

The algorithm and support functions for converting a normalized Fulcro database to a tree of denormalized props.

The algorithm and support functions for converting a normalized Fulcro database to a tree of denormalized props.
raw docstring

com.fulcrologic.fulcro.algorithms.do-not-use

Some misc. utility functions. These are primarily meant for internal use, and are subject to relocation and removal in the future.

You have been warned. Changes to this ns (or its complete removal) will not be considered breaking changes to the library, and no mention of said changes will even appear in the changelog.

Some misc. utility functions. These are primarily meant for internal use, and are subject to
relocation and removal in the future.

You have been warned. Changes to this ns (or its complete removal)
will not be considered breaking changes to the library, and no mention of said changes
will even appear in the changelog.
raw docstring

com.fulcrologic.fulcro.algorithms.form-state

Functions that assist with supporting form editing/checking/diffing in Fulcro UI. These functions work by making a pristine copy of your entity, and tracking what fields have been touched. You are responsible for triggering these various states by marking fields as complete (mark-complete!), telling it to copy the data to/from pristine (e.g. entity->pristine), and by asking for out-of-date data for the current vs. pristine copy (dirty-fields).

There is also support for detecting which fields have been marked complete and are dirty.

Validation can be done via Clojure spec (not recommended), or by defining your own field validation functions via make-validator (recommended). This general-purpose validation factory function can easily be used to create more automated validation factories that can be more configuration-driven, but this is left as an exercise for the community.

Specs are not recommended because forms commonly have multi-field dependencies that simply are not well-supported, and sometimes the use of things like Fulcro tempids leads to specs that you'd rather not have on your server. Use of spec really boils down to your intention for those spec (i.e. hard validation of final database value vs. potential runtime look of the data as it is manipulated). Specs that include "state" information will cause you more pain than you want, though you can certainly leverage specs anywhere it makes sense using the validator factory.

IMPORTANT: This namespace is about (possibly recursive) form data management. Rendering and such are not part of the stated intention. See Fulcro RAD for more fully-automated, multi-platform form generation.

See the Developer's Guide for more information.

Functions that assist with supporting form editing/checking/diffing in Fulcro UI.  These functions work
by making a pristine copy of your entity, and tracking what fields have been touched.  You are responsible
for triggering these various states by marking fields as complete (`mark-complete!`), telling it to
copy the data to/from pristine (e.g. `entity->pristine`), and by asking for out-of-date data for the current
vs. pristine copy (`dirty-fields`).

There is also support for detecting which fields have been marked complete and are dirty.

Validation can be done via Clojure spec (not recommended), or by defining your own field validation functions via
`make-validator` (recommended). This general-purpose validation factory function can easily be used to create more
automated validation factories that can be more configuration-driven, but this is left as an exercise for the community.

Specs are not recommended because forms commonly have multi-field dependencies that simply are
not well-supported, and sometimes the use of things like Fulcro tempids leads to specs that you'd
rather not have on your server. Use of spec really boils down to your intention for those
spec (i.e. hard validation of final database value vs. potential runtime look of the data as
it is manipulated). Specs that include "state" information will cause you more pain than
you want, though you can certainly leverage specs anywhere it makes sense using the validator factory.

IMPORTANT: This namespace is about *(possibly recursive) form data management*. Rendering and
such are not part of the stated intention. See Fulcro RAD for more fully-automated,
multi-platform form generation.

See the Developer's Guide for more information.
raw docstring

com.fulcrologic.fulcro.algorithms.indexing

Functions that implement the query and component indexing. Fulcro keeps indexes of on-screen components by ident and class. These enable Fulcro to find on-screen components for things like targeted refresh. You are allowed to use the indexes to find components for whatever purpose suits your needs (e.g. looking at component options).

Functions that implement the query and component indexing. Fulcro keeps indexes of on-screen
components by ident and class. These enable Fulcro to find on-screen components for things
like targeted refresh. You are allowed to use the indexes to find components for whatever
purpose suits your needs (e.g. looking at component options).
raw docstring

com.fulcrologic.fulcro.algorithms.lookup

Fulcro is quite customizable, and all of the pluggable algorithms are stored on the app. This very easily leads to a desire to alias the long com.fulcrologic.fulcro.application namespace to something like app for easy access to keyword aliasing, but in Clojure this leads to circular references. This namespace exists simply to save typing and hassle with respect to that. It includes app-algorithm which can look up a plug-in algorithm on an app using a simple keyword without having to require the application ns.

Fulcro is quite customizable, and all of the pluggable algorithms are stored on the app. This
very easily leads to a desire to alias the long com.fulcrologic.fulcro.application namespace
to something like `app` for easy access to keyword aliasing, but in Clojure this leads
to circular references. This namespace exists simply to save typing and hassle with
respect to that. It includes `app-algorithm` which can look up a plug-in algorithm on
an app using a simple keyword without having to require the application ns.
raw docstring

com.fulcrologic.fulcro.algorithms.normalize

Functions for dealing with normalizing Fulcro databases. In particular tree->db.

Functions for dealing with normalizing Fulcro databases. In particular `tree->db`.
raw docstring

com.fulcrologic.fulcro.algorithms.normalized-state

Functions that can be used against a normalized Fulcro state database. This namespace also includes some handy aliases to useful functions that work on normalized state from other namespaces.

Functions that can be used against a normalized Fulcro state database. This namespace also includes some handy aliases
to useful functions that work on normalized state from other namespaces.
raw docstring

com.fulcrologic.fulcro.algorithms.scheduling

Algorithms for delaying some action by a particular amount of time.

Algorithms for delaying some action by a particular amount of time.
raw docstring

com.fulcrologic.fulcro.algorithms.tempid

Functions for making and consuming Fulcro temporary IDs. Tempids are used when the client is optimistically creating a new entity and you want to be able to detect that on the server when the data is sent. Additionally, Fulcro mutations can return a remapping instruction from the server to rewrite all tempids in the client (state, network queues, etc.) atomically.

This allows the client to safely generate new entities with a temporary ID and let the server remap them to the real IDs at some future time. Transit read/write is included, so that (de)serialization of them can be consistent whenever needed (see the transit ns in this package).

Functions for making and consuming Fulcro temporary IDs. Tempids are used when the client is optimistically
creating a new entity and you want to be able to detect that on the server when the data is sent. Additionally,
Fulcro mutations can return a remapping instruction from the server to rewrite all tempids in the client
(state, network queues, etc.) atomically.

This allows the client to safely generate new entities with a temporary ID and let the server remap them to the real
IDs at some future time.  Transit read/write is included, so that (de)serialization of them can be consistent whenever
needed (see the `transit` ns in this package).
raw docstring

com.fulcrologic.fulcro.algorithms.timbre-support

Logging helpers to make js console logging more readable. The recommended use of these functions is as follows:

  • Make sure you're using Binaryage devtools (on classpath. shadow-cljs will auto-add it when detected).
  • IMPORTANT: Enable custom formatters in console settings for Chrome. This will print cljs data as cljs (instead of raw js).
  • Make a development preload cljs file, and tell shadow-cljs to preload it.
  • In the preload file, add something like this:
(ns app.development-preload
  (:require
    [taoensso.timbre :as log]
    [com.fulcrologic.fulcro.algorithms.timbre-support :refer [console-appender prefix-output-fn]))

(log/set-level! :debug)
(log/merge-config! {:output-fn prefix-output-fn
                    :appenders {:console (console-appender)}})

and you'll get much more readable error messages in the js console.

NOTE: when logging errors, be sure to log the exception first. This is documented in timbre, but easy to miss:

(try
  ...
  (catch :default ex
    (log/error ex ...))

See the development_preload.cljs and shadow-cljs.edn files in the latest Fulcro 3 template for an example.

Logging helpers to make js console logging more readable. The recommended use of these functions is as follows:

- Make sure you're using Binaryage devtools (on classpath. shadow-cljs will auto-add it when detected).
- IMPORTANT: Enable custom formatters in console settings for Chrome. This will print cljs data as cljs (instead of raw js).
- Make a development preload cljs file, and tell shadow-cljs to preload it.
- In the preload file, add something like this:

```
(ns app.development-preload
  (:require
    [taoensso.timbre :as log]
    [com.fulcrologic.fulcro.algorithms.timbre-support :refer [console-appender prefix-output-fn]))

(log/set-level! :debug)
(log/merge-config! {:output-fn prefix-output-fn
                    :appenders {:console (console-appender)}})
```

and you'll get much more readable error messages in the js console.

NOTE: when logging errors, be sure to log the exception first. This is documented in timbre, but easy to miss:

```
(try
  ...
  (catch :default ex
    (log/error ex ...))
```

See the development_preload.cljs and shadow-cljs.edn files in the latest Fulcro 3 template for an example.
raw docstring

com.fulcrologic.fulcro.algorithms.transit

Transit functions for the on-the-wire EDN communication to common remotes. Includes support for Fulcro tempids, and can be extended to support additional application-specific data types.

Transit functions for the on-the-wire EDN communication to common remotes. Includes support for Fulcro tempids,
and can be extended to support additional application-specific data types.
raw docstring

com.fulcrologic.fulcro.algorithms.tx-processing

The transaction processing in Fulcro is (intended to be) pluggable. This namespace is the implementation for the default transaction processing . At the present time there is no documentation on how such an override would be written, nor is it necessarily recommended since many of the desirable and built-in behaviors of Fulcro are codified here.

The transaction processing in Fulcro is (intended to be) pluggable. This namespace is the
implementation for the default transaction processing . At the present time there is no documentation on how
such an override would be written, nor is it necessarily recommended since many of the desirable and built-in
behaviors of Fulcro are codified here. 
raw docstring

com.fulcrologic.fulcro.algorithms.tx-processing-debug

Helper functions for debugging tx processing. Uses pprint, which adds a lot to build size, so it is in a separate ns to keep it out of prod builds.

Helper functions for debugging tx processing.  Uses pprint, which adds
a lot to build size, so it is in a separate ns to keep it out of prod builds.
raw docstring

com.fulcrologic.fulcro.algorithms.tx-processing.synchronous-tx-processing

A transaction processing system that does as much synchronously as possible, and removes various elements of complexity that were inherited from Fulcro 2 in the standard tx processing.

See with-synchronous-transactions for how to install it.

This tx processing system does as much work synchronously as possible, though it does try to preserve the call-order semantics of the standard transaction processing: That is to say that if the optimistic action of a transaction submits a new transaction then that new submission will run after the current already-in-progress transaction has finished processing:

(defmutation g [_]
  (action [{:keys [state]}] (swap! state ...))
  (ok-action [{:keys [app]}] (transact! app [(h)]))
  (remote [_] true))

(defmutation f [_]
  (action [{:keys [state app]}]
    (swap! state ...)
    (transact! app [(g)])))

...
(dom/a {:onClick (fn []
                   (transact! this [(f {:x 1})])
                   (transact! this [(f {:x 2})])
                   (transact! this [(f {:x 3})])))

A user clicking the above link with std processing could see any of the following:

f,f,f,g,g,g,h,h,h
f,f,f,g,h,g,g,h,h
f,f,f,g,g,h,g,h,h
etc.

In sync tx processing, you would more likely see:

f,g,f,g,f,g,h,h,h

because there is no guarantee in Fulcro's semantics about the space between two calls to transact!. If your application relies on the groupings that happen with the standard tx processing (submissions while holding a thread go into the queue first) then your application may break when you switch to sync processing.

Note that transactions are treated as atomically as possible. So, if you want a specific grouping you should submit it as a single tx:

(transact! [(f) (g)])
(transact! [(f) (g)])

is guaranteed to do f,g,f,g, and never f,f,g,g, though it is still possible to see f,g,h,f,g,h.

This sync transaction processing system allows you to push most (if not all) behavior of even nested transactions into a single synchronous operation. This will lead to significant improvements in the snappiness of the UI for optimistic operation and should also reduce over-rendering (multiple calls to render due to multiple async operations).

If your remote is mocked as a synchronous operation, then you can also leverage this tx processor to enable completely synchronous testing of your headless Fulcro application.

WARNING: This tx processing system does not support:

  • ptransact!: Pessimistic transactions are a legacy feature of Fulcro 2 that is no longer necessary. New applications should not use the feature, and this sync tx processing system does not support it. The call will succeed, but will behave as a normal transact!.
A transaction processing system that does as much synchronously as possible, and removes various elements
of complexity that were inherited from Fulcro 2 in the standard tx processing.

See `with-synchronous-transactions` for how to install it.

This tx processing system does as much work synchronously as possible, though it does try to preserve the
call-order *semantics* of the standard transaction processing: That is to say that if the optimistic action
of a transaction submits a new transaction then that new submission will run *after* the current already-in-progress
transaction has finished processing:

```
(defmutation g [_]
  (action [{:keys [state]}] (swap! state ...))
  (ok-action [{:keys [app]}] (transact! app [(h)]))
  (remote [_] true))

(defmutation f [_]
  (action [{:keys [state app]}]
    (swap! state ...)
    (transact! app [(g)])))

...
(dom/a {:onClick (fn []
                   (transact! this [(f {:x 1})])
                   (transact! this [(f {:x 2})])
                   (transact! this [(f {:x 3})])))
```

A user clicking the above link with std processing could see any of the following:

```
f,f,f,g,g,g,h,h,h
f,f,f,g,h,g,g,h,h
f,f,f,g,g,h,g,h,h
etc.
```

In sync tx processing, you would more likely see:

```
f,g,f,g,f,g,h,h,h
```

because there is *no guarantee* in Fulcro's semantics about the space between two calls to `transact!`. If your
application relies on the groupings that happen with the standard tx processing (submissions while holding a thread
go into the queue first) then your application may break when you switch to sync processing.

Note that transactions *are* treated as atomically as possible. So, if you want a specific grouping you should submit
it as a single tx:

```
(transact! [(f) (g)])
(transact! [(f) (g)])
```

is guaranteed to do `f,g,f,g`, and never `f,f,g,g`, though it is still possible to see `f,g,h,f,g,h`.

This sync transaction processing system allows you to push most (if not all) behavior of even nested transactions into a single
synchronous operation. This will lead to significant improvements in the snappiness of the UI for optimistic operation
and should also reduce over-rendering (multiple calls to render due to multiple async operations).

If your remote is mocked as a synchronous operation, then you can also leverage this tx processor to enable
completely synchronous testing of your headless Fulcro application.

WARNING: This tx processing system does *not* support:

* `ptransact!`: Pessimistic transactions are a legacy feature of Fulcro 2 that is no longer necessary. New
applications should not use the feature, and this sync tx processing system does not support it. The call
will succeed, but will behave as a normal `transact!`.
raw docstring

com.fulcrologic.fulcro.data-fetch

Functions for issuing loads of subgraphs of data for your application. The primary functions of interest are load! and load-field!. Fulcro's composed queries and idents allow these loads to automatically be normalized and merged into your database. The data targeting support allows you to then join that new subgraph to the existing UI data graph. This process is the central topic to understand in Fulcro, and it is to your advantage to study the concepts of Fulcro idents and query composition carefully.

Functions for issuing loads of subgraphs of data for your application. The primary functions of interest are
`load!` and `load-field!`. Fulcro's composed queries and idents allow these loads to automatically be normalized
and merged into your database. The data targeting support allows you to then *join* that new subgraph to the
existing UI data graph. This process is the central topic to understand in Fulcro, and it is to your advantage
to study the concepts of Fulcro idents and query composition carefully.
raw docstring

com.fulcrologic.fulcro.dom

clj

MACROS for generating CLJS code. See dom.cljs. There are both CLJ and CLJS versions of this file, but both are form CLJS. The CLJ file is necessary because macros in CLJS are expanded at compile time in the JVM. There is no way to get macros and functions that work properly for both CLJ and CLJS output, so in order to get both a macro and function that is usable in CLJ and CLJS there need to be two namespaces. The DOM macros/functions that work for CLJ are in dom-server.

Thus, if you are using these in a CLJC file, you MUST require them like this:

(ns my-thing.ui
  (:require
    #?(:clj [com.fulcrologic.fulcro.dom-server :as dom]
       :cljs [com.fulcrologic.fulcro.dom :as dom])))

This is a limitation of the operation of the language itself (if you want both macros for performance in CLJ and CLJS (expanded at compile time to optimal form) as well as function versions for use as lambdas).

MACROS for generating CLJS code. See dom.cljs. There are both CLJ and CLJS versions of this file, but *both* are
form CLJS. The CLJ file is necessary because macros in CLJS are expanded at compile time in the JVM. There is
no way to get macros and functions that work properly for both CLJ and CLJS output, so in order to get
both a macro and function that is usable in CLJ and CLJS there need to be two namespaces. The DOM macros/functions
that work for CLJ are in `dom-server`.

Thus, if you are using these in a CLJC file, you MUST require them like this:

```
(ns my-thing.ui
  (:require
    #?(:clj [com.fulcrologic.fulcro.dom-server :as dom]
       :cljs [com.fulcrologic.fulcro.dom :as dom])))
```

This is a limitation of the operation of the language itself (if you want both macros for performance in CLJ and CLJS
(expanded at compile time to optimal form) as well as function versions for use as lambdas).
cljs

Client-side DOM macros and functions. For isomorphic (server) support, see also com.fulcrologic.fulcro.dom-server

Client-side DOM macros and functions. For isomorphic (server) support, see also com.fulcrologic.fulcro.dom-server
raw docstring

com.fulcrologic.fulcro.dom-server

Support for rendering DOM from CLJ. Must be separate to enable same-named macros in CLJS for performance.

Usage: Create your UI in CLJC files, and require with conditional reader tags:

(ns app.ui (:require #?(:clj [com.fulcrologic.fulcro.dom-server :as dom] :cljs [com.fulcrologic.fulcro.dom :as dom])))

Support for rendering DOM from CLJ. Must be separate to enable same-named macros in CLJS for performance.

Usage: Create your UI in CLJC files, and require with conditional reader tags:

(ns app.ui
  (:require
    #?(:clj [com.fulcrologic.fulcro.dom-server :as dom] :cljs [com.fulcrologic.fulcro.dom :as dom])))
raw docstring

com.fulcrologic.fulcro.dom.html-entities

Defs of the proper unicode characters so you can use html entities in your DOM functions without having to look them up (or type out silly things like "\u00C6"

For example:

(ns my.ui
  (:require
    [com.fulcrologic.fulcro.dom.html-entities :as ent]))
    
...
   (dom/div ent/nbsp ent/copy)
...
Defs of the proper unicode characters so you can use html entities in your DOM functions without having to
look them up (or type out silly things like "\u00C6"

For example:

```
(ns my.ui
  (:require
    [com.fulcrologic.fulcro.dom.html-entities :as ent]))
    
...
   (dom/div ent/nbsp ent/copy)
...
```
raw docstring

com.fulcrologic.fulcro.dom.icons

SVG-encoded material UI icons.

See https://material-ui.com/components/icons

SVG-encoded material UI icons.

See https://material-ui.com/components/icons
raw docstring

com.fulcrologic.fulcro.dom.inputs

A namespace for dealing with inputs in HTML DOM when you wish to control a value in the data model that cannot be directly represented by normal HTML inputs (which always use strings). For example, you want to have an int in your data model, but HTML5 number inputs return a string. The primary utility is StringBufferedInput which generates a new React class that wraps an HTML input. The namespace also includes a few uses that are handy (at least as examples): ui-int-input and ui-keyword-input. See the source of those for examples.

A namespace for dealing with inputs in HTML DOM when you wish to control a value in the data model
that cannot be directly represented by normal HTML inputs (which always use strings). For example, you want to have an int in
your data model, but HTML5 number inputs return a string. The primary utility is `StringBufferedInput` which generates
a new React class that wraps an HTML `input`. The namespace also includes a few uses that are handy (at least as
examples): `ui-int-input` and `ui-keyword-input`. See the source of those for examples.
raw docstring

com.fulcrologic.fulcro.mutations

Mutations are the central mechanism of getting things done in Fulcro. The term mutation refers to two things:

  • The literal data that stands for the operation. These are lists with a single symbol and a map of parameters. In earlier version, you had to quote them: '[(f {:x 1})], but Fulcro 3 includes a way to declare them so that they auto-quote themselves for convenience. This can be confusing to new users. Remember that a mutation call is nothing more than a submission of this data via comp/transact! (i.e. call f with the parameter {:x 1}).
  • One or more definitions of what to do when the mutation is requested.

The former are submitted with transact! and can be written like so:

;; The unquote on the parameters is typically needed because you'll use surrounding binding values in them.
(let [x 3
      some-local-value 42]
  (comp/transact! this `[(f ~{:x x}) (g ~{:y some-local-value})]))
;; or, if pre-declared and required:
(let [x 3
      some-local-value 42]
  (comp/transact! this [(f {:x x}) (g {:y some-local-value})]))

This works because a mutation definition actually builds a record that response to function calls. This means

(defn func [x] (inc x))
(defmutation f [params] ...)

;; A regular function runs when called...
(func 3)
;; => 4

;; A mutation simply returns its expression when called:
(f {:x 1})
;; => (f {:x 1})

This allows you to embed a mutation expression without quoting in your calls to transact (if desired) or with quoting if you have something like a circular reference problem.

See the Developer's Guide for more information.

Mutations are the central mechanism of getting things done in Fulcro. The term mutation refers to two things:

* The literal data that stands for the operation. These are lists with a single symbol and a map of parameters. In
earlier version, you had to quote them: `'[(f {:x 1})]`, but Fulcro 3 includes a way to declare them so that they
auto-quote themselves for convenience. This can be confusing to new users. Remember that a mutation call is nothing
more than a *submission* of this data via `comp/transact!` (i.e. call `f` with the parameter `{:x 1}`).
* One or more definitions of what to do when the mutation is requested.

The former are submitted with `transact!` and can be written like so:

```
;; The unquote on the parameters is typically needed because you'll use surrounding binding values in them.
(let [x 3
      some-local-value 42]
  (comp/transact! this `[(f ~{:x x}) (g ~{:y some-local-value})]))
;; or, if pre-declared and required:
(let [x 3
      some-local-value 42]
  (comp/transact! this [(f {:x x}) (g {:y some-local-value})]))
```

This works because a mutation *definition* actually builds a record that response to function calls. This means

```
(defn func [x] (inc x))
(defmutation f [params] ...)

;; A regular function runs when called...
(func 3)
;; => 4

;; A mutation simply returns its expression when called:
(f {:x 1})
;; => (f {:x 1})
```

This allows you to embed a mutation expression without quoting in your calls to transact (if desired) or with
quoting if you have something like a circular reference problem.

See the Developer's Guide for more information.
raw docstring

com.fulcrologic.fulcro.networking.file-upload

cljs

Client-side middleware that can be used with HTTP remotes so that mutations can attach file uploads to mutation parameters.

Client-side middleware that can be used with HTTP remotes so that mutations can attach file uploads to mutation
parameters.
raw docstring

com.fulcrologic.fulcro.networking.file-url

Support for converting binary network responses to a usable File URL in a browser. This file is CLJC so the functions exist for SSR, but they do nothing in CLJ.

Support for converting binary network responses to a usable File URL in a browser. This
file is CLJC so the functions exist for SSR, but they do nothing in CLJ.
raw docstring

com.fulcrologic.fulcro.networking.mock-server-remote

Simple adapter code that allows you to use a generic parser 'as if' it were a client remote in CLJS.

Simple adapter code that allows you to use a generic parser 'as if' it were a client remote in CLJS.
raw docstring

com.fulcrologic.fulcro.networking.tenacious-remote

A wrapper for remotes that adds automatic retry with exponential back-off behavior. This makes the remote more tolerant of flaky network communications, and is a simple wrapper that should work with any remote implementation. NOTE: Fulcro websockets already has automatic retry support which works a bit differently than this one. Be careful that you understand what you are doing if you configure them both at the same time.

See com.fulcrologic.fulcro.offline for features that help support true offline modes of operation.

A wrapper for remotes that adds automatic retry with exponential back-off behavior. This makes the remote more
tolerant of flaky network communications, and is a simple wrapper that should work with any remote implementation.
NOTE: Fulcro websockets already has automatic retry support which works a bit differently than this one. Be careful
that you understand what you are doing if you configure them both at the same time.

See `com.fulcrologic.fulcro.offline` for features that help support true offline modes of operation.
raw docstring

com.fulcrologic.fulcro.offline.browser-edn-store

An implementation of a DurableEDNStore that uses Browser local storage to save/load the EDN.

An implementation of a DurableEDNStore that uses Browser local storage to save/load the EDN.
raw docstring

com.fulcrologic.fulcro.offline.durable-edn-store

A protocol for storing/loading EDN from some kind of durable storage. This protocol is used by the offline support to isolate the need to persist data from the runtime environment, since Fulcro may be running in node/electron, a browser, or a mobile device.

A protocol for storing/loading EDN from some kind of durable storage. This protocol is used by the offline support
to isolate the need to persist data from the runtime environment, since Fulcro may be running in node/electron, a
browser, or a mobile device.
raw docstring

com.fulcrologic.fulcro.offline.durable-mutations

Support for durable mutations that can be automatically retried against a remote until a positive confirmation of success is received, or a specific kind of error indicates it cannot succeed.

You must configure your application in order to use this support. In particular, a durable storage for the mutations must be defined so that they can survive application restarts, power failures, etc. Your implementation of that storage will determine the overall reliability of these mutations. Additionally, you may define a custom optimistic tempid strategy that can do tempid remappings before ever talking to the server.

The mutations in a durable transaction must be:

  • Idempotent
  • Order-independent

This system asserts that the mutation in question will eventually run. However, it exposes the details of what is really going on at the mutation layer so that you can customize the behavior as needed.

IMPORTANT: The optimistic side of the mutation will run any time the mutation is tried. You can check (via durable-mutations/retry?) if this is a retry, and decide if there is anything to do in the UI.

Optimistic temporary ID remapping is supported, but requires that you define a TempidStrategy. This can be done by either pre-allocating a range from the server, or by allowing the client to use generated UUIDs (i.e. the UUID within the tempid itself). Your server must agree on this strategy for consistent operation.

It is a valid strategy to not resolve the tempids on the client, in which case your app state will have tempids on the items submitted until the real mutation completes. Tempid rewrites from the server are always applied, even if you had previously remapped them on the client.

Server-side implementations of durable mutations cannot have any meaningful return value other than :tempids since there is no guarantee when the real mutation will run.

There is a closure goog.define of BACKOFF_LIMIT_MS which defaults to 30000 (ms). This limits the maximum wait time between mutation retries and can be modified via compiler settings. See compiler docs.

NOTE: The backoff will cause mutations to appear somewhat slowly when network communication resumes. This is by design, and will prevent a flood of requests after a server outage. Caution: Setting this too low can cause blockage on retry logic when the network is down.

There is also a LOOP_TIMEOUT_MS (default 20ms). Any durable mutation transact submission, on average, appear to have this much latency. Setting it too low will cause the browser to waste a lot of CPU looking for trouble, setting it too high will annoy the user. DO NOT SET THIS TO 0.

Installation: See with-durable-mutations.

Usage: Use transact! from this ns, or add :com.fulcrologic.fulcro.offline.durable-mutations/durable? true to the options of your call to comp/transact!. Do not include follow-on reads in the transaction if using comp/transact!.

Support for durable mutations that can be automatically retried against a remote until a positive
confirmation of success is received, or a specific kind of error indicates it cannot succeed.

You must configure your application in order to use this support. In particular, a durable storage for the mutations
must be defined so that they can survive application restarts, power failures, etc.  Your implementation of that storage will determine
the overall reliability of these mutations. Additionally, you *may* define a custom optimistic tempid strategy that can do
tempid remappings before ever talking to the server.

The mutations in a durable transaction *must* be:

* Idempotent
* Order-independent

This system asserts that the mutation in question *will eventually* run. However, it exposes the details of
what is really going on at the mutation layer so that you can customize the behavior as needed.

IMPORTANT: The optimistic side of the mutation will run any time the mutation is tried. You can check (via
`durable-mutations/retry?`) if this is a retry, and decide if there is anything to do in the UI.

Optimistic temporary ID remapping is supported, but requires that you define a TempidStrategy.
This can be done by either pre-allocating a range from the server, or by allowing the client to use generated
UUIDs (i.e. the UUID within the tempid itself). *Your server must agree on this strategy for consistent operation*.

It is a valid strategy to *not* resolve the tempids on the client, in which case your app state will have tempids
on the items submitted until the real mutation completes. Tempid rewrites from the server are always applied, even
if you had previously remapped them on the client.

Server-side implementations of durable mutations cannot have any meaningful return value other than `:tempids` since
there is no guarantee when the real mutation will run.

There is a closure goog.define of BACKOFF_LIMIT_MS which defaults to 30000 (ms). This limits the maximum wait time between
mutation retries and can be modified via compiler settings. See compiler docs.

NOTE: The backoff will cause mutations to appear somewhat slowly when network communication resumes. This is by design,
and will prevent a flood of requests after a server outage. Caution: Setting this too low can cause blockage on retry
logic when the network is down.

There is also a LOOP_TIMEOUT_MS (default 20ms). Any durable mutation transact submission, on average, appear
to have this much latency. Setting it too low will cause the browser to waste a lot of CPU looking for trouble,
setting it too high will annoy the user. DO NOT SET THIS TO 0.

Installation: See `with-durable-mutations`.

Usage: Use `transact!` from this ns, or add `:com.fulcrologic.fulcro.offline.durable-mutations/durable? true` to the
options of your call to `comp/transact!`. Do not include follow-on reads in the transaction if using `comp/transact!`.
raw docstring

com.fulcrologic.fulcro.offline.load-cache

Support for a loading system that supports keeping previously-seen query responses in a persistent cache. It supports the following features:

  • Make a failed load return the last cached value. ** Support for a default value for the load in case you are offline and nothing is in the cache.
  • Support for an eager/fast return from cache even when online. ** Indicating if the actual return should just go to cache, or both cache and app merge.

This support replaces the default definition of the internal-load mutation in your Fulcro app, and hooks cache control into the normal load options (open map). If no caching options are given in a load!, then it uses Fulcro's built-in implementation of load.

WARNING: Mixing this with durable mutations can be a problem. You should only use a load cache on items that cannot be modified by durable mutations unless you're willing to also update the load cache to reflect the mutation changes; otherwise the load cache can get out of sync with the durable mutations and cause all manner of havoc. This facility is primarily about making well-known data (e.g. inventory items, dropdown options, etc.) available even when the server is not responding.

Installation: See with-load-cache

Usage: Use the load! and load-eagerly! functions from this ns. Operations in data-fetch ns will continue to work in an unmodified fashion.

Support for a loading system that supports keeping previously-seen query responses in a persistent
cache. It supports the following features:

* Make a failed load return the last cached value.
** Support for a default value for the load in case you are offline and nothing is in the cache.
* Support for an eager/fast return from cache even when online.
** Indicating if the actual return should just go to cache, or both cache and app merge.

This support replaces the default definition of the `internal-load` mutation in your Fulcro app, and hooks
cache control into the normal load options (open map). If no caching options are given in a `load!`, then
it uses Fulcro's built-in implementation of load.

WARNING: Mixing this with durable mutations can be a problem. You should only use a load cache on
items that *cannot* be modified by durable mutations unless you're willing to also update the
load cache to reflect the mutation changes; otherwise the load cache can get out of sync with the
durable mutations and cause all manner of havoc. This facility is primarily about making well-known
data (e.g. inventory items, dropdown options, etc.) available even when the server is not responding.

Installation: See `with-load-cache`

Usage: Use the `load!` and `load-eagerly!` functions from this ns. Operations in `data-fetch` ns will continue to work
in an unmodified fashion.
raw docstring

com.fulcrologic.fulcro.offline.tempid-strategy

Temporary ID strategy. Used by offline support to enable disconnected applications to define how Fulcro tempids behave when disconnected. The support allows a client decide to implement ID support in whatever way makes sense to the feature set of the application in offline modes.

  • Negotiate a pre-allocated pool of IDs with the server when online.
  • Use client-generated UUIDs
  • Use the UUIDs within the tempids as the real IDs on the server
  • etc.

This ns also includes two pre-written strategies:

TempIDisRealIDStrategy:: This strategy immediately rewrites the tempids in app state to the UUID within the tempid. This allows the client to assign the real ID of the entity immediately, and the server must then either honor that assignment or remap it on success. The server will receive the tempid. This is a very easy way to ensure idempotent save as well, since the server can easily detect when that an incoming tempid has already been saved under that UUID in the database.

NOOPStrategy:: Does nothing. The IDs remain temporary in app state and in the txn sent to the server. Rewrites happen on success.

Temporary ID strategy. Used by offline support to enable disconnected applications to define how Fulcro tempids
 behave when disconnected. The support allows a client decide to implement ID support in whatever way
 makes sense to the feature set of the application in offline modes.

 * Negotiate a pre-allocated pool of IDs with the server when online.
 * Use client-generated UUIDs
 * Use the UUIDs within the tempids as the real IDs on the server
 * etc.

This ns also includes two pre-written strategies:

TempIDisRealIDStrategy:: This strategy immediately rewrites the tempids in app state to the UUID *within* the tempid. This allows
the client to assign the real ID of the entity immediately, and the server must then either honor that assignment or remap it
on success. The server will receive the tempid. This is a very easy way to ensure idempotent save as well, since the
server can easily detect when that an incoming tempid has already been saved under that UUID in the database.

NOOPStrategy:: Does nothing. The IDs remain temporary in app state and in the txn sent to the server. Rewrites happen
on success.
raw docstring

com.fulcrologic.fulcro.raw.components

Fulcro base component functions. This namespace has no hard dependency on React, and includes all of the core routines found in components (that ns just aliases to this one). There is no support in this namespace for creating standard defsc components that work in React-based Fulcro, but instead this namespace includes support for building "normalizing component" from EQL and sample instances. This gives you all of the general data management power with no ties to React.

Fulcro base component functions. This namespace has no hard dependency on React, and includes all of the core routines
found in `components` (that ns just aliases to this one). There is no support in this namespace for creating standard
`defsc` components that work in React-based Fulcro, but instead this namespace includes support for building
"normalizing component" from EQL and sample instances. This gives you all of the general data management power
with no ties to React.
raw docstring

com.fulcrologic.fulcro.react.error-boundaries

A macro and predefined component that can create a boundary above which errors cannot propagate. Read the docstring of error-boundary carefully. Works with server-side rendering as well, and provides for development-time retries to recover after a hot code reload without having to reload the entire page.

A macro and predefined component that can create a boundary above which errors cannot propagate. Read the docstring
of `error-boundary` carefully. Works with server-side rendering as well, and provides for development-time retries
to recover after a hot code reload without having to reload the entire page.
raw docstring

com.fulcrologic.fulcro.react.hooks

React hooks wrappers and helpers. The wrappers are simple API simplifications that help when using hooks from Clojurescript, but this namespace also includes utilities for using Fulcro's data/network management from raw React via hooks.

See use-root, use-component, and use-uism.

React hooks wrappers and helpers. The wrappers are simple API simplifications that help when using hooks from
Clojurescript, but this namespace also includes utilities for using Fulcro's data/network management from raw React
via hooks.

See `use-root`, `use-component`, and `use-uism`.
raw docstring

com.fulcrologic.fulcro.rendering.ident-optimized-render

A render optimization algorithm for refreshing the UI via props tunnelling (setting new props on a component's state in a pre-agreed location). This algorithm analyzes database changes and on-screen components to update components (by ident) whose props have changed.

Prop change detection is done by scanning the database in only the locations that on-screen components are querying (derived by the mounted component idents, and any ident-joins in the queries).

A render optimization algorithm for refreshing the UI via props tunnelling (setting new props on a component's
state in a pre-agreed location). This algorithm analyzes database changes and on-screen components to update
components (by ident) whose props have changed.

Prop change detection is done by scanning the database in *only* the locations that on-screen components are querying
(derived by the mounted component idents, and any ident-joins in the queries).
raw docstring

com.fulcrologic.fulcro.rendering.keyframe-render

The keyframe optimized render.

The keyframe optimized render.
raw docstring

com.fulcrologic.fulcro.rendering.keyframe-render2

Just like keyframe render, but supports :only-refresh option.

Just like keyframe render, but supports `:only-refresh` option.
raw docstring

com.fulcrologic.fulcro.rendering.multiple-roots-renderer

Like keyframe-render2, but also supports free-floating roots.

WARNING: THIS RENDERER SHOULD BE CONSIDERED DEPRECATED (even though for legacy reasons it is the default) in favor of using hooks with helpers like use-component.

General usage:

  1. Set this nses render! as your application's optimized render function.
  2. Create a class that follows all of the normal rules for a Fulcro root (no ident, has initial state, composes children queries/initial-state, etc. a. Add mount/unmount register/deregister calls
  3. Use floating-root-factory to generate a Fulcro factory, or floating-root-react-class to generate a vanilla React wrapper class that renders the new root. a. Use the factory in normal Fuclro rendering, but don't pass it props, or b. Use (dom/create-element ReactClass) to render the vanilla wrapper, or c. Use the vanilla wrapper class when a js library controls rendering (like routing).

Example:

(defonce app (app/fulcro-app {:optimized-render! mroot/render!}))

(defsc AltRoot [this {:keys [alt-child]}]
  ;; query is from ROOT of the db, just like normal root.
  {:query                 [{:alt-child (comp/get-query OtherChild)}]
   :componentDidMount     (fn [this] (mroot/register-root! this {:app app}))
   :componentWillUnmount  (fn [this] (mroot/deregister-root! this {:app app}))
   :shouldComponentUpdate (fn [] true)
   :initial-state         {:alt-child [{:id 1 :n 22}
                                       {:id 2 :n 44}]}}
  (dom/div
    (mapv ui-other-child alt-child)))

;; For use in the body of normal defsc components.
(def ui-alt-root (mroot/floating-root-factory AltRoot))

;; For use as plain React class
(def PlainAltRoot (mroot/floating-root-react-class AltRoot app))

...

(some-js-library #js {:thing PlainAltRoot})

(defsc NormalFulcroClass [this props]
  {:query [:stuff]
   :ident (fn [] [:x 1])
   ...}
  (dom/div
    ;; ok to use within defsc components:
    (ui-alt-root)
    ;; how to use the plain react class, which is how js libs would use it:
    (dom/create-element PlainAltRoot)))

Like keyframe-render2, but also supports free-floating roots.

WARNING: THIS RENDERER SHOULD BE CONSIDERED DEPRECATED (even though for legacy reasons it is the default)
in favor of using hooks with helpers like `use-component`.

General usage:

1. Set this nses `render!` as your application's optimized render function.
2. Create a class that follows all of the normal rules for a Fulcro root (no ident, has initial state,
composes children queries/initial-state, etc.
   a. Add mount/unmount register/deregister calls
2. Use floating-root-factory to generate a Fulcro factory, or floating-root-react-class to generate
a vanilla React wrapper class that renders the new root.
   a. Use the factory in normal Fuclro rendering, but don't pass it props, or
   b. Use `(dom/create-element ReactClass)` to render the vanilla wrapper, or
   c. Use the vanilla wrapper class when a js library controls rendering (like routing).

Example:

```
(defonce app (app/fulcro-app {:optimized-render! mroot/render!}))

(defsc AltRoot [this {:keys [alt-child]}]
  ;; query is from ROOT of the db, just like normal root.
  {:query                 [{:alt-child (comp/get-query OtherChild)}]
   :componentDidMount     (fn [this] (mroot/register-root! this {:app app}))
   :componentWillUnmount  (fn [this] (mroot/deregister-root! this {:app app}))
   :shouldComponentUpdate (fn [] true)
   :initial-state         {:alt-child [{:id 1 :n 22}
                                       {:id 2 :n 44}]}}
  (dom/div
    (mapv ui-other-child alt-child)))

;; For use in the body of normal defsc components.
(def ui-alt-root (mroot/floating-root-factory AltRoot))

;; For use as plain React class
(def PlainAltRoot (mroot/floating-root-react-class AltRoot app))

...

(some-js-library #js {:thing PlainAltRoot})

(defsc NormalFulcroClass [this props]
  {:query [:stuff]
   :ident (fn [] [:x 1])
   ...}
  (dom/div
    ;; ok to use within defsc components:
    (ui-alt-root)
    ;; how to use the plain react class, which is how js libs would use it:
    (dom/create-element PlainAltRoot)))

```
raw docstring

com.fulcrologic.fulcro.routing.dynamic-routing

A router that uses Fulcro dynamic queries to optimize query performance on rendering and provides a number of useful features such as easy composition, control over route targeting, on-screen component vetoes of routing requests, etc.

NOTE: This router is not concerned with HTML5 history events or URL management. This router is intended to be usable in server-side rendering, React Native, and anywhere else Fulcro might be used. Therefore it is not tied to a particular rendering platform's idea of location management (i.e. URLs).

The structure of the route composition (and its representation as a sequence of string path components) is intended to be easy to integrate with HTML5 history and URL control.

A router that uses Fulcro dynamic queries to optimize query performance on rendering and provides a number of useful
features such as easy composition, control over route targeting, on-screen component vetoes of routing requests, etc.

NOTE: This router is *not* concerned with HTML5 history events or URL management. This router is intended to be usable
in server-side rendering, React Native, and anywhere else Fulcro might be used. Therefore it is not tied to a particular
rendering platform's idea of location management (i.e. URLs).

The structure of the route composition (and its representation as a sequence of string path components) is intended to
be easy to integrate with HTML5 history and URL control.
raw docstring

com.fulcrologic.fulcro.server.api-middleware

Standard Ring middleware for setting up servers to handle Fulcro requests. These assume you will be using a library like Pathom to create a parser that can properly dispatch resolution of requests. See the Developer's Guide or the Fulcro template for examples of usage.

Standard Ring middleware for setting up servers to handle Fulcro requests. These assume you will be using a library
like Pathom to create a parser that can properly dispatch resolution of requests. See the Developer's Guide or
the Fulcro template for examples of usage.
raw docstring

com.fulcrologic.fulcro.server.config

Utilities for managing server configuration via EDN files.

The general design requirements of this support are that you should be able to:

  • Specify your configuration as EDN.
  • Specify a reasonable set of server config values as "defaults" so that specific environments can override just what matters.
  • Override the defaults by deep-merging an environment-specific config file over the defaults.
  • Specify individual overrides via environment variables. ** Support rich data types from environment variables, like maps, numerics, etc.

So the basic operation is that you create a default EDN file and one or more environment files (e.g. dev.edn, prod.edn, joes-test-env.edn, etc. You can then use a combination of runtime parameters, JVM properties, and environment variables to end up with your runtime configuration.

See load-config! for more detailed usage.

Utilities for managing server configuration via EDN files.

The general design requirements of this support are that you should be able to:

* Specify your configuration as EDN.
* Specify a reasonable set of server config values as "defaults" so that specific environments can override
just what matters.
* Override the defaults by deep-merging an environment-specific config file over the defaults.
* Specify individual overrides via environment variables.
** Support rich data types from environment variables, like maps, numerics, etc.

So the basic operation is that you create a default EDN file and one or more environment files (e.g.
`dev.edn`, `prod.edn`, `joes-test-env.edn`, etc. You can then use a combination of runtime parameters,
JVM properties, and environment variables to end up with your runtime configuration.

See `load-config!` for more detailed usage.
raw docstring

com.fulcrologic.fulcro.specs

No vars found in this namespace.

com.fulcrologic.fulcro.ui-state-machines

Support for structuring the logic of component interactions as a state machine. Useful when the logic of a group of components becomes non-trivial, which is often. Note that it is not recommended that you try to structure large parts of your application as a state machine (since this implementation is closer to FSM than state charts), but it turns out that most applications work very well with groups of components under separate state machines as somewhat larger modules of the overall application. See the Developer's Guide for more information on working with this namespace.

Support for structuring the logic of component interactions as a state machine. Useful when
the logic of a group of components becomes non-trivial, which is often. Note that it is not
recommended that you try to structure large parts of your application as a state machine
(since this implementation is closer to FSM than state charts), but it turns out that
most applications work very well with groups of components under separate state machines
as somewhat larger modules of the overall application. See the Developer's Guide for
more information on working with this namespace.
raw docstring

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

× close