This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* takes a list of async functions and executes them one at a time | |
*/ | |
async function serial( | |
fnList: Array<() => Promise<void>>, | |
nextIndex?: number = 0, | |
) { | |
let current = fnList[nextIndex]; | |
if (!current) return; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A persistent, async store based on Cache API | |
* NOTE this is experimental | |
**/ | |
type Options = { | |
name: string | |
version: number | |
userId: string | |
type: "json" | "text" | "blob" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getMonths(locale: string, format: 'long' | 'short' = 'long') { | |
const monthNames = []; | |
const currentYear = new Date().getFullYear(); | |
for (let i = 0; i < 12; i++) { | |
monthNames.push( | |
new Date(currentYear, i, 1).toLocaleDateString(locale, { | |
month: format | |
})); | |
} | |
return monthNames; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eu -o pipefail | |
count=$(find . -depth 1 -name "*.HEIC" | wc -l | sed 's/[[:space:]]*//') | |
echo "converting $count files .HEIC files to .jpg" | |
magick mogrify -monitor -format jpg *.HEIC | |
echo "Remove .HEIC files? [y/n]" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function useCallIfMounted() { | |
let isMounted = React.useRef(false); | |
React.useEffect(() => { | |
isMounted.current = true; | |
return () => isMounted.current = false; | |
}, [isMounted]); | |
return React.useCallback((fn) => isMounted.current && fn(), [isMounted]); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// NOTE can't use lodash.memoize because we need 2 caches and v2 doesn't support replacing the cache implementation | |
// TS type note: the below type is inspired by Lodash v4 types | |
function memoize<T extends (...args: any) => any>(fn: T, resolver?: (...args: any[]) => any) { | |
let objectCache = new WeakMap<any, any>(); // WeakMap can only store objects as keys and allows the objects to get GC'ed out | |
let primitiveCache = new Map<any, any>(); // Map can store anything as a key but no auto GC | |
return function(...args: Parameters<T>): ReturnType<T> { | |
// just in case things got out of hand, dump the cache if too many entries | |
if (primitiveCache.size > 10000) { | |
primitiveCache.clear(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
target="${1:-/Applications}" | |
check() { | |
stat "$1/Contents/Frameworks/Electron Framework.framework" &> /dev/null | |
if [[ $? = 0 ]]; then | |
echo "$1 uses Electron" | |
fi | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ObservableMap<K, V> extends Map<K, V> { | |
readonly events = new EventEmitter(); | |
set(key: K, value: V) { | |
let previousValue = this.get(key); | |
super.set(key, value); | |
this.events.emit("update", { | |
key, | |
action: "set", | |
previousValue, | |
currentValue: this.get(key) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventEmitter { | |
constructor() { | |
this.target = new EventTarget(); | |
} | |
on(eventName, listener) { | |
return this.target.addEventListener(eventName, listener); | |
} | |
once(eventName, listener) { | |
return this.target.addEventListener(eventName, listener, { once: true }); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Who needs eventemitter3, mitt, or some other library when you can use native DOM APIs? 😁 | |
let eventEmitter = new EventTarget(); | |
eventEmitter.addEventListener('test', console.log); // CustomEvent { type: 'test', detail: 123, ... } | |
eventEmitter.dispatchEvent(new CustomEvent('test', { detail: 123 })); |
NewerOlder