Skip to content

Commit 9d48c47

Browse files
committed
Refactor afterLoad interface to expose raw plugin context
1 parent 1646b27 commit 9d48c47

File tree

4 files changed

+118
-14
lines changed

4 files changed

+118
-14
lines changed

docs/customization/plugin-api.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ A plugin return value may contain any of these keys, where `myStateKey` is a nam
1919
},
2020
components: {},
2121
wrapComponents: {},
22-
afterLoad: (system) => {}
22+
afterLoad: (system) => {},
2323
fn: {},
2424
}
2525
```
@@ -366,17 +366,20 @@ const MyWrapComponentPlugin = function(system) {
366366

367367
##### `afterLoad`
368368

369-
The `afterLoad` plugin method allows you to get a reference to the system after your plugin has been registered with the system.
369+
The `afterLoad` plugin method allows you to get a reference to the system after your plugin has been registered.
370370

371-
This interface is used in the core code to attach methods that are driven by bound selectors or actions directly to the system.
371+
This interface is used in the core code to attach methods that are driven by bound selectors or actions directly to the plugin context.
372+
373+
The plugin context, which is bound to `this`, is undocumented, but below is an example of how to attach a bound action as a top-level method:
372374

373375
```javascript
374376
const MyMethodProvidingPlugin = function() {
375377
return {
376378
afterLoad(system) {
377379
// at this point in time, your actions have been bound into the system
378380
// so you can do things with them
379-
system.myMethod = system.exampleActions.updateFavoriteColor
381+
this.rootInjects = this.rootInjects || {}
382+
this.rootInjects.myMethod = system.exampleActions.updateFavoriteColor
380383
},
381384
statePlugins: {
382385
example: {

src/core/plugins/auth/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import * as specWrapActionReplacements from "./spec-wrap-actions"
66
export default function() {
77
return {
88
afterLoad(system) {
9-
system.initOAuth = system.authActions.configureAuth
9+
this.rootInjects = this.rootInjects || {}
10+
this.rootInjects.initOAuth = system.authActions.configureAuth
1011
},
1112
statePlugins: {
1213
auth: {

src/core/system.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,11 @@ export default class Store {
6868
if(rebuild) {
6969
this.buildSystem()
7070
}
71-
72-
if(Array.isArray(plugins)) {
73-
plugins.forEach(plugin => {
74-
if(plugin.afterLoad) {
75-
plugin.afterLoad(this.getSystem())
76-
}
77-
})
71+
72+
const needAnotherRebuild = callAfterLoad.call(this.system, plugins, this.getSystem())
73+
74+
if(needAnotherRebuild) {
75+
this.buildSystem()
7876
}
7977
}
8078

@@ -328,6 +326,25 @@ function combinePlugins(plugins, toolbox) {
328326
return {}
329327
}
330328

329+
function callAfterLoad(plugins, system, { hasLoaded } = {}) {
330+
let calledSomething = hasLoaded
331+
if(isObject(plugins) && !isArray(plugins)) {
332+
if(typeof plugins.afterLoad === "function") {
333+
calledSomething = true
334+
plugins.afterLoad.call(this, system)
335+
}
336+
}
337+
338+
if(isFunc(plugins))
339+
return callAfterLoad.call(this, plugins(system), system, { hasLoaded: calledSomething })
340+
341+
if(isArray(plugins)) {
342+
return plugins.map(plugin => callAfterLoad.call(this, plugin, system, { hasLoaded: calledSomething }))
343+
}
344+
345+
return calledSomething
346+
}
347+
331348
// Wraps deepExtend, to account for certain fields, being wrappers.
332349
// Ie: we need to convert some fields into arrays, and append to them.
333350
// Rather than overwrite

test/core/system/system.js

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,13 +684,13 @@ describe("bound system", function(){
684684
})
685685

686686
describe("afterLoad", function() {
687-
it("should call an plugin's `afterLoad` method after the plugin is loaded", function() {
687+
it("should call a plugin's `afterLoad` method after the plugin is loaded", function() {
688688
// Given
689689
const system = new System({
690690
plugins: [
691691
{
692692
afterLoad(system) {
693-
system.wow = system.dogeSelectors.wow
693+
this.rootInjects.wow = system.dogeSelectors.wow
694694
},
695695
statePlugins: {
696696
doge: {
@@ -705,6 +705,89 @@ describe("bound system", function(){
705705
]
706706
})
707707

708+
// When
709+
var res = system.getSystem().wow()
710+
expect(res).toEqual("so selective")
711+
})
712+
it("should call a preset plugin's `afterLoad` method after the plugin is loaded", function() {
713+
// Given
714+
const MyPlugin = {
715+
afterLoad(system) {
716+
this.rootInjects.wow = system.dogeSelectors.wow
717+
},
718+
statePlugins: {
719+
doge: {
720+
selectors: {
721+
wow: () => (system) => {
722+
return "so selective"
723+
}
724+
}
725+
}
726+
}
727+
}
728+
729+
const system = new System({
730+
plugins: [
731+
[MyPlugin]
732+
]
733+
})
734+
735+
// When
736+
var res = system.getSystem().wow()
737+
expect(res).toEqual("so selective")
738+
})
739+
it("should call a function preset plugin's `afterLoad` method after the plugin is loaded", function() {
740+
// Given
741+
const MyPlugin = {
742+
afterLoad(system) {
743+
this.rootInjects.wow = system.dogeSelectors.wow
744+
},
745+
statePlugins: {
746+
doge: {
747+
selectors: {
748+
wow: () => (system) => {
749+
return "so selective"
750+
}
751+
}
752+
}
753+
}
754+
}
755+
756+
const system = new System({
757+
plugins: [
758+
() => {
759+
return [MyPlugin]
760+
}
761+
]
762+
})
763+
764+
// When
765+
var res = system.getSystem().wow()
766+
expect(res).toEqual("so selective")
767+
})
768+
it("should call a registered plugin's `afterLoad` method after the plugin is loaded", function() {
769+
// Given
770+
const MyPlugin = {
771+
afterLoad(system) {
772+
this.rootInjects.wow = system.dogeSelectors.wow
773+
},
774+
statePlugins: {
775+
doge: {
776+
selectors: {
777+
wow: () => (system) => {
778+
return "so selective"
779+
}
780+
}
781+
}
782+
}
783+
}
784+
785+
const system = new System({
786+
plugins: []
787+
})
788+
789+
system.register([MyPlugin])
790+
708791
// When
709792
var res = system.getSystem().wow()
710793
expect(res).toEqual("so selective")

0 commit comments

Comments
 (0)