Files
MajoorWaldi-ComfyUI-Majoor-…/ui/features/stacks/liveAssetGate.ts
T

86 lines
3.0 KiB
TypeScript

function _normalizeJobId(jobId: any) {
return String(jobId || "").trim();
}
function _assetFileKey(detail: any) {
const filename = String(detail?.filename || "").trim();
const filepath = String(detail?.filepath || "").trim();
const subfolder = String(detail?.subfolder || "").trim();
const type = String(detail?.type || detail?.source || "output")
.trim()
.toLowerCase();
const rootId = String(detail?.root_id || detail?.custom_root_id || "").trim();
return `${type}|${rootId}|${subfolder}|${filename || filepath}`;
}
function _copyWithJobId(detail: any, jobId: any) {
if (!jobId) return detail;
if (String(detail?.job_id || "").trim() === jobId) return detail;
return { ...(detail || {}), job_id: jobId };
}
export function createLiveAssetGate(): Record<string, any> {
const pendingJobs = new Map();
function markPendingJob(jobId: any, { files = [], expectedCount = null } = {}) {
const normalizedJobId = _normalizeJobId(jobId);
if (!normalizedJobId) return;
const fileKeys = new Set();
for (const file of Array.isArray(files) ? files : []) {
const key = _assetFileKey(file);
if (key) fileKeys.add(key);
}
pendingJobs.set(normalizedJobId, {
expectedCount: Math.max(0, Number(expectedCount ?? fileKeys.size) || 0),
fileKeys,
markedAt: Date.now(),
});
}
function clearPendingJob(jobId: any) {
const normalizedJobId = _normalizeJobId(jobId);
if (!normalizedJobId) return;
pendingJobs.delete(normalizedJobId);
}
function resolveJobId(detail: any) {
const explicit = _normalizeJobId(detail?.job_id);
if (explicit) return explicit;
const key = _assetFileKey(detail);
if (!key) return "";
let bestJobId = "";
let oldestTime = Infinity;
for (const [jobId, meta] of pendingJobs.entries()) {
if (meta?.fileKeys?.has?.(key) && (meta.markedAt ?? Infinity) < oldestTime) {
oldestTime = meta.markedAt ?? Infinity;
bestJobId = jobId;
}
}
return bestJobId;
}
function prepare(detail: any) {
const jobId = resolveJobId(detail);
if (!jobId) return { detail, jobId: "", defer: false };
const normalizedDetail = _copyWithJobId(detail, jobId);
const pending = pendingJobs.get(jobId);
if (!pending) return { detail: normalizedDetail, jobId, defer: false };
const stackId = String(normalizedDetail?.stack_id || "").trim();
const expectedCount = Math.max(0, Number(pending?.expectedCount || 0) || 0);
const isMultiOutput = expectedCount > 1;
return {
detail: normalizedDetail,
jobId,
defer: isMultiOutput && !stackId,
};
}
return {
markPendingJob,
clearPendingJob,
resolveJobId,
prepare,
_pendingJobs: pendingJobs,
};
}