Code related to my live coding recording, Fulcro live coding 3 - Simplify with UISM.
## | |
## Install FE dependencies ## | |
## | |
FROM node:19.4.0 AS npm | |
WORKDIR /opt | |
COPY package.json yarn.lock ./ | |
RUN yarn install | |
## | |
## BUILD BE ## |
#!/bin/sh | |
## | |
## BEWARE: Check with your impl. of top what exactly it returns, it migth differ from mine | |
## | |
# Usage: ./monitor-usage.sh <PID of the process> | |
# Output: top.dat with lines such as `1539689171 305m 2.0`, i.e. unix time - memory with m suffix - CPU load in % | |
# To plot the output, see https://gist.github.com/holyjak/1b58dedae3207b4a56c9abcde5f3fdb5 | |
export PID=$1 | |
rm top.dat | |
while true; do top -p $PID -bn 1 -em | egrep '^ *[0-9]+' | awk -v now=$(date +%s.%N) '{print now,$6,$9}' >> top.dat; done |
Complexity is the root of all evil. So how do we make simple webapps in Fulcro?
The key here is I think a good separation of concerns. In particular:
Separate rendering and business logic. Render functions (i.e. defsc
bodies) contain no or minimal logic, ideally at most simple conditionals or applications of external, pure functions that produce in-line derived data (that is not worth pre-computing externally). This is partially enabled by the fact that props are optimized for the UI, i.e. they contain exactly the data the components need. Pathom is the "backend for frontend" responsible for returning the data in the optimal tree shape but also with the optimal content, adapting from the general domain data (as stored in a database) to the specific UI needs. Changes to the state and side-effects are triggered from the UI but defined and processed externally. They are defined by Fulcro mutations, "transacted" as data, and processed separately, with hooks for customization of the process. Finally, any
(ns ssr-test | |
"Try server-side rendering in Fulcro where we want to display a non-default | |
dynamic router target. | |
*BEWARE*: This is an exploration. I have *no* idea what is the correct way." | |
(:require | |
[com.fulcrologic.fulcro.application :as app] | |
[com.fulcrologic.fulcro.algorithms.denormalize :as denorm] | |
[com.fulcrologic.fulcro.algorithms.server-render :as ssr] | |
[com.fulcrologic.fulcro.components :as comp :refer [defsc]] | |
[com.fulcrologic.fulcro.dom-server :as dom :refer [div label input]] |
;; Example of using forwardRef and passing the result to a HoC JS component | |
;; ... | |
(defn shallow-js->clj [^js obj] | |
(persistent! | |
(reduce (fn [r k] (assoc! r (keyword k) (gobj/get obj k))) | |
(transient {}) (js-keys obj)))) | |
;; My Fulcro component that needs a DOMElement ref and is passed to the JS HoC | |
(defsc MyDropdownList [this {:dropdown/keys [text] :as props}] ; Fulcro props |
IAM policy that we attach to CI users so that our CI server can deploy new versions of our applications to our EB environments without giving them too many permissions. When some permissions are missing, deploys may fail with the useless and misleading ERROR event log
Service:AmazonCloudFormation, Message:TemplateURL must reference a valid S3 object to which you have access.
(Notice that in many cases the error has nothing to do with S3 but can be caused by any missing permissions, for instance autoscaling:SuspendProcesse
. Yes, it sucks.)
The policy can certainly be tightened more, it is not the most restrictive policy that works. As Kyle points out, the full EC2 rights are likely the biggest problem.
Self note: see Obsidian
Note
|
Work in progress |
How would you solve a requirement using code?
For some requirements it is easy to see how to map them onto the functionality and structure that Fulcro offers, while for others it might not be trivial. The goal of this document is to collect various examples of such non-trivial cases, eventually with solutions, so that people can better learn to use Fulcro.
Source code for my Telia Full Stack Feast talk "Want more from your frontend framework!" (slides) (6/2020), comparing Redux with REST and a Fulcro with Pathom (Graph API).
Use case we are implementing: Show “hot deals” in your webshop, loaded on-demand.
PS: For the sake of simplicity I am cheating a little and presenting the Fulcro HotDeals component as a root component. If it was used as a child, we would need to either change the a Link Query or make sure that the :deals
are presented as a property on the parent component. Also, I use unqualified keys for brevity. This is not recommended in practice.
;; A macro to create a decorator (wrapper) for a objects implementing a Java interface | |
;; Disclaimer: The code most certainly is not perfect and does not handle some corner cases | |
;; License: The Unlicense http://unlicense.org/ | |
(require '[clojure.string :as str]) | |
(defn type->tag [parameter-type] | |
(let [array? (-> parameter-type name (str/ends-with? "<>")) | |
primitive? '#{int long float double short boolean byte char} | |
type (if array? | |
(-> parameter-type name (str/replace #"<>$" "") symbol) |