Skip to content

Instantly share code, notes, and snippets.

@inodaf
Last active March 6, 2018 22:15
Show Gist options
  • Save inodaf/98569245fddaf8d1689d87418fc1b4de to your computer and use it in GitHub Desktop.
Save inodaf/98569245fddaf8d1689d87418fc1b4de to your computer and use it in GitHub Desktop.
Simple way to define your functional modules. Just for study purposes.
(function simpleFp() {
const Utils = {
getFunctionArity(fn) {
return fn.length
},
getFunctionModule(fnName, fnArity) {
const fnPath = fnName.split('.')
const isOuter = fnPath.length > 1
if (isOuter) {
const module = fnPath[0]
const name = Utils.getFunctionName(fnPath[1], fnArity)
return { isOuter, module, name }
} else {
const name = Utils.getFunctionName(fnPath[0], fnArity)
return { name }
}
},
getFunctionName(name, arity) {
return `${name}/${arity}`
},
setRootStore() {
window.__module_store__ = {}
},
getRootStore() {
return window.__module_store__
}
}
Utils.setRootStore()
window.defmodule = (moduleName, module) => {
const methods = {
def(name, fn) {
const rootStore = Utils.getRootStore()
const fnArity = Utils.getFunctionArity(fn)
const fnName = Utils.getFunctionName(name, fnArity)
return rootStore[moduleName] = {
...rootStore[moduleName],
[fnName]: fn
}
},
run(nameExp, ...args) {
const fnArity = Utils.getFunctionArity(args)
const nextCall = Utils.getFunctionModule(nameExp, fnArity)
const rootStore = Utils.getRootStore()
if (nextCall.isOuter) {
return rootStore[nextCall.module][nextCall.name].apply(null, args)
} else {
return rootStore[moduleName][nextCall.name].apply(null, args)
}
},
callback(name, fn) {
const rootStore = Utils.getRootStore()
rootStore[moduleName].callbacks[name] = fn
},
init() {
const rootStore = Utils.getRootStore()
rootStore[moduleName] = { callbacks: null }
rootStore[moduleName].callbacks = {
start: function () { }
}
return window.setTimeout(() => rootStore[moduleName].callbacks.start(), 1)
}
}
methods.init()
return module({
def: methods.def,
run: methods.run,
callback: methods.callback
})
}
}())
@inodaf
Copy link
Author

inodaf commented Mar 6, 2018

Usage:

defmodule('App', ({ def, run, callback }) => {
  def('write_dom', (joke) => {
    document.body.innerHTML = joke
  })

  callback('start', async () => {
    const randomJoke = await run('ChuckNorris.get_joke').then(r => r.json())
    const travelJoke = await run('ChuckNorris.get_joke', 'travel').then(r => r.json())
    
    return run('write_dom', `
      Random: ${randomJoke.value}
      Travel: ${travelJoke.value}
    `)
  })
})

defmodule('ChuckNorris', ({ def }) => {
  const endpoint = 'https://api.chucknorris.io/jokes/random'

  def('get_joke', () => {
    return fetch(endpoint)
  })

  def('get_joke', (category) => {
    return fetch(`${endpoint}?category=${category}`)
  })
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment