feat: support source map & reload

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-05-07 17:12:15 +08:00
parent d50506ab9d
commit 40e9d1db6e
8 changed files with 90 additions and 25 deletions

View File

@ -21,10 +21,54 @@ export namespace plugin {
export interface PluginManager { export interface PluginManager {
scan(folder: string): void; scan(folder: string): void;
build(): void; build(): void;
loadFromFile(file: string): Plugin;
load(...args: any[]): void; load(...args: any[]): void;
enable(...args: any[]): void; enable(...args: any[]): void;
disable(...args: any[]): void; disable(...args: any[]): void;
reload(...args: any[]): void; reload(...args: any[]): void;
getPlugins(): Map<string, any>; getPlugins(): Map<string, any>;
} }
export interface Plugin {
description: PluginMetadata;
logger: Console;
load(): void;
enable(): void;
disable(): void;
}
interface BaseMetadata {
/**
*
*/
name?: string;
/**
*
*/
servers?: string[];
}
export interface PluginMetadata extends BaseMetadata {
/**
*
*/
name: string;
/**
*
*/
prefix?: string;
/**
*
*/
version: string;
/**
*
*/
author: string | string[];
/**
* __filename
*/
source: string;
/**
*
*/
target?: any;
}
} }

View File

@ -30,13 +30,13 @@ declare global {
} }
interface String { interface String {
trimLeft(); trimLeft(): string;
trimRight(); trimRight(): string;
} }
interface Object { interface Object {
setPrototypeOf(obj: object, prototype: object); setPrototypeOf(obj: object, prototype: object): void;
bindProperties(to: object, from: object); bindProperties(to: object, from: object): void;
} }
namespace NodeJS { namespace NodeJS {
@ -68,7 +68,7 @@ declare global {
stack(err: Error): string[]; stack(err: Error): string[];
sender(...args: any): void; sender(...args: any): void;
console(...args: any): void; console(...args: any): void;
i18n(name: string, ...params: any[]); i18n(name: string, ...params: any[]): void;
} }
} }

View File

