Skip to content

Instantly share code, notes, and snippets.

View mvhenten's full-sized avatar
💭
I may be slow to respond.

Matthijs van Henten mvhenten

💭
I may be slow to respond.
  • Amsterdam, The Netherlands
View GitHub Profile
type RequiredDefined<T extends Record<string, unknown>> = {
[key in keyof T]-?:NonNullable<T[key]>
}
export function assertOptions<Options extends Record<string, unknown>, Keys extends keyof Options, Result extends Pick<Options, Keys>>(options:Options, ...keys:Keys[]):RequiredDefined<Result> {
const result = {} as Record<string, unknown>
for (let key of keys as string[]) {
if (options[key] === undefined) {
throw new TypeError(`Expected ${String(key)} to be defined`);
@mvhenten
mvhenten / use-validate.ts
Last active March 5, 2023 13:58
Utility hook that helps with: https://cloudscape.design/patterns/general/validation/ "Validate the data after a user submits a form for the first time. Don’t validate before the user submits the form for the first time. On subsequent attempts, validate as the user completes each field."
import { useState } from "react";
type ValidationValues = Record<string, unknown>;
type ValidationFunction<T> = (v: T) => string | void;
export type ValidationErrors = Record<string, string[]>;
function runValidation(
key: string,
validators: ValidationFunction<unknown>[],
@mvhenten
mvhenten / gif.sh
Created January 27, 2023 15:07
creat a gif from screen recording
ffmpeg -i $input -vf "fps=16,scale=960:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=32:reserve_transparent=0[p];[s1][p]paletteuse" demo-create-row.gif
import { suite, test, TestContext } from "./mtap";
suite("test label", ({ test }) => {
test("another test", (t:TestContext) => {
t.assert("OK computer");
t.assert(false, "intentionally failed");
});
test("hula hoop", (t:TestContext) => {
t.assert(true, "juhu");
import { set, get, createStore, UseStore, values, clear } from 'idb-keyval';
export abstract class Ministor<ItemType> {
private db: UseStore;
constructor() {
const ns = this.constructor.name;
this.db = createStore(ns, [ns, "items"].join(":"));
}
/**
And the winner is:
Encoding and decoding 100000 items.
+--------------+--------+--------+--------------+
| Encoding | encode | decode | size (bytes) |
+--------------+--------+--------+--------------+
| msgpack-lite | 504 | 206 | 1568544 |
| msgpack5 | 448 | 352 | 1568544 |
/**
Generate ascii table in 30 lines of readable code from a list of objects:
table([
{
description: "description",
value: "value"
},
{
description: "some variable desc",
@mvhenten
mvhenten / setup_agw_vpclink.sh
Last active June 4, 2020 09:22
setup_agw_vpclink.sh
@mvhenten
mvhenten / post-merge
Last active June 6, 2016 12:28 — forked from sindresorhus/post-merge
git hook to run a command after `git pull` if a specified file was changed.
#/usr/bin/env bash
# git hook to run a command after `git pull` if a specified file was changed
# Run `chmod +x post-merge` to make it executable then put it into `.git/hooks/`.
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() {
echo "$changed_files" | grep --quiet "$1" && eval "$2"
}
"use strict";
/**
* Instead of squatting https://www.npmjs.com/package/window
* Why not make it something useful like:
*/
module.exports = typeof window == "undefined" ? null : window;