Skip to content

Instantly share code, notes, and snippets.

View holyjak's full-sized avatar
💓
Loving Clojure

Jakub Holý holyjak

💓
Loving Clojure
View GitHub Profile
@holyjak
holyjak / about.md
Created March 4, 2023 15:04
Fulcro live coding 3 - Simplify with UISM - files
##
## Install FE dependencies ##
##
FROM node:19.4.0 AS npm
WORKDIR /opt
COPY package.json yarn.lock ./
RUN yarn install
##
## BUILD BE ##
@holyjak
holyjak / monitor-usage.sh
Last active February 14, 2023 14:03
Script to monitor the usage of CPU, memory by a process via `top`
#!/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

@holyjak
holyjak / fulcr-ssr-test.clj
Created January 22, 2021 11:30
Experiments in Fulcro SSR with dynamic routers
(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]]
@holyjak
holyjak / tmp_fulcro_forwardRef.cljs
Last active July 11, 2022 06:26
TMP: Example of using forwardRef and passing the result to a HoC JS component
;; 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
@holyjak
holyjak / README.md
Last active June 20, 2022 07:58
IAM policy to allow Continuous Integration user to deploy to AWS Elastic Beanstalk

IAM policy to allow Continuous Integration user to deploy to AWS Elastic Beanstalk

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.

@holyjak
holyjak / fulro-modelling-puzzles.adoc
Last active February 19, 2022 18:04
Fulcro Modelling Puzzles - how would you model a requirement in code?

Fulcro Modelling Puzzles

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.

@holyjak
holyjak / Fulcr-x-Redux-talk.md
Last active December 2, 2021 10:18
Want more from your frontend framework!

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.

@holyjak
holyjak / defdecorator.clj
Last active October 15, 2021 13:59
Macro to create a decorator (wrapper) for a objects implementing a Java interface
;; 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)