jsgui3-server 0.0.138 → 0.0.140

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.
Files changed (57) hide show
  1. package/AGENTS.md +87 -0
  2. package/README.md +12 -0
  3. package/docs/GUIDE_TO_AGENTIC_WORKFLOWS_BY_GROK.md +19 -0
  4. package/docs/advanced-usage-examples.md +1360 -0
  5. package/docs/agent-development-guide.md +386 -0
  6. package/docs/api-reference.md +916 -0
  7. package/docs/broken-functionality-tracker.md +285 -0
  8. package/docs/bundling-system-deep-dive.md +525 -0
  9. package/docs/cli-reference.md +393 -0
  10. package/docs/comprehensive-documentation.md +1403 -0
  11. package/docs/configuration-reference.md +808 -0
  12. package/docs/controls-development.md +859 -0
  13. package/docs/documentation-review/CURRENT_REVIEW.md +95 -0
  14. package/docs/function-publishers-json-apis.md +847 -0
  15. package/docs/getting-started-with-json.md +518 -0
  16. package/docs/minification-compression-sourcemaps-status.md +482 -0
  17. package/docs/minification-compression-sourcemaps-test-results.md +205 -0
  18. package/docs/publishers-guide.md +313 -0
  19. package/docs/resources-guide.md +615 -0
  20. package/docs/serve-helpers.md +406 -0
  21. package/docs/simple-server-api-design.md +13 -0
  22. package/docs/system-architecture.md +275 -0
  23. package/docs/troubleshooting.md +698 -0
  24. package/examples/json/README.md +115 -0
  25. package/examples/json/basic-api/README.md +345 -0
  26. package/examples/json/basic-api/server.js +199 -0
  27. package/examples/json/simple-api/README.md +125 -0
  28. package/examples/json/simple-api/diagnostic-report.json +73 -0
  29. package/examples/json/simple-api/diagnostic-test.js +433 -0
  30. package/examples/json/simple-api/server-debug.md +58 -0
  31. package/examples/json/simple-api/server.js +91 -0
  32. package/examples/json/simple-api/test.js +215 -0
  33. package/http/responders/static/Static_Route_HTTP_Responder.js +1 -2
  34. package/package.json +19 -8
  35. package/publishers/helpers/assigners/static-compressed-response-buffers/Single_Control_Webpage_Server_Static_Compressed_Response_Buffers_Assigner.js +65 -12
  36. package/publishers/helpers/preparers/static/bundle/Static_Routes_Responses_Webpage_Bundle_Preparer.js +6 -1
  37. package/publishers/http-function-publisher.js +59 -38
  38. package/publishers/http-webpage-publisher.js +48 -1
  39. package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +38 -146
  40. package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +54 -5
  41. package/resources/processors/bundlers/js/esbuild/Core_JS_Single_File_Minifying_Bundler_Using_ESBuild.js +36 -4
  42. package/serve-factory.js +36 -9
  43. package/server.js +10 -4
  44. package/test-report.json +0 -0
  45. package/tests/README.md +250 -0
  46. package/tests/assigners.test.js +316 -0
  47. package/tests/bundlers.test.js +329 -0
  48. package/tests/configuration-validation.test.js +530 -0
  49. package/tests/content-analysis.test.js +641 -0
  50. package/tests/end-to-end.test.js +496 -0
  51. package/tests/error-handling.test.js +746 -0
  52. package/tests/performance.test.js +653 -0
  53. package/tests/publishers.test.js +395 -0
  54. package/tests/temp_invalid.js +7 -0
  55. package/tests/temp_invalid_utf8.js +1 -0
  56. package/tests/temp_malformed.js +10 -0
  57. package/tests/test-runner.js +261 -0
