Skip to content

Instantly share code, notes, and snippets.

@galvez
Created June 26, 2018 14:31
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save galvez/57771b43caf26cdbc9f903c0e81dbb63 to your computer and use it in GitHub Desktop.
Save galvez/57771b43caf26cdbc9f903c0e81dbb63 to your computer and use it in GitHub Desktop.
// 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