add: 更新循环任务固定调度

This commit is contained in:
2026-06-20 11:07:54 +08:00
parent 1b15ef30b3
commit aff11b77b6
9 changed files with 464 additions and 192 deletions
+1 -65
View File
@@ -1,49 +1,12 @@
// state.js — minimal pub/sub store + hash router + localStorage-backed
// job metadata cache. Vanilla, no framework.
const JOB_META_KEY = "webgui:jobMeta";
const JOB_META_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
// state.js — minimal pub/sub store + hash router. Vanilla, no framework.
const listeners = new Set();
const state = {
remotes: [], // [{ name, type }]
jobs: new Map(), // jobid -> { jobid, status, progress, action, src, dst }
providers: null, // cached /config/providers response
// jobMeta is persisted to localStorage so the jobs view can show
// src/dst for jobs after a page reload. Keyed by jobid (number).
jobMeta: loadJobMeta(),
};
function loadJobMeta() {
try {
const raw = localStorage.getItem(JOB_META_KEY);
if (!raw) return new Map();
const arr = JSON.parse(raw);
if (!Array.isArray(arr)) return new Map();
const now = Date.now();
const map = new Map();
for (const [id, meta] of arr) {
if (meta && typeof meta.submittedAt === "number") {
if (now - meta.submittedAt < JOB_META_TTL_MS) {
map.set(Number(id), meta);
}
}
}
return map;
} catch {
return new Map();
}
}
function saveJobMeta() {
try {
const arr = Array.from(state.jobMeta.entries());
localStorage.setItem(JOB_META_KEY, JSON.stringify(arr));
} catch {
// localStorage might be unavailable (private mode, quota); ignore.
}
}
export function getState() {
return state;
}
@@ -64,33 +27,6 @@ export function subscribe(fn) {
return () => listeners.delete(fn);
}
// --- Job metadata API ---
export function rememberJob(jobid, { action, src, dst }) {
state.jobMeta.set(Number(jobid), {
action,
src,
dst,
submittedAt: Date.now(),
});
saveJobMeta();
}
export function getJobMeta(jobid) {
return state.jobMeta.get(Number(jobid));
}
export function listJobMeta() {
return Array.from(state.jobMeta.entries())
.map(([jobid, meta]) => ({ jobid: Number(jobid), ...meta }))
.sort((a, b) => b.jobid - a.jobid);
}
export function forgetJob(jobid) {
state.jobMeta.delete(Number(jobid));
saveJobMeta();
}
// --- Router ---
// Hash-based routes:
// #/remotes