Update variables v2 state handling

This commit is contained in:
2026-02-01 02:49:35 +08:00
parent 4b0541610b
commit bcf664e9a0
6 changed files with 1008 additions and 128 deletions

View File

@@ -0,0 +1,123 @@
import { getContext } from '../../../../../../extensions.js';
const LWB_RULES_V2_KEY = 'LWB_RULES_V2';
let rulesTable = {};
export function loadRulesFromMeta() {
try {
const meta = getContext()?.chatMetadata || {};
rulesTable = meta[LWB_RULES_V2_KEY] || {};
} catch {
rulesTable = {};
}
}
export function saveRulesToMeta() {
try {
const meta = getContext()?.chatMetadata || {};
meta[LWB_RULES_V2_KEY] = { ...rulesTable };
getContext()?.saveMetadataDebounced?.();
} catch {}
}
export function getRuleNode(path) {
return rulesTable[path] || null;
}
export function setRule(path, rule) {
rulesTable[path] = { ...(rulesTable[path] || {}), ...rule };
}
export function clearRule(path) {
delete rulesTable[path];
saveRulesToMeta();
}
export function clearAllRules() {
rulesTable = {};
saveRulesToMeta();
}
export function getParentPath(absPath) {
const parts = String(absPath).split('.').filter(Boolean);
if (parts.length <= 1) return '';
return parts.slice(0, -1).join('.');
}
/**
* 验证操作
* @param {string} op - set/inc/push/pop/del
* @param {string} absPath - 规范化路径
* @param {*} payload - set的值 / inc的delta / push的值 / pop的值
* @param {*} currentValue - 当前值
*/
export function validate(op, absPath, payload, currentValue) {
const node = getRuleNode(absPath);
const parentPath = getParentPath(absPath);
const parentNode = parentPath ? getRuleNode(parentPath) : null;
const isNewKey = currentValue === undefined;
// 父层 $lock不允许新增/删除 key
if (parentNode?.lock) {
if (isNewKey && (op === 'set' || op === 'push')) {
return { allow: false, reason: 'parent-locked' };
}
if (op === 'del') {
return { allow: false, reason: 'parent-locked' };
}
}
// 当前 $ro不允许改值
if (node?.ro && (op === 'set' || op === 'inc')) {
return { allow: false, reason: 'ro' };
}
// 当前 $lock不允许改结构
if (node?.lock && (op === 'push' || op === 'pop' || op === 'del')) {
return { allow: false, reason: 'lock' };
}
// set 数值约束
if (op === 'set') {
const num = Number(payload);
if (Number.isFinite(num) && (node?.min !== undefined || node?.max !== undefined)) {
let v = num;
if (node.min !== undefined) v = Math.max(v, node.min);
if (node.max !== undefined) v = Math.min(v, node.max);
return { allow: true, value: v };
}
// enum
if (node?.enum?.length) {
if (!node.enum.includes(String(payload ?? ''))) {
return { allow: false, reason: 'enum' };
}
}
return { allow: true, value: payload };
}
// inc返回最终值
if (op === 'inc') {
const delta = Number(payload);
if (!Number.isFinite(delta)) return { allow: false, reason: 'delta-nan' };
const cur = Number(currentValue) || 0;
let d = delta;
// step 限制
if (node?.step !== undefined && node.step >= 0) {
if (d > node.step) d = node.step;
if (d < -node.step) d = -node.step;
}
let next = cur + d;
// range 限制
if (node?.min !== undefined) next = Math.max(next, node.min);
if (node?.max !== undefined) next = Math.min(next, node.max);
return { allow: true, value: next };
}
return { allow: true, value: payload };
}