Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Last active March 19, 2018 07:17
Show Gist options
  • Select an option

  • Save kana-sama/1a96fa932cd6c5e9687a3a1ba2bf4a0c to your computer and use it in GitHub Desktop.

Select an option

Save kana-sama/1a96fa932cd6c5e9687a3a1ba2bf4a0c to your computer and use it in GitHub Desktop.
const locked = createState();
const opened = createState();
const push = createAction();
const coin = createAction();
const hack = createAction();
const turnstile = createMachine(locked, {
[locked]: {
[coin]: () => opened(0),
[hack]: (_, coins) => opened(coins)
},
[opened]: {
[coin]: coins => opened(coins + 1),
[push]: coins => (coins === 0 ? locked : opened(coins - 1))
}
});
const turnstileInstance = turnstile.create();
turnstileInstance.subscribe({
[locked]() {
console.log(`=> locked`);
},
[opened](n) {
console.log(`=> opened(${n})`);
}
}); // => locked
turnstileInstance.dispatch(coin); // ​​​​​ => opened(0)​​​​​
turnstileInstance.dispatch(coin); // ​​​​ ​=> opened(1)​​​​​
turnstileInstance.dispatch(push); // ​ ​​​​=> opened(0)​​​​​
turnstileInstance.dispatch(push); // => locked
turnstileInstance.dispatch(hack(5)); // => opened(5)
const createAction = () => {
const id = Symbol();
const action = payload => ({
payload,
id,
[Symbol.toPrimitive]: () => id
});
return Object.assign(action, {
id,
[Symbol.toPrimitive]: () => id
});
};
const createState = () => {
const id = Symbol();
const state = value => ({
value,
id,
[Symbol.toPrimitive]: () => id
});
return Object.assign(state, {
id,
[Symbol.toPrimitive]: () => id
});
};
const createMachine = (initialState, scheme) => {
return {
create() {
const subscribers = [];
let state = initialState;
function getState() {
return state;
}
function dispatch(action) {
if (action in scheme[state]) {
state = scheme[state][action](state.value, action.payload);
for (const subscriber of subscribers) {
subscriber[state](state.value);
}
}
}
function subscribe(subscriber) {
subscribers.push(subscriber);
subscriber[state](state.value);
}
return {
getState,
dispatch,
subscribe
};
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment