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 wait(ms, opts = {}) { | |
return new Promise((resolve, reject) => { | |
let timerId = setTimeout(resolve, ms); | |
if (opts.signal) { | |
// implement aborting logic for our async operation | |
opts.signal.addEventListener('abort', event => { | |
clearTimeout(timerId); | |
reject(event); | |
}); | |
} |
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
// in preload scripts, we have access to node.js and electron APIs | |
// the remote web app will not have access, so this is safe | |
const { ipcRenderer: ipc, remote } = require('electron'); | |
init(); | |
function init() { | |
// Expose a bridging API to by setting an global on `window`. | |
// We'll add methods to it here first, and when the remote web app loads, | |
// it'll add some additional methods as well. |
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
const { app, BrowserWindow } = require('electron'); | |
const path = require('path'); | |
const Store = require('./store.js'); | |
let mainWindow; //do this so that the window object doesn't get GC'd | |
// First instantiate the class | |
const store = new Store({ | |
// We'll call our data file 'user-preferences' | |
configName: 'user-preferences', | |
defaults: { |
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 createOnlineEmitter() { | |
let cbs = []; //array of registered callbacks for the event | |
let unsub; //function for removing the main event listener | |
//this is the main event listener that gets registered with window.online/offline event | |
const mainListener = (isOnline) => { | |
//call all the subscribed callbacks | |
cbs.forEach(cb => cb(isOnline)); | |
}; |
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 objToParams(obj) { | |
const params = new URLSearchParams(); | |
for(let key in obj) { | |
if(Array.isArray(obj[key])) { | |
obj[key].forEach(item => params.append(key, item)); | |
} | |
else if(typeof obj[key] === 'object') { | |
continue; | |
} | |
else { |
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 })); |
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]); | |
} |