Skip to content

Instantly share code, notes, and snippets.

@reaktivo
Created August 29, 2018 15:21
Show Gist options
  • Save reaktivo/3b96533947ea7c54c07e8b30b85b0a4f to your computer and use it in GitHub Desktop.
Save reaktivo/3b96533947ea7c54c07e8b30b85b0a4f to your computer and use it in GitHub Desktop.
State Ideas
const state = {
// user: {
// isLoggedIn: false,
// email: "",
// password: "",
// details: {
// firstName: "",
// lastName: ""
// }
// },
todos: [
{
id: 0,
text: "Pierce",
done: false
},
{
id: 1,
text: "Finn",
done: false
}
]
};
// const api = {
// async post() {
// return Promise.resolve({
// data: {
// success: true
// }
// });
// }
// };
const actions = {
// userLogin: ({ get, set }) => async payload => {
// const { isLoggedIn, details } = get(state => state.user);
// if (!isLoggedIn) {
// return details;
// }
// try {
// const details = await api.post("/login", {
// email: payload.email,
// password: payload.password
// });
// set({ user: details });
// return details;
// } catch (e) {
// return undefined;
// }
// },
addTodo: ({ get, set }) => text => {
const todos = get(state => state.todos);
set(state => ({
todos: [
...todos,
{
id: todos[todos.length - 1].id,
text,
done: false
}
]
}));
}
};
function attempt(fn) {
try {
return fn();
} catch (e) {
return undefined;
}
}
const identity = value => value;
function create(state, actions) {
let subscribers = [];
const notify = () => {
subscribers = subscribers.map(subscriber => {
const result = get(subscriber.selector);
if (result !== subscriber.result) {
subscriber.callback(result);
return {
callback,
result,
selector,
}
}
return subscriber;
});
}
const get = (selector = identity, defaults) =>
attempt(() => selector(state)) || defaults;
const set = (updater) => {
attempt(() => {
state = updater(state);
notify();
});
};
const getter = (...args) => () => get(...args);
const setter = (...args) => () => set(...args);
const subscribe = (selector = identity, callback) => {
const result = get(selector);
const subscriber = { selector, callback, result }
callback(result);
subscribers = subscribers.concat(subscriber);
// add unsubscribe here
return () => {
const indexOfSubscriber = subscribers.indexOf(subscriber);
if (indexOfSubscriber > -1) {
subscribers = [
...subscribers.slice(0, indexOfSubscriber),
...subscribers.slice(indexOfSubscriber + 1)
]
}
}
}
const mappedActions = Object.entries(actions).reduce(
(acc, [key, action]) => {
acc[key] = async (...args) => action(mappedActions)(...args);
return acc;
},
{ get, getter, set, setter, subscribe }
);
return mappedActions
}
const store = create(state, actions);
(async () => {
store.subscribe(state => state.todos, todos => {
console.log(todos);
});
await store.addTodo("some todo");
await store.addTodo("another todo");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment