@trustquery/browser 0.1.0 → 0.2.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustquery/browser",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Turn any textarea into an interactive trigger-based editor with inline styling",
5
5
  "type": "module",
6
6
  "main": "dist/trustquery.js",
@@ -103,8 +103,6 @@ export default class CommandScanner {
103
103
  // Sort by length (longest first) to match longer patterns first
104
104
  commands.sort((a, b) => b.match.length - a.match.length);
105
105
 
106
- console.log('[CommandScanner] Parsed commands:', commands.length, commands);
107
-
108
106
  return commands;
109
107
  }
110
108
 
@@ -127,7 +125,11 @@ export default class CommandScanner {
127
125
  matches.push(...lineMatches);
128
126
  });
129
127
 
130
- console.log('[CommandScanner] Found', matches.length, 'matches');
128
+ // Only log when matches are found
129
+ if (matches.length > 0) {
130
+ console.log(`[CommandScanner] Found ${matches.length} matches`);
131
+ }
132
+
131
133
  return matches;
132
134
  }
133
135
 
@@ -21,7 +21,9 @@ export default class DropdownManager {
21
21
  this.selectedDropdownIndex = 0;
22
22
  this.keyboardHandler = null;
23
23
 
24
- console.log('[DropdownManager] Initialized with offset:', this.options.dropdownOffset);
24
+ if (this.options.debug) {
25
+ console.log('[DropdownManager] Initialized with offset:', this.options.dropdownOffset);
26
+ }
25
27
  }
26
28
 
27
29
  /**
@@ -102,7 +104,9 @@ export default class DropdownManager {
102
104
  document.addEventListener('click', this.closeDropdownHandler);
103
105
  }, 0);
104
106
 
105
- console.log('[DropdownManager] Dropdown shown with', options.length, 'options');
107
+ if (this.options.debug) {
108
+ console.log('[DropdownManager] Dropdown shown with', options.length, 'options');
109
+ }
106
110
  }
107
111
 
108
112
  /**
@@ -536,7 +540,9 @@ export default class DropdownManager {
536
540
  * @param {Object} matchData - Match data
537
541
  */
