Skip to content

Instantly share code, notes, and snippets.

@Phoenix35
Phoenix35 / cachedComparator.js
Last active August 29, 2023 10:45
Insertion sort in JS
/**
* Augments a sort function with a bi-map cache. Useful if the comparison is costly.
* @param {SortFunction} comparator
* @returns {SortFunction}
*/
export function cachedComparator (comparator) {
const cache = new Map();
return (a, b) => {
let result;
@Phoenix35
Phoenix35 / waitForNFulfilled.js
Last active January 14, 2023 16:57
Waits until a specified number of promises is resolved/fulfilled
export async function waitForNFulfilled (n, ...promises) {
const { length } = promises;
if (n >= length)
return Promise.all(promises);
const leftPromises = [];
const tallyPromises = [];
// Promises can resolve on the same tick, so we need to mark the fulfilled ones in parallel
@Phoenix35
Phoenix35 / naive-ndjson.js
Last active July 19, 2022 21:04
node.js NDJSON stream decoder
import { Transform } from "node:stream";
import { StringDecoder } from "node:string_decoder";
const EOL = "\n",
EOLLength = EOL.length;
export function createParser (encoding = "utf8") {
return new Transform({
decodeStrings: false,
readableObjectMode: true,
@Phoenix35
Phoenix35 / greatestCommonAncestor.js
Last active March 20, 2021 03:02
Finds the common ancestor of nodes in a document. Useful for event delegation for example.
/**
* greatestCommonAncestor - Finds the common ancestor of nodes in a document.
* The nodes MUST belong to the same document(fragment).
* @param {...Node} nodes - The nodes whose common ancestor is sought.
* @returns {Node} - The common ancestor to all nodes given as arguments.
*/
export function greatestCommonAncestor () {
return Array.prototype.reduce.call(
arguments, // partial application `?` when? :(
(ancestor, node) => {
@Phoenix35
Phoenix35 / getMatchingFiles.js
Last active April 14, 2020 20:26
An extension of getMatchingExt.js to support predicates in general
"use strict";
const fsP = require("fs").promises;
const path = require("path");
const { cwd, chdir } = process;
const MAX_ARRAY_LENGTH = 2**32 - 1;
/**
* getMatchingFiles - Lazily generates file paths in a given `targetDir` directory matching the predicate
"use strict";
const MAX_ARRAY_LENGTH = 2 ** 32 - 1;
/**
* Insertion sort FTW
* @param str {string}
* @param limit {number}
* @returns {number[]|undefined}
// In-place mutation
export function arrayBulkDelete (array, valueOrPredicate) {
const { length } = array,
predicate = typeof valueOrPredicate === "function"
? valueOrPredicate
: (x) => x === valueOrPredicate,
indicesToDelete = [];
let lastIndex = -2;
"use strict";
/**
* Generate numbers in the Fibonacci sequence in a given interval.
*
* @generator
* @function fibInInterval
* @param {bigint|number} min - The lower limit of the interval.
* @param {bigint|number} max - The upper limit of the interval.
* @yields {bigint} The next number in the Fibonacci sequence respecting the interval.
const nodeResetter = function () {
const knownNodes = new WeakMap;
return {
setupNode (originalNode) {
knownNodes.set(originalNode, originalNode.cloneNode(false));
},
resetNode (originalNode) {
originalNode.parentNode.replaceChild(
knownNodes.get(originalNode).cloneNode(false),
@Phoenix35
Phoenix35 / propertyMapper.mjs
Last active September 13, 2019 13:14
Quick thingy I made to copy while renaming certain props from an object to another
// PLEASE NOTE: this is LAZY! It will only yield properties that are part of `namesMap`
// not all properties of `source`
export function *transformPropertyNames (source, namesMap) {
for (
const [ entryKey, targetKey ] of typeof namesMap[Symbol.iterator] === "function"
? namesMap // iterable
: Object.entries(namesMap) // object-style
)
yield [ targetKey, source[entryKey] ];
}