Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add component mappers
  • Loading branch information
ktsn committed Aug 12, 2018
1 parent 9431332 commit 445e359
Show file tree
Hide file tree
Showing 5 changed files with 383 additions and 46 deletions.
5 changes: 2 additions & 3 deletions .eslintrc.yml
@@ -1,3 +1,2 @@
---
root: true
extends: ktsn-typescript
root: true
extends: ktsn-typescript
14 changes: 7 additions & 7 deletions package.json
Expand Up @@ -41,23 +41,23 @@
"@types/mocha": "^5.2.5",
"@types/power-assert": "1.5.0",
"@vue/test-utils": "^1.0.0-beta.24",
"eslint": "^5.2.0",
"eslint-config-ktsn-typescript": "^1.1.0",
"eslint": "^5.3.0",
"eslint-config-ktsn-typescript": "^1.1.4",
"glob": "^7.1.2",
"npm-run-all": "^4.1.3",
"power-assert": "^1.6.0",
"prettier": "1.14.2",
"prettier-config-ktsn": "^1.0.0",
"rollup": "^0.64.0",
"rollup": "^0.64.1",
"rollup-plugin-replace": "^2.0.0",
"testem": "^2.9.0",
"testem": "^2.9.2",
"ts-loader": "^4.4.2",
"typescript": "^2.9.2",
"uglify-js": "^3.4.5",
"typescript": "^3.0.1",
"uglify-js": "^3.4.7",
"vue": "^2.5.17",
"vue-template-compiler": "^2.5.17",
"vuex": "^3.0.1",
"webpack": "^4.16.1",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0",
"webpack-espower-loader": "^2.0.0"
}
Expand Down
98 changes: 81 additions & 17 deletions src/module.ts
Expand Up @@ -5,7 +5,11 @@ import {
GetterTree,
CommitOptions,
DispatchOptions,
MutationTree
MutationTree,
mapState,
mapGetters,
mapMutations,
mapActions
} from 'vuex'
import { BG0, BM0, BA0, Payload } from './assets'
import { get, assert, Class, mapValues } from './utils'
Expand Down Expand Up @@ -34,6 +38,14 @@ export interface Dispatch<A> {
): Promise<any>
}

export type MappedFunction<Fn, R> = Payload<Fn> extends undefined
? (payload?: Payload<Fn>) => R
: (payload: Payload<Fn>) => R

export type RestArgs<Fn> = Fn extends (_: any, ...args: infer R) => any
? R
: never

export interface ModuleOptions<S, G extends BG0, M extends BM0, A extends BA0> {
state?: Class<S>
getters?: Class<G>
Expand All @@ -47,18 +59,12 @@ export class Module<S, G extends BG0, M extends BM0, A extends BA0> {
private store: Store<any> | undefined = undefined

commit: Commit<M> = (type: any, payload: any, options?: any): void => {
assert(
this.path && this.store,
'you need to provide the module into the Vuex store before using it.'
)
this.ensureStore()
return this.normalizedDispatch(this.store!.commit, type, payload, options)
}

dispatch: Dispatch<A> = (type: any, payload: any, options?: any): any => {
assert(
this.path && this.store,
'you need to provide the module into the Vuex store before using it.'
)
this.ensureStore()
return this.normalizedDispatch(this.store!.dispatch, type, payload, options)
}

Expand Down Expand Up @@ -89,19 +95,70 @@ export class Module<S, G extends BG0, M extends BM0, A extends BA0> {
}
}

mapState<K extends keyof S>(map: K[]): { [Key in K]: () => S[Key] }
mapState<T extends Record<string, keyof S>>(
map: T
): { [Key in keyof T]: () => S[T[Key]] }
mapState<T extends Record<string, (state: S, getters: G) => any>>(
map: T
): { [Key in keyof T]: () => ReturnType<T[Key]> }
mapState(map: any): { [key: string]: () => any } {
this.ensureStore()
const namespace = this.namespace()
return namespace === '' ? mapState(map) : mapState(namespace, map)
}

mapGetters<K extends keyof G>(map: K[]): { [Key in K]: () => G[Key] }
mapGetters<T extends Record<string, keyof G>>(
map: T
): { [Key in keyof T]: () => G[T[Key]] }
mapGetters(map: any): { [key: string]: () => any } {
this.ensureStore()
const namespace = this.namespace()
return namespace === '' ? mapGetters(map) : mapGetters(namespace, map)
}

mapMutations<K extends keyof M>(
map: K[]
): { [Key in K]: MappedFunction<M[K], void> }
mapMutations<T extends Record<string, keyof M>>(
map: T
): { [Key in keyof T]: MappedFunction<M[T[Key]], void> }
mapMutations<
T extends Record<string, (commit: Commit<M>, ...args: any[]) => any>
>(
map: T
): { [Key in keyof T]: (...args: RestArgs<T[Key]>) => ReturnType<T[Key]> }
mapMutations(map: any): { [key: string]: (...args: any[]) => any } {
this.ensureStore()
const namespace = this.namespace()
return namespace === '' ? mapMutations(map) : mapMutations(namespace, map)
}

mapActions<K extends keyof A>(
map: K[]
): { [Key in K]: MappedFunction<A[K], Promise<any>> }
mapActions<T extends Record<string, keyof A>>(
map: T
): { [Key in keyof T]: MappedFunction<A[T[Key]], Promise<any>> }
mapActions<
T extends Record<string, (dispatch: Dispatch<A>, ...args: any[]) => any>
>(
map: T
): { [Key in keyof T]: (...args: RestArgs<T[Key]>) => ReturnType<T[Key]> }
mapActions(map: any): { [key: string]: (...args: any[]) => any } {
this.ensureStore()
const namespace = this.namespace()
return namespace === '' ? mapActions(map) : mapActions(namespace, map)
}

get state(): S {
assert(
this.path && this.store,
'you need to provide the module into the Vuex store before using it.'
)
this.ensureStore()
return get(this.path!, this.store!.state)
}

get getters(): G {
assert(
this.path && this.store,
'you need to provide the module into the Vuex store before using it.'
)
this.ensureStore()
return this.namespacedGetters()
}

Expand Down Expand Up @@ -167,6 +224,13 @@ export class Module<S, G extends BG0, M extends BM0, A extends BA0> {
private namespacedType(type: string): string {
return this.namespace() + type
}

private ensureStore(): void {
assert(
this.path && this.store,
'you need to provide the module into the Vuex store before using it.'
)
}
}

function initGetters<S, G extends BG0, M extends BM0, A extends BA0>(
Expand Down

0 comments on commit 445e359

Please sign in to comment.