refactor: standardize frontend file naming

This commit is contained in:
Dariusz L
2026-08-14 16:56:46 +02:00
parent b5f09e88fb
commit 5ea337fb51
138 changed files with 391 additions and 391 deletions
+8 -8
View File
@@ -22,17 +22,17 @@ be edited independently.
These modules are the main seams between the frontend domains:
- `app/CanvasView.ts` composes the canvas runtime without registering a second
- `app/canvas_view.ts` composes the canvas runtime without registering a second
ComfyUI extension as an import side effect.
- `app/LayerForgeConnections.ts` owns graph identity, workflow connections,
- `app/layer_forge_connections.ts` owns graph identity, workflow connections,
and ComfyUI event/WebSocket integration.
- `canvas/CanvasHistory.ts` owns bounded undo/redo stacks and snapshot
- `canvas/canvas_history.ts` owns bounded undo/redo stacks and snapshot
cloning.
- `io/CanvasIO.ts` owns image input/output transport and render/export
- `io/canvas_io.ts` owns image input/output transport and render/export
coordination.
- `media/ImageCache.ts` owns in-memory image identity and cache lifetime;
- `media/image_cache.ts` owns in-memory image identity and cache lifetime;
IndexedDB persistence remains under `persistence/`.
- `mask/MaskResultUtils.ts` owns shared mask-result conversion and application;
- `mask/mask_result_utils.ts` owns shared mask-result conversion and application;
editor-specific side effects stay in the individual integrations.
- `persistence/contracts.ts` owns the shared persisted-state and worker-message
contracts used by the database and persistence worker.
@@ -54,8 +54,8 @@ The lower-level domains remain independent of application composition:
dependencies;
- ComfyUI-provided modules under `scripts/` are external runtime dependencies.
The root `src/CanvasView.ts` file is the single served bootstrap. It invokes
the registration function from `src/app/CanvasView.ts`; the implementation
The root `src/canvas_view.ts` file is the single served bootstrap. It invokes
the registration function from `src/app/canvas_view.ts`; the implementation
module itself must not register the extension as an import side effect.
The dependency rules are covered by `tests/test_architecture_boundaries.mjs`.
+6 -6
View File
@@ -35,18 +35,18 @@ The generated files in `js/` are served by ComfyUI. Keep `src/` as the source of
The frontend is organized by responsibility:
- `src/CanvasView.ts` is the stable ComfyUI bootstrap. Its implementation is in `src/app/CanvasView.ts`.
- `src/app/LayerForgeConnections.ts` contains graph identity, workflow
- `src/canvas_view.ts` is the stable ComfyUI bootstrap. Its implementation is in `src/app/canvas_view.ts`.
- `src/app/layer_forge_connections.ts` contains graph identity, workflow
connections, and ComfyUI event/WebSocket integration used by the canvas.
- `src/canvas/` contains the canvas runtime, layers, state, rendering, selection, tools, and interactions.
- `src/canvas/CanvasHistory.ts` contains the bounded undo/redo snapshot model.
- `src/canvas/canvas_history.ts` contains the bounded undo/redo snapshot model.
- `src/io/` contains ComfyUI input and output handling.
- `src/mask/` contains mask editing, mask algorithms, and detector/editor integrations.
- `src/mask/MaskResultUtils.ts` contains shared mask-result conversion and
- `src/mask/mask_result_utils.ts` contains shared mask-result conversion and
application helpers; SAM and matting integrations retain their own side
effects.
- `src/media/` contains image, blob, upload, preview, and export helpers.
- `src/media/ImageCache.ts` contains the in-memory image cache. IndexedDB image
- `src/media/image_cache.ts` contains the in-memory image cache. IndexedDB image
persistence and reference tracking remain in `src/persistence/`.
- `src/persistence/` contains IndexedDB and image-reference persistence.
- `src/persistence/contracts.ts` contains shared persisted-state and worker
@@ -54,7 +54,7 @@ The frontend is organized by responsibility:
- `src/shared/` contains shared types and error handling.
- `src/utils/` contains smaller cross-cutting browser and ComfyUI helpers.
ComfyUI scans the generated web directory recursively. Only `js/CanvasView.js` invokes `registerLayerForgeExtension`; `js/app/CanvasView.js` exports the registration function without invoking it, preventing duplicate extension registration.
ComfyUI scans the generated web directory recursively. Only `js/canvas_view.js` invokes `registerLayerForgeExtension`; `js/app/canvas_view.js` exports the registration function without invoking it, preventing duplicate extension registration.
## Watch mode
+15 -15
View File
@@ -6,23 +6,23 @@ import { api } from "../../../scripts/api.js";
import { ChangeTracker } from "../../../scripts/changeTracker.js";
// @ts-ignore
import { $el } from "../../../scripts/ui.js";
import { addStylesheet, getUrl, loadTemplate } from "../utils/ResourceManager.js";
import { Canvas, configureCanvasImagePreviewWidget } from "../canvas/Canvas.js";
import { canvasNodeInstances, installLayerForgeMultiImagePromptPatch, installLayerForgeVirtualWirePatch, isLayerForgeTransportInput, pruneLayerForgeTransportInputs, scheduleLayerForgeImageConnectionConversion, } from "./LayerForgeConnections.js";
import { addStylesheet, getUrl, loadTemplate } from "../utils/resource_manager.js";
import { Canvas, configureCanvasImagePreviewWidget } from "../canvas/canvas.js";
import { canvasNodeInstances, installLayerForgeMultiImagePromptPatch, installLayerForgeVirtualWirePatch, isLayerForgeTransportInput, pruneLayerForgeTransportInputs, scheduleLayerForgeImageConnectionConversion, } from "./layer_forge_connections.js";
import { clearAllCanvasStates, getCanvasState, setCanvasState } from "../persistence/db.js";
import { getCanvasStateKey } from "../utils/CanvasStateKey.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { loadImageFromBlob } from "../media/ImageUtils.js";
import { getCanvasStateKey } from "../utils/canvas_state_key.js";
import { createCanvas } from "../utils/common_utils.js";
import { loadImageFromBlob } from "../media/image_utils.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showErrorNotification, showSuccessNotification, showInfoNotification, showWarningNotification } from "../utils/NotificationUtils.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/IconLoader.js";
import { exportCanvasImage } from "../media/CanvasExportUtils.js";
import { getFlattenedCanvasBlob } from "../media/CanvasBlobUtils.js";
import { loadPreviewImage } from "../media/PreviewUtils.js";
import { getImageAddMode } from "../utils/CanvasInputUtils.js";
import { clearLayerForgeImageInputLinks, getLayerForgeImageInputLinks, getLayerForgeMaskInputSlot, hasLayerForgeImageInput, } from "../utils/MultiImageInputUtils.js";
import { fetchMattingModelStatus, fetchMattingSettings, saveMattingSettings as saveMattingSettingsToServer, } from "../utils/MattingUtils.js";
import { cancelSAMDetectorMonitoring, setupSAMDetectorHook } from "../mask/SAMDetectorIntegration.js";
import { showErrorNotification, showSuccessNotification, showInfoNotification, showWarningNotification } from "../utils/notification_utils.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/icon_loader.js";
import { exportCanvasImage } from "../media/canvas_export_utils.js";
import { getFlattenedCanvasBlob } from "../media/canvas_blob_utils.js";
import { loadPreviewImage } from "../media/preview_utils.js";
import { getImageAddMode } from "../utils/canvas_input_utils.js";
import { clearLayerForgeImageInputLinks, getLayerForgeImageInputLinks, getLayerForgeMaskInputSlot, hasLayerForgeImageInput, } from "../utils/multi_image_input_utils.js";
import { fetchMattingModelStatus, fetchMattingSettings, saveMattingSettings as saveMattingSettingsToServer, } from "../utils/matting_utils.js";
import { cancelSAMDetectorMonitoring, setupSAMDetectorHook } from "../mask/sam_detector_integration.js";
const log = createModuleLogger('Canvas_view');
const DEFAULT_MATTING_SETTINGS = {
modelPath: '',
@@ -1,7 +1,7 @@
// Graph integration for virtual image links and multi-image prompt transport.
// @ts-ignore
import { app } from "../../../scripts/app.js";
import { addLayerForgeImageInputLink, getLayerForgeImageInputLinks, getLayerForgeImageInputSlot, LAYERFORGE_MAX_IMAGE_INPUTS, removeLayerForgeImageInputLink, } from "../utils/MultiImageInputUtils.js";
import { addLayerForgeImageInputLink, getLayerForgeImageInputLinks, getLayerForgeImageInputSlot, LAYERFORGE_MAX_IMAGE_INPUTS, removeLayerForgeImageInputLink, } from "../utils/multi_image_input_utils.js";
export const canvasNodeInstances = new Map();
let layerForgeQuickCreateMenu = null;
let layerForgeQuickCreateCanvas = null;
+17 -17
View File
@@ -1,22 +1,22 @@
// @ts-ignore
import { api } from "../../../scripts/api.js";
import { MaskTool } from "../mask/MaskTool.js";
import { ShapeTool } from "./ShapeTool.js";
import { CustomShapeMenu } from "./CustomShapeMenu.js";
import { CanvasState } from "./CanvasState.js";
import { CanvasInteractions } from "./CanvasInteractions.js";
import { CanvasLayers } from "./CanvasLayers.js";
import { CanvasLayersPanel } from "./CanvasLayersPanel.js";
import { CanvasRenderer } from "./CanvasRenderer.js";
import { CanvasIO } from "../io/CanvasIO.js";
import { ImageReferenceManager } from "../persistence/ImageReferenceManager.js";
import { BatchPreviewManager } from "./BatchPreviewManager.js";
import { ImageCache } from "../media/ImageCache.js";
import { MaskTool } from "../mask/mask_tool.js";
import { ShapeTool } from "./shape_tool.js";
import { CustomShapeMenu } from "./custom_shape_menu.js";
import { CanvasState } from "./canvas_state.js";
import { CanvasInteractions } from "./canvas_interactions.js";
import { CanvasLayers } from "./canvas_layers.js";
import { CanvasLayersPanel } from "./canvas_layers_panel.js";
import { CanvasRenderer } from "./canvas_renderer.js";
import { CanvasIO } from "../io/canvas_io.js";
import { ImageReferenceManager } from "../persistence/image_reference_manager.js";
import { BatchPreviewManager } from "./batch_preview_manager.js";
import { ImageCache } from "../media/image_cache.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { debounce, createCanvas } from "../utils/CommonUtils.js";
import { MaskEditorIntegration } from "../mask/MaskEditorIntegration.js";
import { CanvasSelection } from "./CanvasSelection.js";
import { removeLayersWithLifecycle } from "../utils/LayerRemovalUtils.js";
import { debounce, createCanvas } from "../utils/common_utils.js";
import { MaskEditorIntegration } from "../mask/mask_editor_integration.js";
import { CanvasSelection } from "./canvas_selection.js";
import { removeLayersWithLifecycle } from "../utils/layer_removal_utils.js";
const useChainCallback = (original, next) => {
if (original === undefined || original === null) {
return next;
@@ -187,7 +187,7 @@ export class Canvas {
this.render();
}
else {
log.warn("$$canvas-image-preview widget not found in Canvas.js");
log.warn("$$canvas-image-preview widget not found in canvas.js");
}
}
/**
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { snapToGrid, getSnapAdjustment, isPointInRotatedLayer } from "../utils/CommonUtils.js";
import { loadImageFromBlob } from "../media/ImageUtils.js";
import { getImageAddMode } from "../utils/CanvasInputUtils.js";
import { snapToGrid, getSnapAdjustment, isPointInRotatedLayer } from "../utils/common_utils.js";
import { loadImageFromBlob } from "../media/image_utils.js";
import { getImageAddMode } from "../utils/canvas_input_utils.js";
const log = createModuleLogger('CanvasInteractions');
export class CanvasInteractions {
constructor(canvas) {
@@ -1,17 +1,17 @@
import { saveImage } from "../persistence/db.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { generateUUID, generateUniqueFileName, createCanvas, getBoundsFromPoints, getLayerWorldCorners, isPointInLayerLocalBounds, isPointInRotatedLayer, localToWorld, worldToLayerLocal } from "../utils/CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { showErrorNotification } from "../utils/NotificationUtils.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
import { generateUUID, generateUniqueFileName, createCanvas, getBoundsFromPoints, getLayerWorldCorners, isPointInLayerLocalBounds, isPointInRotatedLayer, localToWorld, worldToLayerLocal } from "../utils/common_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
import { showErrorNotification } from "../utils/notification_utils.js";
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
// @ts-ignore
import { app } from "../../../scripts/app.js";
// @ts-ignore
import { ComfyApp } from "../../../scripts/app.js";
import { ClipboardManager } from "../utils/ClipboardManager.js";
import { createDistanceFieldMaskSync } from "../mask/ImageAnalysis.js";
import { fillInverseAlphaMask } from "../mask/MaskPixelUtils.js";
import { blobToDataUrl } from "../media/ImageUtils.js";
import { ClipboardManager } from "../utils/clipboard_manager.js";
import { createDistanceFieldMaskSync } from "../mask/image_analysis.js";
import { fillInverseAlphaMask } from "../mask/mask_pixel_utils.js";
import { blobToDataUrl } from "../media/image_utils.js";
const log = createModuleLogger('CanvasLayers');
export class CanvasLayers {
constructor(canvas) {
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/IconLoader.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/icon_loader.js";
import { createCanvas } from "../utils/common_utils.js";
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
const log = createModuleLogger('CanvasLayersPanel');
export class CanvasLayersPanel {
constructor(canvas) {
@@ -1,5 +1,5 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { getBoundsFromPoints, getLayerWorldBounds, isPointInRotatedLayer, localToWorld, worldToLocal } from "../utils/CommonUtils.js";
import { getBoundsFromPoints, getLayerWorldBounds, isPointInRotatedLayer, localToWorld, worldToLocal } from "../utils/common_utils.js";
const log = createModuleLogger('CanvasRenderer');
export class CanvasRenderer {
constructor(canvas) {
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { generateUUID } from "../utils/CommonUtils.js";
import { removeLayersWithLifecycle } from "../utils/LayerRemovalUtils.js";
import { generateUUID } from "../utils/common_utils.js";
import { removeLayersWithLifecycle } from "../utils/layer_removal_utils.js";
const log = createModuleLogger('CanvasSelection');
export class CanvasSelection {
constructor(canvas) {
@@ -1,10 +1,10 @@
import { getCanvasState, setCanvasState, saveImage, getImage } from "../persistence/db.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showAlertNotification } from "../utils/NotificationUtils.js";
import { generateUUID, cloneLayers, getStateSignature, debounce, createCanvas, cloneCanvas } from "../utils/CommonUtils.js";
import { loadImage } from "../media/ImageUtils.js";
import { getCanvasStateKey } from "../utils/CanvasStateKey.js";
import { HistoryStack } from "./CanvasHistory.js";
import { showAlertNotification } from "../utils/notification_utils.js";
import { generateUUID, cloneLayers, getStateSignature, debounce, createCanvas, cloneCanvas } from "../utils/common_utils.js";
import { loadImage } from "../media/image_utils.js";
import { getCanvasStateKey } from "../utils/canvas_state_key.js";
import { HistoryStack } from "./canvas_history.js";
import { CURRENT_PERSISTED_STATE_VERSION, migratePersistedCanvasState, } from '../persistence/contracts.js';
const log = createModuleLogger('CanvasState');
export class CanvasState {
@@ -38,7 +38,7 @@ export class CanvasState {
this._debouncedSave = null;
try {
// @ts-ignore
this.stateSaverWorker = new Worker(new URL('../persistence/state-saver.worker.js', import.meta.url), { type: 'module' });
this.stateSaverWorker = new Worker(new URL('../persistence/state_saver.worker.js', import.meta.url), { type: 'module' });
log.info("State saver worker initialized successfully.");
this.stateSaverWorker.onmessage = (e) => {
log.info("Message from state saver worker:", e.data);
@@ -1,5 +1,5 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
const log = createModuleLogger('CustomShapeMenu');
export class CustomShapeMenu {
constructor(canvas) {
@@ -1,5 +1,5 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { getBoundsFromPoints } from '../utils/CommonUtils.js';
import { getBoundsFromPoints } from '../utils/common_utils.js';
const log = createModuleLogger('ShapeTool');
export class ShapeTool {
constructor(canvas) {
+1 -1
View File
@@ -1,5 +1,5 @@
// Stable frontend entrypoint loaded by ComfyUI.
// The implementation module is also served recursively, so registration is
// intentionally invoked only from this root bootstrap.
import { registerLayerForgeExtension } from "./app/CanvasView.js";
import { registerLayerForgeExtension } from "./app/canvas_view.js";
registerLayerForgeExtension();
+7 -7
View File
@@ -1,11 +1,11 @@
import { createCanvas } from "../utils/CommonUtils.js";
import { createCanvas } from "../utils/common_utils.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showErrorNotification } from "../utils/NotificationUtils.js";
import { webSocketManager } from "../utils/WebSocketManager.js";
import { scaleImageToFit, loadImage, blobToDataUrl, tensorToImageData, createImageFromImageData } from "../media/ImageUtils.js";
import { postImageBlob } from "../media/ImageUploadUtils.js";
import { getImageAddMode, isFitOnAddEnabled } from "../utils/CanvasInputUtils.js";
import { getLayerForgeImageInputLinks, getLayerForgeImageInputSlot, getLayerForgeMaskInputSlot, hasLayerForgeImageInput, removeLayerForgeImageInputLink, } from "../utils/MultiImageInputUtils.js";
import { showErrorNotification } from "../utils/notification_utils.js";
import { webSocketManager } from "../utils/web_socket_manager.js";
import { scaleImageToFit, loadImage, blobToDataUrl, tensorToImageData, createImageFromImageData } from "../media/image_utils.js";
import { postImageBlob } from "../media/image_upload_utils.js";
import { getImageAddMode, isFitOnAddEnabled } from "../utils/canvas_input_utils.js";
import { getLayerForgeImageInputLinks, getLayerForgeImageInputSlot, getLayerForgeMaskInputSlot, hasLayerForgeImageInput, removeLayerForgeImageInputLink, } from "../utils/multi_image_input_utils.js";
const log = createModuleLogger('CanvasIO');
const IMAGE_CACHE_BUSTER_QUERY_KEYS = new Set([
'cachebust',
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { calculateDistanceTransform, rasterizeDistanceFieldMask } from "./MaskPixelUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/common_utils.js";
import { calculateDistanceTransform, rasterizeDistanceFieldMask } from "./mask_pixel_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('ImageAnalysis');
/**
* Creates a distance field mask based on the alpha channel of an image.
@@ -3,15 +3,15 @@ import { app } from "../../../scripts/app.js";
// @ts-ignore
import { ComfyApp } from "../../../scripts/app.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showErrorNotification } from "../utils/NotificationUtils.js";
import { uploadImageBlob } from "../media/ImageUploadUtils.js";
import { processMaskForViewport } from "./MaskProcessingUtils.js";
import { applyMaskResultToTool } from "./MaskResultUtils.js";
import { updateNodePreview } from "../media/PreviewUtils.js";
import { showErrorNotification } from "../utils/notification_utils.js";
import { uploadImageBlob } from "../media/image_upload_utils.js";
import { processMaskForViewport } from "./mask_processing_utils.js";
import { applyMaskResultToTool } from "./mask_result_utils.js";
import { updateNodePreview } from "../media/preview_utils.js";
import { mask_editor_showing, mask_editor_listen_for_cancel } from "./mask_utils.js";
import { cloneCanvas } from "../utils/CommonUtils.js";
import { getFlattenedCanvasBlob } from "../media/CanvasBlobUtils.js";
import { loadImage } from "../media/ImageUtils.js";
import { cloneCanvas } from "../utils/common_utils.js";
import { getFlattenedCanvasBlob } from "../media/canvas_blob_utils.js";
import { loadImage } from "../media/image_utils.js";
const log = createModuleLogger('MaskEditorIntegration');
export class MaskEditorIntegration {
constructor(canvas) {
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/common_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('MaskProcessingUtils');
async function processImagePixels(sourceImage, targetWidth, targetHeight, pixelTransform, contextErrorMessage) {
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(targetWidth, targetHeight, '2d', { willReadFrequently: true });
@@ -1,5 +1,5 @@
import { convertToImage } from "../media/ImageUtils.js";
import { processImageToMask } from "./MaskProcessingUtils.js";
import { convertToImage } from "../media/image_utils.js";
import { processImageToMask } from "./mask_processing_utils.js";
export async function createMaskImageFromResult(sourceImage, options) {
const processedMask = await processImageToMask(sourceImage, {
targetWidth: options.targetWidth,
+2 -2
View File
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas, createCanvasWithContext } from "../utils/CommonUtils.js";
import { applyLuminanceAsAlpha, calculateDistanceTransform, imageDataToBinaryMask, rasterizeDistanceFieldMask } from "./MaskPixelUtils.js";
import { createCanvas, createCanvasWithContext } from "../utils/common_utils.js";
import { applyLuminanceAsAlpha, calculateDistanceTransform, imageDataToBinaryMask, rasterizeDistanceFieldMask } from "./mask_pixel_utils.js";
const log = createModuleLogger('Mask_tool');
export class MaskTool {
constructor(canvasInstance, callbacks = {}) {
+1 -1
View File
@@ -1,5 +1,5 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('MaskUtils');
export function new_editor(app) {
if (!app)
@@ -1,11 +1,11 @@
// @ts-ignore
import { ComfyApp } from "../../../scripts/app.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showInfoNotification, showSuccessNotification, showErrorNotification } from "../utils/NotificationUtils.js";
import { uploadCanvasAsImage, uploadImageBlob } from "../media/ImageUploadUtils.js";
import { applyMaskResultToTool } from "./MaskResultUtils.js";
import { updateNodePreview } from "../media/PreviewUtils.js";
import { validateAndFixClipspace } from "../utils/ClipspaceUtils.js";
import { showInfoNotification, showSuccessNotification, showErrorNotification } from "../utils/notification_utils.js";
import { uploadCanvasAsImage, uploadImageBlob } from "../media/image_upload_utils.js";
import { applyMaskResultToTool } from "./mask_result_utils.js";
import { updateNodePreview } from "../media/preview_utils.js";
import { validateAndFixClipspace } from "../utils/clipspace_utils.js";
const log = createModuleLogger('SAMDetectorIntegration');
function scheduleSAMMonitoringTimeout(node, callback, delay) {
const existingTimers = node.samMonitoringTimers;
@@ -1,4 +1,4 @@
import { getFlattenedCanvasBlob } from './CanvasBlobUtils.js';
import { getFlattenedCanvasBlob } from './canvas_blob_utils.js';
function openBlob(blob) {
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
@@ -1,9 +1,9 @@
// @ts-ignore
import { api } from "../../../scripts/api.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { resolveCanvasBlob } from './CanvasBlobUtils.js';
import { loadImage } from './ImageUtils.js';
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
import { resolveCanvasBlob } from './canvas_blob_utils.js';
import { loadImage } from './image_utils.js';
const log = createModuleLogger('ImageUploadUtils');
export async function postImageBlob(request, transport = (input, init) => api.fetchApi(input, init)) {
const formData = new FormData();
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
import { createCanvas } from "../utils/common_utils.js";
const log = createModuleLogger('ImageUtils');
function tensorToRgbaPixels(tensor, dimensionsLog) {
const shape = tensor.shape;
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { resolveCanvasBlob, supportsFlattenedCanvasBlob } from './CanvasBlobUtils.js';
import { loadImage, loadImageFromBlob } from './ImageUtils.js';
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
import { resolveCanvasBlob, supportsFlattenedCanvasBlob } from './canvas_blob_utils.js';
import { loadImage, loadImageFromBlob } from './image_utils.js';
const log = createModuleLogger('PreviewUtils');
export async function loadPreviewImage(blob, options) {
const isCanvasSource = options.source === 'canvas';
@@ -1,4 +1,4 @@
import { generateUUID } from "./CommonUtils.js";
import { generateUUID } from "./common_utils.js";
const WORKFLOW_ID_PROPERTY = "__layerForgeWorkflowId";
const WORKFLOW_EXTRA_ID = "layerforgeWorkflowId";
function getRootGraph(node) {
@@ -1,8 +1,8 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showNotification, showInfoNotification, showErrorNotification, showWarningNotification } from "./NotificationUtils.js";
import { withErrorHandling, createValidationError, createNetworkError, createFileError } from "../shared/ErrorHandler.js";
import { safeClipspacePaste } from "./ClipspaceUtils.js";
import { loadImage, loadImageFromBlob } from "../media/ImageUtils.js";
import { showNotification, showInfoNotification, showErrorNotification, showWarningNotification } from "./notification_utils.js";
import { withErrorHandling, createValidationError, createNetworkError, createFileError } from "../shared/error_handler.js";
import { safeClipspacePaste } from "./clipspace_utils.js";
import { loadImage, loadImageFromBlob } from "../media/image_utils.js";
// @ts-ignore
import { api } from "../../../scripts/api.js";
const log = createModuleLogger('ClipboardManager');
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "./CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "./common_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('IconLoader');
// Define tool constants for LayerForge
export const LAYERFORGE_TOOLS = {
@@ -1,7 +1,7 @@
// @ts-ignore
import { $el } from "../../../scripts/ui.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
const log = createModuleLogger('ResourceManager');
export const addStylesheet = withErrorHandling(function (url) {
if (!url) {
@@ -1,5 +1,5 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
const log = createModuleLogger('WebSocketManager');
export class WebSocketManager {
constructor(url) {
+1 -1
View File
@@ -10,7 +10,7 @@
"test:coverage": "node --experimental-test-coverage --test tests/*.mjs",
"lint": "eslint js/ tests/ --max-warnings=0",
"lint:fix": "eslint js/ tests/ --fix",
"test:coverage:critical": "node --experimental-test-coverage --test-coverage-include=js/canvas/CanvasHistory.js --test-coverage-include=js/persistence/contracts.js --test-coverage-include=js/utils/WebSocketManager.js --test-coverage-lines=65 --test-coverage-functions=65 --test-coverage-branches=50 --test tests/test_canvas_history.mjs tests/test_persistence_contracts.mjs tests/test_persistence_resilience.mjs tests/test_async_lifecycle_resilience.mjs",
"test:coverage:critical": "node --experimental-test-coverage --test-coverage-include=js/canvas/canvas_history.js --test-coverage-include=js/persistence/contracts.js --test-coverage-include=js/utils/web_socket_manager.js --test-coverage-lines=65 --test-coverage-functions=65 --test-coverage-branches=50 --test tests/test_canvas_history.mjs tests/test_persistence_contracts.mjs tests/test_persistence_resilience.mjs tests/test_async_lifecycle_resilience.mjs",
"watch": ".\\node_modules\\.bin\\tsc.cmd --watch",
"watch:build": "nodemon --watch src --ext ts,css,html --exec .\\build.bat"
},
@@ -9,10 +9,10 @@ import {ChangeTracker} from "../../../scripts/changeTracker.js";
// @ts-ignore
import {$el} from "../../../scripts/ui.js";
import { addStylesheet, getUrl, loadTemplate } from "../utils/ResourceManager.js";
import { addStylesheet, getUrl, loadTemplate } from "../utils/resource_manager.js";
import {Canvas, configureCanvasImagePreviewWidget} from "../canvas/Canvas.js";
import type {CanvasWidget} from "./CanvasWidgetTypes.js";
import {Canvas, configureCanvasImagePreviewWidget} from "../canvas/canvas.js";
import type {CanvasWidget} from "./canvas_widget_types.js";
import {
canvasNodeInstances,
installLayerForgeMultiImagePromptPatch,
@@ -20,18 +20,18 @@ import {
isLayerForgeTransportInput,
pruneLayerForgeTransportInputs,
scheduleLayerForgeImageConnectionConversion,
} from "./LayerForgeConnections.js";
} from "./layer_forge_connections.js";
import {clearAllCanvasStates, getCanvasState, setCanvasState} from "../persistence/db.js";
import {getCanvasStateKey} from "../utils/CanvasStateKey.js";
import {generateUniqueFileName, createCanvas} from "../utils/CommonUtils.js";
import { loadImageFromBlob } from "../media/ImageUtils.js";
import {getCanvasStateKey} from "../utils/canvas_state_key.js";
import {generateUniqueFileName, createCanvas} from "../utils/common_utils.js";
import { loadImageFromBlob } from "../media/image_utils.js";
import {createModuleLogger} from "../log_system/log_funcs.js";
import {showErrorNotification, showSuccessNotification, showInfoNotification, showWarningNotification} from "../utils/NotificationUtils.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/IconLoader.js";
import { exportCanvasImage, type CanvasExportAction } from "../media/CanvasExportUtils.js";
import { getFlattenedCanvasBlob, type CanvasBlobVariant } from "../media/CanvasBlobUtils.js";
import { loadPreviewImage } from "../media/PreviewUtils.js";
import { getImageAddMode } from "../utils/CanvasInputUtils.js";
import {showErrorNotification, showSuccessNotification, showInfoNotification, showWarningNotification} from "../utils/notification_utils.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/icon_loader.js";
import { exportCanvasImage, type CanvasExportAction } from "../media/canvas_export_utils.js";
import { getFlattenedCanvasBlob, type CanvasBlobVariant } from "../media/canvas_blob_utils.js";
import { loadPreviewImage } from "../media/preview_utils.js";
import { getImageAddMode } from "../utils/canvas_input_utils.js";
import {
addLayerForgeImageInputLink,
clearLayerForgeImageInputLinks,
@@ -41,15 +41,15 @@ import {
hasLayerForgeImageInput,
LAYERFORGE_MAX_IMAGE_INPUTS,
removeLayerForgeImageInputLink,
} from "../utils/MultiImageInputUtils.js";
} from "../utils/multi_image_input_utils.js";
import {
fetchMattingModelStatus,
fetchMattingSettings,
saveMattingSettings as saveMattingSettingsToServer,
type MattingServerSettings,
type MattingSettingsUpdate,
} from "../utils/MattingUtils.js";
import { cancelSAMDetectorMonitoring, registerImageInClipspace, startSAMDetectorMonitoring, setupSAMDetectorHook } from "../mask/SAMDetectorIntegration.js";
} from "../utils/matting_utils.js";
import { cancelSAMDetectorMonitoring, registerImageInClipspace, startSAMDetectorMonitoring, setupSAMDetectorHook } from "../mask/sam_detector_integration.js";
import type { ComfyNode, Layer, AddMode } from '../shared/types';
const log = createModuleLogger('Canvas_view');
@@ -1,4 +1,4 @@
import type { Canvas } from "../canvas/Canvas.js";
import type { Canvas } from "../canvas/canvas.js";
export interface CanvasWidget {
canvas: Canvas;
@@ -2,7 +2,7 @@
// @ts-ignore
import {app} from "../../../scripts/app.js";
import {showErrorNotification} from "../utils/NotificationUtils.js";
import {showErrorNotification} from "../utils/notification_utils.js";
import {
addLayerForgeImageInputLink,
clearLayerForgeImageInputLinks,
@@ -12,8 +12,8 @@ import {
hasLayerForgeImageInput,
LAYERFORGE_MAX_IMAGE_INPUTS,
removeLayerForgeImageInputLink,
} from "../utils/MultiImageInputUtils.js";
import type {CanvasWidget} from "./CanvasWidgetTypes.js";
} from "../utils/multi_image_input_utils.js";
import type {CanvasWidget} from "./canvas_widget_types.js";
export const canvasNodeInstances = new Map<number, CanvasWidget>();
@@ -1,5 +1,5 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import type { Canvas } from './Canvas';
import type { Canvas } from './canvas';
import type { Layer, Point } from '../shared/types';
const log = createModuleLogger('BatchPreviewManager');
+17 -17
View File
@@ -6,23 +6,23 @@ import {app} from "../../../scripts/app.js";
import {ComfyApp} from "../../../scripts/app.js";
import {removeImage} from "../persistence/db.js";
import {MaskTool} from "../mask/MaskTool.js";
import {ShapeTool} from "./ShapeTool.js";
import {CustomShapeMenu} from "./CustomShapeMenu.js";
import {CanvasState} from "./CanvasState.js";
import {CanvasInteractions} from "./CanvasInteractions.js";
import {CanvasLayers} from "./CanvasLayers.js";
import {CanvasLayersPanel} from "./CanvasLayersPanel.js";
import {CanvasRenderer} from "./CanvasRenderer.js";
import {CanvasIO} from "../io/CanvasIO.js";
import {ImageReferenceManager} from "../persistence/ImageReferenceManager.js";
import {BatchPreviewManager} from "./BatchPreviewManager.js";
import {ImageCache} from "../media/ImageCache.js";
import {MaskTool} from "../mask/mask_tool.js";
import {ShapeTool} from "./shape_tool.js";
import {CustomShapeMenu} from "./custom_shape_menu.js";
import {CanvasState} from "./canvas_state.js";
import {CanvasInteractions} from "./canvas_interactions.js";
import {CanvasLayers} from "./canvas_layers.js";
import {CanvasLayersPanel} from "./canvas_layers_panel.js";
import {CanvasRenderer} from "./canvas_renderer.js";
import {CanvasIO} from "../io/canvas_io.js";
import {ImageReferenceManager} from "../persistence/image_reference_manager.js";
import {BatchPreviewManager} from "./batch_preview_manager.js";
import {ImageCache} from "../media/image_cache.js";
import {createModuleLogger} from "../log_system/log_funcs.js";
import { debounce, createCanvas } from "../utils/CommonUtils.js";
import {MaskEditorIntegration} from "../mask/MaskEditorIntegration.js";
import {CanvasSelection} from "./CanvasSelection.js";
import {removeLayersWithLifecycle} from "../utils/LayerRemovalUtils.js";
import { debounce, createCanvas } from "../utils/common_utils.js";
import {MaskEditorIntegration} from "../mask/mask_editor_integration.js";
import {CanvasSelection} from "./canvas_selection.js";
import {removeLayersWithLifecycle} from "../utils/layer_removal_utils.js";
import type { ComfyNode, Layer, Viewport, Point, AddMode, Shape, OutputAreaBounds } from '../shared/types';
const useChainCallback = (original: any, next: any) => {
@@ -271,7 +271,7 @@ export class Canvas {
this.node.setDirtyCanvas?.(true, true);
this.render();
} else {
log.warn("$$canvas-image-preview widget not found in Canvas.js");
log.warn("$$canvas-image-preview widget not found in canvas.js");
}
}
@@ -1,8 +1,8 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { snapToGrid, getSnapAdjustment, isPointInRotatedLayer } from "../utils/CommonUtils.js";
import { loadImageFromBlob } from "../media/ImageUtils.js";
import { getImageAddMode } from "../utils/CanvasInputUtils.js";
import type { Canvas } from './Canvas';
import { snapToGrid, getSnapAdjustment, isPointInRotatedLayer } from "../utils/common_utils.js";
import { loadImageFromBlob } from "../media/image_utils.js";
import { getImageAddMode } from "../utils/canvas_input_utils.js";
import type { Canvas } from './canvas';
import type { Layer, Point } from '../shared/types';
const log = createModuleLogger('CanvasInteractions');
@@ -10,19 +10,19 @@ import {
isPointInRotatedLayer,
localToWorld,
worldToLayerLocal
} from "../utils/CommonUtils.js";
import {withErrorHandling, createValidationError} from "../shared/ErrorHandler.js";
import {showErrorNotification, showSuccessNotification} from "../utils/NotificationUtils.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
} from "../utils/common_utils.js";
import {withErrorHandling, createValidationError} from "../shared/error_handler.js";
import {showErrorNotification, showSuccessNotification} from "../utils/notification_utils.js";
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
// @ts-ignore
import {app} from "../../../scripts/app.js";
// @ts-ignore
import {ComfyApp} from "../../../scripts/app.js";
import { ClipboardManager } from "../utils/ClipboardManager.js";
import { createDistanceFieldMaskSync } from "../mask/ImageAnalysis.js";
import { fillInverseAlphaMask } from "../mask/MaskPixelUtils.js";
import { blobToDataUrl } from "../media/ImageUtils.js";
import type { Canvas } from './Canvas';
import { ClipboardManager } from "../utils/clipboard_manager.js";
import { createDistanceFieldMaskSync } from "../mask/image_analysis.js";
import { fillInverseAlphaMask } from "../mask/mask_pixel_utils.js";
import { blobToDataUrl } from "../media/image_utils.js";
import type { Canvas } from './canvas';
import type { Layer, Point, AddMode, ClipboardPreference } from '../shared/types';
const log = createModuleLogger('CanvasLayers');
@@ -1,8 +1,8 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/IconLoader.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
import type { Canvas } from './Canvas';
import { iconLoader, LAYERFORGE_TOOLS } from "../utils/icon_loader.js";
import { createCanvas } from "../utils/common_utils.js";
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
import type { Canvas } from './canvas';
import type { Layer } from '../shared/types';
const log = createModuleLogger('CanvasLayersPanel');
@@ -1,5 +1,5 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { getBoundsFromPoints, getLayerWorldBounds, isPointInRotatedLayer, localToWorld, worldToLocal } from "../utils/CommonUtils.js";
import { getBoundsFromPoints, getLayerWorldBounds, isPointInRotatedLayer, localToWorld, worldToLocal } from "../utils/common_utils.js";
const log = createModuleLogger('CanvasRenderer');
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { generateUUID } from "../utils/CommonUtils.js";
import { removeLayersWithLifecycle } from "../utils/LayerRemovalUtils.js";
import { generateUUID } from "../utils/common_utils.js";
import { removeLayersWithLifecycle } from "../utils/layer_removal_utils.js";
const log = createModuleLogger('CanvasSelection');
@@ -1,12 +1,12 @@
import {getCanvasState, setCanvasState, saveImage, getImage} from "../persistence/db.js";
import {createModuleLogger} from "../log_system/log_funcs.js";
import {showAlertNotification, showAllNotificationTypes} from "../utils/NotificationUtils.js";
import {generateUUID, cloneLayers, getStateSignature, debounce, createCanvas, cloneCanvas} from "../utils/CommonUtils.js";
import {loadImage} from "../media/ImageUtils.js";
import {getCanvasStateKey} from "../utils/CanvasStateKey.js";
import {withErrorHandling} from "../shared/ErrorHandler.js";
import {HistoryStack, type HistoryInfo} from "./CanvasHistory.js";
import type { Canvas } from './Canvas';
import {showAlertNotification, showAllNotificationTypes} from "../utils/notification_utils.js";
import {generateUUID, cloneLayers, getStateSignature, debounce, createCanvas, cloneCanvas} from "../utils/common_utils.js";
import {loadImage} from "../media/image_utils.js";
import {getCanvasStateKey} from "../utils/canvas_state_key.js";
import {withErrorHandling} from "../shared/error_handler.js";
import {HistoryStack, type HistoryInfo} from "./canvas_history.js";
import type { Canvas } from './canvas';
import type { Layer, ComfyNode } from '../shared/types';
import {
CURRENT_PERSISTED_STATE_VERSION,
@@ -66,7 +66,7 @@ export class CanvasState {
try {
// @ts-ignore
this.stateSaverWorker = new Worker(new URL('../persistence/state-saver.worker.js', import.meta.url), { type: 'module' });
this.stateSaverWorker = new Worker(new URL('../persistence/state_saver.worker.js', import.meta.url), { type: 'module' });
log.info("State saver worker initialized successfully.");
this.stateSaverWorker.onmessage = (e: MessageEvent) => {
@@ -1,6 +1,6 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { addStylesheet, getUrl } from "../utils/ResourceManager.js";
import type { Canvas } from './Canvas';
import { addStylesheet, getUrl } from "../utils/resource_manager.js";
import type { Canvas } from './canvas';
const log = createModuleLogger('CustomShapeMenu');
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { getBoundsFromPoints } from '../utils/CommonUtils.js';
import type { Canvas } from './Canvas.js';
import { getBoundsFromPoints } from '../utils/common_utils.js';
import type { Canvas } from './canvas.js';
import type { Point } from '../shared/types.js';
const log = createModuleLogger('ShapeTool');
+1 -1
View File
@@ -1,6 +1,6 @@
// Stable frontend entrypoint loaded by ComfyUI.
// The implementation module is also served recursively, so registration is
// intentionally invoked only from this root bootstrap.
import { registerLayerForgeExtension } from "./app/CanvasView.js";
import { registerLayerForgeExtension } from "./app/canvas_view.js";
registerLayerForgeExtension();
+8 -8
View File
@@ -1,18 +1,18 @@
import { createCanvas } from "../utils/CommonUtils.js";
import { createCanvas } from "../utils/common_utils.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showErrorNotification } from "../utils/NotificationUtils.js";
import { webSocketManager } from "../utils/WebSocketManager.js";
import { scaleImageToFit, loadImage, blobToDataUrl, tensorToImageData, createImageFromImageData } from "../media/ImageUtils.js";
import { postImageBlob } from "../media/ImageUploadUtils.js";
import { getImageAddMode, isFitOnAddEnabled } from "../utils/CanvasInputUtils.js";
import { showErrorNotification } from "../utils/notification_utils.js";
import { webSocketManager } from "../utils/web_socket_manager.js";
import { scaleImageToFit, loadImage, blobToDataUrl, tensorToImageData, createImageFromImageData } from "../media/image_utils.js";
import { postImageBlob } from "../media/image_upload_utils.js";
import { getImageAddMode, isFitOnAddEnabled } from "../utils/canvas_input_utils.js";
import {
getLayerForgeImageInputLinks,
getLayerForgeImageInputSlot,
getLayerForgeMaskInputSlot,
hasLayerForgeImageInput,
removeLayerForgeImageInputLink,
} from "../utils/MultiImageInputUtils.js";
import type { Canvas } from '../canvas/Canvas';
} from "../utils/multi_image_input_utils.js";
import type { Canvas } from '../canvas/canvas';
import type { Layer, Shape, AddMode } from '../shared/types';
const log = createModuleLogger('CanvasIO');
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { calculateDistanceTransform, rasterizeDistanceFieldMask } from "./MaskPixelUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/common_utils.js";
import { calculateDistanceTransform, rasterizeDistanceFieldMask } from "./mask_pixel_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('ImageAnalysis');
@@ -5,15 +5,15 @@ import {ComfyApp} from "../../../scripts/app.js";
// @ts-ignore
import {api} from "../../../scripts/api.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showErrorNotification } from "../utils/NotificationUtils.js";
import { uploadCanvasAsImage, uploadCanvasWithMaskAsImage, uploadImageBlob } from "../media/ImageUploadUtils.js";
import { processMaskForViewport } from "./MaskProcessingUtils.js";
import { applyMaskResultToTool } from "./MaskResultUtils.js";
import { updateNodePreview } from "../media/PreviewUtils.js";
import { showErrorNotification } from "../utils/notification_utils.js";
import { uploadCanvasAsImage, uploadCanvasWithMaskAsImage, uploadImageBlob } from "../media/image_upload_utils.js";
import { processMaskForViewport } from "./mask_processing_utils.js";
import { applyMaskResultToTool } from "./mask_result_utils.js";
import { updateNodePreview } from "../media/preview_utils.js";
import { mask_editor_showing, mask_editor_listen_for_cancel } from "./mask_utils.js";
import { cloneCanvas } from "../utils/CommonUtils.js";
import { getFlattenedCanvasBlob } from "../media/CanvasBlobUtils.js";
import { loadImage } from "../media/ImageUtils.js";
import { cloneCanvas } from "../utils/common_utils.js";
import { getFlattenedCanvasBlob } from "../media/canvas_blob_utils.js";
import { loadImage } from "../media/image_utils.js";
const log = createModuleLogger('MaskEditorIntegration');
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "../utils/CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/common_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('MaskProcessingUtils');
@@ -1,5 +1,5 @@
import {convertToImage} from "../media/ImageUtils.js";
import {processImageToMask} from "./MaskProcessingUtils.js";
import {convertToImage} from "../media/image_utils.js";
import {processImageToMask} from "./mask_processing_utils.js";
export interface MaskResultOptions {
targetWidth: number;
@@ -1,12 +1,12 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { createCanvas, createCanvasWithContext } from "../utils/CommonUtils.js";
import { createCanvas, createCanvasWithContext } from "../utils/common_utils.js";
import {
applyLuminanceAsAlpha,
calculateDistanceTransform,
imageDataToBinaryMask,
rasterizeDistanceFieldMask
} from "./MaskPixelUtils.js";
import type { Canvas } from '../canvas/Canvas';
} from "./mask_pixel_utils.js";
import type { Canvas } from '../canvas/canvas';
import type { Point, CanvasState, Layer } from '../shared/types';
const log = createModuleLogger('Mask_tool');
+2 -2
View File
@@ -1,6 +1,6 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import type { Canvas } from '../canvas/Canvas.js';
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
import type { Canvas } from '../canvas/canvas.js';
// @ts-ignore
import {ComfyApp} from "../../../scripts/app.js";
@@ -3,11 +3,11 @@ import { api } from "../../../scripts/api.js";
// @ts-ignore
import { ComfyApp } from "../../../scripts/app.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { showInfoNotification, showSuccessNotification, showErrorNotification } from "../utils/NotificationUtils.js";
import { uploadCanvasAsImage, uploadImageBlob } from "../media/ImageUploadUtils.js";
import { applyMaskResultToTool } from "./MaskResultUtils.js";
import { updateNodePreview } from "../media/PreviewUtils.js";
import { validateAndFixClipspace } from "../utils/ClipspaceUtils.js";
import { showInfoNotification, showSuccessNotification, showErrorNotification } from "../utils/notification_utils.js";
import { uploadCanvasAsImage, uploadImageBlob } from "../media/image_upload_utils.js";
import { applyMaskResultToTool } from "./mask_result_utils.js";
import { updateNodePreview } from "../media/preview_utils.js";
import { validateAndFixClipspace } from "../utils/clipspace_utils.js";
import type { ComfyNode } from '../shared/types';
const log = createModuleLogger('SAMDetectorIntegration');
@@ -1,4 +1,4 @@
import { getFlattenedCanvasBlob, type CanvasBlobVariant } from './CanvasBlobUtils.js';
import { getFlattenedCanvasBlob, type CanvasBlobVariant } from './canvas_blob_utils.js';
export type CanvasExportAction = 'open' | 'copy' | 'download';
@@ -1,9 +1,9 @@
// @ts-ignore
import { api } from "../../../scripts/api.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { resolveCanvasBlob, type CanvasBlobVariant } from './CanvasBlobUtils.js';
import { loadImage } from './ImageUtils.js';
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
import { resolveCanvasBlob, type CanvasBlobVariant } from './canvas_blob_utils.js';
import { loadImage } from './image_utils.js';
const log = createModuleLogger('ImageUploadUtils');
@@ -1,6 +1,6 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import {withErrorHandling, createValidationError} from "../shared/ErrorHandler.js";
import { createCanvas } from "../utils/CommonUtils.js";
import {withErrorHandling, createValidationError} from "../shared/error_handler.js";
import { createCanvas } from "../utils/common_utils.js";
import type { Tensor, ImageDataPixel } from '../shared/types';
const log = createModuleLogger('ImageUtils');
@@ -1,7 +1,7 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { resolveCanvasBlob, supportsFlattenedCanvasBlob, type CanvasBlobVariant } from './CanvasBlobUtils.js';
import { loadImage, loadImageFromBlob } from './ImageUtils.js';
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
import { resolveCanvasBlob, supportsFlattenedCanvasBlob, type CanvasBlobVariant } from './canvas_blob_utils.js';
import { loadImage, loadImageFromBlob } from './image_utils.js';
import type { ComfyNode } from '../shared/types';
const log = createModuleLogger('PreviewUtils');
@@ -1,6 +1,6 @@
import {removeImage, getAllImageIds} from "./db.js";
import {createModuleLogger} from "../log_system/log_funcs.js";
import type { Canvas } from '../canvas/Canvas';
import type { Canvas } from '../canvas/canvas';
import type { Layer, CanvasState } from '../shared/types';
const log = createModuleLogger('ImageReferenceManager');
+2 -2
View File
@@ -1,5 +1,5 @@
import type { Canvas as CanvasClass } from '../canvas/Canvas';
import type { CanvasLayers } from '../canvas/CanvasLayers';
import type { Canvas as CanvasClass } from '../canvas/canvas';
import type { CanvasLayers } from '../canvas/canvas_layers';
export interface ComfyWidget {
name: string;
@@ -1,4 +1,4 @@
import {generateUUID} from "./CommonUtils.js";
import {generateUUID} from "./common_utils.js";
const WORKFLOW_ID_PROPERTY = "__layerForgeWorkflowId";
const WORKFLOW_EXTRA_ID = "layerforgeWorkflowId";
@@ -1,8 +1,8 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { showNotification, showInfoNotification, showErrorNotification, showWarningNotification } from "./NotificationUtils.js";
import { withErrorHandling, createValidationError, createNetworkError, createFileError } from "../shared/ErrorHandler.js";
import { safeClipspacePaste } from "./ClipspaceUtils.js";
import { loadImage, loadImageFromBlob } from "../media/ImageUtils.js";
import { showNotification, showInfoNotification, showErrorNotification, showWarningNotification } from "./notification_utils.js";
import { withErrorHandling, createValidationError, createNetworkError, createFileError } from "../shared/error_handler.js";
import { safeClipspacePaste } from "./clipspace_utils.js";
import { loadImage, loadImageFromBlob } from "../media/image_utils.js";
// @ts-ignore
import {api} from "../../../scripts/api.js";
@@ -1,6 +1,6 @@
import { createModuleLogger } from "../log_system/log_funcs.js";
import { createCanvas } from "./CommonUtils.js";
import { withErrorHandling, createValidationError } from "../shared/ErrorHandler.js";
import { createCanvas } from "./common_utils.js";
import { withErrorHandling, createValidationError } from "../shared/error_handler.js";
const log = createModuleLogger('IconLoader');
@@ -1,7 +1,7 @@
// @ts-ignore
import { $el } from "../../../scripts/ui.js";
import { createModuleLogger } from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
const log = createModuleLogger('ResourceManager');
@@ -1,5 +1,5 @@
import {createModuleLogger} from "../log_system/log_funcs.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/ErrorHandler.js";
import { withErrorHandling, createValidationError, createNetworkError } from "../shared/error_handler.js";
import type { WebSocketMessage, AckCallbacks } from "../shared/types.js";
const log = createModuleLogger('WebSocketManager');
+5 -5
View File
@@ -2,9 +2,9 @@ import assert from 'node:assert/strict';
import { access, readFile } from 'node:fs/promises';
import test from 'node:test';
const canvasViewPath = new URL('../src/app/CanvasView.ts', import.meta.url);
const widgetTypesPath = new URL('../src/app/CanvasWidgetTypes.ts', import.meta.url);
const connectionsPath = new URL('../src/app/LayerForgeConnections.ts', import.meta.url);
const canvasViewPath = new URL('../src/app/canvas_view.ts', import.meta.url);
const widgetTypesPath = new URL('../src/app/canvas_widget_types.ts', import.meta.url);
const connectionsPath = new URL('../src/app/layer_forge_connections.ts', import.meta.url);
test('app integration responsibilities have dedicated modules', async () => {
await Promise.all([
@@ -15,8 +15,8 @@ test('app integration responsibilities have dedicated modules', async () => {
const canvasViewSource = await readFile(canvasViewPath, 'utf8');
const connectionsSource = await readFile(connectionsPath, 'utf8');
assert.match(canvasViewSource, /from ["']\.\/CanvasWidgetTypes\.js["']/);
assert.match(canvasViewSource, /from ["']\.\/LayerForgeConnections\.js["']/);
assert.match(canvasViewSource, /from ["']\.\/canvas_widget_types\.js["']/);
assert.match(canvasViewSource, /from ["']\.\/layer_forge_connections\.js["']/);
assert.match(connectionsSource, /export const canvasNodeInstances/);
assert.match(connectionsSource, /export const installLayerForgeVirtualWirePatch/);
assert.match(connectionsSource, /export const installLayerForgeMultiImagePromptPatch/);
+3 -3
View File
@@ -50,7 +50,7 @@ function extractImports(source) {
function getDomain(filePath) {
const pathFromRoot = relative(SRC_ROOT, filePath);
const [domain] = pathFromRoot.split(sep);
return domain === 'CanvasView.ts' ? 'root' : domain;
return domain === 'canvas_view.ts' ? 'root' : domain;
}
function getImportedDomain(importerPath, specifier) {
@@ -70,9 +70,9 @@ test('source root contains only the stable ComfyUI bootstrap', async () => {
.map((filePath) => relative(SRC_ROOT, filePath))
.sort();
assert.deepEqual(rootFiles, ['CanvasView.ts']);
assert.deepEqual(rootFiles, ['canvas_view.ts']);
const bootstrapSource = await readFile(resolve(SRC_ROOT, 'CanvasView.ts'), 'utf8');
const bootstrapSource = await readFile(resolve(SRC_ROOT, 'canvas_view.ts'), 'utf8');
assert.match(bootstrapSource, /registerLayerForgeExtension\(\);/);
assert.doesNotMatch(bootstrapSource, /app\.registerExtension\(/);
});
+5 -5
View File
@@ -49,7 +49,7 @@ test('WebSocket manager reconnects and rejects pending acknowledgements on destr
});
try {
const { WebSocketManager, webSocketManager } = await import('../js/utils/WebSocketManager.js?resilience');
const { WebSocketManager, webSocketManager } = await import('../js/utils/web_socket_manager.js?resilience');
const manager = new WebSocketManager('ws://localhost/layerforge/canvas_ws');
manager.reconnectInterval = 0;
@@ -87,10 +87,10 @@ test('WebSocket manager reconnects and rejects pending acknowledgements on destr
test('async integrations cancel work and ignore results after their owner is destroyed', async () => {
const [canvasSource, samSource, maskSource, canvasStateSource] = await Promise.all([
readFile(new URL('../src/app/CanvasView.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/SAMDetectorIntegration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/MaskEditorIntegration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/CanvasState.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/app/canvas_view.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/sam_detector_integration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/mask_editor_integration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/canvas_state.ts', import.meta.url), 'utf8'),
]);
assert.match(canvasSource, /new AbortController\(\)/);
@@ -3,8 +3,8 @@ import { readFile } from 'node:fs/promises';
import test from 'node:test';
const [canvasIOSource, maskEditorSource] = await Promise.all([
readFile(new URL('../src/io/CanvasIO.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/MaskEditorIntegration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/io/canvas_io.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/mask_editor_integration.ts', import.meta.url), 'utf8'),
]);
function getMethodBody(source, methodName, nextMethodName) {
@@ -2,15 +2,15 @@ import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import test from 'node:test';
import { blobToDataUrl, loadImageFromBlob } from '../js/media/ImageUtils.js';
import { blobToDataUrl, loadImageFromBlob } from '../js/media/image_utils.js';
const sourceFiles = await Promise.all([
readFile(new URL('../src/media/ImageUtils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/utils/ClipboardManager.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/CanvasInteractions.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/app/CanvasView.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/CanvasLayers.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/io/CanvasIO.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/image_utils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/utils/clipboard_manager.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/canvas_interactions.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/app/canvas_view.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/canvas/canvas_layers.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/io/canvas_io.ts', import.meta.url), 'utf8'),
]);
test('Blob and File image entry points use the shared loading helpers', () => {
+7 -7
View File
@@ -6,15 +6,15 @@ import {
getFlattenedCanvasBlob,
resolveCanvasBlob,
supportsFlattenedCanvasBlob,
} from '../js/media/CanvasBlobUtils.js';
import { createPreviewFromCanvas } from '../js/media/PreviewUtils.js';
} from '../js/media/canvas_blob_utils.js';
import { createPreviewFromCanvas } from '../js/media/preview_utils.js';
const sourceFiles = await Promise.all([
readFile(new URL('../src/media/ImageUploadUtils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/PreviewUtils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/MaskEditorIntegration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/app/CanvasView.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/CanvasBlobUtils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/image_upload_utils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/preview_utils.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/mask/mask_editor_integration.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/app/canvas_view.ts', import.meta.url), 'utf8'),
readFile(new URL('../src/media/canvas_blob_utils.ts', import.meta.url), 'utf8'),
]);
function installPreviewStubs() {

Some files were not shown because too many files have changed in this diff Show More