@zolomedia/bifrost-client 1.7.74

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 (140) hide show
  1. package/L1_Foundation/L1_Foundation.js +13 -0
  2. package/L1_Foundation/bootstrap/bootstrap.js +11 -0
  3. package/L1_Foundation/bootstrap/bootstrap_hooks.js +123 -0
  4. package/L1_Foundation/bootstrap/bootstrap_index.js +15 -0
  5. package/L1_Foundation/bootstrap/bootstrap_logger.js +135 -0
  6. package/L1_Foundation/bootstrap/cdn_loader.js +217 -0
  7. package/L1_Foundation/bootstrap/module_registry.js +102 -0
  8. package/L1_Foundation/bootstrap/prism_loader.js +164 -0
  9. package/L1_Foundation/config/client_config.js +110 -0
  10. package/L1_Foundation/config/config.js +7 -0
  11. package/L1_Foundation/connection/connection.js +8 -0
  12. package/L1_Foundation/connection/websocket_connection.js +122 -0
  13. package/L1_Foundation/constants/bifrost_constants.js +284 -0
  14. package/L1_Foundation/constants/constants.js +7 -0
  15. package/L1_Foundation/logger/logger.js +10 -0
  16. package/L2_Handling/L2_Handling.js +15 -0
  17. package/L2_Handling/cache/cache.js +22 -0
  18. package/L2_Handling/cache/cache_constants.js +69 -0
  19. package/L2_Handling/cache/orchestration/cache_manager.js +299 -0
  20. package/L2_Handling/cache/orchestration/cache_orchestrator.js +260 -0
  21. package/L2_Handling/cache/orchestration/orchestration.js +12 -0
  22. package/L2_Handling/cache/storage/session_manager.js +289 -0
  23. package/L2_Handling/cache/storage/storage.js +10 -0
  24. package/L2_Handling/cache/storage/storage_manager.js +590 -0
  25. package/L2_Handling/display/composite/composite.js +13 -0
  26. package/L2_Handling/display/composite/dashboard_renderer.js +221 -0
  27. package/L2_Handling/display/composite/swiper_renderer.js +564 -0
  28. package/L2_Handling/display/composite/terminal_renderer.js +922 -0
  29. package/L2_Handling/display/composite/wizard_conditional_renderer.js +274 -0
  30. package/L2_Handling/display/display.js +30 -0
  31. package/L2_Handling/display/feedback/feedback.js +11 -0
  32. package/L2_Handling/display/feedback/progressbar_renderer.js +418 -0
  33. package/L2_Handling/display/feedback/spinner_renderer.js +246 -0
  34. package/L2_Handling/display/inputs/button_renderer.js +634 -0
  35. package/L2_Handling/display/inputs/form_renderer.js +583 -0
  36. package/L2_Handling/display/inputs/input_renderer.js +658 -0
  37. package/L2_Handling/display/inputs/inputs.js +12 -0
  38. package/L2_Handling/display/navigation/menu_renderer.js +206 -0
  39. package/L2_Handling/display/navigation/navigation.js +11 -0
  40. package/L2_Handling/display/navigation/navigation_renderer.js +703 -0
  41. package/L2_Handling/display/orchestration/orchestration.js +11 -0
  42. package/L2_Handling/display/orchestration/renderer.js +430 -0
  43. package/L2_Handling/display/orchestration/zdisplay_orchestrator.js +1759 -0
  44. package/L2_Handling/display/outputs/alert_renderer.js +161 -0
  45. package/L2_Handling/display/outputs/audio_renderer.js +94 -0
  46. package/L2_Handling/display/outputs/card_renderer.js +229 -0
  47. package/L2_Handling/display/outputs/code_renderer.js +66 -0
  48. package/L2_Handling/display/outputs/dl_renderer.js +131 -0
  49. package/L2_Handling/display/outputs/header_renderer.js +162 -0
  50. package/L2_Handling/display/outputs/icon_renderer.js +107 -0
  51. package/L2_Handling/display/outputs/image_renderer.js +145 -0
  52. package/L2_Handling/display/outputs/list_renderer.js +190 -0
  53. package/L2_Handling/display/outputs/outputs.js +19 -0
  54. package/L2_Handling/display/outputs/table_renderer.js +765 -0
  55. package/L2_Handling/display/outputs/text_renderer.js +818 -0
  56. package/L2_Handling/display/outputs/typography_renderer.js +293 -0
  57. package/L2_Handling/display/outputs/video_renderer.js +116 -0
  58. package/L2_Handling/display/primitives/document_structure_primitives.js +319 -0
  59. package/L2_Handling/display/primitives/form_primitives.js +526 -0
  60. package/L2_Handling/display/primitives/generic_containers.js +109 -0
  61. package/L2_Handling/display/primitives/interactive_primitives.js +305 -0
  62. package/L2_Handling/display/primitives/link_primitives.js +552 -0
  63. package/L2_Handling/display/primitives/lists_primitives.js +262 -0
  64. package/L2_Handling/display/primitives/media_primitives.js +383 -0
  65. package/L2_Handling/display/primitives/primitives.js +19 -0
  66. package/L2_Handling/display/primitives/semantic_element_primitive.js +226 -0
  67. package/L2_Handling/display/primitives/table_primitives.js +528 -0
  68. package/L2_Handling/display/primitives/typography_primitives.js +175 -0
  69. package/L2_Handling/display/specialized/input_request_renderer.js +467 -0
  70. package/L2_Handling/display/specialized/specialized.js +10 -0
  71. package/L2_Handling/hooks/hooks.js +9 -0
  72. package/L2_Handling/hooks/menu_integration.js +57 -0
  73. package/L2_Handling/hooks/widget_hook_manager.js +292 -0
  74. package/L2_Handling/message/message.js +8 -0
  75. package/L2_Handling/message/message_handler.js +701 -0
  76. package/L2_Handling/navigation/navigation.js +8 -0
  77. package/L2_Handling/navigation/navigation_manager.js +403 -0
  78. package/L2_Handling/zhooks/features/cache_live.js +287 -0
  79. package/L2_Handling/zhooks/features/crumbs_live.js +292 -0
  80. package/L2_Handling/zhooks/zhooks_manager.js +65 -0
  81. package/L2_Handling/zvaf/zvaf.js +8 -0
  82. package/L2_Handling/zvaf/zvaf_manager.js +334 -0
  83. package/L3_Abstraction/L3_Abstraction.js +12 -0
  84. package/L3_Abstraction/orchestrator/container_unwrapper.js +101 -0
  85. package/L3_Abstraction/orchestrator/group_renderer.js +698 -0
  86. package/L3_Abstraction/orchestrator/input_event_handler.js +797 -0
  87. package/L3_Abstraction/orchestrator/metadata_processor.js +249 -0
  88. package/L3_Abstraction/orchestrator/navbar_builder.js +201 -0
  89. package/L3_Abstraction/orchestrator/orchestrator.js +13 -0
  90. package/L3_Abstraction/orchestrator/wizard_gate_handler.js +360 -0
  91. package/L3_Abstraction/renderer/renderer.js +1 -0
  92. package/L3_Abstraction/session/session.js +1 -0
  93. package/L4_Orchestration/L4_Orchestration.js +11 -0
  94. package/L4_Orchestration/client/client.js +1 -0
  95. package/L4_Orchestration/facade/facade.js +9 -0
  96. package/L4_Orchestration/facade/manager_registry.js +118 -0
  97. package/L4_Orchestration/facade/renderer_registry.js +274 -0
  98. package/L4_Orchestration/lifecycle/asset_loader.js +255 -0
  99. package/L4_Orchestration/lifecycle/initializer.js +135 -0
  100. package/L4_Orchestration/lifecycle/lifecycle.js +8 -0
  101. package/L4_Orchestration/rendering/facade.js +94 -0
  102. package/L4_Orchestration/rendering/rendering.js +7 -0
  103. package/LICENSE +21 -0
  104. package/README.md +82 -0
  105. package/bifrost_client.js +204 -0
  106. package/bifrost_core.js +1686 -0
  107. package/docs/ARCHITECTURE.md +111 -0
  108. package/docs/PROTOCOL.md +106 -0
  109. package/docs/RENDERERS.md +101 -0
  110. package/docs/SECURITY.md +92 -0
  111. package/package.json +24 -0
  112. package/syntax/prism-zconfig.js +41 -0
  113. package/syntax/prism-zenv.js +69 -0
  114. package/syntax/prism-zolo-theme.css +288 -0
  115. package/syntax/prism-zolo.js +380 -0
  116. package/syntax/prism-zschema.js +38 -0
  117. package/syntax/prism-zspark.js +25 -0
  118. package/syntax/prism-zui.js +68 -0
  119. package/zSys/accessibility/accessibility.js +10 -0
  120. package/zSys/accessibility/emoji_accessibility.js +173 -0
  121. package/zSys/dom/block_utils.js +122 -0
  122. package/zSys/dom/container_utils.js +370 -0
  123. package/zSys/dom/dom.js +13 -0
  124. package/zSys/dom/dom_utils.js +328 -0
  125. package/zSys/dom/encoding_utils.js +117 -0
  126. package/zSys/dom/style_utils.js +71 -0
  127. package/zSys/errors/error_display.js +299 -0
  128. package/zSys/errors/errors.js +10 -0
  129. package/zSys/theme/color_utils.js +274 -0
  130. package/zSys/theme/dark_mode_utils.js +272 -0
  131. package/zSys/theme/size_utils.js +256 -0
  132. package/zSys/theme/spacing_utils.js +405 -0
  133. package/zSys/theme/theme.js +14 -0
  134. package/zSys/theme/zbase.css +1735 -0
  135. package/zSys/theme/zbase_inject.js +161 -0
  136. package/zSys/theme/ztheme_utils.js +305 -0
  137. package/zSys/validation/error_boundary.js +201 -0
  138. package/zSys/validation/validation.js +11 -0
  139. package/zSys/validation/validation_utils.js +238 -0
  140. package/zSys/zSys.js +14 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * MenuRenderer - Handles menu rendering and interaction in Bifrost mode
