数据迁移

This commit is contained in:
王一之 2025-04-23 18:07:46 +08:00
parent 498d36567b
commit d9fdded7fb
12 changed files with 156 additions and 41 deletions

31
.gitignore vendored
View File

@ -1,16 +1,31 @@
# Local # Logs
.DS_Store logs
*.local *.log
*.log* npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Dist
node_modules node_modules
dist/ dist
dist-ssr
*.local
# IDE # Editor directories and files
.vscode/* .vscode
!.vscode/extensions.json !.vscode/extensions.json
.idea .idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
coverage coverage
CHANGELOG.md
tailwind.config.js tailwind.config.js
.env

View File

@ -1,8 +1,9 @@
import { db } from "./repo/dao"; import { db } from "./repo/dao";
import { Script } from "./repo/scripts"; import { Script, ScriptAndCode, ScriptCodeDAO, ScriptDAO } from "./repo/scripts";
import { Subscribe, SubscribeDAO } from "./repo/subscribe";
// 0.10.0重构,重命名字段,统一使用小峰驼 // 0.10.0重构,重命名字段,统一使用小峰驼
function renameField(): void { function renameField() {
db.version(16) db.version(16)
.stores({ .stores({
scripts: scripts:
@ -33,9 +34,100 @@ function renameField(): void {
export: "++id,&scriptId", export: "++id,&scriptId",
}); });
// 将脚本数据迁移到chrome.storage // 将脚本数据迁移到chrome.storage
// db.version(18) db.version(18).upgrade(async (tx) => {
// .stores({}) // 迁移脚本
// .upgrade((tx) => {}); const scripts = await tx.table("scripts").toArray();
const scriptDAO = new ScriptDAO();
const scriptCodeDAO = new ScriptCodeDAO();
await Promise.all(
scripts.map((script: ScriptAndCode) => {
const {
uuid,
name,
namespace,
author,
originDomain,
subscribeUrl,
type,
sort,
status,
runStatus,
metadata,
createtime,
checktime,
code,
} = script;
return scriptDAO
.save({
uuid,
name,
namespace,
author,
originDomain,
subscribeUrl,
type,
sort,
status,
runStatus,
metadata,
createtime,
checktime,
})
.then((s) =>
scriptCodeDAO.save({
uuid: s.uuid,
code,
})
);
})
);
// 迁移订阅
const subscribe = await tx.table("subscribe").toArray();
const subscribeDAO = new SubscribeDAO();
await Promise.all(
subscribe.map((s: Subscribe) => {
const { url, name, code, author, scripts, metadata, status, createtime, updatetime, checktime } = s;
return subscribeDAO.save({
url,
name,
code,
author,
scripts,
metadata,
status,
createtime,
updatetime,
checktime,
});
})
);
// 迁移value
interface MV2Value {
id: number;
scriptId: number;
storageName?: string;
key: string;
value: any;
createtime: number;
updatetime: number;
}
const values = await tx.table("value").toArray();
const valueDAO = new ScriptCodeDAO();
await Promise.all(
values.map((v) => {
const { scriptId, storageName, key, value, createtime } = v;
return valueDAO.save({
scriptId,
storageName,
key,
value,
createtime,
});
})
);
// 迁移permission
});
return db.open();
} }
export default function migrate() { export default function migrate() {
@ -90,7 +182,8 @@ export default function migrate() {
value: "++id,scriptId,storageName,key,createtime", value: "++id,scriptId,storageName,key,createtime",
}) })
.upgrade((tx) => { .upgrade((tx) => {
tx.table("value") return tx
.table("value")
.toCollection() .toCollection()
.modify((value) => { .modify((value) => {
if (value.namespace) { if (value.namespace) {
@ -112,5 +205,5 @@ export default function migrate() {
permission: "++id,scriptId,[scriptId+permission+permissionValue],createtime,updatetime", permission: "++id,scriptId,[scriptId+permission+permissionValue],createtime,updatetime",
}); });
// 使用小峰驼统一命名规范 // 使用小峰驼统一命名规范
renameField(); return renameField();
} }

View File

@ -35,7 +35,15 @@ export default class ServiceWorkerManager {
const value = new ValueService(this.api.group("value"), this.sender); const value = new ValueService(this.api.group("value"), this.sender);
const script = new ScriptService(systemConfig, this.api.group("script"), this.mq, value, resource); const script = new ScriptService(systemConfig, this.api.group("script"), this.mq, value, resource);
script.init(); script.init();
const runtime = new RuntimeService(systemConfig, this.api.group("runtime"), this.sender, this.mq, value, script); const runtime = new RuntimeService(
systemConfig,
this.api.group("runtime"),
this.sender,
this.mq,
value,
script,
resource
);
runtime.init(); runtime.init();
const popup = new PopupService(this.api.group("popup"), this.mq, runtime); const popup = new PopupService(this.api.group("popup"), this.mq, runtime);
popup.init(); popup.init();

View File

@ -36,12 +36,22 @@ export class ResourceService {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
cache: Map<string, { [key: string]: Resource }> = new Map();
public async getScriptResources(script: Script): Promise<{ [key: string]: Resource }> { public async getScriptResources(script: Script): Promise<{ [key: string]: Resource }> {
return Promise.resolve({ // 优先从内存中获取
if (this.cache.has(script.uuid)) {
return Promise.resolve(this.cache.get(script.uuid) || {});
}
// 资源不存在,重新加载
const res = await Promise.resolve({
...((await this.getResourceByType(script, "require")) || {}), ...((await this.getResourceByType(script, "require")) || {}),
...((await this.getResourceByType(script, "require-css")) || {}), ...((await this.getResourceByType(script, "require-css")) || {}),
...((await this.getResourceByType(script, "resource")) || {}), ...((await this.getResourceByType(script, "resource")) || {}),
}); });
// 缓存到内存
this.cache.set(script.uuid, res);
return res;
} }
async getResourceByType(script: Script, type: ResourceType): Promise<{ [key: string]: Resource }> { async getResourceByType(script: Script, type: ResourceType): Promise<{ [key: string]: Resource }> {
@ -159,6 +169,8 @@ export class ResourceService {
} }
public async addResource(url: string, uuid: string, type: ResourceType): Promise<Resource> { public async addResource(url: string, uuid: string, type: ResourceType): Promise<Resource> {
// 删除缓存
this.cache.delete(uuid);
const u = this.parseUrl(url); const u = this.parseUrl(url);
let result = await this.getResourceModel(u.url); let result = await this.getResourceModel(u.url);
// 资源不存在,重新加载 // 资源不存在,重新加载

View File

@ -26,8 +26,9 @@ import Logger from "@App/app/logger/logger";
import LoggerCore from "@App/app/logger/core"; import LoggerCore from "@App/app/logger/core";
import PermissionVerify from "./permission_verify"; import PermissionVerify from "./permission_verify";
import { SystemConfig } from "@App/pkg/config/config"; import { SystemConfig } from "@App/pkg/config/config";
import { ResourceService } from "./resource";
// 为了优化性能存储到缓存时删除了code与value // 为了优化性能存储到缓存时删除了code、value与resource
export interface ScriptMatchInfo extends ScriptRunResouce { export interface ScriptMatchInfo extends ScriptRunResouce {
matches: string[]; matches: string[];
excludeMatches: string[]; excludeMatches: string[];
@ -54,7 +55,8 @@ export class RuntimeService {
private sender: MessageSend, private sender: MessageSend,
private mq: MessageQueue, private mq: MessageQueue,
private value: ValueService, private value: ValueService,
private script: ScriptService private script: ScriptService,
private resource: ResourceService
) {} ) {}
async init() { async init() {
@ -212,18 +214,18 @@ export class RuntimeService {
return scriptRes; return scriptRes;
}); });
const enableScript = scripts.filter((item) => item); const enableScript = scripts.filter((item) => item) as ScriptMatchInfo[];
await Promise.all([ await Promise.all([
// 加载value // 加载value
...enableScript.map(async (script) => { ...enableScript.map(async (script) => {
const value = await this.value.getScriptValue(script!); const value = await this.value.getScriptValue(script!);
script!.value = value; script.value = value;
}), }),
// 加载resource // 加载resource
...enableScript.map(async (script) => { ...enableScript.map(async (script) => {
// const resource = await this.script.buildScriptRunResource(script!); const resource = await this.resource.getScriptResources(script);
// script!.resource = resource; script.resource = resource;
}), }),
]); ]);
@ -328,8 +330,10 @@ export class RuntimeService {
this.scriptMatchCache.forEach((val, key) => { this.scriptMatchCache.forEach((val, key) => {
scriptMatch[key] = val; scriptMatch[key] = val;
// 优化性能,将不需要的信息去掉 // 优化性能,将不需要的信息去掉
// 而且可能会超过缓存的存储限制
scriptMatch[key].code = ""; scriptMatch[key].code = "";
scriptMatch[key].value = {}; scriptMatch[key].value = {};
scriptMatch[key].resource = {};
}); });
return await Cache.getInstance().set("scriptMatch", scriptMatch); return await Cache.getInstance().set("scriptMatch", scriptMatch);
} }

View File

@ -4,7 +4,6 @@ import DBWriter from "./app/logger/db_writer";
import { LoggerDAO } from "./app/repo/logger"; import { LoggerDAO } from "./app/repo/logger";
import { OffscreenManager } from "./app/service/offscreen"; import { OffscreenManager } from "./app/service/offscreen";
// 初始化数据库
migrate(); migrate();
function main() { function main() {

View File

@ -8,12 +8,9 @@ import "@App/index.css";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { store } from "@App/pages/store/store.ts"; import { store } from "@App/pages/store/store.ts";
import LoggerCore from "@App/app/logger/core.ts"; import LoggerCore from "@App/app/logger/core.ts";
import migrate from "@App/app/migrate.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts"; import DBWriter from "@App/app/logger/db_writer.ts";
// 初始化数据库
migrate();
// 初始化日志组件 // 初始化日志组件
const loggerCore = new LoggerCore({ const loggerCore = new LoggerCore({
writer: new DBWriter(new LoggerDAO()), writer: new DBWriter(new LoggerDAO()),

View File

@ -8,12 +8,9 @@ import "@App/index.css";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { store } from "@App/pages/store/store.ts"; import { store } from "@App/pages/store/store.ts";
import LoggerCore from "@App/app/logger/core.ts"; import LoggerCore from "@App/app/logger/core.ts";
import migrate from "@App/app/migrate.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts"; import DBWriter from "@App/app/logger/db_writer.ts";
// 初始化数据库
migrate();
// 初始化日志组件 // 初始化日志组件
const loggerCore = new LoggerCore({ const loggerCore = new LoggerCore({
writer: new DBWriter(new LoggerDAO()), writer: new DBWriter(new LoggerDAO()),

View File

@ -8,12 +8,9 @@ import "@App/index.css";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { store } from "@App/pages/store/store.ts"; import { store } from "@App/pages/store/store.ts";
import LoggerCore from "@App/app/logger/core.ts"; import LoggerCore from "@App/app/logger/core.ts";
import migrate from "@App/app/migrate.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts"; import DBWriter from "@App/app/logger/db_writer.ts";
// 初始化数据库
migrate();
// 初始化日志组件 // 初始化日志组件
const loggerCore = new LoggerCore({ const loggerCore = new LoggerCore({
writer: new DBWriter(new LoggerDAO()), writer: new DBWriter(new LoggerDAO()),

View File

@ -8,15 +8,12 @@ import "@arco-design/web-react/dist/css/arco.css";
import "@App/locales/locales"; import "@App/locales/locales";
import "@App/index.css"; import "@App/index.css";
import "./index.css"; import "./index.css";
import migrate from "@App/app/migrate.ts";
import LoggerCore from "@App/app/logger/core.ts"; import LoggerCore from "@App/app/logger/core.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts"; import DBWriter from "@App/app/logger/db_writer.ts";
import registerEditor from "@App/pkg/utils/monaco-editor.ts"; import registerEditor from "@App/pkg/utils/monaco-editor.ts";
import storeSubscribe from "../store/subscribe.ts"; import storeSubscribe from "../store/subscribe.ts";
// 初始化数据库
migrate();
registerEditor(); registerEditor();
// 初始化日志组件 // 初始化日志组件
const loggerCore = new LoggerCore({ const loggerCore = new LoggerCore({

View File

@ -2,7 +2,6 @@ import React from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
import App from "./App.tsx"; import App from "./App.tsx";
import LoggerCore from "@App/app/logger/core.ts"; import LoggerCore from "@App/app/logger/core.ts";
import migrate from "@App/app/migrate.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts"; import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts"; import DBWriter from "@App/app/logger/db_writer.ts";
import "@arco-design/web-react/dist/css/arco.css"; import "@arco-design/web-react/dist/css/arco.css";
@ -12,8 +11,6 @@ import "./index.css";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { store } from "../store/store.ts"; import { store } from "../store/store.ts";
// 初始化数据库
migrate();
// 初始化日志组件 // 初始化日志组件
const loggerCore = new LoggerCore({ const loggerCore = new LoggerCore({
writer: new DBWriter(new LoggerDAO()), writer: new DBWriter(new LoggerDAO()),

View File

@ -1,5 +1,4 @@
import ServiceWorkerManager from "./app/service/service_worker"; import ServiceWorkerManager from "./app/service/service_worker";
import migrate from "./app/migrate";
import LoggerCore from "./app/logger/core"; import LoggerCore from "./app/logger/core";
import DBWriter from "./app/logger/db_writer"; import DBWriter from "./app/logger/db_writer";
import { LoggerDAO } from "./app/repo/logger"; import { LoggerDAO } from "./app/repo/logger";
@ -7,8 +6,8 @@ import { ExtensionMessage } from "@Packages/message/extension_message";
import { Server } from "@Packages/message/server"; import { Server } from "@Packages/message/server";
import { MessageQueue } from "@Packages/message/message_queue"; import { MessageQueue } from "@Packages/message/message_queue";
import { ServiceWorkerMessageSend } from "@Packages/message/window_message"; import { ServiceWorkerMessageSend } from "@Packages/message/window_message";
import migrate from "./app/migrate";
// 初始化数据库
migrate(); migrate();
const OFFSCREEN_DOCUMENT_PATH = "src/offscreen.html"; const OFFSCREEN_DOCUMENT_PATH = "src/offscreen.html";