Skip to content

Commit

Permalink
♻️ 重构userconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Oct 30, 2022
1 parent 313e44e commit 43a332d
Show file tree
Hide file tree
Showing 25 changed files with 728 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Archive production artifacts
uses: actions/upload-artifact@v3
with:
name: scriptcat-extension
name: all-artifacts
path: |
dist/*.zip
dist/*.crx
Expand Down
67 changes: 67 additions & 0 deletions example/userconfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// ==UserScript==
// @name userconfig
// @namespace https://bbs.tampermonkey.net.cn/
// @version 0.1.0
// @description 会在页面上显示用户配置,可以可视化的进行配置
// @author You
// @background
// @grant GM_getValue
// ==/UserScript==

/* ==UserConfig==
group1:
configA: # 键值为group.config,例如本键为:group1.configA
title: 配置A # 配置的标题
description: 这是一个文本类型的配置 # 配置的描述内容
type: text # 选项类型,如果不填写会根据数据自动识别
default: 默认值 # 配置的默认值
min: 2 # 文本最短2个字符
max: 18 # 文本最长18个字符
password: true # 设置为密码
configB:
title: 配置B
description: 这是一个选择框的配置
type: checkbox
default: true
configC:
title: 配置C
description: 这是一个列表选择的配置
type: select
default: 1
values: [1,2,3,4,5]
configD:
title: 配置D
description: 这是一个动态列表选择的配置
type: select
bind: $cookies # 动态显示绑定的values,值是以$开头的key,value需要是一个数组
configE:
title: 配置E
description: 这是一个多选列表的配置
type: mult-select
default: [1]
values: [1,2,3,4,5]
configF:
title: 配置F
description: 这是一个动态多选列表的配置
type: mult-select
bind: $cookies
configG:
title: 配置G
description: 这是一个数字的配置
type: number
default: 1
min: 10 # 最小值
max: 16 # 最大值
unit: 分 # 表示单位
---
group2:
configX:
title: 配置A
description: 这是一个文本类型的配置
default: 默认值
type: text
==/UserConfig== */