538
542
  handleDropdownSelect(option, matchData) {
539
- console.log('[DropdownManager] Dropdown option selected:', option, 'for:', matchData.text);
543
+ if (this.options.debug) {
544
+ console.log('[DropdownManager] Dropdown option selected:', option, 'for:', matchData.text);
545
+ }
540
546
 
541
547
  // Check if option has on-select.display
542
548
  if (option['on-select'] && option['on-select'].display && this.options.textarea) {
@@ -562,7 +568,9 @@ export default class DropdownManager {
562
568
  const inputEvent = new Event('input', { bubbles: true });
563
569
  textarea.dispatchEvent(inputEvent);
564
570
 
565
- console.log('[DropdownManager] Appended to', matchData.text, '→', newText);
571
+ if (this.options.debug) {
572
+ console.log('[DropdownManager] Appended to', matchData.text, '→', newText);
573
+ }
566
574
  }
567
575
  }
568
576
 
@@ -587,6 +595,8 @@ export default class DropdownManager {
587
595
  */
588
596
  destroy() {
589
597
  this.cleanup();
590
- console.log('[DropdownManager] Destroyed');
598
+ if (this.options.debug) {
599
+ console.log('[DropdownManager] Destroyed');
600
+ }
591
601
  }
592
602
  }
@@ -28,17 +28,21 @@ export default class InteractionHandler {
28
28
  this.bubbleManager = new BubbleManager({
29
29
  bubbleDelay: this.options.bubbleDelay,
30
30
  styleManager: this.options.styleManager,
31
- commandHandlers: this.options.commandHandlers
31
+ commandHandlers: this.options.commandHandlers,
32
+ debug: this.options.debug
32
33
  });
33
34
 
34
35
  this.dropdownManager = new DropdownManager({
35
36
  styleManager: this.options.styleManager,
36
37
  textarea: this.options.textarea,
37
38
  onWordClick: this.options.onWordClick,
38
- dropdownOffset: this.options.dropdownOffset
39
+ dropdownOffset: this.options.dropdownOffset,
40
+ debug: this.options.debug
39
41
  });
40
42
 
41
- console.log('[InteractionHandler] Initialized');
43
+ if (this.options.debug) {
44
+ console.log('[InteractionHandler] Initialized');
45
+ }
42
46
  }
43
47
 
44
48
  /**
@@ -76,7 +80,9 @@ export default class InteractionHandler {
76
80
  }
77
81
  });
78
82
 
79
- console.log('[InteractionHandler] Updated with', matches.length, 'interactive elements');
83
+ if (this.options.debug) {
84
+ console.log('[InteractionHandler] Updated with', matches.length, 'interactive elements');
85
+ }
80
86
  }
81
87
 
82
88
  /**
@@ -12,10 +12,13 @@ export default class OverlayRenderer {
12
12
  this.options = {
13
13
  theme: options.theme || 'light',
14
14
  commandHandlers: options.commandHandlers || null,
15
+ debug: options.debug || false,
15
16
  ...options
16
17
  };
17
18
 
18
- console.log('[OverlayRenderer] Initialized');
19
+ if (this.options.debug) {
20
+ console.log('[OverlayRenderer] Initialized');
21
+ }
19
22
  }
20
23
 
21
24
  /**
@@ -35,7 +38,9 @@ export default class OverlayRenderer {
35
38
  // Update overlay
36
39
  this.overlay.innerHTML = linesHTML;
37
40
 
38
- console.log('[OverlayRenderer] Rendered', lines.length, 'lines with', matches.length, 'matches');
41
+ if (this.options.debug) {
42
+ console.log('[OverlayRenderer] Rendered', lines.length, 'lines with', matches.length, 'matches');
43
+ }
39
44
  }
40
45
 
41
46
  /**
package/src/TrustQuery.js CHANGED
@@ -7,6 +7,7 @@ import InteractionHandler from './InteractionHandler.js';
7
7
  import StyleManager from './StyleManager.js';
8
8
  import CommandHandlerRegistry from './CommandHandlers.js';
9
9
  import AutoGrow from './AutoGrow.js';
10
+ import ValidationStateManager from './ValidationStateManager.js';
10
11
 
11
12
  export default class TrustQuery {
12
13
  // Store all instances
@@ -108,6 +109,7 @@ export default class TrustQuery {
108
109
  // Events (callbacks)
109
110
  onWordClick: events.onWordClick || options.onWordClick || null,
110
111
  onWordHover: events.onWordHover || options.onWordHover || null,
112
+ onValidationChange: events.onValidationChange || options.onValidationChange || null,
111
113
 
112
114
  // Theme/style options (passed to StyleManager)
113
115
  backgroundColor: ui.backgroundColor || options.backgroundColor,
@@ -144,7 +146,8 @@ export default class TrustQuery {
144
146
  // Initialize renderer
145
147
  this.renderer = new OverlayRenderer(this.overlay, {
146
148
  theme: this.options.theme,
147
- commandHandlers: this.commandHandlers // Pass handlers for styling
149
+ commandHandlers: this.commandHandlers, // Pass handlers for styling
150
+ debug: this.options.debug // Pass debug flag
148
151
  });
149
152
 
150
153
  // Initialize scanner (will be configured when command map loads)
@@ -158,7 +161,13 @@ export default class TrustQuery {
158
161
  onWordHover: this.options.onWordHover,
159
162
  styleManager: this.styleManager, // Pass style manager for bubbles/dropdowns
160
163
  commandHandlers: this.commandHandlers, // Pass handlers for bubble content
161
- textarea: this.textarea // Pass textarea for on-select display updates
164
+ textarea: this.textarea, // Pass textarea for on-select display updates
165
+ debug: this.options.debug // Pass debug flag
166
+ });
167
+
168
+ // Initialize validation state manager
169
+ this.validationStateManager = new ValidationStateManager({
170
+ onValidationChange: this.options.onValidationChange
162
171
  });
163
172
 
164
173
  // Initialize features
@@ -357,6 +366,11 @@ export default class TrustQuery {
357
366
 
358
367
  // Update interaction handler with new elements
359
368
  this.interactionHandler.update();
369
+
370
+ // Update validation state
371
+ if (this.validationStateManager) {
372
+ this.validationStateManager.update(matches);
373
+ }
360
374
  }
361
375
 
362
376
  /**
@@ -0,0 +1,105 @@
1
+ // ValidationStateManager - Tracks validation state and triggers callbacks
2
+
3
+ export default class ValidationStateManager {
4
+ /**
5
+ * Create validation state manager
6
+ * @param {Object} options - Configuration
7
+ */
8
+ constructor(options = {}) {
9
+ this.options = {
10
+ onValidationChange: options.onValidationChange || null,
11
+ ...options
12
+ };
13
+
14
+ this.state = {
15
+ hasBlockingError: false,
16
+ errors: [], // matches with message-state: 'error'
17
+ warnings: [], // matches with message-state: 'warning'
18
+ info: [] // matches with message-state: 'info'
19
+ };
20
+
21
+ console.log('[ValidationStateManager] Initialized');
22
+ }
23
+
24
+ /**
25
+ * Update validation state based on current matches
26
+ * @param {Array} matches - Current matches from scanner
27
+ */
28
+ update(matches) {
29
+ // Reset state
30
+ const newState = {
31
+ hasBlockingError: false,
32
+ errors: [],
33
+ warnings: [],
34
+ info: []
35
+ };
36
+
37
+ // Categorize current matches
38
+ matches.forEach(match => {
39
+ const messageState = match.intent?.handler?.['message-state'];
40
+ const blockSubmit = match.intent?.handler?.['block-submit'] === true;
41
+
42
+ if (blockSubmit) {
43
+ newState.hasBlockingError = true;
44
+ }
45
+
46
+ switch (messageState) {
47
+ case 'error':
48
+ newState.errors.push(match);
49
+ break;
50
+ case 'warning':
51
+ newState.warnings.push(match);
52
+ break;
53
+ case 'info':
54
+ newState.info.push(match);
55
+ break;
56
+ }
57
+ });
58
+
59
+ // Check if state changed
60
+ const stateChanged =
61
+ this.state.hasBlockingError !== newState.hasBlockingError ||
62
+ this.state.errors.length !== newState.errors.length ||
63
+ this.state.warnings.length !== newState.warnings.length ||
64
+ this.state.info.length !== newState.info.length;
65
+
66
+ if (stateChanged) {
67
+ this.state = newState;
68
+
69
+ // Trigger callback
70
+ if (this.options.onValidationChange) {
71
+ this.options.onValidationChange(this.state);
72
+ }
73
+
74
+ console.log('[ValidationStateManager] State changed:', {
75
+ hasBlockingError: newState.hasBlockingError,
76
+ errors: newState.errors.length,
77
+ warnings: newState.warnings.length,
78
+ info: newState.info.length
79
+ });
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Get current validation state
85
+ * @returns {Object} Current validation state
86
+ */
87
+ getState() {
88
+ return { ...this.state };
89
+ }
90
+
91
+ /**
92
+ * Reset validation state to empty
93
+ */
94
+ reset() {
95
+ this.update([]);
96
+ }
97
+
98
+ /**
99
+ * Check if there are blocking errors
100
+ * @returns {boolean} True if there are blocking errors
101
+ */
102
+ hasBlockingErrors() {
103
+ return this.state.hasBlockingError;
104
+ }
105
+ }