Contributing¶
Thank you for your interest in actively participating in the project's development! Please read the Contributor Covenant Code of Conduct and the Contributor License Agreement first.
The project is written in ClojureScript - a compiler for Clojure that targets JavaScript, and is based on re-frame - a framework for building Modern Web Apps in ClojureScript. You should probably take a look at their exceptional documentation first.
Style Guide¶
We try to follow the Clojure Style Guide as much as possible.
An additional resource about how to name Clojure functions by Stuart Sierra.
In addition to the idiomatic names, we use the following conventions
e -> event el, els -> element, elements attr, attrs -> attribute, attributes prop, props -> property, properties w, h -> width, height t -> time h, m, s, ms -> hours, minutes, seconds, milliseconds
App structure¶
Main structure
src\ ├── renderer\ <--- Renderer Process ├── electron\ <--- Main Process & Preload script ├── lang\ <--- Translation files └── worker\ <--- Web Workers
We are trying to split our code under renderer into relatively independent modules, following re-frame's app structure suggestions with some minor additions.
module\ ├── core.cljs <--- entry point ├── db.cljs <--- schema, validation ├── views.cljs <--- reagent views ├── events.cljs <--- event handlers ├── subs.cljs <--- subscription handlers ├── handlers.cljs <--- helper functions for db transformations ├── effects.cljs <--- effect handlers ├── hierarchy.cljs <--- multimethods and hierarchies ├── styles.css <--- styles └── README.md <--- documentation
Re-frame recommendations¶
Avoid chaining events to create new ones. Always prefer composing pure functions that
directly transform the db. That is the whole purpose of handlers
namespace.
Use interceptors sparingly. Although they look (and probably are) ingenious, it is hard to write and reason with them. Doing things explicitly, is usually easier to grasp and maintain.
Always use auto-qualified keywords (e.g. ::copy
) for subscriptions, events and effects.
You can use as-alias
to require those namespaces without evaluating the registrations
multiple times.
Spec¶
We use malli to describe the shape of our app db and selectively validate incoming data (e.g. file loading). We also use this spec to generate default values. Full db validation is enabled on dev mode.
Function schemas
are selectively applied to pure and critical namespaces, such as utils and handlers.
By default, function schemas are instrumented only during tests to avoid performance
overhead. However, runtime instrumentation can also be enabled in the development
environment (see renderer.dev
).
Useful development shortcuts¶
Ctrl+Shift+I Toggle devtools
Ctrl+Shift+X Toggle 10x
Ctrl+R Reload app