Refactor codebase for consistent formatting and style

This commit applies consistent code formatting across multiple files, including spacing, indentation, and object destructuring. No functional changes were made; the update improves code readability and maintainability.
This commit is contained in:
Dariusz L
2025-06-27 07:13:20 +02:00
parent b40d645a79
commit 375ed6a2b8
13 changed files with 163 additions and 143 deletions

View File

@@ -7,6 +7,7 @@ import {CanvasRenderer} from "./CanvasRenderer.js";
import {CanvasIO} from "./CanvasIO.js"; import {CanvasIO} from "./CanvasIO.js";
import {ImageReferenceManager} from "./ImageReferenceManager.js"; import {ImageReferenceManager} from "./ImageReferenceManager.js";
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
const log = createModuleLogger('Canvas'); const log = createModuleLogger('Canvas');
export class Canvas { export class Canvas {
@@ -45,7 +46,7 @@ export class Canvas {
this.canvasIO = new CanvasIO(this); this.canvasIO = new CanvasIO(this);
this.imageReferenceManager = new ImageReferenceManager(this); this.imageReferenceManager = new ImageReferenceManager(this);
this.interaction = this.canvasInteractions.interaction; this.interaction = this.canvasInteractions.interaction;
this.setupEventListeners(); this.setupEventListeners();
this.initNodeData(); this.initNodeData();
@@ -137,6 +138,7 @@ export class Canvas {
this.onSelectionChange(); this.onSelectionChange();
} }
} }
async copySelectedLayers() { async copySelectedLayers() {
return this.canvasLayers.copySelectedLayers(); return this.canvasLayers.copySelectedLayers();
} }
@@ -265,8 +267,6 @@ export class Canvas {
} }
async getFlattenedCanvasAsBlob() { async getFlattenedCanvasAsBlob() {
return this.canvasLayers.getFlattenedCanvasAsBlob(); return this.canvasLayers.getFlattenedCanvasAsBlob();
} }

View File

