Skip to content

Instantly share code, notes, and snippets.

Avatar

Harry sonhanguyen

  • Melbourne, Australia
View GitHub Profile
View cv.htm
<head>
<style>
@media print { body { height: 297mm } }
body {
width: 210mm;
font-family: 'Courier New', Courier, monospace;
margin: 0;
display: flex;
}
@sonhanguyen
sonhanguyen / parser.ts
Last active Dec 24, 2020
Composable validation
View parser.ts
// I could not find any validation library (zod, io-ts etc) that allows custom error types
// so quickly wipped this up, note that the errors here are string literals but they
// might as well be, say, custom classes for pattern matching later
// think about error messages that you need to translate to many languages in the front-end
const formValidator = <S extends Record<string, Validator<any, any>>>(schema: S): Validator<
{ [K in keyof S]: Infer<S[K]>['Input'] },
{ [K in keyof S]:
{ error: Infer<S[K]>['Error']
value: Infer<S[K]>['Input']
@sonhanguyen
sonhanguyen / lens.ts
Last active Nov 30, 2020
typescript optics
View lens.ts
type Lens<State, Value> = {
(_: State): Value
set: (_: Value) => (_: State) => State
map<T>(_: Lens<Value, T>): Lens<State, T>
}
type Prop<K extends string, V = any> = Lens<Record<K, V>, V>
@sonhanguyen
sonhanguyen / cache.py
Last active Oct 17, 2020
A filesystem-based memoization decorator
View cache.py
import os
import collections
import pickle
import json
import urllib.parse
import re
from functools import wraps
from typing import Callable, Any
from dataclasses import dataclass, fields
View side panel style for using with Tree Tabs
/*#region Vivaldi */
#browser:not(.is-settingspage) > #header {
min-height: 0 !important;
height: 0;
}
#panels-container #panels > #switch {
-webkit-app-region: drag;
}
View gist:4743d4b7c479d52c43a5447f831271ee
type NumericIndex = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type Index<T extends any[]> = NumericIndex & keyof T
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type Builder<State = {}> = {
(): State
<A extends string[]>(...namedArgsOrder: A): <
V extends { [K in keyof A]: any },
T = UnionToIntersection<{ [K in Index<A>]: Record<string & A[K], V[K]> }[Index<A>]>
@sonhanguyen
sonhanguyen / overload.ts
Last active Sep 20, 2019
OverloadBuilder
View overload.ts
type Func = (..._) => any
const overload = <Default extends Func>(defaultFunc: Default): OverloadBuilder<Default> => {
// @ts-ignore
const match = cases => Object.assign(
(...args) => {
const matcher = cases.find(([ guard ]) => guard(args))
const func = matcher
? matcher[1]
: defaultFunc
@sonhanguyen
sonhanguyen / Default.bttpreset
Created Jul 20, 2019
Better touch tool setup for window management
View Default.bttpreset
{
"BTTPresetName" : "Default",
"BTTGeneralSettings" : {
"disableScrollingIf3" : true,
"BTTPasteWhenTriggeringClipboardAgain" : true,
"BTTForceNormalClickPressure5F" : 200,
"disableScrollingIf2" : true,
"BTTDidRegisterForUpdateStats" : "3.140",
"BTTShowControlStrip" : true,
"BTTShowControlStripItem" : true,
@sonhanguyen
sonhanguyen / esnextbin.md
Last active Jul 8, 2019
esnextbin sketch
View esnextbin.md
type Dec = Record<number, never> & [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

type A = Dec[12]

type Overload<T extends Signature[]> = {
  [K in number & keyof T]: (...args: Args<T[K]>) => Return<T[K]>
}

type Args<S extends Signature> = any[] & {
@sonhanguyen
sonhanguyen / mixin_delegate_decorator.ts
Last active May 26, 2019
kotlin's style delegate in typescript
View mixin_delegate_decorator.ts
function delegateTo(prop: string) {
const { __proto__ } = this
Object.setPrototypeOf(this,
new Proxy({}, {
get: (target, name) => {
target = this[prop]
if (name === prop) return target
if (name in __proto__) return __proto__[name]
return target ? target[name] : undefined