@ -87,7 +87,7 @@ export class XMLHttpRequest {
private _statusText: string = null; private _statusText: string = null;
private _response: any; private _response: any;
private _responseURL: string; private _responseURL: string;
private _responseHeaders: HttpHeader; private _responseHeaders: HttpHeader = {};
private _connection = null; private _connection = null;
@ -228,7 +228,7 @@ export class XMLHttpRequest {
private setResponseHeaders(header: any) { private setResponseHeaders(header: any) {
this._responseHeaders = {}; this._responseHeaders = {};
header.forEach((key, value) => { header.forEach((key: string | number, value: string | any[]) => {
this._responseHeaders[key] = value[value.length - 1] this._responseHeaders[key] = value[value.length - 1]
}); });
} }

View File

@ -1,12 +1,13 @@
export const METADATA_KEY = { export const METADATA_KEY = {
plugin: "@ccms/plugin:plugin", plugin: Symbol.for("@ccms/plugin:plugin"),
cmd: "@ccms/plugin:cmd", souece: Symbol.for("@ccms/plugin:souece"),
tab: "@ccms/plugin:tab", cmd: Symbol.for("@ccms/plugin:cmd"),
listener: "@ccms/plugin:listener", tab: Symbol.for("@ccms/plugin:tab"),
config: "@ccms/plugin:config", listener: Symbol.for("@ccms/plugin:listener"),
config: Symbol.for("@ccms/plugin:config"),
stage: { stage: {
load: "@ccms/plugin:stage:load", load: Symbol.for("@ccms/plugin:stage:load"),
enable: "@ccms/plugin:stage:enable", enable: Symbol.for("@ccms/plugin:stage:enable"),
disable: "@ccms/plugin:stage:disable" disable: Symbol.for("@ccms/plugin:stage:disable")
} }
}; };

View File

@ -1,7 +1,7 @@
import { injectable, decorate } from "@ccms/container"; import { injectable, decorate } from "@ccms/container";
import { interfaces } from './interfaces' import { interfaces } from './interfaces'
import { METADATA_KEY } from './constants' import { METADATA_KEY } from './constants'
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils'
/** /**
* MiaoScript plugin * MiaoScript plugin
@ -10,11 +10,15 @@ import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata
export function plugin(metadata: interfaces.PluginMetadata) { export function plugin(metadata: interfaces.PluginMetadata) {
return function (target: any) { return function (target: any) {
metadata.target = target; metadata.target = target;
metadata.source = metadata.source + '';
decorate(injectable(), target); decorate(injectable(), target);
Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target); Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas(); const previousMetadata: Map<string, interfaces.PluginMetadata> = getPluginMetadatas();
previousMetadata.set(metadata.name, metadata); previousMetadata.set(metadata.name, metadata);
Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect); Reflect.defineMetadata(METADATA_KEY.plugin, previousMetadata, Reflect);
const previousSources: Map<string, interfaces.PluginMetadata> = getPluginSources();
previousSources.set(metadata.source, metadata);
Reflect.defineMetadata(METADATA_KEY.souece, previousSources, Reflect);
}; };
} }

View File

@ -1,6 +1,5 @@
import { server, MiaoScriptConsole, event } from "@ccms/api"; import { server, MiaoScriptConsole, event } from "@ccms/api";
import { METADATA_KEY } from './constants' import { injectable, inject } from "@ccms/container";
import { injectable, inject, postConstruct } from "@ccms/container";
import { getPluginMetadata } from "./utils"; import { getPluginMetadata } from "./utils";
export namespace interfaces { export namespace interfaces {

View File

@ -3,7 +3,7 @@ import { plugin, server, command, event } from '@ccms/api'
import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container' import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container'
import * as fs from '@ccms/common/dist/fs' import * as fs from '@ccms/common/dist/fs'
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata, getPluginSources } from './utils'
import { interfaces } from './interfaces' import { interfaces } from './interfaces'
import { getConfigLoader } from './config' import { getConfigLoader } from './config'
@ -26,6 +26,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
private initialized: boolean = false private initialized: boolean = false
private pluginMap: Map<string, interfaces.Plugin> private pluginMap: Map<string, interfaces.Plugin>
private plugnMappings: Map<string, interfaces.PluginMetadata>
initialize() { initialize() {
if (this.pluginInstance !== null && this.initialized !== true) { if (this.pluginInstance !== null && this.initialized !== true) {
@ -34,6 +35,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
this.pluginMap = new Map() this.pluginMap = new Map()
console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType }); console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType });
this.initialized = true; this.initialized = true;
this.plugnMappings = getPluginSources()
} }
} }
@ -60,6 +62,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
this.execPluginStage(plugin, stage) this.execPluginStage(plugin, stage)
} }
loadFromFile(file: string): interfaces.Plugin {
this.loadPlugin(file)
let plugin = this.buildPlugin(this.plugnMappings.get(file))
this.load(plugin)
this.enable(plugin)
return plugin;
}
load(...args: any[]): void { load(...args: any[]): void {
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
this.runPluginStage(plugin, 'load', () => { this.runPluginStage(plugin, 'load', () => {
@ -89,10 +99,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
reload(...args: any[]): void { reload(...args: any[]): void {
this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => { this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => {
this.disable(pl) this.disable(pl)
this.loadPlugin(pl.description.source) this.loadFromFile(pl.description.source)
pl = this.buildPlugin(getPlugin(pl.description.name))
this.load(pl)
this.enable(pl)
}) })
} }
@ -166,13 +173,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
} }
private allowProcess(servers: string[]) { private allowProcess(servers: string[]) {
// Not set servers allow // Not set servers -> allow
if (!servers || !servers.length) return true if (!servers || !servers.length) return true
// include !type deny // include !type -> deny
let denyServers = servers.filter(svr => svr.startsWith("!")) let denyServers = servers.filter(svr => svr.startsWith("!"))
if (denyServers.length !== 0) { if (denyServers.length !== 0) {
return !denyServers.includes(`!${this.serverType}`) return !denyServers.includes(`!${this.serverType}`)
} else { } else {
// only include -> allow
return servers.includes(this.serverType) return servers.includes(this.serverType)
} }
} }

View File

@ -9,6 +9,14 @@ function getPlugin(name: string) {
return getPluginMetadatas().get(name); return getPluginMetadatas().get(name);
} }
function getPluginSources() {
let pluginSources: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
METADATA_KEY.souece,
Reflect
) || new Map<string, interfaces.PluginMetadata>();
return pluginSources;
}
function getPluginMetadatas() { function getPluginMetadatas() {
let pluginMetadatas: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata( let pluginMetadatas: Map<string, interfaces.PluginMetadata> = Reflect.getMetadata(
METADATA_KEY.plugin, METADATA_KEY.plugin,
@ -68,6 +76,7 @@ function getPluginStageMetadata(target: any, stage: string) {
export { export {
getPlugin, getPlugin,
getPlugins, getPlugins,
getPluginSources,
getPluginMetadatas, getPluginMetadatas,
getPluginMetadata, getPluginMetadata,
getPluginCommandMetadata, getPluginCommandMetadata,