@vib3code/sdk 2.0.1 → 2.0.3-canary.0a63e71

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 (192) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +245 -0
  3. package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
  4. package/DOCS/ARCHITECTURE.md +1 -0
  5. package/DOCS/CI_TESTING.md +2 -0
  6. package/DOCS/CLI_ONBOARDING.md +3 -1
  7. package/DOCS/CONTROL_REFERENCE.md +2 -0
  8. package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +119 -0
  9. package/DOCS/ENV_SETUP.md +2 -0
  10. package/DOCS/EPIC_SCROLL_EVENTS.md +775 -0
  11. package/DOCS/EXPANSION_DESIGN.md +979 -0
  12. package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
  13. package/DOCS/EXPORT_FORMATS.md +2 -0
  14. package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
  15. package/DOCS/HANDOFF_LANDING_PAGE.md +156 -0
  16. package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +495 -0
  17. package/DOCS/LICENSING_TIERS.md +2 -0
  18. package/DOCS/MASTER_PLAN_2026-01-31.md +4 -2
  19. package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +939 -0
  20. package/DOCS/OBS_SETUP_GUIDE.md +2 -0
  21. package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
  22. package/DOCS/PRODUCT_STRATEGY.md +65 -0
  23. package/DOCS/PROJECT_SETUP.md +2 -0
  24. package/DOCS/README.md +105 -0
  25. package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +99 -0
  26. package/DOCS/RENDERER_LIFECYCLE.md +2 -0
  27. package/DOCS/REPO_MANIFEST.md +2 -0
  28. package/DOCS/ROADMAP.md +113 -0
  29. package/DOCS/SCROLL_TIMELINE_v3.md +271 -0
  30. package/DOCS/SITE_REFACTOR_PLAN.md +102 -0
  31. package/DOCS/STATUS.md +26 -0
  32. package/DOCS/SYSTEM_INVENTORY.md +37 -32
  33. package/DOCS/TELEMETRY_EXPORTS.md +2 -0
  34. package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +87 -0
  35. package/DOCS/VISUAL_ANALYSIS_FACETAD.md +135 -0
  36. package/DOCS/VISUAL_ANALYSIS_SIMONE.md +97 -0
  37. package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +88 -0
  38. package/DOCS/WEBGPU_STATUS.md +121 -38
  39. package/DOCS/XR_BENCHMARKS.md +2 -0
  40. package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -0
  41. package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -0
  42. package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -0
  43. package/DOCS/archive/SESSION_014_PLAN.md +1 -0
  44. package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -0
  45. package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -0
  46. package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -0
  47. package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -0
  48. package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +3 -1
  49. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +233 -0
  50. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +129 -0
  51. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -0
  52. package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
  53. package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
  54. package/DOCS/dev-tracks/README.md +12 -0
  55. package/README.md +26 -13
  56. package/cpp/CMakeLists.txt +236 -0
  57. package/cpp/bindings/embind.cpp +269 -0
  58. package/cpp/build.sh +129 -0
  59. package/cpp/geometry/Crystal.cpp +103 -0
  60. package/cpp/geometry/Fractal.cpp +136 -0
  61. package/cpp/geometry/GeometryGenerator.cpp +262 -0
  62. package/cpp/geometry/KleinBottle.cpp +71 -0
  63. package/cpp/geometry/Sphere.cpp +134 -0
  64. package/cpp/geometry/Tesseract.cpp +94 -0
  65. package/cpp/geometry/Tetrahedron.cpp +83 -0
  66. package/cpp/geometry/Torus.cpp +65 -0
  67. package/cpp/geometry/WarpFunctions.cpp +238 -0
  68. package/cpp/geometry/Wave.cpp +85 -0
  69. package/cpp/include/vib3_ffi.h +238 -0
  70. package/cpp/math/Mat4x4.cpp +409 -0
  71. package/cpp/math/Mat4x4.hpp +209 -0
  72. package/cpp/math/Projection.cpp +142 -0
  73. package/cpp/math/Projection.hpp +148 -0
  74. package/cpp/math/Rotor4D.cpp +322 -0
  75. package/cpp/math/Rotor4D.hpp +204 -0
  76. package/cpp/math/Vec4.cpp +303 -0
  77. package/cpp/math/Vec4.hpp +225 -0
  78. package/cpp/src/vib3_ffi.cpp +607 -0
  79. package/cpp/tests/Geometry_test.cpp +213 -0
  80. package/cpp/tests/Mat4x4_test.cpp +494 -0
  81. package/cpp/tests/Projection_test.cpp +298 -0
  82. package/cpp/tests/Rotor4D_test.cpp +423 -0
  83. package/cpp/tests/Vec4_test.cpp +489 -0
  84. package/docs/webgpu-live.html +1 -1
  85. package/package.json +41 -30
  86. package/src/agent/index.js +1 -3
  87. package/src/agent/mcp/MCPServer.js +1220 -144
  88. package/src/agent/mcp/index.js +1 -1
  89. package/src/agent/mcp/stdio-server.js +264 -0
  90. package/src/agent/mcp/tools.js +498 -31
  91. package/src/cli/index.js +431 -47
  92. package/src/core/CanvasManager.js +97 -204
  93. package/src/core/ErrorReporter.js +1 -1
  94. package/src/core/Parameters.js +1 -1
  95. package/src/core/VIB3Engine.js +93 -4
  96. package/src/core/VitalitySystem.js +53 -0
  97. package/src/core/index.js +18 -0
  98. package/src/core/renderers/FacetedRendererAdapter.js +10 -9
  99. package/src/core/renderers/HolographicRendererAdapter.js +13 -9
  100. package/src/core/renderers/QuantumRendererAdapter.js +11 -7
  101. package/src/creative/AestheticMapper.js +628 -0
  102. package/src/creative/ChoreographyPlayer.js +481 -0
  103. package/src/creative/index.js +11 -0
  104. package/src/experimental/GameLoop.js +72 -0
  105. package/src/experimental/LatticePhysics.js +100 -0
  106. package/src/experimental/LiveDirector.js +143 -0
  107. package/src/experimental/PlayerController4D.js +154 -0
  108. package/src/experimental/VIB3Actor.js +138 -0
  109. package/src/experimental/VIB3Compositor.js +117 -0
  110. package/src/experimental/VIB3Link.js +122 -0
  111. package/src/experimental/VIB3Orchestrator.js +146 -0
  112. package/src/experimental/VIB3Universe.js +109 -0
  113. package/src/experimental/demos/CrystalLabyrinth.js +202 -0
  114. package/src/export/TradingCardManager.js +3 -4
  115. package/src/export/index.js +11 -1
  116. package/src/faceted/FacetedSystem.js +260 -394
  117. package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
  118. package/src/geometry/generators/Crystal.js +2 -2
  119. package/src/geometry/warp/HypersphereCore.js +53 -24
  120. package/src/holograms/HolographicVisualizer.js +84 -98
  121. package/src/holograms/RealHolographicSystem.js +194 -43
  122. package/src/math/Mat4x4.js +308 -105
  123. package/src/math/Rotor4D.js +124 -40
  124. package/src/math/Vec4.js +200 -103
  125. package/src/math/index.js +7 -7
  126. package/src/polychora/PolychoraSystem.js +77 -0
  127. package/src/quantum/QuantumEngine.js +103 -66
  128. package/src/quantum/QuantumVisualizer.js +31 -22
  129. package/src/reactivity/index.js +3 -5
  130. package/src/render/LayerPresetManager.js +372 -0
  131. package/src/render/LayerReactivityBridge.js +344 -0
  132. package/src/render/LayerRelationshipGraph.js +610 -0
  133. package/src/render/MultiCanvasBridge.js +148 -25
  134. package/src/render/ShaderLoader.js +38 -0
  135. package/src/render/ShaderProgram.js +4 -4
  136. package/src/render/UnifiedRenderBridge.js +4 -1
  137. package/src/render/backends/WebGPUBackend.js +8 -4
  138. package/src/render/index.js +27 -2
  139. package/src/scene/Node4D.js +74 -24
  140. package/src/scene/index.js +4 -4
  141. package/src/shaders/common/geometry24.glsl +65 -0
  142. package/src/shaders/common/geometry24.wgsl +54 -0
  143. package/src/shaders/common/rotation4d.glsl +4 -4
  144. package/src/shaders/common/rotation4d.wgsl +2 -2
  145. package/src/shaders/common/uniforms.wgsl +15 -8
  146. package/src/shaders/faceted/faceted.frag.glsl +220 -80
  147. package/src/shaders/faceted/faceted.frag.wgsl +144 -90
  148. package/src/shaders/holographic/holographic.frag.glsl +28 -9
  149. package/src/shaders/holographic/holographic.frag.wgsl +112 -41
  150. package/src/shaders/quantum/quantum.frag.glsl +1 -0
  151. package/src/shaders/quantum/quantum.frag.wgsl +6 -4
  152. package/src/testing/ParallelTestFramework.js +2 -2
  153. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
  154. package/src/viewer/GalleryUI.js +17 -0
  155. package/src/viewer/ViewerPortal.js +2 -2
  156. package/src/viewer/index.js +1 -1
  157. package/tools/headless-renderer.js +258 -0
  158. package/tools/shader-sync-verify.js +14 -8
  159. package/tools/site-analysis/all-reports.json +32 -0
  160. package/tools/site-analysis/combined-analysis.md +50 -0
  161. package/tools/site-analyzer.mjs +779 -0
  162. package/tools/visual-catalog/capture.js +276 -0
  163. package/tools/visual-catalog/composite.js +138 -0
  164. package/types/adaptive-sdk.d.ts +204 -5
  165. package/types/agent/cli.d.ts +78 -0
  166. package/types/agent/index.d.ts +18 -0
  167. package/types/agent/mcp.d.ts +87 -0
  168. package/types/agent/telemetry.d.ts +190 -0
  169. package/types/core/VIB3Engine.d.ts +26 -0
  170. package/types/core/index.d.ts +261 -0
  171. package/types/creative/AestheticMapper.d.ts +72 -0
  172. package/types/creative/ChoreographyPlayer.d.ts +96 -0
  173. package/types/creative/index.d.ts +17 -0
  174. package/types/export/index.d.ts +243 -0
  175. package/types/geometry/index.d.ts +164 -0
  176. package/types/math/index.d.ts +214 -0
  177. package/types/render/LayerPresetManager.d.ts +78 -0
  178. package/types/render/LayerReactivityBridge.d.ts +85 -0
  179. package/types/render/LayerRelationshipGraph.d.ts +174 -0
  180. package/types/render/index.d.ts +3 -0
  181. package/types/scene/index.d.ts +204 -0
  182. package/types/systems/index.d.ts +244 -0
  183. package/types/variations/index.d.ts +62 -0
  184. package/types/viewer/index.d.ts +225 -0
  185. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +0 -34
  186. package/DOCS/DEV_TRACK_ANALYSIS.md +0 -77
  187. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +0 -42
  188. package/DOCS/SESSION_014_PLAN.md +0 -195
  189. package/DOCS/SESSION_LOG_2026-01-07.md +0 -56
  190. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +0 -72
  191. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +0 -738
  192. /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