@@ -0,0 +1,859 @@
1
+ # Controls Development Guide
2
+
3
+ ## When to Read
4
+
5
+ This document explains how to develop custom controls for JSGUI3 Server. Read this when:
6
+ - You want to create custom UI components
7
+ - You need to understand the control lifecycle and patterns
8
+ - You're extending existing controls or creating new ones
9
+ - You want to understand data binding and event handling
10
+ - You're working on client-side JavaScript for JSGUI3 applications
11
+
12
+ **Note:** For using existing controls, see [README.md](../README.md). For system architecture, see [docs/system-architecture.md](docs/system-architecture.md).
13
+
14
+ ## Overview
15
+
16
+ Controls are the fundamental UI building blocks in JSGUI3. They represent reusable components that can be composed together to create complex user interfaces. Controls handle their own rendering, event management, and data binding.
17
+
18
+ ## Control Hierarchy
19
+
20
+ ### Base Classes
21
+
22
+ #### Active_HTML_Document
23
+
24
+ **Purpose:** The root class for all UI controls that render as complete HTML documents.
25
+
26
+ **Key Features:**
27
+ - Provides the main HTML document structure
28
+ - Manages CSS and JavaScript bundling
29
+ - Handles client-server communication
30
+ - Provides context for child controls
31
+
32
+ **Basic Structure:**
33
+ ```javascript
34
+ const jsgui = require('jsgui3-client');
35
+ const { controls, Control, Data_Object, field } = jsgui;
36
+ const Active_HTML_Document = require('jsgui3-server/controls/Active_HTML_Document');
37
+
38
+ class My_Custom_Control extends Active_HTML_Document {
39
+ constructor(spec = {}) {
40
+ spec.__type_name = spec.__type_name || 'my_custom_control';
41
+ super(spec);
42
+ const { context } = this;
43
+
44
+ // Defensive CSS class application
45
+ if (typeof this.body.add_class === 'function') {
46
+ this.body.add_class('my-custom-control');
47
+ }
48
+
49
+ // Control composition
50
+ const compose = () => {
51
+ // Create and add child controls here
52
+ const button = new controls.Button({
53
+ context,
54
+ text: 'Click Me'
55
+ });
56
+ this.body.add(button);
57
+ };
58
+
59
+ // Conditional composition (only if not attached to existing DOM)
60
+ if (!spec.el) { compose(); }
61
+ }
62
+
63
+ activate() {
64
+ if (!this.__active) {
65
+ super.activate();
66
+ const { context } = this;
67
+
68
+ // Event handlers and activation logic
69
+ context.on('window-resize', e_resize => {
70
+ // Handle resize events
71
+ });
72
+ }
73
+ }
74
+ }
75
+
76
+ // Static CSS definition
77
+ My_Custom_Control.css = `
78
+ * { margin: 0; padding: 0; }
79
+ body {
80
+ overflow-x: hidden;
81
+ overflow-y: hidden;
82
+ background-color: #E0E0E0;
83
+ }
84
+ .my-custom-control {
85
+ padding: 20px;
86
+ background: #f0f0f0;
87
+ }
88
+ `;
89
+
90
+ // Register control globally
91
+ controls.My_Custom_Control = My_Custom_Control;
92
+ module.exports = jsgui;
93
+ ```
94
+
95
+ #### Control (Base)
96
+
97
+ **Purpose:** The fundamental building block for all UI components.
98
+
99
+ **Key Features:**
100
+ - Basic control lifecycle management
101
+ - Property system
102
+ - Event handling
103
+ - DOM manipulation
104
+
105
+ ### Specialized Controls
106
+
107
+ #### Window
108
+
109
+ **Purpose:** Draggable, resizable container control.
110
+
111
+ **Features:**
112
+ - Title bar with drag functionality
113
+ - Resizable borders
114
+ - Child control containment
115
+ - Positioning and sizing
116
+
117
+ ```javascript
118
+ const window = new controls.Window({
119
+ context,
120
+ title: 'My Window',
121
+ pos: [100, 100], // [x, y] position
122
+ size: [400, 300] // [width, height]
123
+ });
124
+
125
+ // Add content to window
126
+ window.inner.add(childControl);
127
+ this.body.add(window);
128
+ ```
129
+
130
+ #### Panel
131
+
132
+ **Purpose:** Basic container for grouping controls.
133
+
134
+ **Features:**
135
+ - Simple containment
136
+ - Background styling
137
+ - Border and padding options
138
+
139
+ #### Button
140
+
141
+ **Purpose:** Interactive button control.
142
+
143
+ **Features:**
144
+ - Click event handling
145
+ - Text and styling customization
146
+ - Disabled state support
147
+
148
+ ```javascript
149
+ const button = new controls.Button({
150
+ context,
151
+ text: 'Click Me',
152
+ onclick: () => {
153
+ console.log('Button clicked!');
154
+ }
155
+ });
156
+ ```
157
+
158
+ #### Text_Input
159
+
160
+ **Purpose:** Text input field control.
161
+
162
+ **Features:**
163
+ - Data binding support
164
+ - Validation
165
+ - Placeholder text
166
+ - Input event handling
167
+
168
+ ```javascript
169
+ const input = new controls.Text_Input({
170
+ context,
171
+ placeholder: 'Enter text...',
172
+ data: { model: sharedDataModel, field_name: 'username' }
173
+ });
174
+ ```
175
+
176
+ ## Control Lifecycle
177
+
178
+ ### 1. Construction
179
+
180
+ ```javascript
181
+ constructor(spec = {}) {
182
+ // Set type name for debugging
183
+ spec.__type_name = spec.__type_name || 'control_name';
184
+
185
+ // Call parent constructor
186
+ super(spec);
187
+
188
+ // Extract context (always available)
189
+ const { context } = this;
190
+
191
+ // Initialize control properties
192
+ // Compose UI (if not attached to existing DOM)
193
+ }
194
+ ```
195
+
196
+ ### 2. Composition
197
+
198
+ ```javascript
199
+ const compose = () => {
200
+ // Create child controls
201
+ const child = new controls.SomeControl({ context });
202
+
203
+ // Configure child properties
204
+ child.text = 'Hello';
205
+
206
+ // Add to parent
207
+ this.body.add(child);
208
+ };
209
+
210
+ // Only compose if not attached to existing element
211
+ if (!spec.el) { compose(); }
212
+ ```
213
+
214
+ ### 3. Activation
215
+
216
+ ```javascript
217
+ activate() {
218
+ // Prevent double activation
219
+ if (!this.__active) {
220
+ // Call parent activation FIRST
221
+ super.activate();
222
+
223
+ // Extract context again (convention)
224
+ const { context } = this;
225
+
226
+ // Register event handlers
227
+ context.on('event-name', handler);
228
+
229
+ // Initialize data bindings
230
+ // Start timers or intervals
231
+ // Establish connections
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### 4. Deactivation/Cleanup
237
+
238
+ ```javascript
239
+ deactivate() {
240
+ // Remove event handlers
241
+ // Close connections
242
+ // Clear timers
243
+ // Release resources
244
+
245
+ super.deactivate();
246
+ }
247
+ ```
248
+
249
+ ## Data Binding
250
+
251
+ ### Data_Object and Fields
252
+
253
+ **Purpose:** Reactive data models that automatically update bound controls.
254
+
255
+ ```javascript
256
+ // Create data model
257
+ this.data = { model: new Data_Object({ context }) };
258
+
259
+ // Add reactive fields
260
+ field(this.data.model, 'name');
261
+ field(this.data.model, 'email');
262
+ field(this.data.model, 'age');
263
+
264
+ // Register with context for lifecycle management
265
+ context.register_control(this.data.model);
266
+
267
+ // Changes trigger UI updates automatically
268
+ this.data.model.name = 'John Doe';
269
+ ```
270
+
271
+ ### Control Data Binding
272
+
273
+ ```javascript
274
+ const input = new controls.Text_Input({
275
+ context,
276
+ label: { text: 'Name:' },
277
+ data: {
278
+ model: this.data.model,
279
+ field_name: 'name'
280
+ }
281
+ });
282
+
283
+ // Control automatically updates when model changes
284
+ // Model automatically updates when control changes
285
+ ```
286
+
287
+ ### Shared Data Models
288
+
289
+ ```javascript
290
+ // Multiple controls can share the same model
291
+ const model = new Data_Object({ context });
292
+ field(model, 'value');
293
+
294
+ const picker1 = new Date_Picker({
295
+ context,
296
+ data: { model: model }
297
+ });
298
+
299
+ const picker2 = new Date_Picker({
300
+ context,
301
+ data: { model: model }
302
+ });
303
+
304
+ // Both pickers stay synchronized
305
+ ```
306
+
307
+ ## Event Handling
308
+
309
+ ### Context Events
310
+
311
+ ```javascript
312
+ activate() {
313
+ if (!this.__active) {
314
+ super.activate();
315
+ const { context } = this;
316
+
317
+ // Browser events
318
+ context.on('window-resize', e_resize => {
319
+ // Handle window resize
320
+ this.resize_content();
321
+ });
322
+
323
+ // Custom application events
324
+ context.on('data-updated', data => {
325
+ // Handle data updates
326
+ this.refresh_display();
327
+ });
328
+ }
329
+ }
330
+ ```
331
+
332
+ ### Control Events
333
+
334
+ ```javascript
335
+ const button = new controls.Button({
336
+ context,
337
+ text: 'Save',
338
+ onclick: () => {
339
+ // Handle button click
340
+ this.save_data();
341
+ }
342
+ });
343
+ ```
344
+
345
+ ### Custom Events
346
+
347
+ ```javascript
348
+ // Emit custom events
349
+ this.raise('custom-event', { data: 'value' });
350
+
351
+ // Listen for custom events
352
+ context.on('custom-event', (data) => {
353
+ console.log('Received:', data);
354
+ });
355
+ ```
356
+
357
+ ## CSS and Styling
358
+
359
+ ### Static CSS Definition
360
+
361
+ ```javascript
362
+ MyControl.css = `
363
+ /* Global resets (common pattern) */
364
+ * {
365
+ margin: 0;
366
+ padding: 0;
367
+ }
368
+
369
+ /* Body styling */
370
+ body {
371
+ overflow-x: hidden;
372
+ overflow-y: hidden;
373
+ background-color: #E0E0E0;
374
+ }
375
+
376
+ /* Control-specific styles */
377
+ .my-control {
378
+ padding: 20px;
379
+ background: linear-gradient(45deg, #f0f0f0, #e0e0e0);
380
+ border-radius: 8px;
381
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
382
+ }
383
+
384
+ /* Responsive design */
385
+ @media (max-width: 768px) {
386
+ .my-control {
387
+ padding: 10px;
388
+ }
389
+ }
390
+ `;
391
+ ```
392
+
393
+ ### Dynamic Styling
394
+
395
+ ```javascript
396
+ // Add CSS classes
397
+ if (typeof this.body.add_class === 'function') {
398
+ this.body.add_class('my-control');
399
+ this.body.add_class('theme-dark');
400
+ }
401
+
402
+ // Remove classes
403
+ this.body.remove_class('theme-dark');
404
+
405
+ // Check for classes
406
+ if (this.body.has_class('active')) {
407
+ // Handle active state
408
+ }
409
+ ```
410
+
411
+ ### CSS Extraction and Bundling
412
+
413
+ CSS is automatically extracted from control classes and bundled by the server:
414
+
415
+ 1. Server scans all control classes for `.css` properties
416
+ 2. CSS is concatenated in dependency order
417
+ 3. Result is served as a single stylesheet
418
+ 4. Updates require server restart (no hot reload)
419
+
420
+ ## Control Composition Patterns
421
+
422
+ ### Container Pattern
423
+
424
+ ```javascript
425
+ class Dashboard extends Active_HTML_Document {
426
+ constructor(spec = {}) {
427
+ super(spec);
428
+ const { context } = this;
429
+
430
+ if (typeof this.body.add_class === 'function') {
431
+ this.body.add_class('dashboard');
432
+ }
433
+
434
+ const compose = () => {
435
+ // Header section
436
+ const header = new controls.Panel({
437
+ context,
438
+ css_class: 'dashboard-header'
439
+ });
440
+ header.add(new controls.Label({
441
+ context,
442
+ text: 'Dashboard'
443
+ }));
444
+
445
+ // Content grid
446
+ const grid = new controls.Grid({
447
+ context,
448
+ rows: 2,
449
+ cols: 3
450
+ });
451
+
452
+ // Add widgets to grid
453
+ grid.add(new StatsWidget({ context }), 0, 0);
454
+ grid.add(new ChartWidget({ context }), 0, 1);
455
+ grid.add(new ListWidget({ context }), 1, 0);
456
+
457
+ this.body.add(header);
458
+ this.body.add(grid);
459
+ };
460
+
461
+ if (!spec.el) { compose(); }
462
+ }
463
+ }
464
+ ```
465
+
466
+ ### Mixin Pattern
467
+
468
+ ```javascript
469
+ // Using mixins for reusable functionality
470
+ const { dragable } = mixins;
471
+
472
+ class DraggablePanel extends Control {
473
+ constructor(spec = {}) {
474
+ super(spec);
475
+
476
+ // Apply draggable mixin
477
+ dragable(this, {
478
+ handle: '.drag-handle'
479
+ });
480
+ }
481
+ }
482
+ ```
483
+
484
+ ### Factory Pattern
485
+
486
+ ```javascript
487
+ class ControlFactory {
488
+ static createButton(context, config) {
489
+ return new controls.Button({
490
+ context,
491
+ text: config.text || 'Button',
492
+ onclick: config.onClick,
493
+ css_class: config.className
494
+ });
495
+ }
496
+
497
+ static createInput(context, config) {
498
+ return new controls.Text_Input({
499
+ context,
500
+ placeholder: config.placeholder,
501
+ data: config.data,
502
+ validator: config.validator
503
+ });
504
+ }
505
+ }
506
+
507
+ // Usage
508
+ const saveButton = ControlFactory.createButton(context, {
509
+ text: 'Save',
510
+ onClick: () => this.save()
511
+ });
512
+ ```
513
+
514
+ ## Error Handling and Validation
515
+
516
+ ### Input Validation
517
+
518
+ ```javascript
519
+ class ValidatedInput extends Control {
520
+ constructor(spec = {}) {
521
+ super(spec);
522
+ this.validator = spec.validator;
523
+ }
524
+
525
+ set_value(value) {
526
+ if (this.validator && !this.validator(value)) {
527
+ this.show_error('Invalid input');
528
+ return false;
529
+ }
530
+
531
+ this.clear_error();
532
+ super.set_value(value);
533
+ return true;
534
+ }
535
+
536
+ show_error(message) {
537
+ this.add_class('error');
538
+ // Show error message
539
+ }
540
+
541
+ clear_error() {
542
+ this.remove_class('error');
543
+ // Hide error message
544
+ }
545
+ }
546
+ ```
547
+
548
+ ### Exception Handling
549
+
550
+ ```javascript
551
+ activate() {
552
+ if (!this.__active) {
553
+ try {
554
+ super.activate();
555
+ const { context } = this;
556
+
557
+ // Risky initialization
558
+ this.initialize_complex_feature();
559
+
560
+ } catch (error) {
561
+ console.error('Failed to activate control:', error);
562
+ // Fallback behavior
563
+ this.enter_safe_mode();
564
+ }
565
+ }
566
+ }
567
+ ```
568
+
569
+ ## Performance Optimization
570
+
571
+ ### Lazy Loading
572
+
573
+ ```javascript
574
+ class LazyControl extends Control {
575
+ constructor(spec = {}) {
576
+ super(spec);
577
+ this._loaded = false;
578
+ }
579
+
580
+ ensure_loaded(callback) {
581
+ if (this._loaded) {
582
+ return callback();
583
+ }
584
+
585
+ // Load heavy resources
586
+ this.load_resources((err) => {
587
+ if (err) return callback(err);
588
+ this._loaded = true;
589
+ callback();
590
+ });
591
+ }
592
+
593
+ activate() {
594
+ if (!this.__active) {
595
+ super.activate();
596
+
597
+ // Lazy load when first activated
598
+ this.ensure_loaded(() => {
599
+ this.initialize_heavy_components();
600
+ });
601
+ }
602
+ }
603
+ }
604
+ ```
605
+
606
+ ### Memory Management
607
+
608
+ ```javascript
609
+ class MemoryManagedControl extends Control {
610
+ constructor(spec = {}) {
611
+ super(spec);
612
+ this._intervals = [];
613
+ this._timeouts = [];
614
+ this._event_handlers = [];
615
+ }
616
+
617
+ set_interval(callback, delay) {
618
+ const id = setInterval(callback, delay);
619
+ this._intervals.push(id);
620
+ return id;
621
+ }
622
+
623
+ set_timeout(callback, delay) {
624
+ const id = setTimeout(callback, delay);
625
+ this._timeouts.push(id);
626
+ return id;
627
+ }
628
+
629
+ add_event_handler(handler_id) {
630
+ this._event_handlers.push(handler_id);
631
+ }
632
+
633
+ deactivate() {
634
+ // Clean up all timers
635
+ this._intervals.forEach(clearInterval);
636
+ this._timeouts.forEach(clearTimeout);
637
+
638
+ // Remove event handlers
639
+ this._event_handlers.forEach(id => {
640
+ // Remove handler logic
641
+ });
642
+
643
+ super.deactivate();
644
+ }
645
+ }
646
+ ```
647
+
648
+ ## Testing Controls
649
+
650
+ ### Unit Testing
651
+
652
+ ```javascript
653
+ const jsgui = require('jsgui3-client');
654
+
655
+ describe('MyControl', () => {
656
+ let control;
657
+ let mock_context;
658
+
659
+ beforeEach(() => {
660
+ mock_context = {
661
+ on: jest.fn(),
662
+ register_control: jest.fn()
663
+ };
664
+
665
+ control = new MyControl({
666
+ context: mock_context
667
+ });
668
+ });
669
+
670
+ it('should initialize correctly', () => {
671
+ expect(control.__type_name).toBe('my_control');
672
+ expect(mock_context.register_control).toHaveBeenCalled();
673
+ });
674
+
675
+ it('should activate properly', () => {
676
+ control.activate();
677
+ expect(control.__active).toBe(true);
678
+ expect(mock_context.on).toHaveBeenCalledWith('window-resize', expect.any(Function));
679
+ });
680
+ });
681
+ ```
682
+
683
+ ### Integration Testing
684
+
685
+ ```javascript
686
+ describe('Control Integration', () => {
687
+ it('should render in browser', async () => {
688
+ const server = await Server.serve({
689
+ ctrl: MyControl,
690
+ port: 0 // Random port
691
+ });
692
+
693
+ // Use puppeteer or similar to test rendering
694
+ const browser = await puppeteer.launch();
695
+ const page = await browser.newPage();
696
+ await page.goto(`http://localhost:${server.port}`);
697
+
698
+ // Test control appears and functions
699
+ const controlExists = await page.$('.my-control');
700
+ expect(controlExists).toBeTruthy();
701
+
702
+ await browser.close();
703
+ await server.close();
704
+ });
705
+ });
706
+ ```
707
+
708
+ ## Best Practices
709
+
710
+ ### Code Organization
711
+ - Use PascalCase for control class names
712
+ - Use snake_case for properties and methods
713
+ - Group related functionality together
714
+ - Document complex logic with comments
715
+
716
+ ### Performance
717
+ - Minimize DOM manipulations
718
+ - Use efficient data structures
719
+ - Implement lazy loading for heavy components
720
+ - Clean up resources properly
721
+
722
+ ### Maintainability
723
+ - Follow established patterns
724
+ - Write comprehensive tests
725
+ - Document configuration options
726
+ - Use meaningful names
727
+
728
+ ### User Experience
729
+ - Provide visual feedback for interactions
730
+ - Handle error states gracefully
731
+ - Support keyboard navigation
732
+ - Ensure responsive design
733
+
734
+ ## Common Patterns and Anti-Patterns
735
+
736
+ ### ✅ Good Patterns
737
+
738
+ **Consistent Constructor Pattern:**
739
+ ```javascript
740
+ constructor(spec = {}) {
741
+ spec.__type_name = spec.__type_name || 'control_name';
742
+ super(spec);
743
+ const { context } = this;
744
+ // ... rest of initialization
745
+ }
746
+ ```
747
+
748
+ **Defensive Programming:**
749
+ ```javascript
750
+ if (typeof this.body.add_class === 'function') {
751
+ this.body.add_class('control-class');
752
+ }
753
+ ```
754
+
755
+ **Proper Activation:**
756
+ ```javascript
757
+ activate() {
758
+ if (!this.__active) {
759
+ super.activate(); // Always call first
760
+ const { context } = this;
761
+ // ... activation logic
762
+ }
763
+ }
764
+ ```
765
+
766
+ ### ❌ Anti-Patterns
767
+
768
+ **Direct DOM Manipulation (avoid when possible):**
769
+ ```javascript
770
+ // Bad - bypasses framework
771
+ this.dom_element.style.color = 'red';
772
+
773
+ // Good - uses framework methods
774
+ this.add_class('error');
775
+ ```
776
+
777
+ **Tight Coupling:**
778
+ ```javascript
779
+ // Bad - assumes specific parent structure
780
+ this.parent.parent.update();
781
+
782
+ // Good - uses events or callbacks
783
+ this.raise('child-updated', { data: this.value });
784
+ ```
785
+
786
+ **Memory Leaks:**
787
+ ```javascript
788
+ // Bad - no cleanup
789
+ setInterval(() => { /* ... */ }, 1000);
790
+
791
+ // Good - tracked and cleaned up
792
+ this.set_interval(() => { /* ... */ }, 1000);
793
+ ```
794
+
795
+ ## Migration and Compatibility
796
+
797
+ ### Upgrading Controls
798
+
799
+ When modifying existing controls:
800
+
801
+ 1. **Maintain API Compatibility:** Don't break existing usage
802
+ 2. **Add Deprecation Warnings:** For changed APIs
803
+ 3. **Provide Migration Guide:** Document upgrade steps
804
+ 4. **Test Thoroughly:** Ensure no regressions
805
+
806
+ ### Framework Updates
807
+
808
+ When JSGUI3 updates:
809
+
810
+ 1. **Check Breaking Changes:** Review changelog
811
+ 2. **Update Dependencies:** Keep jsgui3-client current
812
+ 3. **Test Integration:** Verify control still works
813
+ 4. **Update Patterns:** Adopt new best practices
814
+
815
+ ## Troubleshooting
816
+
817
+ ### Common Issues
818
+
819
+ **Control Not Rendering:**
820
+ - Check if `compose()` is called conditionally
821
+ - Verify CSS is properly defined
822
+ - Ensure control is added to a parent
823
+
824
+ **Events Not Firing:**
825
+ - Confirm activation is called
826
+ - Check event handler registration
827
+ - Verify context is available
828
+
829
+ **Data Binding Issues:**
830
+ - Ensure model is registered with context
831
+ - Check field names match
832
+ - Verify model changes trigger updates
833
+
834
+ **Performance Problems:**
835
+ - Check for unnecessary re-renders
836
+ - Profile event handler execution
837
+ - Monitor memory usage
838
+
839
+ ### Debug Mode
840
+
841
+ Enable debug logging:
842
+ ```javascript
843
+ const control = new MyControl({
844
+ context,
845
+ debug: true
846
+ });
847
+ ```
848
+
849
+ ### Development Tools
850
+
851
+ Use browser developer tools to:
852
+ - Inspect generated HTML/CSS
853
+ - Monitor JavaScript execution
854
+ - Check network requests
855
+ - Profile performance
856
+
857
+ ---
858
+
859
+ This guide provides the foundation for developing controls in JSGUI3. For specific control implementations, refer to the examples in the `examples/` directory and the base classes in `controls/`.