3
+ *
4
+ * This module provides:
5
+ * - Menu HTML rendering with zTheme classes
6
+ * - Click event handlers for menu options
7
+ * - Keyboard navigation support
8
+ * - WebSocket communication for menu selection
9
+ *
10
+ * Integrates with:
11
+ * - zDisplay (via zdisplay_orchestrator.js)
12
+ * - BifrostClient (for WebSocket messaging)
13
+ * - zTheme (for consistent styling)
14
+ */
15
+
16
+ export class MenuRenderer {
17
+ constructor(logger, client) {
18
+ this.client = client;
19
+ this.logger = logger;
20
+ }
21
+
22
+ /**
23
+ * Render menu from backend menu event (full-page menu)
24
+ * @param {Object} message - Menu event data from backend
25
+ */
26
+ renderMenu(message) {
27
+ this.logger.log('[MenuRenderer] Rendering menu', message);
28
+
29
+ const { menu_key, options, title, breadcrumbs, requestId } = message;
30
+
31
+ // Store requestId so selection handler can echo it back to backend
32
+ this._currentRequestId = requestId || null;
33
+ // Normalise menu key — backend may send title+options without menu_key
34
+ const resolvedMenuKey = menu_key || title || 'Menu';
35
+
36
+ const contentElement = this.client._zVaFElement;
37
+ if (!contentElement) {
38
+ this.logger.error('[MenuRenderer] [ERROR] zVaF element not found');
39
+ return;
40
+ }
41
+
42
+ contentElement.innerHTML = '';
43
+
44
+ if (breadcrumbs && Object.keys(breadcrumbs).length > 0) {
45
+ this._renderBreadcrumbs(breadcrumbs, contentElement);
46
+ }
47
+
48
+ const menuHtml = this._createMenuHTML(resolvedMenuKey, options, title || null);
49
+ contentElement.innerHTML += menuHtml;
50
+
51
+ this._attachMenuHandlers(resolvedMenuKey, options);
52
+ this.logger.log('[MenuRenderer] Menu rendered successfully');
53
+ }
54
+
55
+ /**
56
+ * Render menu inline (within a specific container, e.g., dashboard panel)
57
+ * @param {Object} menuData - Menu data { menu_key, options, title, allow_back }
58
+ * @param {HTMLElement} container - Container element to render menu into
59
+ */
60
+ renderMenuInline(menuData, container) {
61
+ this.logger.log('[MenuRenderer] Rendering inline menu', menuData);
62
+
63
+ const { menu_key, options, title, _allow_back, requestId } = menuData;
64
+
65
+ // Store requestId for selection echo
66
+ this._currentRequestId = requestId || null;
67
+
68
+ // Create menu HTML
69
+ const menuHtml = this._createMenuHTML(menu_key || 'Menu', options, title);
70
+
71
+ // Insert into container
72
+ const tempDiv = document.createElement('div');
73
+ tempDiv.innerHTML = menuHtml;
74
+ const menuElement = tempDiv.firstElementChild;
75
+
76
+ if (menuElement && container) {
77
+ container.appendChild(menuElement);
78
+
79
+ // Attach event handlers
80
+ this._attachMenuHandlers(menu_key || 'Menu', options, menuElement);
81
+
82
+ this.logger.log('[MenuRenderer] Inline menu rendered successfully');
83
+ } else {
84
+ this.logger.error('[MenuRenderer] [ERROR] Failed to render inline menu');
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Create menu HTML with zTheme classes
90
+ * @private
91
+ */
92
+ _createMenuHTML(menuKey, options, customTitle = null) {
93
+ const menuTitle = customTitle || menuKey.replace(/[*~]/g, '').trim() || 'Menu';
94
+
95
+ return `
96
+ <div class="zMenu-container zCard zp-4 zmy-4" data-menu="${this._escapeHtml(menuKey)}">
97
+ <h2 class="zCard-title zmb-4">${this._escapeHtml(menuTitle)}</h2>
98
+ <div class="zMenu-options">
99
+ ${options.map((opt, idx) => this._createOptionHTML(opt, idx)).join('')}
100
+ </div>
101
+ </div>
102
+ `;
103
+ }
104
+
105
+ /**
106
+ * Create HTML for a single menu option
107
+ * @private
108
+ */
109
+ _createOptionHTML(option, index) {
110
+ const label = option.label || option.key || option;
111
+ const key = option.key || option;
112
+
113
+ return `
114
+ <div class="zMenu-option zmb-2" data-key="${this._escapeHtml(key)}">
115
+ <button class="zBtn zBtn-outline-primary w-100 text-start zp-3" data-index="${index}">
116
+ <span class="zBadge zBadge-secondary me-2">${index + 1}</span>
117
+ ${this._escapeHtml(label.replace(/[*~^$]/g, ''))}
118
+ </button>
119
+ </div>
120
+ `;
121
+ }
122
+
123
+ /**
124
+ * Render breadcrumbs
125
+ * @private
126
+ */
127
+ _renderBreadcrumbs(breadcrumbs, container) {
128
+ const breadcrumbsHtml = `
129
+ <nav aria-label="breadcrumb" class="zmb-3">
130
+ <ol class="breadcrumb">
131
+ ${Object.entries(breadcrumbs).map(([_scope, trail]) => `
132
+ <li class="breadcrumb-item active">${this._escapeHtml(trail)}</li>
133
+ `).join('')}
134
+ </ol>
135
+ </nav>
136
+ `;
137
+ container.innerHTML = breadcrumbsHtml;
138
+ }
139
+
140
+ /**
141
+ * Attach click and keyboard handlers to menu options
142
+ * @private
143
+ */
144
+ _attachMenuHandlers(menuKey, options, containerElement = null) {
145
+ // If container is provided, scope query to it; otherwise use document
146
+ const root = containerElement || document;
147
+ const optionButtons = root.querySelectorAll('.zMenu-option button');
148
+
149
+ optionButtons.forEach((button, _idx) => {
150
+ button.addEventListener('click', () => {
151
+ const optionDiv = button.closest('.zMenu-option');
152
+ const selectedKey = optionDiv.dataset.key;
153
+
154
+ this.logger.log('[MenuRenderer] Menu selection:', selectedKey);
155
+ this.logger.log('[MenuRenderer] Menu selection', { menu: menuKey, selected: selectedKey });
156
+
157
+ // Visual feedback
158
+ button.classList.add('active');
159
+ button.disabled = true;
160
+
161
+ // Send selection to backend
162
+ this._sendMenuSelection(menuKey, selectedKey);
163
+ });
164
+ });
165
+
166
+ // Keyboard navigation (0-9 for options)
167
+ const keydownHandler = (e) => {
168
+ const num = parseInt(e.key);
169
+ if (!isNaN(num) && num < optionButtons.length) {
170
+ optionButtons[num].click();
171
+ // Remove handler after selection
172
+ document.removeEventListener('keydown', keydownHandler);
173
+ }
174
+ };
175
+
176
+ document.addEventListener('keydown', keydownHandler);
177
+ this.logger.log('[MenuRenderer] Keyboard navigation enabled (0-9)');
178
+ }
179
+
180
+ /**
181
+ * Send menu selection to backend via WebSocket
182
+ * @private
183
+ */
184
+ _sendMenuSelection(menuKey, selected) {
185
+ const message = {
186
+ event: 'menu_selection',
187
+ menu_key: menuKey,
188
+ selected: selected,
189
+ requestId: this._currentRequestId || undefined,
190
+ };
191
+
192
+ this.logger.log('[MenuRenderer] Sending menu selection to backend:', message);
193
+ this.client.send(message);
194
+ }
195
+
196
+ /**
197
+ * Escape HTML to prevent XSS
198
+ * @private
199
+ */
200
+ _escapeHtml(text) {
201
+ const div = document.createElement('div');
202
+ div.textContent = text;
203
+ return div.innerHTML;
204
+ }
205
+ }
206
+
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Navigation Rendering Module Barrel Export
3
+ *
4
+ * Navigation components (menus, breadcrumbs, navigation bars).
5
+ *
6
+ * @module rendering/navigation
7
+ * @layer 3 (Navigation Rendering)
8
+ */
9
+
10
+ export * from './menu_renderer.js';
11
+ export * from './navigation_renderer.js';