Skip to content

Commit 43a332d

Browse files
committed
♻️ 重构userconfig
1 parent 313e44e commit 43a332d

25 files changed

Lines changed: 728 additions & 137 deletions

File tree

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
- name: Archive production artifacts
3232
uses: actions/upload-artifact@v3
3333
with:
34-
name: scriptcat-extension
34+
name: all-artifacts
3535
path: |
3636
dist/*.zip
3737
dist/*.crx

example/userconfig.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// ==UserScript==
2+
// @name userconfig
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description 会在页面上显示用户配置,可以可视化的进行配置
6+
// @author You
7+
// @background
8+
// @grant GM_getValue
9+
// ==/UserScript==
10+
11+
/* ==UserConfig==
12+
group1:
13+
configA: # 键值为group.config,例如本键为:group1.configA
14+
title: 配置A # 配置的标题
15+
description: 这是一个文本类型的配置 # 配置的描述内容
16+
type: text # 选项类型,如果不填写会根据数据自动识别
17+
default: 默认值 # 配置的默认值
18+
min: 2 # 文本最短2个字符
19+
max: 18 # 文本最长18个字符
20+
password: true # 设置为密码
21+
configB:
22+
title: 配置B
23+
description: 这是一个选择框的配置
24+
type: checkbox
25+
default: true
26+
configC:
27+
title: 配置C
28+
description: 这是一个列表选择的配置
29+
type: select
30+
default: 1
31+
values: [1,2,3,4,5]
32+
configD:
33+
title: 配置D
34+
description: 这是一个动态列表选择的配置
35+
type: select
36+
bind: $cookies # 动态显示绑定的values,值是以$开头的key,value需要是一个数组
37+
configE:
38+
title: 配置E
39+
description: 这是一个多选列表的配置
40+
type: mult-select
41+
default: [1]
42+
values: [1,2,3,4,5]
43+
configF:
44+
title: 配置F
45+
description: 这是一个动态多选列表的配置
46+
type: mult-select
47+
bind: $cookies
48+
configG:
49+
title: 配置G
50+
description: 这是一个数字的配置
51+
type: number
52+
default: 1
53+
min: 10 # 最小值
54+
max: 16 # 最大值
55+
unit: 分 # 表示单位
56+
---
57+
group2:
58+
configX:
59+
title: 配置A
60+
description: 这是一个文本类型的配置
61+
default: 默认值
62+
type: text
63+
==/UserConfig== */
64+
65+
setInterval(() => {
66+
console.log(GM_getValue("group1.configA"));
67+
}, 5000)

