From 7041e17b783915a42f8ed861f6d86c1969fa61c6 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Thu, 13 Sep 2018 00:34:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20add=20middleware=20functionality=20to?= =?UTF-8?q?=20=E2=80=98connect=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/analytics.js | 19 +++++++++++-------- src/content.js | 4 ++++ src/driver/connect.js | 32 ++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/analytics.js b/src/analytics.js index 0eac5b9..a0d2e04 100644 --- a/src/analytics.js +++ b/src/analytics.js @@ -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) { diff --git a/src/content.js b/src/content.js index 0bb24d4..b553ce6 100644 --- a/src/content.js +++ b/src/content.js @@ -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) diff --git a/src/driver/connect.js b/src/driver/connect.js index 8451576..f0f9f03 100644 --- a/src/driver/connect.js +++ b/src/driver/connect.js @@ -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 :)