@datorama/akita
Version:
A Reactive State Management Tailored-Made for JS Applications
117 lines • 4.22 kB
JavaScript
import { setSkipAction } from './actions';
import { isDefined } from './isDefined';
import { $$addStore, $$deleteStore, $$updateStore } from './dispatchers';
import { __stores__ } from './stores';
import { capitalize } from './capitalize';
import { isNotBrowser } from './root';
let subs = [];
export function akitaDevtools(ngZoneOrOptions, options = {}) {
if (isNotBrowser)
return;
if (!window.__REDUX_DEVTOOLS_EXTENSION__) {
return;
}
subs.length &&
subs.forEach((s) => {
if (s.unsubscribe) {
s.unsubscribe();
}
else {
s && s();
}
});
const isAngular = ngZoneOrOptions && ngZoneOrOptions['run'];
if (!isAngular) {
ngZoneOrOptions = ngZoneOrOptions || {};
ngZoneOrOptions.run = (cb) => cb();
options = ngZoneOrOptions;
}
const defaultOptions = { name: 'Akita', shallow: true, storesWhitelist: [] };
const merged = Object.assign({}, defaultOptions, options);
const storesWhitelist = merged.storesWhitelist;
const devTools = window.__REDUX_DEVTOOLS_EXTENSION__.connect(merged);
let appState = {};
const isAllowed = (storeName) => {
if (!storesWhitelist.length) {
return true;
}
return storesWhitelist.indexOf(storeName) > -1;
};
subs.push($$addStore.subscribe((storeName) => {
if (isAllowed(storeName) === false)
return;
appState = {
...appState,
[storeName]: __stores__[storeName]._value(),
};
devTools.send({ type: `[${capitalize(storeName)}] - @@INIT` }, appState);
}));
subs.push($$deleteStore.subscribe((storeName) => {
if (isAllowed(storeName) === false)
return;
delete appState[storeName];
devTools.send({ type: `[${storeName}] - Delete Store` }, appState);
}));
subs.push($$updateStore.subscribe(({ storeName, action }) => {
if (isAllowed(storeName) === false)
return;
const { type, entityIds, skip, ...rest } = action;
const payload = rest.payload;
if (skip) {
setSkipAction(false);
return;
}
const store = __stores__[storeName];
if (!store) {
return;
}
if (options.shallow === false && appState[storeName]) {
const isEqual = JSON.stringify(store._value()) === JSON.stringify(appState[storeName]);
if (isEqual)
return;
}
appState = {
...appState,
[storeName]: store._value(),
};
const normalize = capitalize(storeName);
let msg = isDefined(entityIds) ? `[${normalize}] - ${type} (ids: ${entityIds})` : `[${normalize}] - ${type}`;
if (options.logTrace) {
console.group(msg);
console.trace();
console.groupEnd();
}
if (options.sortAlphabetically) {
const sortedAppState = Object.keys(appState)
.sort()
.reduce((acc, storeName) => {
acc[storeName] = appState[storeName];
return acc;
}, {});
devTools.send({ type: msg, ...payload }, sortedAppState);
return;
}
devTools.send({ type: msg, ...payload }, appState);
}));
subs.push(devTools.subscribe((message) => {
if (message.type === 'DISPATCH') {
const payloadType = message.payload.type;
if (payloadType === 'COMMIT') {
devTools.init(appState);
return;
}
if (message.state) {
const rootState = JSON.parse(message.state);
for (let i = 0, keys = Object.keys(rootState); i < keys.length; i++) {
const storeName = keys[i];
if (__stores__[storeName]) {
ngZoneOrOptions.run(() => {
__stores__[storeName]._setState(() => rootState[storeName], false);
});
}
}
}
}
}));
}
//# sourceMappingURL=devtools.js.map