setInterval(() => {
console.log(GM_getValue("group1.configA"));
}, 5000)
16 changes: 11 additions & 5 deletions src/app/message/internal.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Channel } from "./channel";
import {
ChannelManager,
MessageBroadcast,
IMessageBroadcast,
MessageHander,
MessageManager,
Target,
Expand All @@ -12,26 +12,32 @@ import {
// 扩展内部页用连接,除background页使用,使用runtime.connect连接到background
export default class MessageInternal
extends MessageHander
implements MessageManager, MessageBroadcast
implements MessageManager, IMessageBroadcast
{
port: chrome.runtime.Port;
port!: chrome.runtime.Port;

channelManager: ChannelManager;
channelManager!: ChannelManager;

onDisconnect?: () => void;

constructor(tag: TargetTag) {
super();
this.reconnect(tag);
}

reconnect(tag: TargetTag) {
this.port = chrome.runtime.connect({
name: tag,
});
this.channelManager = new WarpChannelManager((data) => {
this.nativeSend(data);
});

this.port.onMessage.addListener((message) => {
this.handler(message, this.channelManager, { targetTag: "content" });
});
this.port.onDisconnect.addListener(() => {
this.channelManager.free();
this.onDisconnect?.();
});
}

Expand Down
4 changes: 4 additions & 0 deletions src/app/repo/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export interface Config {
type?: ConfigType;
bind?: string;
values?: any[];
password?: boolean;
// 文本类型时是字符串长度,数字类型时是最大值
max?: number;
min?: number;
}

export type UserConfig = { [key: string]: { [key: string]: Config } };
Expand Down
26 changes: 26 additions & 0 deletions src/app/service/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import LoggerCore from "../logger/core";
import Logger from "../logger/logger";
import MessageInternal from "../message/internal";

export type Handler = (data: any) => void | Promise<any>;

export default abstract class Controller {
message: MessageInternal;

name: string;

logger: Logger;

constructor(message: MessageInternal, name: string) {
this.message = message;
this.name = name;
this.logger = LoggerCore.getLogger({
component: this.name,
controller: true,
});
}

public dispatchEvent(event: string, data: any): Promise<any> {
return this.message.syncSend(`${this.name}-${event}`, data);
}
}
29 changes: 20 additions & 9 deletions src/app/service/manager.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { MessageHander } from "../message/message";
import LoggerCore from "../logger/core";
import Logger from "../logger/logger";
import { MessageHander, MessageSender } from "../message/message";

export type Handler = (data: any) => void | Promise<any>;
export type Handler = (data: any, sender: MessageSender) => void | Promise<any>;

export default class Manager {
export default abstract class Manager {
message: MessageHander;

constructor(message: MessageHander) {
name: string;

logger: Logger;

constructor(message: MessageHander, name: string) {
this.message = message;
this.name = name;
this.logger = LoggerCore.getLogger({ component: this.name, manager: true });
}

public listenEvent(action: string, func: Handler) {
this.message.setHandler(action, (_action: string, data: any) => {
return new Promise((resolve) => {
resolve(func(data));
});
});
this.message.setHandler(
`${this.name}-${action}`,
(_action: string, data: any, sender: MessageSender) => {
return new Promise((resolve) => {
resolve(func(data, sender));
});
}
);
}
}
6 changes: 3 additions & 3 deletions src/app/service/script/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ export default class ScriptEventListener {
this.cache = Cache.getInstance();
this.logger = LoggerCore.getInstance().logger({ component: "script" });
Object.keys(events).forEach((event) => {
this.manager.listenEvent(`script-${event}`, events[event].bind(this));
this.manager.listenEvent(event, events[event].bind(this));
});
}

// 安装或者更新脚本,将数据保存到数据库
@ListenEventDecorator("upsert")
public upsertHandler(script: Script) {
public upsertHandler(script: Script, upsertBy: "user" | "sync" = "user") {
return new Promise((resolve, reject) => {
const logger = this.logger.with({
scriptId: script.id,
Expand All @@ -60,7 +60,7 @@ export default class ScriptEventListener {
this.dao.save(script).then(
() => {
logger.info("script upsert success");
ScriptManager.hook.trigger("upsert", script);
ScriptManager.hook.trigger("upsert", script, upsertBy);
resolve({ id: script.id });
},
(e) => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/service/script/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class ScriptManager extends Manager {
systemConfig: SystemConfig;

constructor(center: MessageHander, systemConfig: SystemConfig) {
super(center);
super(center, "script");
this.event = new ScriptEventListener(this, new ScriptDAO());
this.scriptDAO = new ScriptDAO();
this.systemConfig = systemConfig;
Expand Down
2 changes: 1 addition & 1 deletion src/app/service/synchronize/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class SynchronizeEventListener {
}

listenEvent(event: SynchronizeEvent, handler: Handler) {
this.manager.listenEvent(`sync-${event}`, handler);
this.manager.listenEvent(event, handler);
}

init() {
Expand Down
36 changes: 27 additions & 9 deletions src/app/service/synchronize/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import ChromeStorage from "@App/pkg/config/chrome_storage";
import { CloudSyncConfig, SystemConfig } from "@App/pkg/config/config";
import { prepareScriptByCode } from "@App/pkg/utils/script";
import { InfoNotification } from "@App/pkg/utils/utils";
import FileSystemFactory from "@Pkg/filesystem/factory";
import FileSystem, { File } from "@Pkg/filesystem/filesystem";
import Manager from "../manager";
Expand Down Expand Up @@ -64,7 +65,7 @@ export default class SynchronizeManager extends Manager {
resourceManager: ResourceManager,
scriptManager: ScriptManager
) {
super(center);
super(center, "sync");
this.systemConfig = systemConfig;
this.event = new SynchronizeEventListener(this);
this.valueManager = valueManager;
Expand Down Expand Up @@ -123,7 +124,10 @@ export default class SynchronizeManager extends Manager {

const freeFn: (() => void)[] = [];
// 监听脚本更新事件
const upsertFn = async (script: Script) => {
const upsertFn = async (script: Script, upsertBy: string) => {
if (upsertBy === "sync") {
return;
}
await this.pushScript(fs, script);
this.updateFileDigest(fs);
};
Expand All @@ -139,14 +143,22 @@ export default class SynchronizeManager extends Manager {
}

// 先设置死半小时同步一次吧
const ts = setInterval(() => {
this.syncOnce(fs);
const ts = setInterval(async () => {
try {
await this.syncOnce(fs);
} catch (e: any) {
InfoNotification("同步失败,请检查同步配置", e);
}
}, 60 * 30 * 1000);
freeFn.push(() => {
clearInterval(ts);
});

this.syncOnce(fs);
try {
await this.syncOnce(fs);
} catch (e: any) {
InfoNotification("同步失败,请检查同步配置", e);
}
return Promise.resolve(() => {
logger.info("stop cloud sync");
// 当停止云同步时,移除监听
Expand All @@ -155,7 +167,7 @@ export default class SynchronizeManager extends Manager {
}

// 同步一次
async syncOnce(fs: FileSystem) {
async syncOnce(fs: FileSystem): Promise<void> {
this.logger.info("start sync once");
// 首次同步
const list = await fs.list();
Expand Down Expand Up @@ -217,6 +229,7 @@ export default class SynchronizeManager extends Manager {
// 重新获取文件列表,保存文件摘要
this.logger.info("sync complete");
await this.updateFileDigest(fs);
return Promise.resolve();
}

async updateFileDigest(fs: FileSystem) {
Expand Down Expand Up @@ -285,12 +298,17 @@ export default class SynchronizeManager extends Manager {
// 读取代码文件
const r = await fs.open(file.name);
const code = (await r.read("string")) as string;
// 读取meta文件
const meta = await fs.open(`${uuid}.meta.json`);
const metaJson = (await meta.read("string")) as string;
const metaObj = JSON.parse(metaJson) as SyncMeta;
const newScript = await prepareScriptByCode(
code,
script?.downloadUrl || "",
script?.uuid || uuid || undefined
script?.downloadUrl || metaObj.downloadUrl || "",
script?.uuid || metaObj.uuid || undefined
);
this.scriptManager.event.upsertHandler(newScript);
newScript.origin = newScript.origin || metaObj.origin;
this.scriptManager.event.upsertHandler(newScript, "sync");
logger.info("pull script success");
} catch (e) {
logger.error("pull script error", Logger.E(e));
Expand Down
21 changes: 21 additions & 0 deletions src/app/service/value/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import IoC from "@App/app/ioc";
import MessageInternal from "@App/app/message/internal";
import Controller from "../controller";

@IoC.Singleton(MessageInternal)
export default class ValueController extends Controller {
internal: MessageInternal;

constructor(internal: MessageInternal) {
super(internal, "value");
this.internal = internal;
}

public setValue(scriptId: number, key: string, value: any) {
return this.dispatchEvent("upsert", {
scriptId,
key,
value,
});
}
}
Loading

0 comments on commit 43a332d

Please sign in to comment.