@@ -1,217 +1,110 @@
1
1
  /**
2
- * Dead Simple Canvas Manager - Just hide/show containers + fresh engines
3
- * No canvas destruction - HTML canvases stay put, just switch visibility
2
+ * CanvasManager - Creates and manages 5-layer canvas architecture per system.
3
+ *
4
+ * Provides the API surface expected by VIB3Engine:
5
+ * constructor(containerId)
6
+ * createSystemCanvases(systemName) -> string[]
7
+ * registerContext(canvasId, gl)
8
+ * destroy()
4
9
  */
5
10
 
6
11
  export class CanvasManager {
7
- constructor() {
8
- this.currentSystem = null;
9
- this.currentEngine = null;
10
- }
11
-
12
- async switchToSystem(systemName, engineClasses) {
13
- console.log(`🔄 DESTROY OLD → CREATE NEW: ${systemName}`);
14
-
15
- // STEP 1: DESTROY current engine completely
16
- if (this.currentEngine) {
17
- if (this.currentEngine.setActive) {
18
- this.currentEngine.setActive(false);
19
- }
20
- if (this.currentEngine.destroy) {
21
- this.currentEngine.destroy();
22
- }
23
- console.log('💥 Old engine destroyed');
24
- }
25
-
26
- // STEP 2: DESTROY old WebGL contexts
27
- this.destroyOldWebGLContexts();
28
-
29
- // STEP 3: DESTROY all canvases + CREATE 5 fresh ones
30
- this.destroyAllCanvasesAndCreateFresh(systemName);
31
-
32
- // STEP 4: CREATE fresh engine
33
- const engine = await this.createFreshEngine(systemName, engineClasses);
34
-
35
- // STEP 5: Start new engine
36
- if (engine && engine.setActive) {
37
- engine.setActive(true);
12
+ constructor(containerId = 'vib3-container') {
13
+ this.containerId = containerId;
14
+ this.container = (typeof document !== 'undefined')
15
+ ? document.getElementById(containerId)
16
+ : null;
17
+ this.currentSystem = null;
18
+ this.createdCanvases = [];
19
+ this.registeredContexts = new Map();
38
20
  }
39
-
40
- this.currentSystem = systemName;
41
- this.currentEngine = engine;
42
- console.log(`✅ DESTROY → CREATE complete: ${systemName} ready`);
43
- return engine;
44
- }
45
21
 
46
- destroyOldWebGLContexts() {
47
- console.log('💥 COMPLETE DESTRUCTION: WebGL contexts + old system cleanup...');
48
-
49
- // STEP 1: Kill all WebGL contexts first
50
- const allCanvases = document.querySelectorAll('canvas');
51
- let destroyedCount = 0;
52
-
53
- allCanvases.forEach(canvas => {
54
- // Get any existing WebGL context
55
- const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
56
- if (gl) {
57
- // Force context loss
58
- const loseContextExt = gl.getExtension('WEBGL_lose_context');
59
- if (loseContextExt) {
60
- loseContextExt.loseContext();
61
- destroyedCount++;
22
+ /**
23
+ * Create 5 canvases with system-appropriate IDs inside the container.
24
+ * Returns the array of canvas IDs created.
25
+ */
26
+ createSystemCanvases(systemName) {
27
+ // Tear down previous canvases
28
+ this._removeCreatedCanvases();
29
+
30
+ const canvasIds = this._getCanvasIdsForSystem(systemName);
31
+
32
+ if (this.container) {
33
+ const viewWidth = this.container.clientWidth || (typeof window !== 'undefined' ? window.innerWidth : 800);
34
+ const viewHeight = this.container.clientHeight || (typeof window !== 'undefined' ? window.innerHeight : 600);
35
+ const dpr = (typeof window !== 'undefined') ? Math.min(window.devicePixelRatio || 1, 2) : 1;
36
+
37
+ canvasIds.forEach((canvasId, index) => {
38
+ const canvas = document.createElement('canvas');
39
+ canvas.id = canvasId;
40
+ canvas.className = 'visualization-canvas';
41
+ canvas.style.position = 'absolute';
42
+ canvas.style.top = '0';
43
+ canvas.style.left = '0';
44
+ canvas.style.width = '100%';
45
+ canvas.style.height = '100%';
46
+ canvas.style.zIndex = String(index + 1);
47
+ canvas.width = viewWidth * dpr;
48
+ canvas.height = viewHeight * dpr;
49
+ this.container.appendChild(canvas);
50
+ this.createdCanvases.push(canvas);
51
+ });
62
52
  }
63
- }
64
- });
65
-
66
- // STEP 2: Clear all global engine references (old system cleanup)
67
- if (window.engine) {
68
- console.log('💥 Clearing window.engine');
69
- window.engine = null;
70
- }
71
- if (window.quantumEngine) {
72
- console.log('💥 Clearing window.quantumEngine');
73
- window.quantumEngine = null;
74
- }
75
- if (window.holographicSystem) {
76
- console.log('💥 Clearing window.holographicSystem');
77
- window.holographicSystem = null;
53
+
54
+ this.currentSystem = systemName;
55
+ return canvasIds;
78
56
  }
79
- if (window.polychoraSystem) {
80
- console.log('💥 Clearing window.polychoraSystem');
81
- window.polychoraSystem = null;
57
+
58
+ /**
59
+ * Track a WebGL context so we can force-lose it during cleanup.
60
+ */
61
+ registerContext(canvasId, gl) {
62
+ this.registeredContexts.set(canvasId, gl);
82
63
  }
83
-
84
- console.log(`💥 DESTRUCTION COMPLETE: ${destroyedCount} WebGL contexts destroyed, all engine refs cleared`);
85
- }
86
64
 
87
- destroyAllCanvasesAndCreateFresh(systemName) {
88
- console.log('💥 DESTROYING ALL CANVASES + CREATING 5 FRESH ONES');
89
-
90
- // STEP 1: DESTROY all existing canvases completely
91
- const allCanvases = document.querySelectorAll('canvas');
92
- allCanvases.forEach(canvas => canvas.remove());
93
- console.log(`💥 Destroyed ${allCanvases.length} old canvases`);
94
-
95
- // STEP 2: Clear all containers
96
- const containers = ['vib34dLayers', 'quantumLayers', 'holographicLayers', 'polychoraLayers'];
97
- containers.forEach(containerId => {
98
- const container = document.getElementById(containerId);
99
- if (container) {
100
- container.innerHTML = '';
101
- container.style.display = 'none';
102
- }
103
- });
104
-
105
- // STEP 3: CREATE 5 fresh canvases for the new system
106
- const targetId = systemName === 'faceted' ? 'vib34dLayers' : `${systemName}Layers`;
107
- const targetContainer = document.getElementById(targetId);
108
-
109
- if (!targetContainer) {
110
- console.error(`❌ Container ${targetId} not found`);
111
- return;
65
+ /**
66
+ * Destroy all managed canvases and force-lose registered WebGL contexts.
67
+ */
68
+ destroy() {
69
+ // Force-lose all tracked contexts
70
+ for (const [, gl] of this.registeredContexts) {
71
+ try {
72
+ const ext = gl.getExtension('WEBGL_lose_context');
73
+ if (ext) ext.loseContext();
74
+ } catch (_) { /* context may already be lost */ }
75
+ }
76
+ this.registeredContexts.clear();
77
+
78
+ this._removeCreatedCanvases();
79
+ this.currentSystem = null;
112
80
  }
113
-
114
- // Create canvas IDs for this system
115
- const canvasIds = this.getCanvasIdsForSystem(systemName);
116
-
117
- // Create 5 fresh canvases
118
- canvasIds.forEach((canvasId, index) => {
119
- const canvas = document.createElement('canvas');
120
- canvas.id = canvasId;
121
- canvas.className = 'visualization-canvas';
122
- canvas.style.position = 'absolute';
123
- canvas.style.top = '0';
124
- canvas.style.left = '0';
125
- canvas.style.width = '100%';
126
- canvas.style.height = '100%';
127
- canvas.style.zIndex = index + 1;
128
-
129
- // Set canvas dimensions
130
- const viewWidth = window.innerWidth;
131
- const viewHeight = window.innerHeight;
132
- const dpr = Math.min(window.devicePixelRatio || 1, 2);
133
- canvas.width = viewWidth * dpr;
134
- canvas.height = viewHeight * dpr;
135
-
136
- targetContainer.appendChild(canvas);
137
- });
138
-
139
- // Show the target container
140
- targetContainer.style.display = 'block';
141
- targetContainer.style.visibility = 'visible';
142
- targetContainer.style.opacity = '1';
143
-
144
- console.log(`✅ Created 5 fresh canvases for ${systemName}: ${canvasIds.join(', ')}`);
145
- }
146
-
147
- getCanvasIdsForSystem(systemName) {
148
- const baseIds = ['background-canvas', 'shadow-canvas', 'content-canvas', 'highlight-canvas', 'accent-canvas'];
149
-
150
- switch (systemName) {
151
- case 'faceted':
152
- return baseIds;
153
- case 'quantum':
154
- return baseIds.map(id => `quantum-${id}`);
155
- case 'holographic':
156
- return baseIds.map(id => `holo-${id}`);
157
- case 'polychora':
158
- return baseIds.map(id => `polychora-${id}`);
159
- default:
160
- return baseIds;
81
+
82
+ // ── Private helpers ──
83
+
84
+ _removeCreatedCanvases() {
85
+ for (const canvas of this.createdCanvases) {
86
+ canvas.remove();
87
+ }
88
+ this.createdCanvases = [];
161
89
  }
162
- }
163
-
164
- async createFreshEngine(systemName, engineClasses) {
165
- console.log(`🚀 Creating fresh ${systemName} engine`);
166
-
167
- let engine = null;
168
-
169
- try {
170
- switch(systemName) {
171
- case 'faceted':
172
- if (engineClasses.VIB34DIntegratedEngine) {
173
- engine = new engineClasses.VIB34DIntegratedEngine();
174
- window.engine = engine;
175
- console.log('✅ Fresh Faceted engine');
176
- }
177
- break;
178
-
179
- case 'quantum':
180
- if (engineClasses.QuantumEngine) {
181
- engine = new engineClasses.QuantumEngine();
182
- window.quantumEngine = engine;
183
- console.log('✅ Fresh Quantum engine');
184
- }
185
- break;
186
-
187
- case 'holographic':
188
- if (engineClasses.RealHolographicSystem) {
189
- engine = new engineClasses.RealHolographicSystem();
190
- window.holographicSystem = engine;
191
- console.log('✅ Fresh Holographic engine');
192
- }
193
- break;
194
-
195
- case 'polychora':
196
- // POLYCHORA: TBD placeholder - not production ready
197
- // Engine disabled until system is complete
198
- console.warn('⚠️ Polychora system is TBD placeholder - not available');
199
- if (false && engineClasses.NewPolychoraEngine) {
200
- engine = new engineClasses.NewPolychoraEngine();
201
- window.newPolychoraEngine = engine;
202
- console.log('✅ Fresh TRUE 4D Polychora Engine with VIB34D DNA');
203
- }
204
- break;
205
-
206
- default:
207
- console.error(`❌ Unknown system: ${systemName}`);
208
- }
209
-
210
- } catch (error) {
211
- console.error(`💥 Engine creation failed for ${systemName}:`, error);
212
- engine = null;
90
+
91
+ _getCanvasIdsForSystem(systemName) {
92
+ const baseIds = [
93
+ 'background-canvas', 'shadow-canvas', 'content-canvas',
94
+ 'highlight-canvas', 'accent-canvas'
95
+ ];
96
+
97
+ switch (systemName) {
98
+ case 'faceted':
99
+ return baseIds;
100
+ case 'quantum':
101
+ return baseIds.map(id => `quantum-${id}`);
102
+ case 'holographic':
103
+ return baseIds.map(id => `holo-${id}`);
104
+ case 'polychora':
105
+ return baseIds.map(id => `polychora-${id}`);
106
+ default:
107
+ return baseIds;
108
+ }
213
109
  }
214
-
215
- return engine;
216
- }
217
- }
110
+ }
@@ -86,7 +86,7 @@ export class ErrorReporter {
86
86
  timestamp: Date.now(),
87
87
  url: typeof location !== 'undefined' ? location.pathname : '',
88
88
  userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',
89
- sdkVersion: '2.0.0',
89
+ sdkVersion: '2.0.3',
90
90
  };
91
91
 
92
92
  // Custom callback takes priority
@@ -272,7 +272,7 @@ export class ParameterManager {
272
272
  exportConfiguration() {
273
273
  return {
274
274
  type: 'vib34d-integrated-config',
275
- version: '1.0.0',
275
+ version: '2.0.3',
276
276
  timestamp: new Date().toISOString(),
277
277
  name: `VIB34D Config ${new Date().toLocaleDateString()}`,
278
278
  parameters: { ...this.params }
@@ -15,6 +15,7 @@ import { RealHolographicSystem } from '../holograms/RealHolographicSystem.js';
15
15
  import { ReactivityManager } from '../reactivity/ReactivityManager.js';
16
16
  import { ReactivityConfig } from '../reactivity/ReactivityConfig.js';
17
17
  import { SpatialInputSystem } from '../reactivity/SpatialInputSystem.js';
18
+ import { VitalitySystem } from './VitalitySystem.js';
18
19
 
19
20
  export class VIB3Engine {
20
21
  /**
@@ -25,7 +26,7 @@ export class VIB3Engine {
25
26
  */
26
27
  constructor(options = {}) {
27
28
  this.activeSystem = null; // Only one system active at a time
28
- this.currentSystemName = 'quantum';
29
+ this.currentSystemName = options.system || 'quantum';
29
30
  this.parameters = new ParameterManager();
30
31
  this.initialized = false;
31
32
  this.canvasManager = null;
@@ -36,6 +37,9 @@ export class VIB3Engine {
36
37
  /** @type {boolean} Debug mode */
37
38
  this.debug = options.debug || false;
38
39
 
40
+ /** @type {VitalitySystem} Global breathing rhythm */
41
+ this.vitality = new VitalitySystem();
42
+
39
43
  /** @type {ReactivityManager} Reactivity system for audio/tilt/interaction */
40
44
  this.reactivity = new ReactivityManager((name, value) => {
41
45
  this.parameters.setParameter(name, value);
@@ -78,16 +82,44 @@ export class VIB3Engine {
78
82
  }
79
83
 
80
84
  // Initialize starting system
81
- await this.switchSystem(this.currentSystemName);
85
+ const systemOk = await this.switchSystem(this.currentSystemName);
86
+ if (!systemOk) {
87
+ console.error(`VIB3+ Engine: Failed to create initial system "${this.currentSystemName}"`);
88
+ return false;
89
+ }
82
90
 
83
91
  // Sync base parameters to reactivity manager
84
92
  this.reactivity.setBaseParameters(this.parameters.getAllParameters());
85
93
 
94
+ // Start vitality system
95
+ this.vitality.start();
96
+
97
+ // Start global loop to drive vitality updates
98
+ this._startGlobalLoop();
99
+
86
100
  this.initialized = true;
87
101
  console.log('VIB3+ Engine initialized');
88
102
  return true;
89
103
  }
90
104
 
105
+ _startGlobalLoop() {
106
+ this._globalLoopActive = true;
107
+ const loop = () => {
108
+ if (!this._globalLoopActive) return;
109
+ if (this.initialized) {
110
+ // Update breath cycle
111
+ const breath = this.vitality.update();
112
+
113
+ // Push breath to current system
114
+ if (this.activeSystem && this.activeSystem.updateParameters) {
115
+ this.activeSystem.updateParameters({ breath });
116
+ }
117
+ }
118
+ this._globalRafId = requestAnimationFrame(loop);
119
+ };
120
+ this._globalRafId = requestAnimationFrame(loop);
121
+ }
122
+
91
123
  /**
92
124
  * Create and initialize a specific system
93
125
  * CRITICAL: Engines find canvases by ID in DOM, not passed as parameters!
@@ -139,7 +171,7 @@ export class VIB3Engine {
139
171
  }
140
172
  }
141
173
 
142
- const facetedSuccess = system.initialize();
174
+ const facetedSuccess = await system.initialize();
143
175
  if (!facetedSuccess) {
144
176
  throw new Error('Faceted system initialization failed');
145
177
  }
@@ -245,6 +277,17 @@ export class VIB3Engine {
245
277
 
246
278
  if (this.activeSystem && this.activeSystem.updateParameters) {
247
279
  this.activeSystem.updateParameters(params);
280
+ } else if (this.debug && this.activeSystem && !this.activeSystem.updateParameters) {
281
+ console.warn('VIB3+ Engine [debug]: activeSystem missing updateParameters() method');
282
+ } else if (this.debug && !this.activeSystem) {
283
+ console.warn('VIB3+ Engine [debug]: updateCurrentSystemParameters() called with no activeSystem');
284
+ }
285
+
286
+ // Notify parameter change listeners
287
+ if (this._parameterListeners && this._parameterListeners.size > 0) {
288
+ for (const listener of this._parameterListeners) {
289
+ try { listener(params); } catch (_) { /* listener error */ }
290
+ }
248
291
  }
249
292
  }
250
293
 
@@ -534,7 +577,7 @@ export class VIB3Engine {
534
577
  spatialActive: this.spatialInput.enabled,
535
578
  backend: this.getActiveBackendType(),
536
579
  timestamp: new Date().toISOString(),
537
- version: '1.2.0'
580
+ version: '2.0.3'
538
581
  };
539
582
  }
540
583
 
@@ -604,10 +647,56 @@ export class VIB3Engine {
604
647
  }
605
648
  }
606
649
 
650
+ // ========================================================================
651
+ // Convenience Methods (dogfood feedback)
652
+ // ========================================================================
653
+
654
+ /**
655
+ * Create a parameter update callback for use with creative modules.
656
+ * Returns (name, value) => void that calls setParameter internally.
657
+ * Eliminates boilerplate: `(name, value) => engine.setParameter(name, value)`.
658
+ * @returns {(name: string, value: number) => void}
659
+ */
660
+ createParameterCallback() {
661
+ return (name, value) => this.setParameter(name, value);
662
+ }
663
+
664
+ /**
665
+ * Get current breath value from VitalitySystem (0-1).
666
+ * Avoids reaching into engine.vitality.getBreath() directly.
667
+ * @returns {number}
668
+ */
669
+ getBreath() {
670
+ return this.vitality.getBreath();
671
+ }
672
+
673
+ /**
674
+ * Register a listener for parameter changes.
675
+ * Callback receives the full parameter object after each change.
676
+ * @param {(params: object) => void} callback
677
+ * @returns {() => void} Unsubscribe function
678
+ */
679
+ onParameterChange(callback) {
680
+ if (!this._parameterListeners) {
681
+ this._parameterListeners = new Set();
682
+ }
683
+ this._parameterListeners.add(callback);
684
+ return () => this._parameterListeners.delete(callback);
685
+ }
686
+
607
687
  /**
608
688
  * Destroy engine and clean up
609
689
  */
610
690
  destroy() {
691
+ // Cancel global breath loop
692
+ this._globalLoopActive = false;
693
+ if (this._globalRafId) {
694
+ cancelAnimationFrame(this._globalRafId);
695
+ this._globalRafId = null;
696
+ }
697
+
698
+ this.vitality.stop();
699
+
611
700
  // Stop and destroy spatial input
612
701
  if (this.spatialInput) {
613
702
  this.spatialInput.destroy();
@@ -0,0 +1,53 @@
1
+ /**
2
+ * VitalitySystem.js
3
+ * Manages the "breath of life" for the VIB3+ Engine.
4
+ * Generates a global rhythmic breath cycle (Exhale/Evoke) that modulates
5
+ * all visualization systems for a unified, organic feel.
6
+ */
7
+ export class VitalitySystem {
8
+ constructor() {
9
+ this.time = 0;
10
+ this.breath = 0;
11
+ this.cycleDuration = 6000; // 6 seconds per breath
12
+ this.isRunning = false;
13
+ }
14
+
15
+ start() {
16
+ this.isRunning = true;
17
+ this.startTime = Date.now();
18
+ }
19
+
20
+ stop() {
21
+ this.isRunning = false;
22
+ }
23
+
24
+ /**
25
+ * Update the breath cycle.
26
+ * Returns a normalized 0-1 value representing the breath phase.
27
+ * 0 = Empty, 1 = Full
28
+ * Uses a sine wave for smooth organic motion.
29
+ */
30
+ update(deltaTime) {
31
+ if (!this.isRunning) return 0;
32
+
33
+ const now = Date.now();
34
+ const elapsed = now - this.startTime;
35
+
36
+ // 0 to 2PI over cycleDuration
37
+ const phase = (elapsed % this.cycleDuration) / this.cycleDuration;
38
+ const angle = phase * Math.PI * 2;
39
+
40
+ // Smooth sine wave: -1 to 1 -> 0 to 1
41
+ // We use -cos to start at 0 (empty), go to 1 (full), back to 0
42
+ this.breath = (1.0 - Math.cos(angle)) * 0.5;
43
+
44
+ // Add a small "pause" at the top and bottom for realism?
45
+ // For now, pure sine is hypnotic enough.
46
+
47
+ return this.breath;
48
+ }
49
+
50
+ getBreath() {
51
+ return this.breath;
52
+ }
53
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * VIB3+ Core Module
3
+ * @module core
4
+ */
5
+
6
+ export { VIB3Engine } from './VIB3Engine.js';
7
+ export { CanvasManager } from './CanvasManager.js';
8
+ export { ParameterManager } from './Parameters.js';
9
+ export { ParameterMapper } from './ParameterMapper.js';
10
+ export { ErrorReporter } from './ErrorReporter.js';
11
+ export { VitalitySystem } from './VitalitySystem.js';
12
+ export { UnifiedResourceManager } from './UnifiedResourceManager.js';
13
+ export {
14
+ RendererContract,
15
+ RendererContractAdapter,
16
+ verifyRendererContract,
17
+ ResourceManagerContract
18
+ } from './RendererContracts.js';
@@ -8,18 +8,19 @@ export class FacetedRendererAdapter extends RendererContract {
8
8
  }
9
9
 
10
10
  init(context = {}) {
11
- const initialized = this.system.initialize(context.canvas ?? null);
12
- if (!initialized) {
13
- throw new Error('Faceted renderer failed to initialize.');
14
- }
11
+ return this.system.init ? this.system.init(context) : true;
15
12
  }
16
13
 
17
- resize() {
18
- this.system.setupCanvasSize();
14
+ resize(width, height, pixelRatio = 1) {
15
+ if (this.system.resize) {
16
+ this.system.resize(width, height, pixelRatio);
17
+ }
19
18
  }
20
19
 
21
- render() {
22
- this.system.renderFrame();
20
+ render(frameState) {
21
+ if (this.system.render) {
22
+ this.system.render(frameState);
23
+ }
23
24
  }
24
25
 
25
26
  setActive(active) {
@@ -27,6 +28,6 @@ export class FacetedRendererAdapter extends RendererContract {
27
28
  }
28
29
 
29
30
  dispose() {
30
- this.system.stop();
31
+ this.system.dispose();
31
32
  }
32
33
  }
@@ -1,22 +1,26 @@
1
1
  import { RendererContract } from '../RendererContracts.js';
2
- import { HolographicSystem } from '../../holograms/HolographicSystem.js';
2
+ import { RealHolographicSystem } from '../../holograms/RealHolographicSystem.js';
3
3
 
4
4
  export class HolographicRendererAdapter extends RendererContract {
5
- constructor(system = new HolographicSystem({ autoStart: false })) {
5
+ constructor(system = new RealHolographicSystem({ autoStart: false })) {
6
6
  super();
7
7
  this.system = system;
8
8
  }
9
9
 
10
- init() {
11
- return true;
10
+ init(context = {}) {
11
+ return this.system.init ? this.system.init(context) : true;
12
12
  }
13
13
 
14
- resize() {
15
- // Visualizers handle their own resizing.
14
+ resize(width, height, pixelRatio = 1) {
15
+ if (this.system.resize) {
16
+ this.system.resize(width, height, pixelRatio);
17
+ }
16
18
  }
17
19
 
18
- render() {
19
- this.system.renderFrame();
20
+ render(frameState) {
21
+ if (this.system.render) {
22
+ this.system.render(frameState);
23
+ }
20
24
  }
21
25
 
22
26
  setActive(active) {
@@ -24,6 +28,6 @@ export class HolographicRendererAdapter extends RendererContract {
24
28
  }
25
29
 
26
30
  dispose() {
27
- this.system.setActive(false);
31
+ this.system.dispose();
28
32
  }
29
33
  }