Skip to content

Instantly share code, notes, and snippets.

View shesek's full-sized avatar

Nadav Ivgi shesek

View GitHub Profile
setPrototype = Object.setPrototypeOf or (child, parent) -> child.__proto__ = parent
inherit = (parent, child) -> setPrototype child, parent; child.prototype=parent.prototype; child
IdentityMap = (realConstructor) ->
cache = {}
id = realConstructor::idAttribute
inherit realConstructor, (attributes, options) ->
create = -> new realConstructor attributes, options
if objectId = attributes?[id]
@shesek
shesek / concurrent.coffee
Created November 14, 2012 19:58
Limit concurrency of async functions
# Returns a function that invokes `fn`, with maximum concurrency of `max`
# Generalized version of https://gist.github.com/4071443
concurrent = (free, fn) ->
queue = []
r = (a..., cb) ->
# Queue the call if we have too many running
return queue.push [a..., cb] unless free
--free
fn a..., (resp...) ->
++free
@shesek
shesek / request-limit.coffee
Created November 14, 2012 10:34
node.js mikeal/request with concurrency limit
# I've been getting "socket hangup" errors when sending too many
# concurrent HTTP requests with mikeal/request library, so...
request_concurrent = (max) ->
queue = []
running = 0
r = (a..., cb) ->
# Queue the request if we have too many running
return queue.push [a..., cb] if running >= max
++running
@shesek
shesek / chunk.coffee
Created November 6, 2012 19:35
Chunk an array and pass each chunk to callback
# Chunk an array into multiple chunks with a given size, and pass
# each chunk to a callback. This is done that way, instead of creating
# an array of all the chunks, so that big arrays can be chunked without
# having the store all the chunks in memory.
chunk = (arr, size, fn) ->
i = 0
fn arr.slice i, i+=size while i < arr.length
return
@shesek
shesek / gist:3929926
Created October 22, 2012 06:01
Higher order functions for nodejs-style callbacks error handling

I've used promises for quite some time, but ended up going back to nodejs-style callbacks and creating a bunch of higher-order functions that makes handling that easier and reduce the boilerplate code. The two most useful ones, that really made it much easier, deal with error handling/bubbling: (CoffeeScript)

iferr = (errfn, succfn) -> (e, a...) -> if e? then errfn e else succfn a...
throwerr = iferr.bind null, (e) -> throw e


# To let an error bubble up, `iferr` decorates the success function and the error function, and decide which one should handle the response
# This replaces `if (err) return fn err` that you see all over the place
@shesek
shesek / non_empty.coffee
Created October 20, 2012 07:48
Throwing early errors for unexpected empty values
# A quick way to assert that you get a non-null-or-undefined value when you don't expect ONE, and throw early
# errors when it does happen, rather than letting that value go elsewhere.
# Just a simple function that returns the value when its non-null-or-undefined, or throws an error otherwise..
non_empty = (v) -> v ? (throw new Error 'null or undefined encountered where it shouldn\'t')
# (the extra parenthesis are there to make CoffeeScript compilation only execute an IIFE when we're throwing)
# Than, simply:
user_id = non_empty user.id
@shesek
shesek / trello-workable-bookmarklet.js
Last active October 8, 2015 22:58
Trello - view cards you can work on
javascript:(function(){var a,b;a=function(a){return function(){return!!~(this.alt||this.title).indexOf(a)}}($(".member-avatar").attr("title").match(/\(([\w\-]+)\)$/)[1]),b=function(){var b;return!(b=$(this).find(".member img,.member-initials")).length||b.filter(a).length},$("#board").addClass("filtering").find(".list-card").addClass("hide").filter(b).removeClass("hide")})()
@shesek
shesek / simultaneously.coffee
Last active October 7, 2015 11:07
Execute multiple connect middlewares simultaneously
# Allows to execute multiple connect middlewares simultaneously. This is useful when you have middlewares
# that run asynchronously and should run in parallel rather than in a sequence.
# The function below takes a list of middlewares (as separate arguments), and returns a new middleware that
# executes all the passed middlewares together when invoked, and calls `next()` when all of them finish.
simultaneously = (middlewares...) -> (req, res, next)->
left = middlewares.length
one = (err) -> return next err if err?; --left or do next
@shesek
shesek / Y.coffee
Last active December 2, 2016 18:46
Y combinator
# The common one, converted to CoffeeScript
y = (f) -> ((y)-> y y) (y) -> f (n) -> (y y) n
# My version
y = ((y)->y y) (y) -> (f) -> (n) -> (f (y y) f) n
fact = y (f) -> (n) -> if n is 0 then 1 else n * f n-1
# And a simpler way, requires a different `fact` that passes itself to itself
y = (f) -> (n) -> (f f) n
@shesek
shesek / dcoffee
Created April 24, 2012 21:15
Bash script for quickly debugging CoffeeScript line numbers
#!/bin/bash
[ -z $3 ] && AROUND=2 || AROUND=$3
coffee -cp $1 | nl -b a | perl -pe "\$_ = \"\033[1;29m\$_\033[0m\" if (\$. == $2)" | head -n $(($2+$AROUND)) | tail -n $(($AROUND * 2 + 1))
# Usage: dcoffee path/to/file.coffee <LINE NUMBER> [NUMBER OF LINES BEFORE/AFTER]
# A tiny bash script for finding a line in the compiled JavaScript with some context around it,
# useful to quickly check where errors in compiled JavaScript are coming from.
# https://github.com/jashkenas/coffee-script/issues/558 FTW