-
Notifications
You must be signed in to change notification settings - Fork 289
异歩 GM.getValue/getValues/listValues 修正 #898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/v1.3
Are you sure you want to change the base?
异歩 GM.getValue/getValues/listValues 修正 #898
Conversation
a123e26 to
04d6641
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
此 PR 为 GM.getValue、GM.listValues 和 GM.getValues 等异步 API 添加了数据同步机制,确保这些 API 在读取值之前能获取到最新的数据库状态。
主要变更:
- 在 ValueService 中添加
updatetime字段跟踪,记录每次值更新的时间戳 - 实现
GM_waitForFreshValueStateAPI,用于获取最新的 updatetime - 修改 GM.getValue、GM.listValues、GM.getValues 等异步 API,在读取前等待数据同步到最新状态
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/app/service/service_worker/value.ts | 在 setValue 和 setValues 方法中添加 updatetime 跟踪逻辑,新增 waitForFreshValueState 方法 |
| src/app/service/service_worker/gm_api.ts | 添加 GM_waitForFreshValueState API 处理函数 |
| src/app/service/content/types.ts | 在 ValueUpdateDataEncoded 类型中添加 updatetime 字段 |
| src/app/service/content/gm_api.ts | 实现 waitForFreshValueState 函数,修改 GM.getValue、GM.listValues、GM.getValues 使用该函数;修正一处注释的繁体字 |
| src/app/service/content/gm_api.test.ts | 添加 valueDaoUpdatetimeFix 辅助函数,更新测试以支持新的同步机制;修正正则表达式匹配模式 |
| async GM_waitForFreshValueState(request: GMApiRequest<[boolean]>, sender: IGetSender) { | ||
| const param = request.params; | ||
| if (param.length !== 1) { | ||
| throw new Error("there must be one parameter"); | ||
| } | ||
| const ret = await this.value.waitForFreshValueState(request.script.uuid, { | ||
| runFlag: request.runFlag, | ||
| tabId: sender.getSender()?.tab?.id || -1, | ||
| }); | ||
| return ret; | ||
| } |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GM_waitForFreshValueState 函数接收的参数声明为 GMApiRequest<[boolean]>,并验证参数长度必须为 1,但实际上并未使用该参数。在 content/gm_api.ts:255 调用时传递的是 [true],但在函数内部完全没有使用 request.params[0]。要么应该使用该参数,要么应该将类型改为 GMApiRequest<[]> 并移除长度验证。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
之前好像不放东西的话,传送有问题。我没有看到其他没用param的API。
所以就放一个 true 了
先这样吧
|
研究一下效能提升。先轉 draft |
35d670e to
79ad4e2
Compare
7eb600c to
035ce3d
Compare
|
@CodFrm 改好了 测试代码(一):修改后: // ==UserScript==
// @name 测试 GM.getValue 能否取得最新值
// @namespace yourname.scripts
// @version 0.1.0
// @description 把当前网页URL保存到存储列表中
// @author You
// @match *://*/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @grant GM.listValues
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// ==/UserScript==
(function () {
'use strict';
let useAsync = true;
const rid = `${(Math.floor(Math.random() * 5000) + 4000).toString(36)}`;
const trigger = async () => {
console.log(`[${rid}]`,"trigger in " + location.href, "current time = " + Date.now());
useAsync ? action2() : action1();
}
let k = 0;
const action1 = async () => {
++k;
GM_setValue(`${"list_"}${rid}${k}`, Date.now());
console.log(`[${rid}]`, GM_listValues());
};
const action2 = async () => {
++k;
await GM.setValue(`${"list_"}${rid}${k}`, Date.now());
console.log(`[${rid}]`, await GM.listValues());
};
const wins = [];
let tc0;
window.addEventListener("message", (e) => {
if (e.data && typeof e.data === "object" && e.data?.test_call_id && e.data?.type === "response_tc") {
const tc1 = e.data.test_call_id;
if (tc1 === tc0) {
trigger();
}
}
});
if (location.search.startsWith("?test_call=") && top !== window) {
const usp = new URLSearchParams(location.search);
const tc = usp.get("test_call");
if (tc) {
tc0 = tc;
window.top.postMessage({ type: "done_iframe_tc", test_call_id: tc }, "*");
}
} else if (window.location.href.includes("example.com") && top === window) {
const test_call_id = `tc${Date.now()}_${Math.random()}`;
tc0 = test_call_id;
let q = 1;
let ec = 0;
const doFunc = async (elements) => {
console.log(`[${rid}]`,"---- ADD SOME INFO... ------");
await (useAsync ? action2() : action1());
await (useAsync ? action2() : action1());
await (useAsync ? action2() : action1());
console.log(`[${rid}]`,"---------------------------");
setTimeout(() => {
console.log(`[${rid}]`,"do trigger");
for (const iframe of elements) {
try {
iframe.contentWindow.postMessage({ type: "response_tc", test_call_id },
"*"
)
} catch (e) {
// ignored
}
}
window.postMessage({ type: "response_tc", test_call_id }, "*");
setTimeout(async () => {
console.log(`[${rid}]`,"final list", await GM.listValues());
}, 1500)
}, 1500);
}
window.addEventListener("message", (e) => {
if (e.data && typeof e.data === "object" && e.data?.test_call_id && e.data?.type === "done_iframe_tc") {
const tc = e.data.test_call_id;
if (tc === test_call_id) {
const elements = document.querySelectorAll("iframe.tt0011");
// wins.push([e.source, e.origin]);
wins.push(1);
if (wins.length === elements.length && elements.length === ec && q) {
q = 0;
doFunc(elements);
}
}
}
});
const makeIframe = () => {
const elm = document.body.appendChild(document.createElement("iframe"));
elm.classList.add("tt0011");
return elm;
}
ec = 3;
setTimeout(()=>{
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 1800);
setTimeout(()=>{
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 2400);
setTimeout(() => {
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 3200);
}
})();测试代码(二):(有 // ==UserScript==
// @name Example Script for GM_lock
// @namespace yourname.scripts
// @version 0.1
// @description 把当前网页URL保存到存储列表中
// @author You
// @match *://*/*
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.setValues
// @grant GM.deleteValue
// @grant GM.deleteValues
// @grant GM.listValues
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// @require https://update.greasyfork.org/scripts/554436/1692608/GM_lock.js
// @noframes
// ==/UserScript==
/* global GM_lock */
(function () {
'use strict';
GM_lock("lock_urls", async () => {
console.log("开始", Date.now(), performance.now());
// 等一下这个页面SC的缓存更新
// await new Promise(resolve => setTimeout(resolve, 50));
// 从存储中读取已有的列表
let list = await GM.getValue('list', []); // 设置默认值为空数组
// 如果当前URL不在列表中,就添加进去
console.log("初始列表:", list.slice());
if (!list.includes(location.href)) {
list.push(location.href);
await GM.setValue('list', list);
console.log('✅ 已保存此页面到列表:', location.href);
} else {
console.log('ℹ️ 当前页面已在列表中');
}
// 可选:在控制台查看当前列表
console.log('当前列表:', list.slice());
// 等一下其他页面SC的缓存更新
// await new Promise(resolve => setTimeout(resolve, 50));
console.log("结束", Date.now(), performance.now());
});
})(); |
|
和 #936 有关连的改动。 我先开一个 分支 develop/raw-message 处理一下。 |

概述 Descriptions
异歩 GM.getValue/getValues/listValues 修正
变更内容 Changes
增加内部函数
GM_waitForFreshValueState, 会传最新的scriptRes.updatetime若valueUpdate未触发,把Promise加至
readFreshes进行等待截图 Screenshots