Files
DemonGatanjieu-Anomalous_Mo…/web/modules/canvas_history.js
T
DemonGatanjieuandClaude Opus 5.5 698a256a16 feat(model-check): download missing models, to the folder you choose
Model Check offers Download (and Download all) for a missing model whose
source names one exact file: Civitai by the workflow's fingerprint, or a
Civitai version / Hugging Face / GitHub file link the workflow carries.
A dialog shows each file's size, source and full destination, with the
models folder (when there are several) and subfolder changeable; Settings
> Model downloads sets the default: where the workflow says (the node
needs no change) or a set folder, {base} sorting by base model and
matching an existing folder in any spelling.

Downloads run one at a time into <file>.part, continue after an
interruption, are checked against the SHA-256 before they get their name,
never replace a file, and send the Civitai key to Civitai only. Finished
files are put into their nodes (one Ctrl+Z step each), scanned for info
and covers, and recorded in the activity log.

A change of fingerprints alone (after any scan) no longer takes a Ctrl+Z
step that seemed to do nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:28:51 +08:00

50 lines
2.2 KiB
JavaScript

/**
* ComfyUI's Ctrl+Z history. It takes a step on its own events (a mouse button or key let
* go); a canvas write made by a drop (no mouse-up follows a drag), in a click handler or
* after a request finishes would otherwise land in no step, and Ctrl+Z would skip it.
* Call after every canvas write. Takes `app` so pure modules can use it. Also keeps a change of
* fingerprints alone (absorbFingerprintChange) out of the history.
*/
export function recordCanvasStep(app) {
try {
const tracker = app?.extensionManager?.workflow?.activeWorkflow?.changeTracker;
if (typeof tracker?.captureCanvasState === 'function') tracker.captureCanvasState();
else tracker?.checkState?.(); // older ComfyUI
} catch (error) {
console.warn('[AMB] Ctrl+Z history: step not recorded.', error);
}
}
// What a saved workflow carries from the fingerprint cache (hash_resolver.js), not the canvas.
const DERIVED = ['anomalous_hashes', 'anomalous_model_sources'];
function withoutDerived(state) {
const extra = { ...(state?.extra || {}) };
for (const key of DERIVED) delete extra[key];
return { ...state, extra };
}
/**
* After the fingerprint cache changes (a scan, a download), the workflow serializes with
* other fingerprints although nothing on the canvas changed; ComfyUI would take that as a
* step, and the next Ctrl+Z would seem to do nothing. When that is the only difference, the
* history's current state takes it without a step.
*/
export function absorbFingerprintChange(app) {
try {
const tracker = app?.extensionManager?.workflow?.activeWorkflow?.changeTracker;
const graph = app?.rootGraph || app?.graph;
if (!tracker?.activeState || typeof graph?.serialize !== 'function') return;
const current = JSON.parse(JSON.stringify(graph.serialize()));
const a = withoutDerived(tracker.activeState);
const b = withoutDerived(current);
const same = typeof tracker.constructor?.graphEqual === 'function'
? tracker.constructor.graphEqual(a, b)
: JSON.stringify(a) === JSON.stringify(b);
if (same) tracker.activeState = current;
} catch (error) {
console.warn('[AMB] Ctrl+Z history: could not take the new fingerprints in.', error);
}
}