Skip to content

Instantly share code, notes, and snippets.

@AriPerkkio
AriPerkkio / increase-specificity.scss
Last active January 18, 2024 13:09
SCSS Increase specificity mixin
@mixin increase-specificity($times: 1) {
$selector: "";
@for $index from 1 through $times {
$selector: #{$selector}#{&};
}
&#{$selector} {
@content;
}
@AriPerkkio
AriPerkkio / eslintrc.js
Created November 28, 2023 09:12
import/no-restricted-paths config
{
// Forbid importing modules directly from feature directories
// Allow importing from feature directory's entrypoint, e.g. src/site/index.ts
// https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-restricted-paths.md
"import/no-restricted-paths": [
"error",
{
zones: ["actions", "admin", "api", "site", "shared"]
.map((directory) => [
{
@AriPerkkio
AriPerkkio / script.sh
Created October 4, 2023 07:01
NPM publish snapshot
$ npm --no-git-tag-version version ${npm_package_version}-snapshot-${GIT_COMMIT}
$ npm publish --tag snapshot
@AriPerkkio
AriPerkkio / print-headings.js
Created August 2, 2023 06:30
Query HTML headings and print them
printHeadings();
function printHeadings() {
const headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
const formatted = Array.from(headings).map((element) => {
const tag = element.tagName;
const padding = parseInt(tag.charAt(1)) - 1;
const text = element.textContent?.replace(/\s{2,}/g, " ");
@AriPerkkio
AriPerkkio / invert-binary-tree.ts
Created April 20, 2023 09:15
Typescript type system binary tree inversion
type InvertTree<Tree extends Leaf> = Tree extends {
left: infer Left;
right: infer Right;
}
? Left extends Leaf
? Right extends Leaf
? { left: InvertTree<Right>; right: InvertTree<Left>; id: Tree["id"] }
: { left: undefined; right: InvertTree<Left>; id: Tree["id"] } // There is left but no right
: Right extends Leaf
? { left: InvertTree<Right>; right: undefined; id: Tree["id"] } // There is right but no left
@AriPerkkio
AriPerkkio / tic-tac-toe.ts
Created April 9, 2023 09:17
Typescript type system Tic-tac-toe game
/* Typings */
type TicTacToe<
MovesOrNextBoard extends Board | Turn[], // On initial round this will be a Turn[], on next rounds it will be a Board with some moves done
MovesOrMissing extends Turn[] = [], // On initial round this will be empty, on next rounds it will be the moves
PreviousMark extends ValidMark | undefined = undefined, // On initial round this will be missing, on next rounds it will be the mark of the last move
CurrentBoard extends Board = ResolveBoardFromArgs<MovesOrNextBoard>, // Parsed argument
Moves extends Turn[] = ResolveNextMovesFromArgs<MovesOrNextBoard, MovesOrMissing> // Parsed argument
> =
Moves extends [infer NextMove, ...infer NextMoves] ?
NextMove extends Turn ?
@AriPerkkio
AriPerkkio / . vm.mjs
Last active March 17, 2023 07:07
isolated vm + dynamic import
/*
$ node --watch --no-warnings --experimental-vm-modules --experimental-import-meta-resolve vm.mjs
*/
import vm from "node:vm";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { JSDOM } from "jsdom";
const server = {
async fetchModule(filename) {
@AriPerkkio
AriPerkkio / process.mjs
Last active March 8, 2023 09:43
Node inspector worker_threads + child_process
/*
* Run as `node process.mjs` and open Chrome DevTools or similar debugging tool
*/
import { fork } from "node:child_process";
import { fileURLToPath } from "node:url";
import inspector from "node:inspector";
const filename = fileURLToPath(import.meta.url);
if (!process.env.SOME_FLAG) {
@AriPerkkio
AriPerkkio / . index.mjs
Last active January 31, 2023 13:36
node:inspector + V8 Profiler.*PreciseCoverage
import { writeFileSync } from "node:fs";
import inspector from "node:inspector";
function firstMethod() {}
function secondMethod() {}
const session = new inspector.Session();
const collectedCoverage = [];
session.connect();
/*
rm -rf ./profiling
node --cpu-prof --cpu-prof-dir=./profiling index.mjs
*/
import { fileURLToPath } from "node:url";
import vm from "node:vm";
import { Worker, isMainThread } from "node:worker_threads";
globalThis.variableInGlobalScope = "Hello world";