src/app/message/internal.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Channel } from "./channel";
22
import {
33
ChannelManager,
4-
MessageBroadcast,
4+
IMessageBroadcast,
55
MessageHander,
66
MessageManager,
77
Target,
@@ -12,26 +12,32 @@ import {
1212
// 扩展内部页用连接,除background页使用,使用runtime.connect连接到background
1313
export default class MessageInternal
1414
extends MessageHander
15-
implements MessageManager, MessageBroadcast
15+
implements MessageManager, IMessageBroadcast
1616
{
17-
port: chrome.runtime.Port;
17+
port!: chrome.runtime.Port;
1818

19-
channelManager: ChannelManager;
19+
channelManager!: ChannelManager;
20+
21+
onDisconnect?: () => void;
2022

2123
constructor(tag: TargetTag) {
2224
super();
25+
this.reconnect(tag);
26+
}
27+
28+
reconnect(tag: TargetTag) {
2329
this.port = chrome.runtime.connect({
2430
name: tag,
2531
});
2632
this.channelManager = new WarpChannelManager((data) => {
2733
this.nativeSend(data);
2834
});
29-
3035
this.port.onMessage.addListener((message) => {
3136
this.handler(message, this.channelManager, { targetTag: "content" });
3237
});
3338
this.port.onDisconnect.addListener(() => {
3439
this.channelManager.free();
40+
this.onDisconnect?.();
3541
});
3642
}
3743

src/app/repo/scripts.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export interface Config {
4141
type?: ConfigType;
4242
bind?: string;
4343
values?: any[];
44+
password?: boolean;
45+
// 文本类型时是字符串长度,数字类型时是最大值
46+
max?: number;
47+
min?: number;
4448
}
4549

4650
export type UserConfig = { [key: string]: { [key: string]: Config } };

src/app/service/controller.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import LoggerCore from "../logger/core";
2+
import Logger from "../logger/logger";
3+
import MessageInternal from "../message/internal";
4+
5+
export type Handler = (data: any) => void | Promise<any>;
6+
7+
export default abstract class Controller {
8+
message: MessageInternal;
9+
10+
name: string;
11+
12+
logger: Logger;
13+
14+
constructor(message: MessageInternal, name: string) {
15+
this.message = message;
16+
this.name = name;
17+
this.logger = LoggerCore.getLogger({
18+
component: this.name,
19+
controller: true,
20+
});
21+
}
22+
23+
public dispatchEvent(event: string, data: any): Promise<any> {
24+
return this.message.syncSend(`${this.name}-${event}`, data);
25+
}
26+
}

src/app/service/manager.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
1-
import { MessageHander } from "../message/message";
1+
import LoggerCore from "../logger/core";
2+
import Logger from "../logger/logger";
3+
import { MessageHander, MessageSender } from "../message/message";
24

3-
export type Handler = (data: any) => void | Promise<any>;
5+
export type Handler = (data: any, sender: MessageSender) => void | Promise<any>;
46

5-
export default class Manager {
7+
export default abstract class Manager {
68
message: MessageHander;
79

8-
constructor(message: MessageHander) {
10+
name: string;
11+
12+
logger: Logger;
13+
14+
constructor(message: MessageHander, name: string) {
915
this.message = message;
16+
this.name = name;
17+
this.logger = LoggerCore.getLogger({ component: this.name, manager: true });
1018
}
1119

1220
public listenEvent(action: string, func: Handler) {
13-
this.message.setHandler(action, (_action: string, data: any) => {
14-
return new Promise((resolve) => {
15-
resolve(func(data));
16-
});
17-
});
21+
this.message.setHandler(
22+
`${this.name}-${action}`,
23+
(_action: string, data: any, sender: MessageSender) => {
24+
return new Promise((resolve) => {
25+
resolve(func(data, sender));
26+
});
27+
}
28+
);
1829
}
1930
}

src/app/service/script/event.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ export default class ScriptEventListener {
4242
this.cache = Cache.getInstance();
4343
this.logger = LoggerCore.getInstance().logger({ component: "script" });
4444
Object.keys(events).forEach((event) => {
45-
this.manager.listenEvent(`script-${event}`, events[event].bind(this));
45+
this.manager.listenEvent(event, events[event].bind(this));
4646
});
4747
}
4848

4949
// 安装或者更新脚本,将数据保存到数据库
5050
@ListenEventDecorator("upsert")
51-
public upsertHandler(script: Script) {
51+
public upsertHandler(script: Script, upsertBy: "user" | "sync" = "user") {
5252
return new Promise((resolve, reject) => {
5353
const logger = this.logger.with({
5454
scriptId: script.id,
@@ -60,7 +60,7 @@ export default class ScriptEventListener {
6060
this.dao.save(script).then(
6161
() => {
6262
logger.info("script upsert success");
63-
ScriptManager.hook.trigger("upsert", script);
63+
ScriptManager.hook.trigger("upsert", script, upsertBy);
6464
resolve({ id: script.id });
6565
},
6666
(e) => {

src/app/service/script/manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class ScriptManager extends Manager {
3636
systemConfig: SystemConfig;
3737

3838
constructor(center: MessageHander, systemConfig: SystemConfig) {
39-
super(center);
39+
super(center, "script");
4040
this.event = new ScriptEventListener(this, new ScriptDAO());
4141
this.scriptDAO = new ScriptDAO();
4242
this.systemConfig = systemConfig;

src/app/service/synchronize/event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default class SynchronizeEventListener {
3030
}
3131

3232
listenEvent(event: SynchronizeEvent, handler: Handler) {
33-
this.manager.listenEvent(`sync-${event}`, handler);
33+
this.manager.listenEvent(event, handler);
3434
}
3535

3636
init() {

src/app/service/synchronize/manager.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import ChromeStorage from "@App/pkg/config/chrome_storage";
1616
import { CloudSyncConfig, SystemConfig } from "@App/pkg/config/config";
1717
import { prepareScriptByCode } from "@App/pkg/utils/script";
18+
import { InfoNotification } from "@App/pkg/utils/utils";
1819
import FileSystemFactory from "@Pkg/filesystem/factory";
1920
import FileSystem, { File } from "@Pkg/filesystem/filesystem";
2021
import Manager from "../manager";
@@ -64,7 +65,7 @@ export default class SynchronizeManager extends Manager {
6465
resourceManager: ResourceManager,
6566
scriptManager: ScriptManager
6667
) {
67-
super(center);
68+
super(center, "sync");
6869
this.systemConfig = systemConfig;
6970
this.event = new SynchronizeEventListener(this);
7071
this.valueManager = valueManager;
@@ -123,7 +124,10 @@ export default class SynchronizeManager extends Manager {
123124

124125
const freeFn: (() => void)[] = [];
125126
// 监听脚本更新事件
126-
const upsertFn = async (script: Script) => {
127+
const upsertFn = async (script: Script, upsertBy: string) => {
128+
if (upsertBy === "sync") {
129+
return;
130+
}
127131
await this.pushScript(fs, script);
128132
this.updateFileDigest(fs);
129133
};
@@ -139,14 +143,22 @@ export default class SynchronizeManager extends Manager {
139143
}
140144

141145
// 先设置死半小时同步一次吧
142-
const ts = setInterval(() => {
143-
this.syncOnce(fs);
146+
const ts = setInterval(async () => {
147+
try {
148+
await this.syncOnce(fs);
149+
} catch (e: any) {
150+
InfoNotification("同步失败,请检查同步配置", e);
151+
}
144152
}, 60 * 30 * 1000);
145153
freeFn.push(() => {
146154
clearInterval(ts);
147155
});
148156

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

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

222235
async updateFileDigest(fs: FileSystem) {
@@ -285,12 +298,17 @@ export default class SynchronizeManager extends Manager {
285298
// 读取代码文件
286299
const r = await fs.open(file.name);
287300
const code = (await r.read("string")) as string;
301+
// 读取meta文件
302+
const meta = await fs.open(`${uuid}.meta.json`);
303+
const metaJson = (await meta.read("string")) as string;
304+
const metaObj = JSON.parse(metaJson) as SyncMeta;
288305
const newScript = await prepareScriptByCode(
289306
code,
290-
script?.downloadUrl || "",
291-
script?.uuid || uuid || undefined
307+
script?.downloadUrl || metaObj.downloadUrl || "",
308+
script?.uuid || metaObj.uuid || undefined
292309
);
293-
this.scriptManager.event.upsertHandler(newScript);
310+
newScript.origin = newScript.origin || metaObj.origin;
311+
this.scriptManager.event.upsertHandler(newScript, "sync");
294312
logger.info("pull script success");
295313
} catch (e) {
296314
logger.error("pull script error", Logger.E(e));

0 commit comments

Comments
 (0)