feat: add middleware functionality to ‘connect’

This commit is contained in:
EnixCoda 2018-09-13 00:34:10 +08:00
parent e727e3bfce
commit 7041e17b78
3 changed files with 43 additions and 12 deletions

View file

@ -5,14 +5,17 @@ export function raiseError(error) {
return reportError(error)
}
export function withErrorLog(func) {
return function () {
try {
func()
} catch (error) {
raiseError(error)
}
}
export function withErrorLog(method, args) {
return [
function() {
try {
method.apply(this, arguments)
} catch (error) {
raiseError(error)
}
},
args,
]
}
function encodeParams(params) {

View file

@ -2,9 +2,13 @@ import React from 'react'
import ReactDOM from 'react-dom'
import Gitako from './components/Gitako'
import { addMiddleware } from './driver/connect'
import { withErrorLog } from './analytics'
import './content.less'
addMiddleware(withErrorLog)
const SideBarElement = document.createElement('div')
document.body.appendChild(SideBarElement)

View file

@ -1,22 +1,46 @@
import React from 'react'
import { withErrorLog } from "../analytics"
const middlewares = []
export function addMiddleware(middleware) {
if (typeof middleware !== 'function') return null
const m = middleware.bind(null)
middlewares.push(m)
return function removeMiddleware() {
const index = middlewares.indexOf(m)
if (index === -1) return
middlewares.splice(index, 1)
}
}
function applyMiddlewares(method, args) {
for(const middleware of middlewares) {
[method = method, args = args] = middleware(method, args) || []
}
return [method, args]
}
function run([method, args]) {
method.apply(null, args)
}
function link(instance, sources) {
const wrappedMethods = {/* [keyof sources] -> wrappedMethods.method */}
const map = new Map(/* sources.creator -> wrappedMethods.method */)
Object.entries(sources).forEach(([key, createMethod]) => {
const method = createMethod(dispatch)
wrappedMethods[key] = method
map.set(createMethod, method)
})
const sourcesValues = Object.values(sources)
function dispatch(...args) {
const isFromSource = Object.values(sources).includes(args[0])
const isFromSource = sourcesValues.includes(args[0])
if (isFromSource) {
withErrorLog(() => map.get(args[0])(...args.slice(1)))()
const [createMethod, ...otherArgs] = args
const method = map.get(createMethod)
run(applyMiddlewares(method, otherArgs))
} else {
// by doing so, no async updater is available anymore
// luckily I don't need them :)