Skip to content

Instantly share code, notes, and snippets.

export type Effect = { type: string; value?: any }
export type State<T> = T
const get: Effect = { type: 'GET' }
const put = (value: any): Effect => ({ type: 'PUT', value })
const runState = <T>(
genFn: () => Generator<Effect, void, State<T>>,
initialState: State<T>,
) => {
@renanpvaz
renanpvaz / intransigent-blocker.js
Last active April 26, 2020 21:37
React component that prevents a child element from having it's styles altered
import React, { useState, useEffect } from 'react'
const findByAttr = (attr, mutations) => mutations.find(m => m.attributeName === attr)
const isBlockerTarget = mutation => 'intransigentBlockerTarget' in mutation.target.dataset
const IntransigentBlocker = props => {
const [id] = useState(+new Date)
useEffect(() => {
const observer = new MutationObserver(mutations => {
const { random, floor } = Math
const CatSack = Object.assign(
(...cats) => ({ pull: () => cats[floor(random() * cats.length)] }),
{ of: (...args) => CatSack(...args) }
)
const sack = CatSack.of('Oof', null, {})
sack.pull()
@renanpvaz
renanpvaz / async-timeout.js
Last active February 1, 2018 15:52
Promises with timeout
const withTimeout = (time, f) => (...args) => (
Promise.race([
new Promise((_, reject) => setTimeout(reject, time, 'TIMEOUT')),
f(...args)
])
)
@renanpvaz
renanpvaz / contract.js
Created January 31, 2018 13:06
experimental higher-order contract function
signatureToTypes = sig => sig
.split(' -> ')
.map(type => ({
Number: {
ctor: Number,
type: 'number',
},
Object: {
ctor: Object,
type: 'object',
const createSlidingPuzzle = (target, size = 50) => {
const shuffle = arr => arr.slice().sort(() => Math.random() > .5)
const shuffleAll = table => shuffle(table).map(shuffle)
const render = table => (
table.forEach(
(column, y) => column
.map((value, x) => !!value ? createTile(value, x, y) : document.createElement('div'))
.forEach(tile => target.appendChild(tile))
)
// phone only
@media (max-width: 599px) {
}
// tablet portrait up
@media (min-width: 600px) {
}
// tablet landscape up
@media (min-width: 900px) {
@renanpvaz
renanpvaz / observer.js
Last active September 4, 2017 19:51
Makes DOM dispatch 'render' and 'destroy' events for added/removed elements
const createObserver = (
({ curry, pipe, evolve, merge, forEach, filter }) => {
const filterNodes = curry(
(filter, container) => {
let currentNode
const nodes = []
const walker = document.createTreeWalker(container, filter)
while (currentNode = walker.nextNode()) nodes.push(currentNode)
@renanpvaz
renanpvaz / decouple-methods.js
Created September 4, 2017 19:40
helper to extract functions from prototypes
const decoupleMethods = (Type, ...names) => names.map(
name => ({ [name]: (a, b) => Type.prototype[name].call(b, a) }) // could be curried
).reduce((acc, next) => Object.assign({}, acc, next))
const { map, filter, forEach, find } = decoupleMethods(
Array,
'map',
'filter',
'forEach',
'find'
@renanpvaz
renanpvaz / f.js
Last active April 14, 2019 23:01
JavaScript function pattern matching inspired by Haskell's
f = (...fns) => {
const [main, ...variations] = fns.reverse()
const ƒunction = (...appliedArgs) => {
const variation = variations.find(
args => appliedArgs.every(
(appliedArg, i) => args.slice().splice(0, args.length - 1)[i] === appliedArg
)
)