Skip to content

Instantly share code, notes, and snippets.

View barneycarroll's full-sized avatar
🛠️
Working on Mithril type stuff

Barney Carroll barneycarroll

🛠️
Working on Mithril type stuff
View GitHub Profile
@barneycarroll
barneycarroll / README.md
Last active April 24, 2018 02:38
Of many sequential promises, only the last is worthy of consequence

There are many scenarios where a particular interaction makes repeated calls to an asynchronous, and each subsequent call invalidates the previous. For example, typing in a field which can query an HTTP service for insights: if I type 'a', and wait long enough, a call should be sent to ask for pertinent suggestions; but if I'm still waiting on that response when I type 'b', then the results of the last call are impertinent. Only the last call's response should resolve.

Calling latest creates a 'promise debouncer' function. Either you pass in the async function there and then and call it without arguments, or you instantiate it empty and pass in the async function upon request. In either case, calling the function before its last promise has resolved will ensure that promise never resolves: only the last request will ever resolve.

@barneycarroll
barneycarroll / BornToDie.js
Created April 11, 2018 16:41
A component which redraws on post-creation & pre-removal, providing `{born, to, die,}` as flags to the supplied function
const BornToDie = v => {
let
born = true,
to = false,
die = false,
let query
let draw
const Historian = Object.assign(
Component => {
const histories = new WeakMap
return {
onbeforeupdate({}, old){
if(Component.onbeforeupdate && Component.onbeforeupdate.apply(this, arguments) === false)
return false
histories.set(old.state, old)
@barneycarroll
barneycarroll / broken.js
Last active March 10, 2018 02:50
Break a promise
const broken = (promise, state = {
pending: true,
settled: false,
resolved: false,
rejected: false,
value: undefined,
error: undefined,
}) => (
@barneycarroll
barneycarroll / README.md
Created March 2, 2018 10:26
When a nested expression is the desired return value

Written to avoid the noisome pattern of

input => {
  const reference = expression with input

  sideEffects(reference)

  return reference 
}
@barneycarroll
barneycarroll / mimix.js
Last active February 28, 2018 19:44
mimix
const {assign, keys} = Object
const scope = fn =>
function(){
return fn(x => x.apply(this, arguments))
}
const compose = (key, values) => (
key === 'view'
?
values.pop()
@barneycarroll
barneycarroll / mithril-view-attrs.md
Created February 23, 2018 15:32
Work in progress: proposal for view attributes as a core mechanism in Mithril

Precedent: render props (or, view attributes)

I've been toying the idea of 'view attributes' for a while, but over the past year they've taken off in the popular domain of React as 'render props'.

A component written to make use of view attributes is a 'view component' inasmuch as it doesn't have an opinion on downstream virtual DOM, but performs a useful function in the context of virtual DOM (whether that be transforming other attribute input, querying DOM or external references, providing state), which can be exposed via the view attribute provided to it.

Here's a sample of view components with associated demos.

The React community has already proved the far-reaching value of this concept to the point where the pattern is part of the official documentation, ahead of 'integrating with other libraries'. React Router

@barneycarroll
barneycarroll / NoopComponent.js
Created February 23, 2018 11:46
Blank view component
export const {
view: v => (
v.attrs.view
?
v.attrs.view.call(v.state, v)
:
v.children
)
}
@barneycarroll
barneycarroll / Blockm.js
Created February 22, 2018 21:23
A collection of view components for Mithril. A view component is one where the component provides no view of its own but instead accepts a view attribute which it then provides with data.
const callOBR = v =>
Promise.all(
['tag', 'attrs']
.map(x =>
v[x]
&& v[x].onbeforeremove
&& v[x].onbeforeremove.call(v.state, v)
)
)