Skip to content

Instantly share code, notes, and snippets.

Gorgi Kosev spion

Block or report user

Report or block spion

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View translate-error.js
function translateError(msg) {
var newErr = new Error(msg); // placed here to get correct stack
return e => {
newErr.originalError = e;
throw newErr;
async function asyncTask() {
const user = await UserModel.findById(1).catch(translateError('No user found'))
spion /
Last active Nov 23, 2019
C++ versus V8 versus luajit versus C benchmark - (hash) tables


This benchmark has been misleading for a while. It was originally made to demonstrate how JIT compilers can do all sorts of crazy stuff to your code - especially LuaJIT - and was meant to be a starting point of discussion about what exactly LuaJIT does and how.

As a result, its not indicative of what its performance may be on more realistic data. Differences can be expected because

  1. the text will not consist of hard-coded constants
spion /
Last active Nov 5, 2019
Adding features to a software product

New features and changes workflow guide

This guide describes what steps usually work best when adding new features to a product. The guidelines are not mandatory; simpler features may not need any of these steps. They exist to help battle the hardest new features to add :)

The steps are not necessarily in the correct order - this is the usual order. Going back to an older step to add/change things is okay.

Brainstorming sessions

Goal: collect all that we can come up with for the new feature or change. Everything goes into an unorganized document (wiki page). Possible ways to organize this document is into proposal items (and proposal detail item for each proposal item).

spion /
Last active Nov 2, 2019
Node streams - a fractal of weird design

Node streams - a fractal of weird design

and a potential refactor that could fix that

This is a list of issues and confusions I've encountered with node streams, and things I wish were designed and implemented differently. If promise-streams is ever going to change to a design that doesn't build on top of node streams, this would be a list of mistakes to avoid

  1. enc parameter - Why is encoding always passed together with the data? It should be a separate concern. It doesn't even make sense in objectMode
  2. eventemitter base - This encourages a lot of random events to be "attached" by other authors which doesn't work. Best to have an uniform (typed) interface so that everyone knows what to expect.
  3. relying on nextTick etc for execution order - This is very unreliable and causes all sorts of unpredictable rules for implementers which are not documented anywhere. When you attach listeners determines what will happen.
  4. no error propagation - we need the
View mobx.js
@observer class Chart(props) {
@computed get data() { return getDataWithinRange(this.props.dateRange) }
@computed get dimensions() { return getDimensions() }
@computed get xScale() { return getXScale() }
@computed get yScale() { return getYScale() }
render() {
// use this.xScale, this.yScale etc. component will re-render automatically if any of those update.
return <svg className="Chart" />
View gist:96b6232b151d1007a2aa396c2e2c478a

Be careful when feature flags affect any shared mutable state. This for example will cause data loss if the flag value changes during the work:

this.fancyModel = FancyModel.createInitial()
this.rustyModel = RustyModel.createInitial()

async loadData() { 
  let flag = await this.ff.isEnabled('flag');
  let data = await this.fetchData();

Understanding this in JavaScript

It's easy to trip up on the meaning of this in JavaScript. The behavior is very different from other languages, which means we have to throw most preconceptions and intuition out the window.

The best way to think of this in JS is as a hidden function argument which is passed in a slightly awkward way. Instead of the normal passing of arguments:

fn(arg1, arg2, arg3)
View typescript-generics-clarity.ts
type ExtractValuesRecusrively<T> = T extends FormState<infer U>
? { [K in keyof U]: ExtractValuesRecusrively<U[K]> }
: T extends FieldState<infer V>
? V
: never;
// vs
type ExtractValuesRecusrively<State> = State extends FormState<infer InnerForm>
? { [FieldKey in keyof InnerForm]: ExtractValuesRecusrively<InnerForm[FieldKey]> }
View 01-readable.dhall
let types = ../types.dhall sha256:e48e21b807dad217a6c3e631fcaf3e950062310bfb4a8bbcecc330eb7b2f60ed
let defaults = ../defaults.dhall sha256:4450e23dc81975d111650e06c0238862944bf699537af6cbacac9c7e471dfabe
let deployment : types.Deployment = defaults.Deployment // {
metadata = defaults.ObjectMeta // { name = "nginx" },
spec = Some ( defaults.DeploymentSpec // {
replicas = Some 2,
template = defaults.PodTemplateSpec // {
metadata = defaults.ObjectMeta // {
View exactExposedMethodReturnTypeRule.ts
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { inspect } from 'util';
* This rule will ensure that methods marked with the "@expose" decorator must be declared in at
* least one interface implemented by the class. It will also ensure that the return type of this
* method has no excess properties compared to those specified in the interface
You can’t perform that action at this time.