Liking cljdoc? Tell your friends :D

Clojars Project

Introduction

What if we used a rules engine to manage all the state of a frontend UI? Can a rules engine replace reframe? Let's find out, children!

There is prior art here, including precept, which tried to use Clara Rules for this purpose. But this time I'm using a rules engine built for fast updates of facts: O'Doyle Rules.

I'm using Rum as my React wrapper, because it is flexible and is great at server-side rendering. The goal is to define Rum components as rules and make them automatically update when the data required by the rules is updated.

Examples

(require
  '[rum.core :as rum]
  '[odoyle.rules :as o]
  '[odoyle.rum :as orum])

(def components
  (orum/ruleset
    {click-counter
     [:what
      [::global ::clicks clicks]
      :then
      (let [*session (orum/prop)]
        [:button {:on-click (fn [_]
                              (swap! *session
                                (fn [session]
                                  (-> session
                                      (o/insert ::global ::clicks (inc clicks))
                                      o/fire-rules))))}
         (str "Clicked " clicks " " (if (= 1 clicks) "time" "times"))])]}))

(def *session
  (-> (reduce o/add-rule (o/->session) components)
      (o/insert ::global ::clicks 0)
      o/fire-rules
      atom))

(rum/mount (click-counter *session) (js/document.querySelector "#app"))

The click-counter rule generates a var holding a valid Rum component. When the values in the :what block are updated, the rule re-fires, which causes the component to update.

Development

  • Install the Clojure CLI tool
  • To develop with figwheel: clj -M:dev
  • To install the release version: clj -M:prod install

Can you improve this documentation?Edit on GitHub

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

× close