Skip to content

Instantly share code, notes, and snippets.

@webstrand
webstrand / wg0.netdev
Created September 13, 2025 21:40
IPv4 and IPv6 wireguard configuration for Proton VPN, using systemd-networkd
[NetDev]
Name=wg0
Kind=wireguard
[WireGuard]
PrivateKey=[snip]
RouteMetric=1000
# Table and fwmark are arbitrary
RouteTable=73547
FirewallMark=0x11f4b
@webstrand
webstrand / vite-plugin-basic-auth.mts
Created September 9, 2025 18:55
Plugin for adding basic auth to vite
import { type Plugin } from "vite";
import { default as parseBasicAuth, type BasicAuthResult } from "basic-auth";
import { createHash, timingSafeEqual, randomBytes } from "node:crypto";
import { type IncomingMessage } from "node:http";
const HASH_FUNCTION = "sha256";
const HASH_SIZE = createHash(HASH_FUNCTION).digest().length;
const SALT_SIZE = 16;
export type HashedPassword = readonly [hash: Buffer, salt: Buffer];
@webstrand
webstrand / order-preserving-multimap.ts
Last active September 5, 2025 14:42
A multimap that preserves the insertion order of its keys and values
class Multimap<K, V> {
#buckets = new Map<K, Map<V, readonly [K, V]>>();
#order = new Set<readonly [K, V]>();
constructor(from?: Iterable<readonly [K, V]> | null) {
if(from != null) for(const { 0: key, 1: value } of from) {
this.add(key, value);
}
}
static fromHeaders<K, V>(headers: Iterable<{name: K, value: V}>) {
#!/usr/bin/env -S cargo +nightly -Zscript
---cargo
[dependencies]
futures = "0.3.31"
input-linux = { version = "0.7.1", features = ["codec", "tokio-util-0_7"] }
tokio = { version = "1.46.1", features = ["full"] }
tokio-util = { version = "0.7.15", features = ["full"] }
---
@webstrand
webstrand / union-to-tuple.mts
Created July 15, 2025 17:34
My favorite way of implementing Union To Tuple in TypeScript
declare const END: unique symbol;
type END = typeof END;
export type UnionToTuple<
T,
I = (() => END) &
((T extends T ? (x: () => T) => void : never) extends (x: infer U) => void
? U
: never),
Acc extends readonly unknown[] = [],
const SYNTAX_CHARACTER = "\\^$\\\\.*+?()[\\]{}|/";
const TABLE_67_CHARACTER = "\\t\\n\\v\\f\\r";
const OTHER_PUNCTUATORS_CHARACTER = ",\\-=<>#&!%:;@~\\'\\\"\\`";
const WHITE_SPACE_CHARACTER =
"\\t\\v\\f\\uFEFF \\u00A0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000";
const LINE_TERMINATOR_CHARACTER = "\\n\\r\\u2028\\u2029";
const MATCH_MALFORMED_LEADING_SURROGATE =
"[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])";
const MATCH_MALFORMED_TRAILING_SURROGATE =
"(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]";
// MIT License 2024 Webstrand
import tseslint from "typescript-eslint";
import {RuleListener, RuleModule} from "@typescript-eslint/utils/ts-eslint";
export default tseslint.config(
tseslint.configs.strictTypeCheckedOnly, // no idea, the files don't match if this is missing
{
plugins: {
webstrand: {
rules: {
@webstrand
webstrand / tsc-one-file.bash
Created April 2, 2025 18:50
Compile one file in a project using `tsc`
#!/usr/bin/env -S unshare -Umr -- bash
set -euo pipefail;
tmpfile=$(mktemp);
cpp -P -E tsconfig.json | FILE=$1 jq '.files = [env.FILE] | del(.include)' > $tmpfile;
mount --bind $tmpfile tsconfig.json;
rm $tmpfile;
exec pnpm exec tsc -p tsconfig.json
@webstrand
webstrand / reactive-remap.mts
Last active March 29, 2025 22:54
Remapping utilities for reactive signals
import {type JSX, createMemo, createRoot, onCleanup} from "solid-js";
import {Public, type RemapOperations, enshroudOperations, remapArray} from "./remap.mts";
export interface RemapOperationsConcrete<key, value, reference> extends RemapOperations<key, value, reference> {
create: (ref: reference, key: key) => value;
intoKey: (ref: reference) => key;
}
export function RemapKeyed<key, val, ref>(props: {
refs: ArrayLike<ref>;
@webstrand
webstrand / deepsixr.rs
Last active March 17, 2025 02:12
Event listener for i3wm, dynamically creates numeric workspaces
#![feature(error_generic_member_access)]
use i3_ipc::{event, reply, I3Stream};
use itertools::Itertools;
use nix::sys::memfd::memfd_create;
use nix::sys::memfd::MemFdCreateFlag;
use std::backtrace::Backtrace;
use std::cmp;
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;