Skip to content

Commit 4c8a627

Browse files
committed
feat: new “extend” method for makeServicePlugin
## API ``` import { makeServicePlugin } from ‘feathers-vuex’ import { feathersClient } from ‘./feathers-client.js’ class Todo { /* truncated */ } makeServicePlugin({ Model: Todo, service: feathersClient.service(‘todos’), extend({ store, module }) { // Listen to other parts of the store store.watch(/* truncated */) return { state: {}, getters: {}, mutations: {}, actions: {} } } }) The old options for customizing the store are still fully functional. The `module` object in the options contains the default state, getters, mutations, and actions merged with the ones provided in the options. They are made available in case this is useful; however, they do not need to be returned `extend` method’s return object. The object returned from `extend` will be merged over the top of the ones in `module`. As a result of this change, the following options are now deprecated in the `makeServicePlugin` method: - state - getters - mutations - actions ## History and Relevance Up until now, `makeServicePlugin` and `makeAuthPlugin` have supported passing `state`, `getters`, `mutations`, and `actions` as keys in the options as shown here: ![Screen Shot 2020-10-29 at 1 14 15 PM](https://user-images.githubusercontent.com/128857/97621627-c8637380-19e8-11eb-9523-98a485440ef0.jpg) This is nice and clean until you need access to the `store` variable to access APIs like `store.watch` (when you want a clean way to define related logic between multiple vuex modules). This issue specifically showed up when I wanted a purely-logical, non-template-based method of watching for authentication from Auth0. Up until now, I have always used the “Gateway Component” pattern that has a conditional in it for if auth is present, then put the majority of the app logic in a child component. As shown in the above example, this extra logic can now live inside the same module as the rest of the service and vuex plugin definition.
1 parent 8d399fa commit 4c8a627

File tree

5 files changed

+285
-103
lines changed

5 files changed

+285
-103
lines changed

src/service-module/make-service-module.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,37 @@ eslint
33
@typescript-eslint/explicit-function-return-type: 0,
44
@typescript-eslint/no-explicit-any: 0
55
*/
6+
import _pick from 'lodash/pick'
7+
import _merge from 'lodash/merge'
68
import makeDefaultState from './service-module.state'
79
import makeGetters from './service-module.getters'
810
import makeMutations from './service-module.mutations'
911
import makeActions from './service-module.actions'
1012
import { Service } from '@feathersjs/feathers'
1113
import { MakeServicePluginOptions } from './types'
14+
import { Store } from 'vuex'
1215

1316
export default function makeServiceModule(
1417
service: Service<any>,
15-
options: MakeServicePluginOptions
18+
options: MakeServicePluginOptions,
19+
store: Store<any>
1620
) {
17-
const defaultState = makeDefaultState(options)
18-
const defaultGetters = makeGetters()
19-
const defaultMutations = makeMutations()
20-
const defaultActions = makeActions(service)
21-
22-
return {
21+
const defaults = {
2322
namespaced: true,
24-
state: Object.assign({}, defaultState, options.state),
25-
getters: Object.assign({}, defaultGetters, options.getters),
26-
mutations: Object.assign({}, defaultMutations, options.mutations),
27-
actions: Object.assign({}, defaultActions, options.actions)
23+
state: makeDefaultState(options),
24+
getters: makeGetters(),
25+
mutations: makeMutations(),
26+
actions: makeActions(service)
2827
}
28+
const fromOptions = _pick(options, [
29+
'state',
30+
'getters',
31+
'mutations',
32+
'actions'
33+
])
34+
const merged = _merge({}, defaults, fromOptions)
35+
const extended = options.extend({ store, module: merged })
36+
const finalModule = _merge({}, merged, extended)
37+
38+
return finalModule
2939
}

src/service-module/make-service-plugin.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ eslint
33
@typescript-eslint/explicit-function-return-type: 0,
44
@typescript-eslint/no-explicit-any: 0
55
*/
6-
import { FeathersVuexOptions, MakeServicePluginOptions } from './types'
6+
import {
7+
FeathersVuexOptions,
8+
MakeServicePluginOptions,
9+
ServicePluginExtendOptions
10+
} from './types'
11+
712
import makeServiceModule from './make-service-module'
813
import { globalModels, prepareAddModel } from './global-models'
914
import enableServiceEvents from './service-module.events'
@@ -13,6 +18,14 @@ import _get from 'lodash/get'
1318
interface ServiceOptionsDefaults {
1419
servicePath: string
1520
namespace: string
21+
extend: (
22+
options: ServicePluginExtendOptions
23+
) => {
24+
state: any
25+
getters: any
26+
mutations: any
27+
actions: any
28+
}
1629
state: {}
1730
getters: {}
1831
mutations: {}
@@ -25,6 +38,7 @@ interface ServiceOptionsDefaults {
2538
const defaults: ServiceOptionsDefaults = {
2639
namespace: '', // The namespace for the Vuex module. Will generally be derived from the service.path, service.name, when available. Otherwise, it must be provided here, explicitly.
2740
servicePath: '',
41+
extend: ({ module }) => module, // for custom plugin (replaces state, getters, mutations, and actions)
2842
state: {}, // for custom state
2943
getters: {}, // for custom getters
3044
mutations: {}, // for custom mutations
@@ -91,7 +105,7 @@ export default function prepareMakeServicePlugin(
91105
return store => {
92106
// (1^) Create and register the Vuex module
93107
options.namespace = makeNamespace(namespace, servicePath, nameStyle)
94-
const module = makeServiceModule(service, options)
108+
const module = makeServiceModule(service, options, store)
95109
// Don't preserve state if reinitialized (prevents state pollution in SSR)
96110
store.registerModule(options.namespace, module, { preserveState: false })
97111

src/service-module/service-module.state.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export default function makeDefaultState(options: MakeServicePluginOptions) {
107107
'instanceDefaults',
108108
'setupInstance',
109109
'handleEvents',
110+
'extend',
110111
'state',
111112
'getters',
112113
'mutations',

src/service-module/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export interface HandleEvents {
3737
removed?: Function
3838
}
3939

40+
export interface ServicePluginExtendOptions {
41+
store: Store<any>
42+
module: any
43+
}
44+
4045
export interface MakeServicePluginOptions {
4146
Model: any
4247
service: Service<any>
@@ -64,6 +69,15 @@ export interface MakeServicePluginOptions {
6469
instanceDefaults?: () => {}
6570
setupInstance?: (data: any, { models, store }) => {}
6671
handleEvents?: HandleEvents
72+
73+
extend?: (
74+
options: ServicePluginExtendOptions
75+
) => {
76+
state?: any
77+
getters?: any
78+
mutations?: any
79+
actions?: any
80+
}
6781
state?: {}
6882
getters?: {}
6983
mutations?: {}

0 commit comments

Comments
 (0)