dashboard/plugins/steve/index.js

137 lines
3.4 KiB
JavaScript

import Vue from 'vue';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
import { mutations as subscribeMutations, actions as subscribeActions } from './subscribe';
import { proxyFor } from './resource-proxy';
import { keyFieldFor } from './normalize';
import { isArray } from '@/utils/array';
function SteveFactory(namespace, baseUrl) {
return {
strict: false,
namespaced: true,
state() {
return {
config: {
baseUrl,
namespace
},
types: {},
socket: null,
wantSocket: false,
pendingSends: [],
};
},
getters,
mutations: {
...mutations,
...subscribeMutations,
},
actions: {
...actions,
...subscribeActions
},
};
}
export default (config = {}) => {
const namespace = config.namespace || '';
config.baseUrl = config.baseUrl || `/${ namespace }`;
return function(store) {
const inst = SteveFactory(namespace, config.baseUrl);
store.registerModule(namespace, inst);
store.commit(`${ namespace }/applyConfig`, config);
if ( !process.client || !window.__NUXT__ ) {
return;
}
// store.subscribe(({ type }, state) => {
// if ( type === 'auth/loggedOut' ) {
// store.dispatch(`${ namespace }/unsubscribe`);
// }
// });
const module = store._modules.root._children[namespace];
const fromServer = window.__NUXT__;
module.context.rootGetters = store.getters;
// Turn all the objects in the store from the server into proxies
const state = fromServer.state[namespace];
Object.keys(state.types).forEach((type) => {
const keyField = keyFieldFor(type);
const cache = state.types[type];
const map = new Map();
for ( let i = 0 ; i < cache.list.length ; i++ ) {
const proxy = proxyFor(module.context, cache.list[i]);
cache.list[i] = proxy;
map.set(proxy[keyField], proxy);
}
Vue.set(cache, 'map', map);
Vue.set(state.types, type, state.types[type]);
});
// Turn all the objects in data from the server into the object from the store;
fromServer.data = recurse(fromServer.data);
function recurse(obj, parent, key) {
if ( isArray(obj) ) {
const rehydrateKey = `__rehydrateAll__${ key }`;
if ( parent && key && parent[rehydrateKey] ) {
const type = parent[rehydrateKey];
delete parent[rehydrateKey];
const cache = state.types[type];
if ( cache ) {
return cache.list;
}
} else {
return obj.map(x => recurse(x));
}
} else if ( obj && typeof obj === 'object' ) {
if ( obj.__rehydrate ) {
const type = obj.type;
const cache = state.types[type];
if ( cache && !obj.__clone ) {
const map = cache.map;
const keyField = keyFieldFor(type);
const entry = map.get(obj[keyField]);
// Map the object to the same instance in the store if possible
if ( entry ) {
return entry;
}
}
delete obj.__rehydrate;
// Or just return a proxied object
return proxyFor(module.context, obj);
} else {
for ( const k of Object.keys(obj) ) {
obj[k] = recurse(obj[k], obj, k);
}
}
}
return obj;
}
};
};