Skip to content

Instantly share code, notes, and snippets.

View DarrenSem's full-sized avatar

Darren Semotiuk DarrenSem

View GitHub Profile
@DarrenSem
DarrenSem / test.js
Last active June 27, 2022 17:54
Test Suite in less than 25 lines
"use strict"; let undef = {}.z, str = (obj, def = "") => String(obj == undef ? def : obj), stringify = value => JSON.stringify(value, null, "\t")
, assert = (condition, msgOrActualExpectedArray, msgPrefix, shouldStringify, z) => {
if(condition)return true;
const pair = Array.isArray(msgOrActualExpectedArray) ? msgOrActualExpectedArray : undef
, [actualValue, expectedValue] = pair || []
, actual = shouldStringify ? stringify(actualValue) : actualValue
, expected = shouldStringify ? stringify(expectedValue) : expectedValue;
throw { name: "Assertion" , message: message = [
str(msgPrefix)
, pair ? `Actual=[${actual}], Expected=[${expected}]` : str(msgOrActualExpectedArray)
@DarrenSem
DarrenSem / ordinal.js
Created July 10, 2022 21:41
ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
// ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
let ordinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
// ^ Final Answer. (below = the story of how I got there...)
"use strict";// ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
let ordinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
@DarrenSem
DarrenSem / replaced(original, pattern1, replacement1, patternX, replacementX).js
Created August 8, 2022 19:59
replaced(original, pattern1, replacement1, patternX, replacementX).js - enables MULTIPLE PAIRS in a single call - very flexible syntax e.g. replaced(original, ["pattern(number)1", "replacement$1"], /p2/, "r2", "p3", "r3")
// replaced(original, pattern1, replacement1, patternX, replacementX).js - enables MULTIPLE PAIRS in a single call - very flexible syntax e.g. replaced(original, ["pattern(number)1", "replacement$1"], /p2/, "r2", "p3", "r3")
var replaced = (p, ...pairsFindReplacewith) => pairsFindReplacewith.flat(Infinity).reduce(
(curr, string, i) =>
i % 2 ? curr.replace(p, string)
: (p = RegExp(string, "g"), curr)
, String(p != null ? p : "") // AKA String(p ?? "") // p != null ? String(p) : ""
)
@DarrenSem
DarrenSem / imageFromDataUrl.js
Created October 29, 2022 18:48
imageFromDataUrl.js (src, callback) and blobFromDataUrl.js (dataUrl)
/////// imageFromDataUrl.js (src, callback) and blobFromDataUrl.js (dataUrl)
// const imageFromDataUrl=(a,b)=>Object.assign(document.createElement("img"),{src:a,onload:b||function(a,b){console.log([`Image loaded (${(b=a.target).width} x ${b.height})\n${new Date}`,this])}});
const imageFromDataUrl = (src, callback) => (
Object.assign(document.createElement("img"), { // or Object.assign(new Image(), ...
src
, onload: callback || function (event, z) {
console.log([`Image loaded (${(z = event.target).width} x ${z.height})\n${new Date}`, this]);
}
})
@DarrenSem
DarrenSem / blobFromDataUrl.js
Created October 29, 2022 18:49
blobFromDataUrl.js and binaryFromDataUrl_RESEARCH (multiple ways including fetch and Uint8Array.from)
/////// binaryFromDataUrl_RESEARCH (multiple ways including fetch and Uint8Array.from).js
// const blobFromDataUrl=(d,z)=>(z=d.match(/^data:(.*?)(?:;base64)?,(.*)/),new Blob([Uint8Array.from(atob(z[2]),a=>a.charCodeAt(0))],{type:z[1]||"octet-stream"}));
// async function binaryFromDataUrl_RESEARCH(src) { // blobOrArrayBufferOrTypedArray = await binaryFromDataUrl_RESEARCH(dataUrl);
const binaryFromDataUrl_RESEARCH = async src => { // blobOrArrayBufferOrTypedArray = await binaryFromDataUrl_RESEARCH(dataUrl);
// src = "data:[<media type>][;base64],<data>" via https://en.wikipedia.org/wiki/Data_URI_scheme#Syntax
// const base64String = src.slice(src.indexOf(",") + 1); // const base64String = src.split(",", 2)[1]
@DarrenSem
DarrenSem / globalThis-tests.js
Created October 30, 2022 23:14
globalThis-tests.js -- everything you ever wondered about globalThis (and possible polyfills) but never thought to ask
// globalThis-tests.js -- everything you ever wondered about globalThis (and possible polyfills) but never thought to ask
// console.clear();
console.log("\nglobalThis-tests.JS\t", new Date());
/////// no pre-setup (typical one-time kind of usage)
// (function (glo) { glo._var_$ = 7; })(typeof globalThis !== "undefined" ? globalThis : typeof global !== "undefined" ? global : this || {}); // .mjs needed additional || {} ... otherwise imo this is a #GoodEnough compromise (and much more clear!) compared to O_O https://mathiasbynens.be/notes/globalthis
// console.log("\n? (preferred way) globalThis._var_$ set by calling IIFE, confirm it was set to 7:\t", globalThis._var_$, "\n");
@DarrenSem
DarrenSem / bufferToHexString.js
Last active October 31, 2022 13:52
bufferToHexString.js (and stringsToBuffer and stringFromCharCodeArray)
// bufferToHexString and stringsToBuffer and stringFromCharCodeArray.js
const bufferToHexString = (arraybuffer, delim = "\t", z = "0123456789abcdef") => [...new Uint8Array(arraybuffer)].map(v => z[v >> 4] + z[v & 15]).join(delim);
const bufferToHex_clearest = (arraybuffer, delim = "\t") => [...new Uint8Array(arraybuffer)].map(v => v.toString(16).padStart(2, "0")).join(delim); // .toString(16).padStart = more clear even if slower than using pre-computed HEX[0..255] https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex/55200387#55200387
const bufferToHex_reduce_instead_of_map = arraybuffer => [...new Uint8Array(arraybuffer)].reduce((acc, v) => acc + v.toString(16).padStart(2, "0"), ""); // reduce instead of map because "map is reimplemented for typed arrays to return a typed array for each element, instead of a Uint8" // https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex/70790307#70790307
const HEX = new Array(0xff); for (let i = 0; i <= 0xff; i++)HEX[i] = i.toSt
@DarrenSem
DarrenSem / upload.js
Created October 31, 2022 18:01
upload.js: LOAD data FROM files (aka 'import/upload') including handling drag-and-drop
/////// upload.js: LOAD data FROM files (aka 'import/upload')...
// const buildFileSelector=(a,m)=>{const c=null==a?"":a+"";return Object.assign(document.createElement("input"),{type:"file"},m&&{multiple:m},c.trim().length&&{accept:c})};
// const resetFileSelector=e=>e&&(e.value=null,e);
// const getFileSelector=(e,c,a,m,r)=>resetFileSelector(e)&&e.readAs===r?e:Object.assign(e||buildFileSelector(a,m),{onchange:c,readAs:r});
// SEE BELOW: handleUploadOrDropExample = event => {
// Warning: "File chooser dialog can only be shown with a user activation." (just like clipboard functionality)
// const buildFileSelector=(a,m)=>{const c=null==a?"":a+"";return Object.assign(document.createElement("input"),{type:"file"},m&&{multiple:m},c.trim().length&&{accept:c})};
@DarrenSem
DarrenSem / dtString.js
Created November 6, 2022 20:02
dtString.js (dateArg, includeTime, defaultDate, defaultReturnValue) '1-2-2022 1:00' returns '02Jan2022 100am' or '02Jan2022'
// dtString.js (dateArg, includeTime, defaultDate, defaultReturnValue) '1-2-2022 1:00' returns '02Jan2022 100am' or '02Jan2022'
const assert=(...a)=>!a.reduce((b,c,d,e,f)=>(f=("function"==typeof c?!c():!c)&&[2>a.length?c:`<arg #${d+1}> ${a.map((a,b)=>`#${b+1} = [ ${a} ]`).join(" , ")}`],f&&console.assert(0,...b[b.push(f)-1]),b),a.length?[]:[a]).length;
const assertMessage = (test, ...messageAndSubstitutions) => assert(test) || console.error(...messageAndSubstitutions) || false;
console.clear();
// 183 chars: const dtString=(a,b,c,e,f=new Date(a),[,,,,g,h,,i]=(f=+f?f:new Date(c)).toLocaleString().toLowerCase().split(/\W/),[,j,k,d]=f.toString().split(" "))=>isNaN(f)?e:`${k}${j}${d}${b?` ${g}${h}${i}`:""}`
const dtString = (dateArg, includeTime, defaultDate, defaultReturnValue, z = new Date(dateArg), [, , , , h, n, , ampm] = (z = +z ? z : new Date(defaultDate)).toLocaleString().toLowerCase().split(/\W/), [, m, d, y] = z.toString().split(" ")) => isNaN(z) ? defaultReturnValue : `${d}${m}${y}${includeTime ? `
@DarrenSem
DarrenSem / assert.js
Last active November 13, 2022 16:34
assert.js - truthy test function in less than 240 characters: assert(testVal1, testVal2, () => "testFunction3", ...argN) plus improvement on normal console.assert: assertMessage(test, ...messageAndSubstitutions)
// assert.js - truthy test function in less than 240 characters: assert(testVal1, testVal2, () => "testFunction3", ...argN)
// plus improvement on normal console.assert: assertMessage(test, ...messageAndSubstitutions)
// https://gist.github.com/DarrenSem (02Nov2022 141pm)
// plus (94 characters) assert_SIMPLEST_no_messages(testVal1, testVal2, () => "testFunction3")
// OR (138 characters) assert_SIMPLEST_with_messages_via_optional_array(testVal1, [testVal2, "msg2a", "msg2b"], [() => "testFunction3", "msg3"])
// 138 char let assert=(...t)=>!!t.reduce((p,f,i,a,m=Array.isArray(f)?f:[f])=>("function"==typeof m[0]?m[0]():m[0])?p:console.assert(0,...m),t.length)
let assert_SIMPLEST_with_messages_via_optional_array = (...tests) => !!tests.reduce(