Last active
May 28, 2018 03:06
-
-
Save artalar/7184057ddc9209c5caf094054e125489 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createRootPath, immutablePreset } from 'pathon'; | |
const createLogger = id => (...args) => console.log(`ID: ${id}`, ...args); | |
const pathSome = createRootPath( | |
// initial state | |
{ list: [{ id: 0, value: Math.random() }] }, | |
// default setters and getters (for `path` to) | |
immutablePreset | |
); | |
const pathSomeList = pathSome.path('list'); | |
// special method for track only structure of collection | |
// accept new `get` handler by first argument | |
// trigger only on `pathSomeList.set()` | |
// (will not trigger for `pathSomeList.path(key).set()`) | |
const pathSomeListIds = pathSomeList.shape(state => state.map(({ id }) => id)); | |
// special method for track and memorize computed data | |
// trigger on `pathSomeList.set()` and `pathSomeList.path(key).set()` | |
const pathSomeListSum = pathSomeList.map( | |
state => state.reduce((acc, { value }) => acc + value), // computed | |
(prevCalc, newCalc) => prevCalc === newCalc // comparator | |
); | |
// it effective to watch list and every item separately | |
const pathSomeListItem0 = pathSomeList.path('0'); | |
pathSome.watch(createLogger('pathSome')); | |
pathSomeList.watch(createLogger('pathSomeList')); | |
pathSomeListIds.watch(createLogger('pathSomeListIds')); | |
pathSomeListSum.watch(createLogger('pathSomeListSum')); | |
pathSomeListItem0.watch(createLogger('pathSomeListItem0')); | |
// update store === dynamic expansion | |
// after this you can `pathSome.path('newField').watch(callback)` | |
pathSome.set({ newField: true }); | |
// "ID: pathSome ...." | |
pathSomeListItem0.set({ value: Math.random() }); | |
// "ID: pathSome ...." | |
// "ID: pathSomeList ...." | |
// "ID: pathSomeListSum ...." | |
// "ID: pathSomeListItem0 ...." | |
// watchers for `pathSomeListIds` will not trigger | |
// `.set` - is method for "extend" collection, but not modify old elements | |
// so it doesn't trigger watchers in nested elements | |
pathSomeList.set([...pathSomeList.get(), { id: 1, value: Math.random() }]); | |
// "ID: pathSome ...." | |
// "ID: pathSomeList ...." | |
// "ID: pathSomeListIds ...." | |
// "ID: pathSomeListSum ...." | |
// `.reset` - is method for rewrite collection | |
// so it will trigger watchers in nested elements | |
pathSomeList.reset(pathSomeList.get().map(element => ({ ...element, newValue: true }))); | |
// "ID: pathSome ...." | |
// "ID: pathSomeList ...." | |
// "ID: pathSomeListIds ...." | |
// "ID: pathSomeListSum ...." | |
// "ID: pathSomeListItem0 ...." // <-- your attention | |
// TODO: `compose` |
export const immutablePreset = {
set: (state, payload) => {
if (state instanceof Map) {
return new Map([...state, ...payload]);
} else if (state instanceof Set) {
return new Set([...state, ...payload]);
} else if (Array.isArray(state)) {
return payload; // ?
} else {
return { ...state, ...payload };
}
},
setPath: path => (state, payload) => {
if (state instanceof Map) {
return new Map(state).set(path, payload);
} else if (state instanceof Set) {
const newState = [...state];
newState[path] = payload;
return new Set(newState);
} else if (Array.isArray(state)) {
const newState = state.slice();
newState[path] = payload;
return newState;
} else {
return { ...state, [path]: payload };
}
},
get: state => state,
getPath: path => state => {
if (state instanceof Map) {
return state.get(path);
} else if (state instanceof Set) {
return [...state][path];
} else {
return state[path];
}
},
// optional memorization
comparator: (prevValue, newValue) => prevValue === newValue
};
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
(речь о новом state manager)
Преимущества библиотеки:
(
path
- это своеобразная автогенерирующаяся линза)createRootPath
и.path
принимает конфиг в котором определяются хендлеры по умолчанию для нового и всех вложенных [.path
] изменений и запросов ). Мутабельные структуры так же можно использовать - потому что отслеживание идет по подписке наpath
.path
,.shape
,.map
,.set
,.reset
,.watch
,.unwatch
.