@@ -26,7 +26,7 @@ export class CanvasIO {
log.info(`Starting saveToServer (disk) with fileName: ${fileName} for node: ${nodeId}`); log.info(`Starting saveToServer (disk) with fileName: ${fileName} for node: ${nodeId}`);
this._saveInProgress = this._performSave(fileName, outputMode); this._saveInProgress = this._performSave(fileName, outputMode);
window.canvasSaveStates.set(saveKey, this._saveInProgress); window.canvasSaveStates.set(saveKey, this._saveInProgress);
try { try {
return await this._saveInProgress; return await this._saveInProgress;
} finally { } finally {
@@ -54,25 +54,25 @@ export class CanvasIO {
} }
return new Promise((resolve) => { return new Promise((resolve) => {
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(this.canvas.width, this.canvas.height); const {canvas: tempCanvas, ctx: tempCtx} = createCanvas(this.canvas.width, this.canvas.height);
const { canvas: maskCanvas, ctx: maskCtx } = createCanvas(this.canvas.width, this.canvas.height); const {canvas: maskCanvas, ctx: maskCtx} = createCanvas(this.canvas.width, this.canvas.height);
tempCtx.fillStyle = '#ffffff'; tempCtx.fillStyle = '#ffffff';
tempCtx.fillRect(0, 0, this.canvas.width, this.canvas.height); tempCtx.fillRect(0, 0, this.canvas.width, this.canvas.height);
const visibilityCanvas = document.createElement('canvas'); const visibilityCanvas = document.createElement('canvas');
visibilityCanvas.width = this.canvas.width; visibilityCanvas.width = this.canvas.width;
visibilityCanvas.height = this.canvas.height; visibilityCanvas.height = this.canvas.height;
const visibilityCtx = visibilityCanvas.getContext('2d', { alpha: true }); const visibilityCtx = visibilityCanvas.getContext('2d', {alpha: true});
maskCtx.fillStyle = '#ffffff'; maskCtx.fillStyle = '#ffffff';
maskCtx.fillRect(0, 0, this.canvas.width, this.canvas.height); maskCtx.fillRect(0, 0, this.canvas.width, this.canvas.height);
log.debug(`Canvas contexts created, starting layer rendering`); log.debug(`Canvas contexts created, starting layer rendering`);
const sortedLayers = this.canvas.layers.sort((a, b) => a.zIndex - b.zIndex); const sortedLayers = this.canvas.layers.sort((a, b) => a.zIndex - b.zIndex);
log.debug(`Processing ${sortedLayers.length} layers in order`); log.debug(`Processing ${sortedLayers.length} layers in order`);
sortedLayers.forEach((layer, index) => { sortedLayers.forEach((layer, index) => {
log.debug(`Processing layer ${index}: zIndex=${layer.zIndex}, size=${layer.width}x${layer.height}, pos=(${layer.x},${layer.y})`); log.debug(`Processing layer ${index}: zIndex=${layer.zIndex}, size=${layer.width}x${layer.height}, pos=(${layer.x},${layer.y})`);
log.debug(`Layer ${index}: blendMode=${layer.blendMode || 'normal'}, opacity=${layer.opacity !== undefined ? layer.opacity : 1}`); log.debug(`Layer ${index}: blendMode=${layer.blendMode || 'normal'}, opacity=${layer.opacity !== undefined ? layer.opacity : 1}`);
tempCtx.save(); tempCtx.save();
tempCtx.globalCompositeOperation = layer.blendMode || 'normal'; tempCtx.globalCompositeOperation = layer.blendMode || 'normal';
tempCtx.globalAlpha = layer.opacity !== undefined ? layer.opacity : 1; tempCtx.globalAlpha = layer.opacity !== undefined ? layer.opacity : 1;
@@ -80,7 +80,7 @@ export class CanvasIO {
tempCtx.rotate(layer.rotation * Math.PI / 180); tempCtx.rotate(layer.rotation * Math.PI / 180);
tempCtx.drawImage(layer.image, -layer.width / 2, -layer.height / 2, layer.width, layer.height); tempCtx.drawImage(layer.image, -layer.width / 2, -layer.height / 2, layer.width, layer.height);
tempCtx.restore(); tempCtx.restore();
log.debug(`Layer ${index} rendered successfully`); log.debug(`Layer ${index} rendered successfully`);
visibilityCtx.save(); visibilityCtx.save();
visibilityCtx.translate(layer.x + layer.width / 2, layer.y + layer.height / 2); visibilityCtx.translate(layer.x + layer.width / 2, layer.y + layer.height / 2);
@@ -96,7 +96,7 @@ export class CanvasIO {
maskData.data[i] = maskData.data[i + 1] = maskData.data[i + 2] = maskValue; maskData.data[i] = maskData.data[i + 1] = maskData.data[i + 2] = maskValue;
maskData.data[i + 3] = 255; maskData.data[i + 3] = 255;
} }
maskCtx.putImageData(maskData, 0, 0); maskCtx.putImageData(maskData, 0, 0);
const toolMaskCanvas = this.canvas.maskTool.getMask(); const toolMaskCanvas = this.canvas.maskTool.getMask();
if (toolMaskCanvas) { if (toolMaskCanvas) {
@@ -111,7 +111,7 @@ export class CanvasIO {
const maskX = this.canvas.maskTool.x; const maskX = this.canvas.maskTool.x;
const maskY = this.canvas.maskTool.y; const maskY = this.canvas.maskTool.y;
log.debug(`Extracting mask from world position (${maskX}, ${maskY}) for output area (0,0) to (${this.canvas.width}, ${this.canvas.height})`); log.debug(`Extracting mask from world position (${maskX}, ${maskY}) for output area (0,0) to (${this.canvas.width}, ${this.canvas.height})`);
const sourceX = Math.max(0, -maskX); // Where in the mask canvas to start reading const sourceX = Math.max(0, -maskX); // Where in the mask canvas to start reading
@@ -130,7 +130,7 @@ export class CanvasIO {
if (copyWidth > 0 && copyHeight > 0) { if (copyWidth > 0 && copyHeight > 0) {
log.debug(`Copying mask region: source(${sourceX}, ${sourceY}) to dest(${destX}, ${destY}) size(${copyWidth}, ${copyHeight})`); log.debug(`Copying mask region: source(${sourceX}, ${sourceY}) to dest(${destX}, ${destY}) size(${copyWidth}, ${copyHeight})`);
tempMaskCtx.drawImage( tempMaskCtx.drawImage(
toolMaskCanvas, toolMaskCanvas,
sourceX, sourceY, copyWidth, copyHeight, // Source rectangle sourceX, sourceY, copyWidth, copyHeight, // Source rectangle
@@ -153,13 +153,13 @@ export class CanvasIO {
const imageData = tempCanvas.toDataURL('image/png'); const imageData = tempCanvas.toDataURL('image/png');
const maskData = maskCanvas.toDataURL('image/png'); const maskData = maskCanvas.toDataURL('image/png');
log.info("Returning image and mask data as base64 for RAM mode."); log.info("Returning image and mask data as base64 for RAM mode.");
resolve({ image: imageData, mask: maskData }); resolve({image: imageData, mask: maskData});
return; return;
} }
const fileNameWithoutMask = fileName.replace('.png', '_without_mask.png'); const fileNameWithoutMask = fileName.replace('.png', '_without_mask.png');
log.info(`Saving image without mask as: ${fileNameWithoutMask}`); log.info(`Saving image without mask as: ${fileNameWithoutMask}`);
tempCanvas.toBlob(async (blobWithoutMask) => { tempCanvas.toBlob(async (blobWithoutMask) => {
log.debug(`Created blob for image without mask, size: ${blobWithoutMask.size} bytes`); log.debug(`Created blob for image without mask, size: ${blobWithoutMask.size} bytes`);
const formDataWithoutMask = new FormData(); const formDataWithoutMask = new FormData();
@@ -193,7 +193,7 @@ export class CanvasIO {
if (resp.status === 200) { if (resp.status === 200) {
const maskFileName = fileName.replace('.png', '_mask.png'); const maskFileName = fileName.replace('.png', '_mask.png');
log.info(`Saving mask as: ${maskFileName}`); log.info(`Saving mask as: ${maskFileName}`);
maskCanvas.toBlob(async (maskBlob) => { maskCanvas.toBlob(async (maskBlob) => {
log.debug(`Created blob for mask, size: ${maskBlob.size} bytes`); log.debug(`Created blob for mask, size: ${maskBlob.size} bytes`);
const maskFormData = new FormData(); const maskFormData = new FormData();
@@ -237,18 +237,18 @@ export class CanvasIO {
async _renderOutputData() { async _renderOutputData() {
return new Promise((resolve) => { return new Promise((resolve) => {
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(this.canvas.width, this.canvas.height); const {canvas: tempCanvas, ctx: tempCtx} = createCanvas(this.canvas.width, this.canvas.height);
const { canvas: maskCanvas, ctx: maskCtx } = createCanvas(this.canvas.width, this.canvas.height); const {canvas: maskCanvas, ctx: maskCtx} = createCanvas(this.canvas.width, this.canvas.height);
tempCtx.fillStyle = '#ffffff'; tempCtx.fillStyle = '#ffffff';
tempCtx.fillRect(0, 0, this.canvas.width, this.canvas.height); tempCtx.fillRect(0, 0, this.canvas.width, this.canvas.height);
const visibilityCanvas = document.createElement('canvas'); const visibilityCanvas = document.createElement('canvas');
visibilityCanvas.width = this.canvas.width; visibilityCanvas.width = this.canvas.width;
visibilityCanvas.height = this.canvas.height; visibilityCanvas.height = this.canvas.height;
const visibilityCtx = visibilityCanvas.getContext('2d', { alpha: true }); const visibilityCtx = visibilityCanvas.getContext('2d', {alpha: true});
maskCtx.fillStyle = '#ffffff'; // Start with a white mask (nothing masked) maskCtx.fillStyle = '#ffffff'; // Start with a white mask (nothing masked)
maskCtx.fillRect(0, 0, this.canvas.width, this.canvas.height); maskCtx.fillRect(0, 0, this.canvas.width, this.canvas.height);
const sortedLayers = this.canvas.layers.sort((a, b) => a.zIndex - b.zIndex); const sortedLayers = this.canvas.layers.sort((a, b) => a.zIndex - b.zIndex);
sortedLayers.forEach((layer) => { sortedLayers.forEach((layer) => {
@@ -289,19 +289,19 @@ export class CanvasIO {
const maskX = this.canvas.maskTool.x; const maskX = this.canvas.maskTool.x;
const maskY = this.canvas.maskTool.y; const maskY = this.canvas.maskTool.y;
log.debug(`[renderOutputData] Extracting mask from world position (${maskX}, ${maskY})`); log.debug(`[renderOutputData] Extracting mask from world position (${maskX}, ${maskY})`);
const sourceX = Math.max(0, -maskX); const sourceX = Math.max(0, -maskX);
const sourceY = Math.max(0, -maskY); const sourceY = Math.max(0, -maskY);
const destX = Math.max(0, maskX); const destX = Math.max(0, maskX);
const destY = Math.max(0, maskY); const destY = Math.max(0, maskY);
const copyWidth = Math.min(toolMaskCanvas.width - sourceX, this.canvas.width - destX); const copyWidth = Math.min(toolMaskCanvas.width - sourceX, this.canvas.width - destX);
const copyHeight = Math.min(toolMaskCanvas.height - sourceY, this.canvas.height - destY); const copyHeight = Math.min(toolMaskCanvas.height - sourceY, this.canvas.height - destY);
if (copyWidth > 0 && copyHeight > 0) { if (copyWidth > 0 && copyHeight > 0) {
tempMaskCtx.drawImage( tempMaskCtx.drawImage(
toolMaskCanvas, toolMaskCanvas,
sourceX, sourceY, copyWidth, copyHeight, sourceX, sourceY, copyWidth, copyHeight,
destX, destY, copyWidth, copyHeight destX, destY, copyWidth, copyHeight
@@ -312,7 +312,7 @@ export class CanvasIO {
for (let i = 0; i < tempMaskData.data.length; i += 4) { for (let i = 0; i < tempMaskData.data.length; i += 4) {
const alpha = tempMaskData.data[i + 3]; const alpha = tempMaskData.data[i + 3];
tempMaskData.data[i] = tempMaskData.data[i+1] = tempMaskData.data[i+2] = alpha; tempMaskData.data[i] = tempMaskData.data[i + 1] = tempMaskData.data[i + 2] = alpha;
tempMaskData.data[i + 3] = 255; // Solid alpha tempMaskData.data[i + 3] = 255; // Solid alpha
} }
tempMaskCtx.putImageData(tempMaskData, 0, 0); tempMaskCtx.putImageData(tempMaskData, 0, 0);
@@ -321,18 +321,18 @@ export class CanvasIO {
maskCtx.globalCompositeOperation = 'screen'; maskCtx.globalCompositeOperation = 'screen';
maskCtx.drawImage(tempMaskCanvas, 0, 0); maskCtx.drawImage(tempMaskCanvas, 0, 0);
} }
const imageDataUrl = tempCanvas.toDataURL('image/png'); const imageDataUrl = tempCanvas.toDataURL('image/png');
const maskDataUrl = maskCanvas.toDataURL('image/png'); const maskDataUrl = maskCanvas.toDataURL('image/png');
resolve({ image: imageDataUrl, mask: maskDataUrl }); resolve({image: imageDataUrl, mask: maskDataUrl});
}); });
} }
async sendDataViaWebSocket(nodeId) { async sendDataViaWebSocket(nodeId) {
log.info(`Preparing to send data for node ${nodeId} via WebSocket.`); log.info(`Preparing to send data for node ${nodeId} via WebSocket.`);
const { image, mask } = await this._renderOutputData(); const {image, mask} = await this._renderOutputData();
try { try {
log.info(`Sending data for node ${nodeId}...`); log.info(`Sending data for node ${nodeId}...`);
@@ -342,7 +342,7 @@ export class CanvasIO {
image: image, image: image,
mask: mask, mask: mask,
}, true); // `true` requires an acknowledgment }, true); // `true` requires an acknowledgment
log.info(`Data for node ${nodeId} has been sent and acknowledged by the server.`); log.info(`Data for node ${nodeId} has been sent and acknowledged by the server.`);
return true; return true;
} catch (error) { } catch (error) {
@@ -357,7 +357,7 @@ export class CanvasIO {
try { try {
log.debug("Adding input to canvas:", {inputImage}); log.debug("Adding input to canvas:", {inputImage});
const { canvas: tempCanvas, ctx: tempCtx } = createCanvas(inputImage.width, inputImage.height); const {canvas: tempCanvas, ctx: tempCtx} = createCanvas(inputImage.width, inputImage.height);
const imgData = new ImageData( const imgData = new ImageData(
inputImage.data, inputImage.data,

View File

@@ -1,5 +1,6 @@
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
import {snapToGrid, getSnapAdjustment} from "./utils/CommonUtils.js"; import {snapToGrid, getSnapAdjustment} from "./utils/CommonUtils.js";
const log = createModuleLogger('CanvasInteractions'); const log = createModuleLogger('CanvasInteractions');
export class CanvasInteractions { export class CanvasInteractions {
@@ -504,7 +505,7 @@ export class CanvasInteractions {
}); });
this.canvas.maskTool.updatePosition(-finalX, -finalY); this.canvas.maskTool.updatePosition(-finalX, -finalY);
this.canvas.viewport.x -= finalX; this.canvas.viewport.x -= finalX;
this.canvas.viewport.y -= finalY; this.canvas.viewport.y -= finalY;
} }

View File

@@ -2,6 +2,7 @@ import {saveImage, removeImage} from "./db.js";
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
import {generateUUID, generateUniqueFileName} from "./utils/CommonUtils.js"; import {generateUUID, generateUniqueFileName} from "./utils/CommonUtils.js";
import {withErrorHandling, createValidationError} from "./ErrorHandler.js"; import {withErrorHandling, createValidationError} from "./ErrorHandler.js";
const log = createModuleLogger('CanvasLayers'); const log = createModuleLogger('CanvasLayers');
export class CanvasLayers { export class CanvasLayers {
@@ -358,6 +359,7 @@ export class CanvasLayers {
this.canvasLayers.selectedLayer = layer; this.canvasLayers.selectedLayer = layer;
this.canvasLayers.render(); this.canvasLayers.render();
} }
isRotationHandle(x, y) { isRotationHandle(x, y) {
if (!this.canvasLayers.selectedLayer) return false; if (!this.canvasLayers.selectedLayer) return false;
@@ -428,12 +430,18 @@ export class CanvasLayers {
const handleRadius = 5; const handleRadius = 5;
const handles = { const handles = {
'nw': {x: this.canvasLayers.selectedLayer.x, y: this.canvasLayers.selectedLayer.y}, 'nw': {x: this.canvasLayers.selectedLayer.x, y: this.canvasLayers.selectedLayer.y},
'ne': {x: this.canvasLayers.selectedLayer.x + this.canvasLayers.selectedLayer.width, y: this.canvasLayers.selectedLayer.y}, 'ne': {
x: this.canvasLayers.selectedLayer.x + this.canvasLayers.selectedLayer.width,
y: this.canvasLayers.selectedLayer.y
},
'se': { 'se': {
x: this.canvasLayers.selectedLayer.x + this.canvasLayers.selectedLayer.width, x: this.canvasLayers.selectedLayer.x + this.canvasLayers.selectedLayer.width,
y: this.canvasLayers.selectedLayer.y + this.canvasLayers.selectedLayer.height y: this.canvasLayers.selectedLayer.y + this.canvasLayers.selectedLayer.height
}, },
'sw': {x: this.canvasLayers.selectedLayer.x, y: this.canvasLayers.selectedLayer.y + this.canvasLayers.selectedLayer.height} 'sw': {
x: this.canvasLayers.selectedLayer.x,
y: this.canvasLayers.selectedLayer.y + this.canvasLayers.selectedLayer.height
}
}; };
for (const [position, point] of Object.entries(handles)) { for (const [position, point] of Object.entries(handles)) {
@@ -443,6 +451,7 @@ export class CanvasLayers {
} }
return null; return null;
} }
showBlendModeMenu(x, y) { showBlendModeMenu(x, y) {
const existingMenu = document.getElementById('blend-mode-menu'); const existingMenu = document.getElementById('blend-mode-menu');
if (existingMenu) { if (existingMenu) {
@@ -533,7 +542,7 @@ export class CanvasLayers {
return await this.canvasLayers.saveToServer(fileName); return await this.canvasLayers.saveToServer(fileName);
} }
}; };
await saveWithFallback(this.canvasLayers.widget.value); await saveWithFallback(this.canvasLayers.widget.value);
if (this.canvasLayers.node) { if (this.canvasLayers.node) {
app.graph.runStep(); app.graph.runStep();
@@ -594,6 +603,7 @@ export class CanvasLayers {
modeElement.appendChild(slider); modeElement.appendChild(slider);
} }
} }
async getFlattenedCanvasAsBlob() { async getFlattenedCanvasAsBlob() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const tempCanvas = document.createElement('canvas'); const tempCanvas = document.createElement('canvas');
@@ -633,6 +643,7 @@ export class CanvasLayers {
}, 'image/png'); }, 'image/png');
}); });
} }
async getFlattenedSelectionAsBlob() { async getFlattenedSelectionAsBlob() {
if (this.canvasLayers.selectedLayers.length === 0) { if (this.canvasLayers.selectedLayers.length === 0) {
return null; return null;

View File

@@ -1,4 +1,5 @@
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
const log = createModuleLogger('CanvasRenderer'); const log = createModuleLogger('CanvasRenderer');
export class CanvasRenderer { export class CanvasRenderer {
@@ -95,7 +96,7 @@ export class CanvasRenderer {
} }
ctx.drawImage(maskImage, this.canvas.maskTool.x, this.canvas.maskTool.y); ctx.drawImage(maskImage, this.canvas.maskTool.x, this.canvas.maskTool.y);
ctx.globalAlpha = 1.0; ctx.globalAlpha = 1.0;
ctx.restore(); ctx.restore();
} }
@@ -105,7 +106,7 @@ export class CanvasRenderer {
ctx.restore(); ctx.restore();
if (this.canvas.canvas.width !== this.canvas.offscreenCanvas.width || if (this.canvas.canvas.width !== this.canvas.offscreenCanvas.width ||
this.canvas.canvas.height !== this.canvas.offscreenCanvas.height) { this.canvas.canvas.height !== this.canvas.offscreenCanvas.height) {
this.canvas.canvas.width = this.canvas.offscreenCanvas.width; this.canvas.canvas.width = this.canvas.offscreenCanvas.width;
this.canvas.canvas.height = this.canvas.offscreenCanvas.height; this.canvas.canvas.height = this.canvas.offscreenCanvas.height;
@@ -115,7 +116,7 @@ export class CanvasRenderer {
renderInteractionElements(ctx) { renderInteractionElements(ctx) {
const interaction = this.canvas.interaction; const interaction = this.canvas.interaction;
if (interaction.mode === 'resizingCanvas' && interaction.canvasResizeRect) { if (interaction.mode === 'resizingCanvas' && interaction.canvasResizeRect) {
const rect = interaction.canvasResizeRect; const rect = interaction.canvasResizeRect;
ctx.save(); ctx.save();
@@ -147,7 +148,7 @@ export class CanvasRenderer {
ctx.restore(); ctx.restore();
} }
} }
if (interaction.mode === 'movingCanvas' && interaction.canvasMoveRect) { if (interaction.mode === 'movingCanvas' && interaction.canvasMoveRect) {
const rect = interaction.canvasMoveRect; const rect = interaction.canvasMoveRect;
ctx.save(); ctx.save();

View File

@@ -2,6 +2,7 @@ import {getCanvasState, setCanvasState, saveImage, getImage} from "./db.js";
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
import {generateUUID, cloneLayers, getStateSignature, debounce} from "./utils/CommonUtils.js"; import {generateUUID, cloneLayers, getStateSignature, debounce} from "./utils/CommonUtils.js";
import {withErrorHandling} from "./ErrorHandler.js"; import {withErrorHandling} from "./ErrorHandler.js";
const log = createModuleLogger('CanvasState'); const log = createModuleLogger('CanvasState');
export class CanvasState { export class CanvasState {
@@ -31,7 +32,7 @@ export class CanvasState {
} }
this._loadInProgress = this._performLoad(); this._loadInProgress = this._performLoad();
try { try {
const result = await this._loadInProgress; const result = await this._loadInProgress;
return result; return result;
@@ -78,7 +79,7 @@ export class CanvasState {
* @returns {Promise<Array>} Załadowane warstwy * @returns {Promise<Array>} Załadowane warstwy
*/ */
async _loadLayers(layersData) { async _loadLayers(layersData) {
const imagePromises = layersData.map((layerData, index) => const imagePromises = layersData.map((layerData, index) =>
this._loadSingleLayer(layerData, index) this._loadSingleLayer(layerData, index)
); );
return Promise.all(imagePromises); return Promise.all(imagePromises);
@@ -111,7 +112,7 @@ export class CanvasState {
*/ */
_loadLayerFromImageId(layerData, index, resolve) { _loadLayerFromImageId(layerData, index, resolve) {
log.debug(`Layer ${index}: Loading image with id: ${layerData.imageId}`); log.debug(`Layer ${index}: Loading image with id: ${layerData.imageId}`);
if (this.canvas.imageCache.has(layerData.imageId)) { if (this.canvas.imageCache.has(layerData.imageId)) {
log.debug(`Layer ${index}: Image found in cache.`); log.debug(`Layer ${index}: Image found in cache.`);
const imageSrc = this.canvas.imageCache.get(layerData.imageId); const imageSrc = this.canvas.imageCache.get(layerData.imageId);
@@ -144,7 +145,7 @@ export class CanvasState {
_convertLegacyLayer(layerData, index, resolve) { _convertLegacyLayer(layerData, index, resolve) {
log.info(`Layer ${index}: Found imageSrc, converting to new format with imageId.`); log.info(`Layer ${index}: Found imageSrc, converting to new format with imageId.`);
const imageId = generateUUID(); const imageId = generateUUID();
saveImage(imageId, layerData.imageSrc) saveImage(imageId, layerData.imageSrc)
.then(() => { .then(() => {
log.info(`Layer ${index}: Image saved to IndexedDB with id: ${imageId}`); log.info(`Layer ${index}: Image saved to IndexedDB with id: ${imageId}`);
@@ -283,7 +284,7 @@ export class CanvasState {
saveMaskState(replaceLast = false) { saveMaskState(replaceLast = false) {
if (!this.canvas.maskTool) return; if (!this.canvas.maskTool) return;
if (replaceLast && this.maskUndoStack.length > 0) { if (replaceLast && this.maskUndoStack.length > 0) {
this.maskUndoStack.pop(); this.maskUndoStack.pop();
} }
@@ -321,7 +322,7 @@ export class CanvasState {
undoLayersState() { undoLayersState() {
if (this.layersUndoStack.length <= 1) return; if (this.layersUndoStack.length <= 1) return;
const currentState = this.layersUndoStack.pop(); const currentState = this.layersUndoStack.pop();
this.layersRedoStack.push(currentState); this.layersRedoStack.push(currentState);
const prevState = this.layersUndoStack[this.layersUndoStack.length - 1]; const prevState = this.layersUndoStack[this.layersUndoStack.length - 1];
@@ -333,7 +334,7 @@ export class CanvasState {
redoLayersState() { redoLayersState() {
if (this.layersRedoStack.length === 0) return; if (this.layersRedoStack.length === 0) return;
const nextState = this.layersRedoStack.pop(); const nextState = this.layersRedoStack.pop();
this.layersUndoStack.push(nextState); this.layersUndoStack.push(nextState);
this.canvas.layers = cloneLayers(nextState); this.canvas.layers = cloneLayers(nextState);
@@ -344,33 +345,33 @@ export class CanvasState {
undoMaskState() { undoMaskState() {
if (!this.canvas.maskTool || this.maskUndoStack.length <= 1) return; if (!this.canvas.maskTool || this.maskUndoStack.length <= 1) return;
const currentState = this.maskUndoStack.pop(); const currentState = this.maskUndoStack.pop();
this.maskRedoStack.push(currentState); this.maskRedoStack.push(currentState);
if (this.maskUndoStack.length > 0) { if (this.maskUndoStack.length > 0) {
const prevState = this.maskUndoStack[this.maskUndoStack.length - 1]; const prevState = this.maskUndoStack[this.maskUndoStack.length - 1];
const maskCanvas = this.canvas.maskTool.getMask(); const maskCanvas = this.canvas.maskTool.getMask();
const maskCtx = maskCanvas.getContext('2d'); const maskCtx = maskCanvas.getContext('2d');
maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height); maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height);
maskCtx.drawImage(prevState, 0, 0); maskCtx.drawImage(prevState, 0, 0);
this.canvas.render(); this.canvas.render();
} }
this.canvas.updateHistoryButtons(); this.canvas.updateHistoryButtons();
} }
redoMaskState() { redoMaskState() {
if (!this.canvas.maskTool || this.maskRedoStack.length === 0) return; if (!this.canvas.maskTool || this.maskRedoStack.length === 0) return;
const nextState = this.maskRedoStack.pop(); const nextState = this.maskRedoStack.pop();
this.maskUndoStack.push(nextState); this.maskUndoStack.push(nextState);
const maskCanvas = this.canvas.maskTool.getMask(); const maskCanvas = this.canvas.maskTool.getMask();
const maskCtx = maskCanvas.getContext('2d'); const maskCtx = maskCanvas.getContext('2d');
maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height); maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height);
maskCtx.drawImage(nextState, 0, 0); maskCtx.drawImage(nextState, 0, 0);
this.canvas.render(); this.canvas.render();
this.canvas.updateHistoryButtons(); this.canvas.updateHistoryButtons();
} }

View File

@@ -672,12 +672,12 @@ async function createCanvasWidget(node, widget, app) {
try { try {
const stats = canvas.getGarbageCollectionStats(); const stats = canvas.getGarbageCollectionStats();
log.info("GC Stats before cleanup:", stats); log.info("GC Stats before cleanup:", stats);
await canvas.runGarbageCollection(); await canvas.runGarbageCollection();
const newStats = canvas.getGarbageCollectionStats(); const newStats = canvas.getGarbageCollectionStats();
log.info("GC Stats after cleanup:", newStats); log.info("GC Stats after cleanup:", newStats);
alert(`Garbage collection completed!\nTracked images: ${newStats.trackedImages}\nTotal references: ${newStats.totalReferences}\nOperations: ${newStats.operationCount}/${newStats.operationThreshold}`); alert(`Garbage collection completed!\nTracked images: ${newStats.trackedImages}\nTotal references: ${newStats.totalReferences}\nOperations: ${newStats.operationCount}/${newStats.operationThreshold}`);
} catch (e) { } catch (e) {
log.error("Failed to run garbage collection:", e); log.error("Failed to run garbage collection:", e);
@@ -789,9 +789,6 @@ async function createCanvasWidget(node, widget, app) {
}; };
const mainContainer = $el("div.painterMainContainer", { const mainContainer = $el("div.painterMainContainer", {
style: { style: {
position: "relative", position: "relative",
@@ -920,7 +917,6 @@ async function createCanvasWidget(node, widget, app) {
if (!window.canvasExecutionStates) { if (!window.canvasExecutionStates) {
window.canvasExecutionStates = new Map(); window.canvasExecutionStates = new Map();
} }
node.canvasWidget = canvas; node.canvasWidget = canvas;
@@ -944,12 +940,12 @@ app.registerExtension({
init() { init() {
const originalQueuePrompt = app.queuePrompt; const originalQueuePrompt = app.queuePrompt;
app.queuePrompt = async function(number, prompt) { app.queuePrompt = async function (number, prompt) {
log.info("Preparing to queue prompt..."); log.info("Preparing to queue prompt...");
if (canvasNodeInstances.size > 0) { if (canvasNodeInstances.size > 0) {
log.info(`Found ${canvasNodeInstances.size} CanvasNode(s). Sending data via WebSocket...`); log.info(`Found ${canvasNodeInstances.size} CanvasNode(s). Sending data via WebSocket...`);
const sendPromises = []; const sendPromises = [];
for (const [nodeId, canvasWidget] of canvasNodeInstances.entries()) { for (const [nodeId, canvasWidget] of canvasNodeInstances.entries()) {
@@ -976,7 +972,7 @@ app.registerExtension({
return; // Stop execution return; // Stop execution
} }
} }
log.info("All pre-prompt tasks complete. Proceeding with original queuePrompt."); log.info("All pre-prompt tasks complete. Proceeding with original queuePrompt.");
return originalQueuePrompt.apply(this, arguments); return originalQueuePrompt.apply(this, arguments);
@@ -994,7 +990,7 @@ app.registerExtension({
return r; return r;
}; };
nodeType.prototype.onAdded = async function() { nodeType.prototype.onAdded = async function () {
log.info(`CanvasNode onAdded, ID: ${this.id}`); log.info(`CanvasNode onAdded, ID: ${this.id}`);
log.debug(`Available widgets in onAdded:`, this.widgets.map(w => w.name)); log.debug(`Available widgets in onAdded:`, this.widgets.map(w => w.name));
@@ -1003,6 +999,10 @@ app.registerExtension({
return; return;
} }
// Iterate through every widget attached to this node
this.widgets.forEach(w => {
log.debug(`Widget name: ${w.name}, type: ${w.type}, value: ${w.value}`);
});
const nodeIdWidget = this.widgets.find(w => w.name === "node_id"); const nodeIdWidget = this.widgets.find(w => w.name === "node_id");
if (nodeIdWidget) { if (nodeIdWidget) {
@@ -1028,7 +1028,7 @@ app.registerExtension({
if (window.canvasExecutionStates) { if (window.canvasExecutionStates) {
window.canvasExecutionStates.delete(this.id); window.canvasExecutionStates.delete(this.id);
} }
const tooltip = document.getElementById(`painter-help-tooltip-${this.id}`); const tooltip = document.getElementById(`painter-help-tooltip-${this.id}`);
if (tooltip) { if (tooltip) {
tooltip.remove(); tooltip.remove();

View File

@@ -60,7 +60,7 @@ export class ErrorHandler {
this.logError(normalizedError, context); this.logError(normalizedError, context);
this.recordError(normalizedError); this.recordError(normalizedError);
this.incrementErrorCount(normalizedError.type); this.incrementErrorCount(normalizedError.type);
return normalizedError; return normalizedError;
} }
@@ -75,29 +75,29 @@ export class ErrorHandler {
if (error instanceof AppError) { if (error instanceof AppError) {
return error; return error;
} }
if (error instanceof Error) { if (error instanceof Error) {
const type = this.categorizeError(error, context); const type = this.categorizeError(error, context);
return new AppError( return new AppError(
error.message, error.message,
type, type,
{ context, ...additionalInfo }, {context, ...additionalInfo},
error error
); );
} }
if (typeof error === 'string') { if (typeof error === 'string') {
return new AppError( return new AppError(
error, error,
ErrorTypes.SYSTEM, ErrorTypes.SYSTEM,
{ context, ...additionalInfo } {context, ...additionalInfo}
); );
} }
return new AppError( return new AppError(
'Unknown error occurred', 'Unknown error occurred',
ErrorTypes.SYSTEM, ErrorTypes.SYSTEM,
{ context, originalError: error, ...additionalInfo } {context, originalError: error, ...additionalInfo}
); );
} }
@@ -109,30 +109,30 @@ export class ErrorHandler {
*/ */
categorizeError(error, context) { categorizeError(error, context) {
const message = error.message.toLowerCase(); const message = error.message.toLowerCase();
if (message.includes('fetch') || message.includes('network') || if (message.includes('fetch') || message.includes('network') ||
message.includes('connection') || message.includes('timeout')) { message.includes('connection') || message.includes('timeout')) {
return ErrorTypes.NETWORK; return ErrorTypes.NETWORK;
} }
if (message.includes('file') || message.includes('read') || if (message.includes('file') || message.includes('read') ||
message.includes('write') || message.includes('path')) { message.includes('write') || message.includes('path')) {
return ErrorTypes.FILE_IO; return ErrorTypes.FILE_IO;
} }
if (message.includes('invalid') || message.includes('required') || if (message.includes('invalid') || message.includes('required') ||
message.includes('validation') || message.includes('format')) { message.includes('validation') || message.includes('format')) {
return ErrorTypes.VALIDATION; return ErrorTypes.VALIDATION;
} }
if (message.includes('image') || message.includes('canvas') || if (message.includes('image') || message.includes('canvas') ||
message.includes('blob') || message.includes('tensor')) { message.includes('blob') || message.includes('tensor')) {
return ErrorTypes.IMAGE_PROCESSING; return ErrorTypes.IMAGE_PROCESSING;
} }
if (message.includes('state') || message.includes('cache') || if (message.includes('state') || message.includes('cache') ||
message.includes('storage')) { message.includes('storage')) {
return ErrorTypes.STATE_MANAGEMENT; return ErrorTypes.STATE_MANAGEMENT;
} }
if (context.toLowerCase().includes('canvas')) { if (context.toLowerCase().includes('canvas')) {
return ErrorTypes.CANVAS; return ErrorTypes.CANVAS;
} }
return ErrorTypes.SYSTEM; return ErrorTypes.SYSTEM;
} }
@@ -224,6 +224,7 @@ export class ErrorHandler {
log.info('Error history cleared'); log.info('Error history cleared');
} }
} }
const errorHandler = new ErrorHandler(); const errorHandler = new ErrorHandler();
/** /**
@@ -233,7 +234,7 @@ const errorHandler = new ErrorHandler();
* @returns {Function} Opakowana funkcja * @returns {Function} Opakowana funkcja
*/ */
export function withErrorHandling(fn, context) { export function withErrorHandling(fn, context) {
return async function(...args) { return async function (...args) {
try { try {
return await fn.apply(this, args); return await fn.apply(this, args);
} catch (error) { } catch (error) {
@@ -251,10 +252,10 @@ export function withErrorHandling(fn, context) {
* @param {string} context - Kontekst wykonania * @param {string} context - Kontekst wykonania
*/ */
export function handleErrors(context) { export function handleErrors(context) {
return function(target, propertyKey, descriptor) { return function (target, propertyKey, descriptor) {
const originalMethod = descriptor.value; const originalMethod = descriptor.value;
descriptor.value = async function(...args) { descriptor.value = async function (...args) {
try { try {
return await originalMethod.apply(this, args); return await originalMethod.apply(this, args);
} catch (error) { } catch (error) {
@@ -266,7 +267,7 @@ export function handleErrors(context) {
throw handledError; throw handledError;
} }
}; };
return descriptor; return descriptor;
}; };
} }
@@ -327,24 +328,25 @@ export async function safeExecute(operation, fallbackValue = null, context = 'Sa
*/ */
export async function retryWithBackoff(operation, maxRetries = 3, baseDelay = 1000, context = 'RetryOperation') { export async function retryWithBackoff(operation, maxRetries = 3, baseDelay = 1000, context = 'RetryOperation') {
let lastError; let lastError;
for (let attempt = 0; attempt <= maxRetries; attempt++) { for (let attempt = 0; attempt <= maxRetries; attempt++) {
try { try {
return await operation(); return await operation();
} catch (error) { } catch (error) {
lastError = error; lastError = error;
if (attempt === maxRetries) { if (attempt === maxRetries) {
break; break;
} }
const delay = baseDelay * Math.pow(2, attempt); const delay = baseDelay * Math.pow(2, attempt);
log.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms`, { error: error.message, context }); log.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms`, {error: error.message, context});
await new Promise(resolve => setTimeout(resolve, delay)); await new Promise(resolve => setTimeout(resolve, delay));
} }
} }
throw errorHandler.handle(lastError, context, { attempts: maxRetries + 1 }); throw errorHandler.handle(lastError, context, {attempts: maxRetries + 1});
} }
export { errorHandler };
export {errorHandler};
export default errorHandler; export default errorHandler;

View File

@@ -1,4 +1,5 @@
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
const log = createModuleLogger('ImageCache'); const log = createModuleLogger('ImageCache');
export class ImageCache { export class ImageCache {

View File

@@ -26,11 +26,11 @@ export class ImageReferenceManager {
if (this.gcTimer) { if (this.gcTimer) {
clearInterval(this.gcTimer); clearInterval(this.gcTimer);
} }
this.gcTimer = setInterval(() => { this.gcTimer = setInterval(() => {
this.performGarbageCollection(); this.performGarbageCollection();
}, this.gcInterval); }, this.gcInterval);
log.info("Garbage collection started with interval:", this.gcInterval / 1000, "seconds"); log.info("Garbage collection started with interval:", this.gcInterval / 1000, "seconds");
} }
@@ -51,11 +51,11 @@ export class ImageReferenceManager {
*/ */
addReference(imageId) { addReference(imageId) {
if (!imageId) return; if (!imageId) return;
const currentCount = this.imageReferences.get(imageId) || 0; const currentCount = this.imageReferences.get(imageId) || 0;
this.imageReferences.set(imageId, currentCount + 1); this.imageReferences.set(imageId, currentCount + 1);
this.imageLastUsed.set(imageId, Date.now()); this.imageLastUsed.set(imageId, Date.now());
log.debug(`Added reference to image ${imageId}, count: ${currentCount + 1}`); log.debug(`Added reference to image ${imageId}, count: ${currentCount + 1}`);
} }
@@ -65,7 +65,7 @@ export class ImageReferenceManager {
*/ */
removeReference(imageId) { removeReference(imageId) {
if (!imageId) return; if (!imageId) return;
const currentCount = this.imageReferences.get(imageId) || 0; const currentCount = this.imageReferences.get(imageId) || 0;
if (currentCount <= 1) { if (currentCount <= 1) {
this.imageReferences.delete(imageId); this.imageReferences.delete(imageId);
@@ -86,7 +86,7 @@ export class ImageReferenceManager {
usedImageIds.forEach(imageId => { usedImageIds.forEach(imageId => {
this.addReference(imageId); this.addReference(imageId);
}); });
log.info(`Updated references for ${usedImageIds.size} unique images`); log.info(`Updated references for ${usedImageIds.size} unique images`);
} }
@@ -120,7 +120,7 @@ export class ImageReferenceManager {
}); });
}); });
} }
log.debug(`Collected ${usedImageIds.size} used image IDs`); log.debug(`Collected ${usedImageIds.size} used image IDs`);
return usedImageIds; return usedImageIds;
} }
@@ -136,7 +136,7 @@ export class ImageReferenceManager {
const allImageIds = await getAllImageIds(); const allImageIds = await getAllImageIds();
const unusedImages = []; const unusedImages = [];
const now = Date.now(); const now = Date.now();
for (const imageId of allImageIds) { for (const imageId of allImageIds) {
if (!usedImageIds.has(imageId)) { if (!usedImageIds.has(imageId)) {
@@ -146,11 +146,11 @@ export class ImageReferenceManager {
if (age > this.maxAge) { if (age > this.maxAge) {
unusedImages.push(imageId); unusedImages.push(imageId);
} else { } else {
log.debug(`Image ${imageId} is unused but too young (age: ${Math.round(age/1000)}s)`); log.debug(`Image ${imageId} is unused but too young (age: ${Math.round(age / 1000)}s)`);
} }
} }
} }
log.debug(`Found ${unusedImages.length} unused images ready for cleanup`); log.debug(`Found ${unusedImages.length} unused images ready for cleanup`);
return unusedImages; return unusedImages;
} catch (error) { } catch (error) {
@@ -168,11 +168,11 @@ export class ImageReferenceManager {
log.debug("No unused images to cleanup"); log.debug("No unused images to cleanup");
return; return;
} }
log.info(`Starting cleanup of ${unusedImages.length} unused images`); log.info(`Starting cleanup of ${unusedImages.length} unused images`);
let cleanedCount = 0; let cleanedCount = 0;
let errorCount = 0; let errorCount = 0;
for (const imageId of unusedImages) { for (const imageId of unusedImages) {
try { try {
@@ -184,16 +184,16 @@ export class ImageReferenceManager {
this.imageReferences.delete(imageId); this.imageReferences.delete(imageId);
this.imageLastUsed.delete(imageId); this.imageLastUsed.delete(imageId);
cleanedCount++; cleanedCount++;
log.debug(`Cleaned up image: ${imageId}`); log.debug(`Cleaned up image: ${imageId}`);
} catch (error) { } catch (error) {
errorCount++; errorCount++;
log.error(`Error cleaning up image ${imageId}:`, error); log.error(`Error cleaning up image ${imageId}:`, error);
} }
} }
log.info(`Garbage collection completed: ${cleanedCount} images cleaned, ${errorCount} errors`); log.info(`Garbage collection completed: ${cleanedCount} images cleaned, ${errorCount} errors`);
} }
@@ -205,10 +205,10 @@ export class ImageReferenceManager {
log.debug("Garbage collection already running, skipping"); log.debug("Garbage collection already running, skipping");
return; return;
} }
this.isGcRunning = true; this.isGcRunning = true;
log.info("Starting garbage collection..."); log.info("Starting garbage collection...");
try { try {
this.updateReferences(); this.updateReferences();
@@ -218,7 +218,7 @@ export class ImageReferenceManager {
const unusedImages = await this.findUnusedImages(usedImageIds); const unusedImages = await this.findUnusedImages(usedImageIds);
await this.cleanupUnusedImages(unusedImages); await this.cleanupUnusedImages(unusedImages);
} catch (error) { } catch (error) {
log.error("Error during garbage collection:", error); log.error("Error during garbage collection:", error);
} finally { } finally {
@@ -232,7 +232,7 @@ export class ImageReferenceManager {
incrementOperationCount() { incrementOperationCount() {
this.operationCount++; this.operationCount++;
log.debug(`Operation count: ${this.operationCount}/${this.operationThreshold}`); log.debug(`Operation count: ${this.operationCount}/${this.operationThreshold}`);
if (this.operationCount >= this.operationThreshold) { if (this.operationCount >= this.operationThreshold) {
log.info(`Operation threshold reached (${this.operationThreshold}), triggering garbage collection`); log.info(`Operation threshold reached (${this.operationThreshold}), triggering garbage collection`);
this.operationCount = 0; // Reset counter this.operationCount = 0; // Reset counter

View File

@@ -1,4 +1,5 @@
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
const log = createModuleLogger('Mask_tool'); const log = createModuleLogger('Mask_tool');
export class MaskTool { export class MaskTool {
@@ -34,7 +35,7 @@ export class MaskTool {
this.x = -extraSpace / 2; this.x = -extraSpace / 2;
this.y = -extraSpace / 2; this.y = -extraSpace / 2;
this.maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height); this.maskCtx.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height);
log.info(`Initialized mask canvas with extended size: ${this.maskCanvas.width}x${this.maskCanvas.height}, origin at (${this.x}, ${this.y})`); log.info(`Initialized mask canvas with extended size: ${this.maskCanvas.width}x${this.maskCanvas.height}, origin at (${this.x}, ${this.y})`);
} }
@@ -46,7 +47,7 @@ export class MaskTool {
this.canvasInstance.canvasState.saveMaskState(); this.canvasInstance.canvasState.saveMaskState();
} }
this.canvasInstance.updateHistoryButtons(); this.canvasInstance.updateHistoryButtons();
log.info("Mask tool activated"); log.info("Mask tool activated");
} }
@@ -54,7 +55,7 @@ export class MaskTool {
this.isActive = false; this.isActive = false;
this.canvasInstance.interaction.mode = 'none'; this.canvasInstance.interaction.mode = 'none';
this.canvasInstance.updateHistoryButtons(); this.canvasInstance.updateHistoryButtons();
log.info("Mask tool deactivated"); log.info("Mask tool deactivated");
} }
@@ -104,17 +105,17 @@ export class MaskTool {
const canvasWidth = this.maskCanvas.width; const canvasWidth = this.maskCanvas.width;
const canvasHeight = this.maskCanvas.height; const canvasHeight = this.maskCanvas.height;
if (canvasX >= 0 && canvasX < canvasWidth && if (canvasX >= 0 && canvasX < canvasWidth &&
canvasY >= 0 && canvasY < canvasHeight && canvasY >= 0 && canvasY < canvasHeight &&
canvasLastX >= 0 && canvasLastX < canvasWidth && canvasLastX >= 0 && canvasLastX < canvasWidth &&
canvasLastY >= 0 && canvasLastY < canvasHeight) { canvasLastY >= 0 && canvasLastY < canvasHeight) {
this.maskCtx.beginPath(); this.maskCtx.beginPath();
this.maskCtx.moveTo(canvasLastX, canvasLastY); this.maskCtx.moveTo(canvasLastX, canvasLastY);
this.maskCtx.lineTo(canvasX, canvasY); this.maskCtx.lineTo(canvasX, canvasY);
const gradientRadius = this.brushSize / 2; const gradientRadius = this.brushSize / 2;
if (this.brushSoftness === 0) { if (this.brushSoftness === 0) {
this.maskCtx.strokeStyle = `rgba(255, 255, 255, ${this.brushStrength})`; this.maskCtx.strokeStyle = `rgba(255, 255, 255, ${this.brushStrength})`;
} else { } else {
@@ -187,21 +188,21 @@ export class MaskTool {
const newWidth = isIncreasingWidth ? width + extraSpace : Math.max(oldWidth, width + extraSpace); const newWidth = isIncreasingWidth ? width + extraSpace : Math.max(oldWidth, width + extraSpace);
const newHeight = isIncreasingHeight ? height + extraSpace : Math.max(oldHeight, height + extraSpace); const newHeight = isIncreasingHeight ? height + extraSpace : Math.max(oldHeight, height + extraSpace);
this.maskCanvas.width = newWidth; this.maskCanvas.width = newWidth;
this.maskCanvas.height = newHeight; this.maskCanvas.height = newHeight;
this.maskCtx = this.maskCanvas.getContext('2d'); this.maskCtx = this.maskCanvas.getContext('2d');
if (oldMask.width > 0 && oldMask.height > 0) { if (oldMask.width > 0 && oldMask.height > 0) {
const offsetX = this.x - oldX; const offsetX = this.x - oldX;
const offsetY = this.y - oldY; const offsetY = this.y - oldY;
this.maskCtx.drawImage(oldMask, offsetX, offsetY); this.maskCtx.drawImage(oldMask, offsetX, offsetY);
log.debug(`Preserved mask content with offset (${offsetX}, ${offsetY})`); log.debug(`Preserved mask content with offset (${offsetX}, ${offsetY})`);
} }
log.info(`Mask canvas resized to ${this.maskCanvas.width}x${this.maskCanvas.height}, position (${this.x}, ${this.y})`); log.info(`Mask canvas resized to ${this.maskCanvas.width}x${this.maskCanvas.height}, position (${this.x}, ${this.y})`);
log.info(`Canvas size change: width ${isIncreasingWidth ? 'increased' : 'decreased'}, height ${isIncreasingHeight ? 'increased' : 'decreased'}`); log.info(`Canvas size change: width ${isIncreasingWidth ? 'increased' : 'decreased'}, height ${isIncreasingHeight ? 'increased' : 'decreased'}`);
} }

View File

@@ -1,4 +1,5 @@
import {createModuleLogger} from "./utils/LoggerUtils.js"; import {createModuleLogger} from "./utils/LoggerUtils.js";
const log = createModuleLogger('db'); const log = createModuleLogger('db');
const DB_NAME = 'CanvasNodeDB'; const DB_NAME = 'CanvasNodeDB';
@@ -89,7 +90,7 @@ export async function getCanvasState(id) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([STATE_STORE_NAME], 'readonly'); const transaction = db.transaction([STATE_STORE_NAME], 'readonly');
const store = transaction.objectStore(STATE_STORE_NAME); const store = transaction.objectStore(STATE_STORE_NAME);
const result = await createDBRequest(store, 'get', id, "Error getting canvas state"); const result = await createDBRequest(store, 'get', id, "Error getting canvas state");
log.debug(`Get success for id: ${id}`, result ? 'found' : 'not found'); log.debug(`Get success for id: ${id}`, result ? 'found' : 'not found');
return result ? result.state : null; return result ? result.state : null;
@@ -100,7 +101,7 @@ export async function setCanvasState(id, state) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([STATE_STORE_NAME], 'readwrite'); const transaction = db.transaction([STATE_STORE_NAME], 'readwrite');
const store = transaction.objectStore(STATE_STORE_NAME); const store = transaction.objectStore(STATE_STORE_NAME);
await createDBRequest(store, 'put', {id, state}, "Error setting canvas state"); await createDBRequest(store, 'put', {id, state}, "Error setting canvas state");
log.debug(`Set success for id: ${id}`); log.debug(`Set success for id: ${id}`);
} }
@@ -110,7 +111,7 @@ export async function removeCanvasState(id) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([STATE_STORE_NAME], 'readwrite'); const transaction = db.transaction([STATE_STORE_NAME], 'readwrite');
const store = transaction.objectStore(STATE_STORE_NAME); const store = transaction.objectStore(STATE_STORE_NAME);
await createDBRequest(store, 'delete', id, "Error removing canvas state"); await createDBRequest(store, 'delete', id, "Error removing canvas state");
log.debug(`Remove success for id: ${id}`); log.debug(`Remove success for id: ${id}`);
} }
@@ -120,7 +121,7 @@ export async function saveImage(imageId, imageSrc) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([IMAGE_STORE_NAME], 'readwrite'); const transaction = db.transaction([IMAGE_STORE_NAME], 'readwrite');
const store = transaction.objectStore(IMAGE_STORE_NAME); const store = transaction.objectStore(IMAGE_STORE_NAME);
await createDBRequest(store, 'put', {imageId, imageSrc}, "Error saving image"); await createDBRequest(store, 'put', {imageId, imageSrc}, "Error saving image");
log.debug(`Image saved successfully for id: ${imageId}`); log.debug(`Image saved successfully for id: ${imageId}`);
} }
@@ -130,7 +131,7 @@ export async function getImage(imageId) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([IMAGE_STORE_NAME], 'readonly'); const transaction = db.transaction([IMAGE_STORE_NAME], 'readonly');
const store = transaction.objectStore(IMAGE_STORE_NAME); const store = transaction.objectStore(IMAGE_STORE_NAME);
const result = await createDBRequest(store, 'get', imageId, "Error getting image"); const result = await createDBRequest(store, 'get', imageId, "Error getting image");
log.debug(`Get image success for id: ${imageId}`, result ? 'found' : 'not found'); log.debug(`Get image success for id: ${imageId}`, result ? 'found' : 'not found');
return result ? result.imageSrc : null; return result ? result.imageSrc : null;
@@ -141,7 +142,7 @@ export async function removeImage(imageId) {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([IMAGE_STORE_NAME], 'readwrite'); const transaction = db.transaction([IMAGE_STORE_NAME], 'readwrite');
const store = transaction.objectStore(IMAGE_STORE_NAME); const store = transaction.objectStore(IMAGE_STORE_NAME);
await createDBRequest(store, 'delete', imageId, "Error removing image"); await createDBRequest(store, 'delete', imageId, "Error removing image");
log.debug(`Remove image success for id: ${imageId}`); log.debug(`Remove image success for id: ${imageId}`);
} }
@@ -151,15 +152,15 @@ export async function getAllImageIds() {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([IMAGE_STORE_NAME], 'readonly'); const transaction = db.transaction([IMAGE_STORE_NAME], 'readonly');
const store = transaction.objectStore(IMAGE_STORE_NAME); const store = transaction.objectStore(IMAGE_STORE_NAME);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const request = store.getAllKeys(); const request = store.getAllKeys();
request.onerror = (event) => { request.onerror = (event) => {
log.error("Error getting all image IDs:", event.target.error); log.error("Error getting all image IDs:", event.target.error);
reject("Error getting all image IDs"); reject("Error getting all image IDs");
}; };
request.onsuccess = (event) => { request.onsuccess = (event) => {
const imageIds = event.target.result; const imageIds = event.target.result;
log.debug(`Found ${imageIds.length} image IDs in database`); log.debug(`Found ${imageIds.length} image IDs in database`);
@@ -173,7 +174,7 @@ export async function clearAllCanvasStates() {
const db = await openDB(); const db = await openDB();
const transaction = db.transaction([STATE_STORE_NAME], 'readwrite'); const transaction = db.transaction([STATE_STORE_NAME], 'readwrite');
const store = transaction.objectStore(STATE_STORE_NAME); const store = transaction.objectStore(STATE_STORE_NAME);
await createDBRequest(store, 'clear', null, "Error clearing canvas states"); await createDBRequest(store, 'clear', null, "Error clearing canvas states");
log.info("All canvas states cleared successfully."); log.info("All canvas states cleared successfully.");
} }

View File

@@ -1,6 +1,6 @@
/** /**
* Logger - Centralny system logowania dla ComfyUI-LayerForge * Logger - Centralny system logowania dla ComfyUI-LayerForge
* *
* Funkcje: * Funkcje:
* - Różne poziomy logowania (DEBUG, INFO, WARN, ERROR) * - Różne poziomy logowania (DEBUG, INFO, WARN, ERROR)
* - Możliwość włączania/wyłączania logów globalnie lub per moduł * - Możliwość włączania/wyłączania logów globalnie lub per moduł
@@ -39,7 +39,7 @@ const LEVEL_NAMES = {
class Logger { class Logger {
constructor() { constructor() {
this.config = { ...DEFAULT_CONFIG }; this.config = {...DEFAULT_CONFIG};
this.logs = []; this.logs = [];
this.enabled = true; this.enabled = true;
this.loadConfig(); this.loadConfig();
@@ -50,7 +50,7 @@ class Logger {
* @param {Object} config - Obiekt konfiguracyjny * @param {Object} config - Obiekt konfiguracyjny
*/ */
configure(config) { configure(config) {
this.config = { ...this.config, ...config }; this.config = {...this.config, ...config};
this.saveConfig(); this.saveConfig();
return this; return this;
} }
@@ -147,7 +147,7 @@ class Logger {
* @param {Object} logData - Dane logu * @param {Object} logData - Dane logu
*/ */
printToConsole(logData) { printToConsole(logData) {
const { timestamp, module, level, levelName, args } = logData; const {timestamp, module, level, levelName, args} = logData;
const prefix = `[${timestamp}] [${module}] [${levelName}]`; const prefix = `[${timestamp}] [${module}] [${levelName}]`;
if (this.config.useColors && typeof console.log === 'function') { if (this.config.useColors && typeof console.log === 'function') {
const color = COLORS[level] || '#000000'; const color = COLORS[level] || '#000000';
@@ -178,7 +178,7 @@ class Logger {
return arg; return arg;
}) })
})); }));
localStorage.setItem(this.config.storageKey, JSON.stringify(simplifiedLogs)); localStorage.setItem(this.config.storageKey, JSON.stringify(simplifiedLogs));
} catch (e) { } catch (e) {
console.error('Failed to save logs to localStorage:', e); console.error('Failed to save logs to localStorage:', e);
@@ -223,7 +223,7 @@ class Logger {
try { try {
const storedConfig = localStorage.getItem('layerforge_logger_config'); const storedConfig = localStorage.getItem('layerforge_logger_config');
if (storedConfig) { if (storedConfig) {
this.config = { ...this.config, ...JSON.parse(storedConfig) }; this.config = {...this.config, ...JSON.parse(storedConfig)};
} }
} catch (e) { } catch (e) {
console.error('Failed to load logger config from localStorage:', e); console.error('Failed to load logger config from localStorage:', e);
@@ -251,23 +251,23 @@ class Logger {
console.warn('No logs to export'); console.warn('No logs to export');
return; return;
} }
let content; let content;
let mimeType; let mimeType;
let extension; let extension;
if (format === 'json') { if (format === 'json') {
content = JSON.stringify(this.logs, null, 2); content = JSON.stringify(this.logs, null, 2);
mimeType = 'application/json'; mimeType = 'application/json';
extension = 'json'; extension = 'json';
} else { } else {
content = this.logs.map(log => content = this.logs.map(log =>
`[${log.timestamp}] [${log.module}] [${log.levelName}] ${log.args.join(' ')}` `[${log.timestamp}] [${log.module}] [${log.levelName}] ${log.args.join(' ')}`
).join('\n'); ).join('\n');
mimeType = 'text/plain'; mimeType = 'text/plain';
extension = 'txt'; extension = 'txt';
} }
const blob = new Blob([content], { type: mimeType }); const blob = new Blob([content], {type: mimeType});
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.href = url;
@@ -277,7 +277,7 @@ class Logger {
document.body.removeChild(a); document.body.removeChild(a);
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
} }
/** /**
* Log na poziomie DEBUG * Log na poziomie DEBUG
* @param {string} module - Nazwa modułu * @param {string} module - Nazwa modułu
@@ -314,6 +314,7 @@ class Logger {
this.log(module, LogLevel.ERROR, ...args); this.log(module, LogLevel.ERROR, ...args);
} }
} }
export const logger = new Logger(); export const logger = new Logger();
export const debug = (module, ...args) => logger.debug(module, ...args); export const debug = (module, ...args) => logger.debug(module, ...args);
export const info = (module, ...args) => logger.info(module, ...args); export const info = (module, ...args) => logger.info(module, ...args);