Skip to content

Instantly share code, notes, and snippets.

@kobzarvs
Created September 14, 2023 02:13
Show Gist options
  • Save kobzarvs/7fac78e2446eee5e715594e69f361372 to your computer and use it in GitHub Desktop.
Save kobzarvs/7fac78e2446eee5e715594e69f361372 to your computer and use it in GitHub Desktop.
import { createStore, createEvent, is, fork, allSettled } from 'effector';
import { produce } from 'immer';
function createCollection(store, events) {
const collection = createStore({});
const setStoreValue = createEvent();
store.on(setStoreValue, (state, value) => value);
let length = 0;
let keys = [];
collection.watch((obj) => {
keys = Object.keys(obj);
length = Object.keys(obj).length;
});
return {
store: collection,
get length() {
return length;
},
get keys() {
return keys;
},
add(key, value) {
const scope = fork();
allSettled(setStoreValue, { scope, params: value });
const item = {
key,
scope,
get value() {
return scope.getState(store);
},
...Object.keys(events).reduce((acc, name) => {
acc[name] = Object.assign(function (params) {
allSettled(events[name], { scope, params });
}, events[name]);
return acc;
}, {}),
};
collection.setState({
...collection.getState(),
[key]: item,
});
return item;
},
};
}
const setUser = createEvent();
const addRole = createEvent();
const removeRole = createEvent();
const $user = createStore({
name: 'guest',
age: -1,
roles: { admin: false, user: false, guest: true },
});
$user
.on(setUser, (user, info) => ({ ...user, ...info }))
.on(
addRole,
produce((user, role) => {
if (['admin', 'user'].includes(role)) {
user.roles.guest = false;
user.roles[role] = true;
} else {
user.roles.guest = true;
user.roles.user = false;
user.roles.admin = false;
}
})
)
.reset(removeRole);
$user.watch((user) => console.log('user:', user.name, user.age, user.roles));
export const $users = createCollection($user, { setUser, addRole, removeRole });
const user1 = $users.add(1, {
name: 'guest',
age: -1,
roles: { admin: false, user: false, guest: true },
});
const user2 = $users.add(2, {
name: 'User 1',
age: 18,
roles: { admin: false, user: true, guest: false },
});
user1.addRole('admin');
user2.addRole('admin');
user1.removeRole();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment