Skip to content

Instantly share code, notes, and snippets.

@klarstrup
Created June 26, 2018 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klarstrup/7483bb9bfbd5d4a4c6160d0ab6f77f9e to your computer and use it in GitHub Desktop.
Save klarstrup/7483bb9bfbd5d4a4c6160d0ab6f77f9e to your computer and use it in GitHub Desktop.
es6 meiosis
/*global ReactDOM, flyd*/
// -- Utility code
const nestUpdate = (update, prop) => func =>
update(model => ({ ...model, [prop]: func(model[prop]) }));
const nest = (create, update, prop) => {
const component = create(nestUpdate(update, prop));
const result = { ...component };
if (component.model) {
result.model = () => ({
[prop]: component.model()
});
}
if (component.view) {
result.view = model => component.view(model[prop]);
}
return result;
};
// -- Application code
const convert = (value, to) =>
Math.round(to === "C" ? ((value - 32) / 9) * 5 : (value * 9) / 5 + 32);
const createTemperature = (label, init) => update => {
const increase = amount => _event =>
update(model => ({ ...model, value: model.value + amount }));
const changeUnits = _event =>
update(model => {
const newUnits = model.units === "C" ? "F" : "C";
return {
...model,
value: convert(model.value, newUnits),
units: newUnits
};
});
return {
model: () => Object.assign({ value: 22, units: "C" }, init),
view: model => (
<div className="temperature">
<span>
{label} Temperature: {model.value}&deg;{model.units}
</span>
<div>
<button onClick={increase(1)}>Increase</button>
<button onClick={increase(-1)}>Decrease</button>
</div>
<div>
<button onClick={changeUnits}>Change Units</button>
</div>
</div>
)
};
};
const createTemperaturePair = update => {
const air = nest(createTemperature("Air"), update, "air");
const water = nest(
createTemperature("Water", { value: 84, units: "F" }),
update,
"water"
);
return {
model: () => Object.assign(air.model(), water.model()),
view: model => (
<div>
{air.view(model)}
{water.view(model)}
</div>
)
};
};
const createApp = update => nest(createTemperaturePair, update, "temperatures");
// -- Meiosis pattern setup code
const update = flyd.stream();
const app = createApp(update);
const models = flyd.scan((model, func) => func(model), app.model(), update);
const element = document.getElementById("app");
models.map(model => ReactDOM.render(app.view(model), element));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment