@yogiswara/honcho-editor-ui 2.9.2 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import { Controller, AdjustmentState, Preset } from './type';
2
2
  import { Gallery } from './type';
3
- import { AdjustmentValues } from '../../lib/editor/honcho-editor';
3
+ import { AdjustmentValues } from "../../lib/editor/honcho-editor";
4
+ import { ColorAdjustment } from "../../services/type";
4
5
  export interface UseHonchoEditorSingleOptions {
5
6
  controller: Controller;
6
7
  initImageId: string;
@@ -28,6 +29,8 @@ export interface UseHonchoEditorSingleActions {
28
29
  setBatchMode: (enabled: boolean) => void;
29
30
  startBatchMode: () => void;
30
31
  endBatchMode: () => void;
32
+ updateFromSocket: (imageId: string, adjustmentTaskId: string, adjustment: ColorAdjustment) => void;
33
+ pushState: (state: AdjustmentState) => void;
31
34
  undo: () => void;
32
35
  redo: () => void;
33
36
  reset: () => void;
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { useCallback, useMemo } from 'react';
2
+ import { useEffect, useCallback, useMemo } from 'react';
3
3
  import { useAdjustmentHistory } from '../useAdjustmentHistory';
4
4
  import { useGallerySwipe } from '../useGallerySwipe';
5
5
  import { usePreset } from '../usePreset';
@@ -15,11 +15,20 @@ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid })
15
15
  const memoizedInitImageId = useMemo(() => initImageId, [initImageId]);
16
16
  const memoizedFirebaseUid = useMemo(() => firebaseUid, [firebaseUid]);
17
17
  // Initialize business logic hooks only
18
- const adjustmentHistory = useAdjustmentHistory(initialAdjustments, memoizedController, memoizedFirebaseUid, memoizedInitImageId);
19
18
  const gallerySwipe = useGallerySwipe(memoizedFirebaseUid, memoizedInitImageId, memoizedController);
19
+ const adjustmentHistory = useAdjustmentHistory(initialAdjustments, memoizedController, memoizedFirebaseUid, gallerySwipe.currentImageData?.id);
20
20
  const presetHook = usePreset(memoizedController, memoizedFirebaseUid, { autoLoad: true });
21
21
  // Find active preset based on current adjustments
22
22
  const activePreset = presetHook.actions.findByAdjustments(adjustmentHistory.currentState);
23
+ // loop on every 5 seconds to refresh the backend()
24
+ useEffect(() => {
25
+ if (gallerySwipe.currentImageData?.id) {
26
+ console.log('Syncing adjustment history from backend for image ID:', gallerySwipe.currentImageData.id);
27
+ adjustmentHistory.actions.syncFromBackend()
28
+ .then(() => { console.log('Adjustment history synced from backend'); })
29
+ .catch(console.error);
30
+ }
31
+ }, [gallerySwipe.currentImageData?.id]);
23
32
  // Actions - pure business logic, no editor interaction - wrapped in useCallback to prevent re-renders
24
33
  const navigateNext = useCallback(() => {
25
34
  if (gallerySwipe.isNextAvailable) {
@@ -47,6 +56,11 @@ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid })
47
56
  const endBatchMode = useCallback(() => {
48
57
  adjustmentHistory.config.setBatchMode(false);
49
58
  }, [adjustmentHistory.config.setBatchMode]);
59
+ const pushState = useCallback(async (state) => {
60
+ await adjustmentHistory.config.setBatchMode(true);
61
+ adjustmentHistory.actions.pushState(state);
62
+ await adjustmentHistory.config.setBatchMode(false, true);
63
+ }, [adjustmentHistory.actions.pushState]);
50
64
  const undo = useCallback(() => {
51
65
  adjustmentHistory.actions.undo();
52
66
  }, [adjustmentHistory.actions.undo]);
@@ -114,6 +128,9 @@ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid })
114
128
  sharpness: adjustments.sharpnessScore,
115
129
  };
116
130
  }, [adjustmentHistory.currentState]);
131
+ const updateFromSocket = useCallback((imageId, adjustmentTaskId, adjustment) => {
132
+ adjustmentHistory.actions.updateFromBackend(imageId, adjustmentTaskId, adjustment);
133
+ }, [adjustmentHistory.actions.updateFromBackend]);
117
134
  const actions = {
118
135
  // Navigation
119
136
  navigateNext,
@@ -123,6 +140,8 @@ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid })
123
140
  setBatchMode,
124
141
  startBatchMode,
125
142
  endBatchMode,
143
+ updateFromSocket,
144
+ pushState,
126
145
  // History
127
146
  undo,
128
147
  redo,
@@ -1,4 +1,5 @@
1
- import { AdjustmentState, Controller } from './editor/type';
1
+ import { AdjustmentState, Controller } from '../hooks/editor/type';
2
+ import { ColorAdjustment } from '../hooks/editor/type';
2
3
  /**
3
4
  * Configuration options for the adjustment history hook
4
5
  */
@@ -47,6 +48,8 @@ export interface HistoryActions {
47
48
  trimHistory: (keepLast: number) => void;
48
49
  /** Sync history from backend using getEditorHistory */
49
50
  syncFromBackend: () => Promise<void>;
51
+ /** Update specific history entry from backend without changing current index */
52
+ updateFromBackend: (imageId: string, adjustmentTaskId: string, adjustment: ColorAdjustment) => void;
50
53
  }
51
54
  /**
52
55
  * Configuration actions for runtime adjustment
@@ -102,6 +102,8 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
102
102
  const [currentState, setCurrentState] = useState(initialState);
103
103
  const currentIndexRef = useRef(0);
104
104
  const currentStateRef = useRef(initialState);
105
+ const currentFirebaseUIDRef = useRef(firebaseUid);
106
+ const currentImageIdRef = useRef(currentImageId);
105
107
  // Batch mode state - ref to avoid triggering effects
106
108
  const batchModeRef = useRef(internalOptions.enableBatching);
107
109
  const batchStartIndexRef = useRef(null);
@@ -112,6 +114,8 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
112
114
  const devWarningsRef = useRef(internalOptions.devWarnings);
113
115
  // Computed current index for return value (defined early for dependencies)
114
116
  const currentIndex = currentIndexRef.current;
117
+ currentFirebaseUIDRef.current = internalOptions.firebaseUid;
118
+ currentImageIdRef.current = internalOptions.currentImageId;
115
119
  // Performance monitoring
116
120
  const performanceRef = useRef({
117
121
  lastHistorySize: 1,
@@ -127,9 +131,11 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
127
131
  // }, [history, currentIndex, initialState]);
128
132
  useEffect(() => {
129
133
  if (internalOptions.currentImageId) {
134
+ console.log(`🔄 Syncing adjustment history from backend for image ID: ${internalOptions.currentImageId}`);
130
135
  syncFromBackend().catch(console.error);
131
136
  }
132
137
  }, [internalOptions.currentImageId, internalOptions.firebaseUid, internalOptions.controller]);
138
+ console.log(internalOptions);
133
139
  const getMemoryUsage = useCallback(() => {
134
140
  try {
135
141
  const historyString = JSON.stringify(history);
@@ -442,18 +448,18 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
442
448
  return newHistory;
443
449
  });
444
450
  // Call controller to create history in backend - OUTSIDE of setHistory callback
445
- if (internalOptions.controller && internalOptions.firebaseUid && internalOptions.currentImageId) {
451
+ if (internalOptions.controller && currentFirebaseUIDRef.current && currentImageIdRef.current) {
446
452
  try {
447
453
  console.log('🔄 Creating editor history in backend for batch mode end');
448
454
  console.log('📋 Current state for backend:', batchStartIndexRef.current, currentStateRef.current, history.length);
449
455
  const createEditorConfigPayload = {
450
- gallery_id: internalOptions.currentImageId,
456
+ gallery_id: currentImageIdRef.current,
451
457
  task_id: taskId,
452
458
  color_adjustment: convertAdjustmentStateToColorAdjustment(currentStateRef.current),
453
459
  ...(replaceFromTaskId && { replace_from: replaceFromTaskId })
454
460
  };
455
461
  // Create editor config with current adjustments
456
- internalOptions.controller.createEditorConfig(internalOptions.firebaseUid, createEditorConfigPayload).then(() => {
462
+ internalOptions.controller.createEditorConfig(currentFirebaseUIDRef.current, createEditorConfigPayload).then(() => {
457
463
  console.log('✅ Successfully created editor history in backend');
458
464
  }).catch((error) => {
459
465
  console.error('❌ Failed to create editor history in backend:', error);
@@ -464,9 +470,7 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
464
470
  }
465
471
  }
466
472
  else {
467
- if (internalOptions.devWarnings) {
468
- console.warn('⚠️ Controller, firebaseUid, or currentImageId not provided - skipping backend history creation');
469
- }
473
+ console.warn('⚠️ Controller, firebaseUid, or currentImageId not provided - skipping backend history creation', { controller, firebaseUid, currentImageId });
470
474
  }
471
475
  }
472
476
  else {
@@ -481,7 +485,7 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
481
485
  batchStartStateRef.current = null;
482
486
  batchModeProcessingRef.current = false; // Reset processing flag
483
487
  }
484
- }, [internalOptions, history]);
488
+ }, [internalOptions.controller, history]);
485
489
  // Sync history from backend using getEditorHistory
486
490
  const syncFromBackend = useCallback(async () => {
487
491
  if (!internalOptions.controller || !internalOptions.firebaseUid || !internalOptions.currentImageId) {
@@ -514,7 +518,32 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
514
518
  }
515
519
  // Handle empty history case
516
520
  if (backendHistoryEntries.length === 0) {
517
- console.log('📝 Backend history is empty, keeping current local history');
521
+ console.log('📝 Backend history is empty, creating initial adjustment with all values set to 0');
522
+ // Create initial adjustment state with all values set to 0
523
+ const initialAdjustmentState = {
524
+ tempScore: 0,
525
+ tintScore: 0,
526
+ saturationScore: 0,
527
+ vibranceScore: 0,
528
+ exposureScore: 0,
529
+ contrastScore: 0,
530
+ highlightsScore: 0,
531
+ shadowsScore: 0,
532
+ whitesScore: 0,
533
+ blacksScore: 0,
534
+ clarityScore: 0,
535
+ sharpnessScore: 0,
536
+ };
537
+ const initialHistoryEntry = {
538
+ state: initialAdjustmentState,
539
+ taskId: `initial_${Date.now()}`
540
+ };
541
+ // Set history with initial adjustment
542
+ setHistory([initialHistoryEntry]);
543
+ currentIndexRef.current = 0;
544
+ currentStateRef.current = initialAdjustmentState;
545
+ setCurrentState(initialAdjustmentState);
546
+ console.log('✅ Created initial history with all adjustments set to 0');
518
547
  return;
519
548
  }
520
549
  // Exit batch mode if active
@@ -537,6 +566,56 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
537
566
  throw error;
538
567
  }
539
568
  }, [internalOptions]);
569
+ // Update specific history entry from backend without changing current index
570
+ const updateFromBackend = useCallback((imageId, adjustmentTaskId, adjustment) => {
571
+ // Ignore updates if imageID doesn't match current image
572
+ if (imageId !== internalOptions.currentImageId) {
573
+ console.log(`🚫 updateFromBackend: Ignoring update for different image (${imageId} vs ${internalOptions.currentImageId})`);
574
+ return;
575
+ }
576
+ // Ignore updates during batch mode
577
+ if (batchModeRef.current) {
578
+ console.log(`🚫 updateFromBackend: Ignoring update during batch mode for taskId: ${adjustmentTaskId}`);
579
+ return;
580
+ }
581
+ console.log(`🔄 updateFromBackend: Received update for taskId: ${adjustmentTaskId}, imageId: ${imageId}`);
582
+ // Convert ColorAdjustment to AdjustmentState
583
+ const updatedState = convertColorAdjustmentToAdjustmentState(adjustment);
584
+ setHistory(prevHistory => {
585
+ // Find the index of the task to update
586
+ const taskIndex = prevHistory.findIndex(entry => entry.taskId === adjustmentTaskId);
587
+ if (taskIndex === -1) {
588
+ // Task doesn't exist in current history, we need to sync from backend
589
+ // to get the complete history with proper chronological order
590
+ console.log(`📝 updateFromBackend: TaskId ${adjustmentTaskId} not found in current history, triggering sync from backend`);
591
+ // Don't modify history here, instead trigger a sync
592
+ // Use setTimeout to avoid calling async function inside setState
593
+ setTimeout(() => {
594
+ syncFromBackend().catch(error => {
595
+ console.error('❌ Failed to sync history after unknown taskId:', error);
596
+ });
597
+ }, 0);
598
+ // Return unchanged history for now
599
+ return prevHistory;
600
+ }
601
+ // Task exists, check if it's the current index
602
+ const isCurrentIndex = taskIndex === currentIndexRef.current;
603
+ if (isCurrentIndex) {
604
+ console.log(`🔄 updateFromBackend: Updating current index (${taskIndex}) but not changing current state`);
605
+ }
606
+ else {
607
+ console.log(`🔄 updateFromBackend: Updating history entry at index ${taskIndex} (far behind current ${currentIndexRef.current})`);
608
+ }
609
+ // Update the specific history entry
610
+ const updatedHistory = [...prevHistory];
611
+ updatedHistory[taskIndex] = {
612
+ state: updatedState,
613
+ taskId: adjustmentTaskId
614
+ };
615
+ return updatedHistory;
616
+ });
617
+ console.log(`✅ updateFromBackend: Successfully updated taskId ${adjustmentTaskId}`);
618
+ }, [internalOptions]);
540
619
  // History info object
541
620
  const historyInfo = useMemo(() => ({
542
621
  canUndo: currentIndex > 0,
@@ -555,8 +634,9 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
555
634
  clearHistory,
556
635
  getHistory,
557
636
  trimHistory,
558
- syncFromBackend
559
- }), [pushState, undo, redo, jumpToIndex, clearHistory, getHistory, trimHistory, syncFromBackend]);
637
+ syncFromBackend,
638
+ updateFromBackend
639
+ }), [pushState, undo, redo, jumpToIndex, clearHistory, getHistory, trimHistory, syncFromBackend, updateFromBackend]);
560
640
  // Config object - stabilized with useMemo
561
641
  const config = useMemo(() => ({
562
642
  setMaxSize,
@@ -1,5 +1,5 @@
1
1
  import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
2
- import { mapAdjustmentStateToColorAdjustment, mapColorAdjustmentToAdjustmentState } from '../utils/adjustment';
2
+ import { mapAdjustmentStateToColorAdjustment, mapColorAdjustmentToAdjustmentState } from "../utils/adjustment";
3
3
  /**
4
4
  * Create default adjustment state
5
5
  */
@@ -0,0 +1,15 @@
1
+ import HonchoEditor from "../lib/editor/honcho-editor";
2
+ declare global {
3
+ interface Window {
4
+ __raceFreeeEditor?: HonchoEditor;
5
+ __raceFreeEditorInitializing?: boolean;
6
+ }
7
+ }
8
+ interface UseEditorHeadlessOptions {
9
+ }
10
+ export declare function useEditorHeadlessRaceFree(options?: UseEditorHeadlessOptions): {
11
+ isReady: boolean;
12
+ error: Error | null;
13
+ editor: HonchoEditor | null;
14
+ };
15
+ export {};
@@ -0,0 +1,88 @@
1
+ import { useState, useEffect, useCallback, useRef } from 'react';
2
+ export function useEditorHeadlessRaceFree(options = {}) {
3
+ const [isReady, setIsReady] = useState(false);
4
+ const [error, setError] = useState(null);
5
+ const componentId = useRef(`component-${Date.now()}-${Math.random()}`);
6
+ console.log(`[RACE-FREE] Hook called in component: ${componentId.current}`);
7
+ // Get or create shared race-free editor instance
8
+ const getOrCreateSharedEditor = useCallback(async () => {
9
+ // If we already have a global instance, return it
10
+ if (window.__raceFreeeEditor) {
11
+ console.log(`[RACE-FREE] Reusing existing shared editor instance`);
12
+ return window.__raceFreeeEditor;
13
+ }
14
+ // If already initializing, wait for completion
15
+ if (window.__raceFreeEditorInitializing) {
16
+ console.log(`[RACE-FREE] Waiting for shared editor initialization...`);
17
+ let attempts = 0;
18
+ while (window.__raceFreeEditorInitializing && attempts < 100) {
19
+ await new Promise(resolve => setTimeout(resolve, 100));
20
+ attempts++;
21
+ }
22
+ if (window.__raceFreeeEditor) {
23
+ return window.__raceFreeeEditor;
24
+ }
25
+ }
26
+ // Start initialization
27
+ window.__raceFreeEditorInitializing = true;
28
+ console.log(`[RACE-FREE] Creating new shared editor instance`);
29
+ try {
30
+ // Wait for global HonchoEditor to be available (loaded by EditorContext)
31
+ console.log(`[RACE-FREE] Waiting for global HonchoEditor...`);
32
+ let attempts = 0;
33
+ const maxAttempts = 100; // 10 seconds max wait
34
+ while (!window.HonchoEditor && attempts < maxAttempts) {
35
+ await new Promise(resolve => setTimeout(resolve, 100));
36
+ attempts++;
37
+ }
38
+ if (!window.HonchoEditor) {
39
+ throw new Error('[RACE-FREE] Global HonchoEditor not available after waiting');
40
+ }
41
+ console.log(`[RACE-FREE] Global HonchoEditor available, creating shared instance`);
42
+ // Create shared instance using the global constructor
43
+ const editorInstance = new window.HonchoEditor();
44
+ console.log(`[RACE-FREE] Created new shared HonchoEditor instance`);
45
+ // Initialize the editor instance
46
+ await editorInstance.initialize(false);
47
+ console.log(`[RACE-FREE] Shared HonchoEditor instance initialized`);
48
+ // Store globally
49
+ window.__raceFreeeEditor = editorInstance;
50
+ console.log(`[RACE-FREE] Shared editor instance ready`);
51
+ return editorInstance;
52
+ }
53
+ catch (err) {
54
+ console.error(`[RACE-FREE] Shared initialization failed:`, err);
55
+ throw err;
56
+ }
57
+ finally {
58
+ window.__raceFreeEditorInitializing = false;
59
+ }
60
+ }, []);
61
+ // Initialize shared editor instance
62
+ useEffect(() => {
63
+ console.log(`[RACE-FREE] Component mounted: ${componentId.current}`);
64
+ const initializeSharedEditor = async () => {
65
+ try {
66
+ await getOrCreateSharedEditor();
67
+ setIsReady(true);
68
+ setError(null);
69
+ console.log(`[RACE-FREE] Component ${componentId.current} ready`);
70
+ }
71
+ catch (err) {
72
+ console.error(`[RACE-FREE] Component ${componentId.current} initialization failed:`, err);
73
+ setError(err instanceof Error ? err : new Error(String(err)));
74
+ setIsReady(false);
75
+ }
76
+ };
77
+ initializeSharedEditor();
78
+ return () => {
79
+ console.log(`[RACE-FREE] Component unmounting: ${componentId.current}`);
80
+ // Note: We don't cleanup the shared editor instance here since other components might be using it
81
+ };
82
+ }, []); // No dependencies to prevent re-initialization
83
+ return {
84
+ isReady,
85
+ error,
86
+ editor: window.__raceFreeeEditor || null
87
+ };
88
+ }
@@ -1,4 +1,101 @@
1
+ /**
2
+ * Honcho Photo Editor - JavaScript Wrapper
3
+ *
4
+ * This wrapper provides a clean interface to the C++ image processing engine.
5
+ *
6
+ * ARCHITECTURE: Dual-Path Processing
7
+ * ================================
8
+ *
9
+ * FRONTEND (Real-time Preview):
10
+ * - Uses GPU-to-GPU rendering via renderToCanvas()
11
+ * - Zero memory copies for 60fps performance
12
+ * - Optimized for interactive UI sliders
13
+ *
14
+ * BACKEND (Server Processing):
15
+ * - Uses CPU memory path via getProcessedImageData()
16
+ * - Full quality data export for server workflows
17
+ * - Headless processing without WebGL context
18
+ * - Batch processing and API endpoints
19
+ *
20
+ * Both paths use the same C++ processing core with identical results.
21
+ * JavaScript handles all UI and canvas rendering.
22
+ * C++ handles all image processing algorithms.
23
+ */
1
24
  export class HonchoEditor {
25
+ static ADJUSTMENT_RANGES: {
26
+ temperature: {
27
+ min: number;
28
+ max: number;
29
+ default: number;
30
+ step: number;
31
+ };
32
+ tint: {
33
+ min: number;
34
+ max: number;
35
+ default: number;
36
+ step: number;
37
+ };
38
+ saturation: {
39
+ min: number;
40
+ max: number;
41
+ default: number;
42
+ step: number;
43
+ };
44
+ vibrance: {
45
+ min: number;
46
+ max: number;
47
+ default: number;
48
+ step: number;
49
+ };
50
+ exposure: {
51
+ min: number;
52
+ max: number;
53
+ default: number;
54
+ step: number;
55
+ };
56
+ contrast: {
57
+ min: number;
58
+ max: number;
59
+ default: number;
60
+ step: number;
61
+ };
62
+ highlights: {
63
+ min: number;
64
+ max: number;
65
+ default: number;
66
+ step: number;
67
+ };
68
+ shadows: {
69
+ min: number;
70
+ max: number;
71
+ default: number;
72
+ step: number;
73
+ };
74
+ whites: {
75
+ min: number;
76
+ max: number;
77
+ default: number;
78
+ step: number;
79
+ };
80
+ blacks: {
81
+ min: number;
82
+ max: number;
83
+ default: number;
84
+ step: number;
85
+ };
86
+ clarity: {
87
+ min: number;
88
+ max: number;
89
+ default: number;
90
+ step: number;
91
+ };
92
+ sharpness: {
93
+ min: number;
94
+ max: number;
95
+ default: number;
96
+ step: number;
97
+ };
98
+ };
2
99
  wasmModule: any;
3
100
  isInitialized: boolean;
4
101
  currentImageData: any;
@@ -203,122 +300,3 @@ export namespace HonchoEditorUtils {
203
300
  */
204
301
  function formatFileSize(bytes: any): string;
205
302
  }
206
- export namespace ADJUSTMENT_RANGES {
207
- namespace temperature {
208
- export let min: number;
209
- export let max: number;
210
- let _default: number;
211
- export { _default as default };
212
- export let step: number;
213
- }
214
- namespace tint {
215
- let min_1: number;
216
- export { min_1 as min };
217
- let max_1: number;
218
- export { max_1 as max };
219
- let _default_1: number;
220
- export { _default_1 as default };
221
- let step_1: number;
222
- export { step_1 as step };
223
- }
224
- namespace saturation {
225
- let min_2: number;
226
- export { min_2 as min };
227
- let max_2: number;
228
- export { max_2 as max };
229
- let _default_2: number;
230
- export { _default_2 as default };
231
- let step_2: number;
232
- export { step_2 as step };
233
- }
234
- namespace vibrance {
235
- let min_3: number;
236
- export { min_3 as min };
237
- let max_3: number;
238
- export { max_3 as max };
239
- let _default_3: number;
240
- export { _default_3 as default };
241
- let step_3: number;
242
- export { step_3 as step };
243
- }
244
- namespace exposure {
245
- let min_4: number;
246
- export { min_4 as min };
247
- let max_4: number;
248
- export { max_4 as max };
249
- let _default_4: number;
250
- export { _default_4 as default };
251
- let step_4: number;
252
- export { step_4 as step };
253
- }
254
- namespace contrast {
255
- let min_5: number;
256
- export { min_5 as min };
257
- let max_5: number;
258
- export { max_5 as max };
259
- let _default_5: number;
260
- export { _default_5 as default };
261
- let step_5: number;
262
- export { step_5 as step };
263
- }
264
- namespace highlights {
265
- let min_6: number;
266
- export { min_6 as min };
267
- let max_6: number;
268
- export { max_6 as max };
269
- let _default_6: number;
270
- export { _default_6 as default };
271
- let step_6: number;
272
- export { step_6 as step };
273
- }
274
- namespace shadows {
275
- let min_7: number;
276
- export { min_7 as min };
277
- let max_7: number;
278
- export { max_7 as max };
279
- let _default_7: number;
280
- export { _default_7 as default };
281
- let step_7: number;
282
- export { step_7 as step };
283
- }
284
- namespace whites {
285
- let min_8: number;
286
- export { min_8 as min };
287
- let max_8: number;
288
- export { max_8 as max };
289
- let _default_8: number;
290
- export { _default_8 as default };
291
- let step_8: number;
292
- export { step_8 as step };
293
- }
294
- namespace blacks {
295
- let min_9: number;
296
- export { min_9 as min };
297
- let max_9: number;
298
- export { max_9 as max };
299
- let _default_9: number;
300
- export { _default_9 as default };
301
- let step_9: number;
302
- export { step_9 as step };
303
- }
304
- namespace clarity {
305
- let min_10: number;
306
- export { min_10 as min };
307
- let max_10: number;
308
- export { max_10 as max };
309
- let _default_10: number;
310
- export { _default_10 as default };
311
- let step_10: number;
312
- export { step_10 as step };
313
- }
314
- namespace sharpness {
315
- let min_11: number;
316
- export { min_11 as min };
317
- let max_11: number;
318
- export { max_11 as max };
319
- let _default_11: number;
320
- export { _default_11 as default };
321
- let step_11: number;
322
- export { step_11 as step };
323
- }
324
- }
@@ -23,20 +23,7 @@
23
23
  * C++ handles all image processing algorithms.
24
24
  */
25
25
  // Adjustment ranges for UI components
26
- const ADJUSTMENT_RANGES = {
27
- temperature: { min: -100, max: 100, default: 0, step: 1 },
28
- tint: { min: -100, max: 100, default: 0, step: 1 },
29
- saturation: { min: -100, max: 100, default: 0, step: 1 },
30
- vibrance: { min: -100, max: 100, default: 0, step: 1 },
31
- exposure: { min: -100, max: 100, default: 0, step: 1 },
32
- contrast: { min: -100, max: 100, default: 0, step: 1 },
33
- highlights: { min: -100, max: 100, default: 0, step: 1 },
34
- shadows: { min: -100, max: 100, default: 0, step: 1 },
35
- whites: { min: -100, max: 100, default: 0, step: 1 },
36
- blacks: { min: -100, max: 100, default: 0, step: 1 },
37
- clarity: { min: -100, max: 100, default: 0, step: 1 },
38
- sharpness: { min: -100, max: 100, default: 0, step: 1 }
39
- };
26
+ // Moved inside HonchoEditor class as static property
40
27
  class HonchoEditor {
41
28
  constructor() {
42
29
  this.wasmModule = null;
@@ -554,6 +541,9 @@ class HonchoEditor {
554
541
  }
555
542
  console.log('✅ Frame applied successfully');
556
543
  }
544
+ else {
545
+ this.clearFrame();
546
+ }
557
547
  // Step 3: Apply all adjustments
558
548
  console.log('🎛️ Applying adjustments:', adjustments);
559
549
  const validAdjustments = [
@@ -718,7 +708,7 @@ class HonchoEditor {
718
708
  * Validate adjustment value against range
719
709
  */
720
710
  validateAdjustment(name, value) {
721
- const range = ADJUSTMENT_RANGES[name];
711
+ const range = HonchoEditor.ADJUSTMENT_RANGES[name];
722
712
  if (!range) {
723
713
  throw new Error(`Unknown adjustment: ${name}`);
724
714
  }
@@ -742,6 +732,21 @@ class HonchoEditor {
742
732
  this.canvas = null;
743
733
  }
744
734
  }
735
+ // Static adjustment ranges for UI components
736
+ HonchoEditor.ADJUSTMENT_RANGES = {
737
+ temperature: { min: -100, max: 100, default: 0, step: 1 },
738
+ tint: { min: -100, max: 100, default: 0, step: 1 },
739
+ saturation: { min: -100, max: 100, default: 0, step: 1 },
740
+ vibrance: { min: -100, max: 100, default: 0, step: 1 },
741
+ exposure: { min: -100, max: 100, default: 0, step: 1 },
742
+ contrast: { min: -100, max: 100, default: 0, step: 1 },
743
+ highlights: { min: -100, max: 100, default: 0, step: 1 },
744
+ shadows: { min: -100, max: 100, default: 0, step: 1 },
745
+ whites: { min: -100, max: 100, default: 0, step: 1 },
746
+ blacks: { min: -100, max: 100, default: 0, step: 1 },
747
+ clarity: { min: -100, max: 100, default: 0, step: 1 },
748
+ sharpness: { min: -100, max: 100, default: 0, step: 1 }
749
+ };
745
750
  // Export for convenience
746
751
  // export default HonchoEditor; // Disabled for browser compatibility
747
752
  // Helper functions for common operations
@@ -816,10 +821,10 @@ const HonchoEditorUtils = {
816
821
  };
817
822
  // Export for both Node.js and browser
818
823
  if (typeof module !== 'undefined' && module.exports) {
819
- module.exports = { HonchoEditor, HonchoEditorUtils, ADJUSTMENT_RANGES };
824
+ module.exports = { HonchoEditor, HonchoEditorUtils };
820
825
  }
821
826
  else {
822
827
  window.HonchoEditor = HonchoEditor;
823
828
  window.HonchoEditorUtils = HonchoEditorUtils;
824
- window.ADJUSTMENT_RANGES = ADJUSTMENT_RANGES;
829
+ //window.ADJUSTMENT_RANGES = ADJUSTMENT_RANGES;
825
830
  }