Skip to content

Instantly share code, notes, and snippets.

View elektronik2k5's full-sized avatar
🐧
Delivering high quality code, out remote! 🏔🏖🌴🇮🇱

Nick Ribal elektronik2k5

🐧
Delivering high quality code, out remote! 🏔🏖🌴🇮🇱
View GitHub Profile
@elektronik2k5
elektronik2k5 / .eslintrc.cjs
Last active May 22, 2024 18:09
Static analysis config
const rootConfig = require('../../.eslintrc.cjs');
/* eslint-disable */
// cspell:ignore singleline linebreak multilines paren
const OFF = 'off';
const WARN = 'warn';
const ERROR = 'error';
module.exports = {
extends: [
...rootConfig.extends,

Code style choices and rationale

We use classes due to their superior static analysis capabilities in TypeScript. However, classes come with well known pitfalls which we want to mitigate by:

  • Avoiding inheritance and using composition. Use TypeScript's implements instead of extends when declaring classes:

    - class MyArray extends Array {}
    + class MyArray implements Array {}

Nullable fields and explicit initialization

In order to allow modularity, enable testability without mocking (which is always a PITA) and keep platform code out of our models, we initialize relevant fields with an explicit null value. However, the flip side is that we must also deal with these null values. The way to do that is via TS's type guards. Here's a real (partial) example:

// A nullable field which can hold a reference to a platform specific API, which may not exist in the test environment.
type MaybeStorage = Storage | null;

interface WithLocalStorage {
  storage: MaybeStorage;

Why MobX?

MobX has one job: reactivity

We use MobX to describe and keep our application domain data, mutate it in a typesafe manner and have the UI and side effects react to those mutations in a controlled way. MobX has one job: change detection and automatic reactions to those changes. It doesn't tell us how to structure our code, which abstractions to use, whether to use classes or POJOs or how to organize files.

And it is always synchronous, which is important because you don't ever need any inspection tools or debugging addons other than debugger to see exactly what's going on. The abstraction is very thin and any change can be traced directly back to the code which triggered it simply by following the stack trace. How you choose to write and structure code is 100% up to you.

MobX isn't tied to any specific platform and only requires a JS runtime. All our models should be free of any platform specific code or dependencies, such as DOM, Node, RN, React, etc. We pass our models to platform sp

@elektronik2k5
elektronik2k5 / input.scss
Created March 6, 2022 15:29
Generated by SassMeister.com.
.gc-card {
--card-header-height: 50px;
--card-footer-height: 36px;
--card-no-data-message-height: 72px;
--card-loader-animation-length: 1500ms;
box-shadow: var(--shadow-A);
background: var(--primary-B);
border-radius: 6px;
overflow: hidden;

Keybase proof

I hereby claim:

  • I am elektronik2k5 on github.
  • I am elektronik (https://keybase.io/elektronik) on keybase.
  • I have a public key ASA25PITsEDjjP4o6cNnDZt6RrlbJBQENVJcsUmGEyJmigo

To claim this, I am signing this object:

@elektronik2k5
elektronik2k5 / SassMeister-input.scss
Created February 18, 2016 10:36
Generated by SassMeister.com.
// ----
// libsass (v3.2.5)
// ----
@mixin mobile-breakpoint() {
@content
}
%tags-base {
border: thin solid;
@elektronik2k5
elektronik2k5 / users.json
Last active August 29, 2015 13:56 — forked from anonymous/filltext.com example response
filltext.com example response
[
{
"id": 1,
"isActive": true,
"categories": "bar",
"fname": "Milind",
"lname": "Darbonne",
"address": "2406 Amet Rd",
"email": "[email protected]",
"uname": "AMcinvale",