瀏覽代碼

Refactor `afterLoad` interface to expose raw plugin context

bubble
Kyle Shockey 6 年之前
父節點
當前提交
9d48c4751a
共有 4 個文件被更改,包括 118 次插入14 次删除
  1. +7
    -4
      docs/customization/plugin-api.md
  2. +2
    -1
      src/core/plugins/auth/index.js
  3. +24
    -7
      src/core/system.js
  4. +85
    -2
      test/core/system/system.js

+ 7
- 4
docs/customization/plugin-api.md 查看文件

@@ -19,7 +19,7 @@ A plugin return value may contain any of these keys, where `myStateKey` is a nam
},
components: {},
wrapComponents: {},
afterLoad: (system) => {}
afterLoad: (system) => {},
fn: {},
}
```
@@ -366,9 +366,11 @@ const MyWrapComponentPlugin = function(system) {

##### `afterLoad`

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

This interface is used in the core code to attach methods that are driven by bound selectors or actions directly to the system.
This interface is used in the core code to attach methods that are driven by bound selectors or actions directly to the plugin context.

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:

```javascript
const MyMethodProvidingPlugin = function() {
@@ -376,7 +378,8 @@ const MyMethodProvidingPlugin = function() {
afterLoad(system) {
// at this point in time, your actions have been bound into the system
// so you can do things with them
system.myMethod = system.exampleActions.updateFavoriteColor
this.rootInjects = this.rootInjects || {}
this.rootInjects.myMethod = system.exampleActions.updateFavoriteColor
},
statePlugins: {
example: {


+ 2
- 1
src/core/plugins/auth/index.js 查看文件

@@ -6,7 +6,8 @@ import * as specWrapActionReplacements from "./spec-wrap-actions"
export default function() {
return {
afterLoad(system) {
system.initOAuth = system.authActions.configureAuth
this.rootInjects = this.rootInjects || {}
this.rootInjects.initOAuth = system.authActions.configureAuth
},
statePlugins: {
auth: {


+ 24
- 7
src/core/system.js 查看文件

@@ -68,13 +68,11 @@ export default class Store {
if(rebuild) {
this.buildSystem()
}
if(Array.isArray(plugins)) {
plugins.forEach(plugin => {
if(plugin.afterLoad) {
plugin.afterLoad(this.getSystem())
}
})

const needAnotherRebuild = callAfterLoad.call(this.system, plugins, this.getSystem())

if(needAnotherRebuild) {
this.buildSystem()
}
}

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

function callAfterLoad(plugins, system, { hasLoaded } = {}) {
let calledSomething = hasLoaded
if(isObject(plugins) && !isArray(plugins)) {
if(typeof plugins.afterLoad === "function") {
calledSomething = true
plugins.afterLoad.call(this, system)
}
}

if(isFunc(plugins))
return callAfterLoad.call(this, plugins(system), system, { hasLoaded: calledSomething })

if(isArray(plugins)) {
return plugins.map(plugin => callAfterLoad.call(this, plugin, system, { hasLoaded: calledSomething }))
}

return calledSomething
}

// Wraps deepExtend, to account for certain fields, being wrappers.
// Ie: we need to convert some fields into arrays, and append to them.
// Rather than overwrite


+ 85
- 2
test/core/system/system.js 查看文件

@@ -684,13 +684,13 @@ describe("bound system", function(){
})

describe("afterLoad", function() {
it("should call an plugin's `afterLoad` method after the plugin is loaded", function() {
it("should call a plugin's `afterLoad` method after the plugin is loaded", function() {
// Given
const system = new System({
plugins: [
{
afterLoad(system) {
system.wow = system.dogeSelectors.wow
this.rootInjects.wow = system.dogeSelectors.wow
},
statePlugins: {
doge: {
@@ -705,6 +705,89 @@ describe("bound system", function(){
]
})

// When
var res = system.getSystem().wow()
expect(res).toEqual("so selective")
})
it("should call a preset plugin's `afterLoad` method after the plugin is loaded", function() {
// Given
const MyPlugin = {
afterLoad(system) {
this.rootInjects.wow = system.dogeSelectors.wow
},
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "so selective"
}
}
}
}
}

const system = new System({
plugins: [
[MyPlugin]
]
})

// When
var res = system.getSystem().wow()
expect(res).toEqual("so selective")
})
it("should call a function preset plugin's `afterLoad` method after the plugin is loaded", function() {
// Given
const MyPlugin = {
afterLoad(system) {
this.rootInjects.wow = system.dogeSelectors.wow
},
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "so selective"
}
}
}
}
}

const system = new System({
plugins: [
() => {
return [MyPlugin]
}
]
})

// When
var res = system.getSystem().wow()
expect(res).toEqual("so selective")
})
it("should call a registered plugin's `afterLoad` method after the plugin is loaded", function() {
// Given
const MyPlugin = {
afterLoad(system) {
this.rootInjects.wow = system.dogeSelectors.wow
},
statePlugins: {
doge: {
selectors: {
wow: () => (system) => {
return "so selective"
}
}
}
}
}

const system = new System({
plugins: []
})

system.register([MyPlugin])

// When
var res = system.getSystem().wow()
expect(res).toEqual("so selective")


Loading…
取消
儲存