数据迁移

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
.DS_Store
*.local
*.log*
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Dist
node_modules
dist/
dist
dist-ssr
*.local
# IDE
.vscode/*
# Editor directories and files
.vscode
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
coverage
CHANGELOG.md
tailwind.config.js
.env

View File

@ -1,8 +1,9 @@
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重构,重命名字段,统一使用小峰驼
function renameField(): void {
function renameField() {
db.version(16)
.stores({
scripts:
@ -33,9 +34,100 @@ function renameField(): void {
export: "++id,&scriptId",
});
// 将脚本数据迁移到chrome.storage
// db.version(18)
// .stores({})
// .upgrade((tx) => {});
db.version(18).upgrade(async (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() {
@ -90,7 +182,8 @@ export default function migrate() {
value: "++id,scriptId,storageName,key,createtime",
})
.upgrade((tx) => {
tx.table("value")
return tx
.table("value")
.toCollection()
.modify((value) => {
if (value.namespace) {
@ -112,5 +205,5 @@ export default function migrate() {
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 script = new ScriptService(systemConfig, this.api.group("script"), this.mq, value, resource);
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();
const popup = new PopupService(this.api.group("popup"), this.mq, runtime);
popup.init();

View File

@ -36,12 +36,22 @@ export class ResourceService {
return Promise.resolve(undefined);
}
cache: Map<string, { [key: string]: Resource }> = new Map();
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-css")) || {}),
...((await this.getResourceByType(script, "resource")) || {}),
});
// 缓存到内存
this.cache.set(script.uuid, res);
return res;
}
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> {
// 删除缓存
this.cache.delete(uuid);
const u = this.parseUrl(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 PermissionVerify from "./permission_verify";
import { SystemConfig } from "@App/pkg/config/config";
import { ResourceService } from "./resource";
// 为了优化性能存储到缓存时删除了code与value
// 为了优化性能存储到缓存时删除了code、value与resource
export interface ScriptMatchInfo extends ScriptRunResouce {
matches: string[];
excludeMatches: string[];
@ -54,7 +55,8 @@ export class RuntimeService {
private sender: MessageSend,
private mq: MessageQueue,
private value: ValueService,
private script: ScriptService
private script: ScriptService,
private resource: ResourceService
) {}
async init() {
@ -212,18 +214,18 @@ export class RuntimeService {
return scriptRes;
});
const enableScript = scripts.filter((item) => item);
const enableScript = scripts.filter((item) => item) as ScriptMatchInfo[];
await Promise.all([
// 加载value
...enableScript.map(async (script) => {
const value = await this.value.getScriptValue(script!);
script!.value = value;
script.value = value;
}),
// 加载resource
...enableScript.map(async (script) => {
// const resource = await this.script.buildScriptRunResource(script!);
// script!.resource = resource;
const resource = await this.resource.getScriptResources(script);
script.resource = resource;
}),
]);
@ -328,8 +330,10 @@ export class RuntimeService {
this.scriptMatchCache.forEach((val, key) => {
scriptMatch[key] = val;
// 优化性能,将不需要的信息去掉
// 而且可能会超过缓存的存储限制
scriptMatch[key].code = "";
scriptMatch[key].value = {};
scriptMatch[key].resource = {};
});
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 { OffscreenManager } from "./app/service/offscreen";
// 初始化数据库
migrate();
function main() {

View File

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

View File

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

View File

@ -8,12 +8,9 @@ import "@App/index.css";
import { Provider } from "react-redux";
import { store } from "@App/pages/store/store.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 DBWriter from "@App/app/logger/db_writer.ts";
// 初始化数据库
migrate();
// 初始化日志组件
const loggerCore = new LoggerCore({
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/index.css";
import "./index.css";
import migrate from "@App/app/migrate.ts";
import LoggerCore from "@App/app/logger/core.ts";
import { LoggerDAO } from "@App/app/repo/logger.ts";
import DBWriter from "@App/app/logger/db_writer.ts";
import registerEditor from "@App/pkg/utils/monaco-editor.ts";
import storeSubscribe from "../store/subscribe.ts";
// 初始化数据库
migrate();
registerEditor();
// 初始化日志组件
const loggerCore = new LoggerCore({

View File

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

View File

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