Created
June 26, 2018 14:31
-
-
Save galvez/57771b43caf26cdbc9f903c0e81dbb63 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// APIStoreProps are properties that need to be | |
// ignored when running APIStore.makeStore() | |
const APIStoreProps = ['use', 'classes', 'constructor', 'init', 'state'] | |
// getMethods returns methods defined | |
// in a given class' prototype, except init and constructor | |
const getMethods = (cls) => { | |
return Object.getOwnPropertyNames(cls.prototype) | |
.reduce((obj, prop) => { | |
if (APIStoreProps.includes(prop)) { | |
return obj | |
} else if (typeof cls.prototype[prop] === 'function') { | |
return { ...obj, [prop]: cls.prototype[prop] } | |
} | |
}, {}) | |
} | |
const getGetters = (cls) => { | |
return Object.getOwnPropertyNames(cls.prototype) | |
.reduce((obj, prop) => { | |
if (APIStoreProps.includes(prop)) { | |
return obj | |
} else if (typeof cls.prototype.__lookupGetter__(prop) === 'function') { | |
return { ...obj, [prop]: cls.prototype.__lookupGetter__(prop) } | |
} | |
}, {}) | |
} | |
// APIStore is a metaclass in the sense that its derived | |
// class serve as data entry points for the makeStore() static method, | |
// whose ultimate purpose is to generate the Vuex global store | |
export class APIStore { | |
static use (cls) { | |
if (!this.classes) { | |
this.classes = [cls] | |
} else { | |
this.classes.push(cls) | |
} | |
} | |
static makeClientReadyHandler (cls) { | |
if (process.browser) { | |
window.onNuxtReady((app) => { | |
if (cls.client) { | |
cls.client(app) | |
} | |
}) | |
} | |
} | |
static makeStore () { | |
if (!this.classes) { | |
this.classes = [] | |
} | |
this.makeClientReadyHandler(this) | |
return { | |
state: this.prototype.state, | |
getters: { | |
...getGetters(this), | |
...this.classes.reduce((obj, cls) => { | |
return { ...obj, ...getGetters(cls) } | |
}, {}) | |
}, | |
actions: { | |
...getMethods(this), | |
...this.classes.reduce((obj, cls) => { | |
return { ...obj, ...getMethods(cls) } | |
}, {}), | |
nuxtServerInit: this.prototype.init, | |
api: apiRequest | |
}, | |
mutations: { | |
...apiErrorMutations, | |
...networkStateMutations, | |
update (state, props) { | |
for (const key in props) { | |
Vue.set(state, key, props[key]) | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment