Skip to content

Instantly share code, notes, and snippets.

@jakubkulhan
Last active January 31, 2016 18:55
Show Gist options
  • Save jakubkulhan/ad54f0be6b66e1ac6b40 to your computer and use it in GitHub Desktop.
Save jakubkulhan/ad54f0be6b66e1ac6b40 to your computer and use it in GitHub Desktop.
// Stateful mixin is default implementation for components with state() method.
// It is intended to be used as decorator.
export function Stateful(klass) {
if (typeof klass === "function") {
Stateful.prototype.getOwnPropertyNames().forEach(function (methodName) {
Object.defineProperty(klass.prototype, methodName, {value: Stateful.prototype[methodName]});
});
return klass;
}
return Stateful;
}
export async function* state(state = {}, actions) {
// fetch() method should (re)load data
if (!state.ok && typeof this.fetch === "function") {
yield state = {...state, ok: null}
try {
yield state = {...state, ...await this.fetch(state)};
} catch (e) {
return {...state, ok: false, error: e};
}
}
// If component has no bound actions, just return state (possibly with fetch()'ed data).
if (actions) {
for (
var done, action;
{done, value: action} = await actions.next() && !done;
) {
if (typeof action === "function") {
handler = action;
} else if (typeof action.handler === "function") {
handler = action.handler;
} else if (typeof action.type === "string") {
var methodName = "on" + action.type.split("_").map((part) =>
part.substring(0, 1).toUpperCase() + part.substring(1).toLowerCase()
).join("");
handler = this[methodName];
}
if (handler) {
handler = handler.call(this, action, state);
if (typeof handler.next === "function") {
for (
var handlerDone, handlerState;
{done: handlerDone, value: handlerState} = await handler.next() && !handlerDone;
) {
yield state = {...state, ...handlerState};
}
} else if (typeof handler.then === "function") {
yield state = {...state, ...await handler};
} else {
yield state = {...state, ...handler};
}
handler = undefined;
}
}
}
return state;
}
Object.defineProperty(Stateful.prototype, "state", {value: state});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment