@vib3code/sdk 2.0.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.
Files changed (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,523 @@
1
+ /**
2
+ * RenderResourceRegistry - Centralized GPU resource lifecycle tracking.
3
+ *
4
+ * Tracks WebGL/WebGPU resources by type with optional byte sizing to help
5
+ * manage disposal and provide lifecycle visibility to renderer contracts.
6
+ *
7
+ * Features:
8
+ * - Resource registration with type, handle, disposer, and metadata
9
+ * - Peak usage tracking (high watermark)
10
+ * - Per-frame delta statistics
11
+ * - Allocation/deallocation history for debugging
12
+ * - Resource leak detection
13
+ * - Timeline recording for performance analysis
14
+ */
15
+
16
+ /**
17
+ * Resource allocation event
18
+ */
19
+ class ResourceEvent {
20
+ constructor(type, action, bytes, label = null) {
21
+ this.timestamp = performance.now();
22
+ this.type = type;
23
+ this.action = action; // 'alloc' | 'free'
24
+ this.bytes = bytes;
25
+ this.label = label;
26
+ }
27
+ }
28
+
29
+ export class RenderResourceRegistry {
30
+ /**
31
+ * @param {object} [options]
32
+ * @param {boolean} [options.trackHistory] - Enable allocation history
33
+ * @param {number} [options.historyLimit] - Max history entries (default 1000)
34
+ * @param {boolean} [options.detectLeaks] - Enable leak detection warnings
35
+ */
36
+ constructor(options = {}) {
37
+ this._resources = new Map();
38
+
39
+ // Diagnostics options
40
+ this._trackHistory = options.trackHistory || false;
41
+ this._historyLimit = options.historyLimit || 1000;
42
+ this._detectLeaks = options.detectLeaks || false;
43
+
44
+ // Peak usage tracking
45
+ this._peakResources = 0;
46
+ this._peakBytes = 0;
47
+ this._peakByType = new Map();
48
+
49
+ // Per-frame delta tracking
50
+ this._frameStartResources = 0;
51
+ this._frameStartBytes = 0;
52
+ this._frameDelta = { resources: 0, bytes: 0 };
53
+
54
+ // Allocation history
55
+ /** @type {ResourceEvent[]} */
56
+ this._history = [];
57
+
58
+ // Leak detection
59
+ this._disposedTypes = new Set();
60
+
61
+ // Statistics
62
+ this._stats = {
63
+ totalAllocations: 0,
64
+ totalDeallocations: 0,
65
+ currentResources: 0,
66
+ currentBytes: 0
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Enable or disable history tracking
72
+ * @param {boolean} enabled
73
+ */
74
+ setHistoryTracking(enabled) {
75
+ this._trackHistory = enabled;
76
+ if (!enabled) {
77
+ this._history = [];
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Mark the start of a frame for delta tracking
83
+ */
84
+ beginFrame() {
85
+ this._frameStartResources = this._stats.currentResources;
86
+ this._frameStartBytes = this._stats.currentBytes;
87
+ }
88
+
89
+ /**
90
+ * Mark the end of a frame and calculate deltas
91
+ * @returns {object} Frame delta statistics
92
+ */
93
+ endFrame() {
94
+ this._frameDelta = {
95
+ resources: this._stats.currentResources - this._frameStartResources,
96
+ bytes: this._stats.currentBytes - this._frameStartBytes
97
+ };
98
+ return this._frameDelta;
99
+ }
100
+
101
+ /**
102
+ * Register a resource
103
+ * @param {string} type - Resource type (buffer, texture, shader, etc.)
104
+ * @param {any} handle - GPU resource handle
105
+ * @param {function} [disposer] - Cleanup function
106
+ * @param {object} [options]
107
+ * @param {number} [options.bytes] - Resource size in bytes
108
+ * @param {string} [options.label] - Debug label
109
+ * @returns {object|null} Resource entry
110
+ */
111
+ register(type, handle, disposer, options = {}) {
112
+ if (!handle) {
113
+ return null;
114
+ }
115
+
116
+ const bytes = options.bytes ?? 0;
117
+ const label = options.label ?? null;
118
+
119
+ const entry = {
120
+ handle,
121
+ disposer,
122
+ bytes,
123
+ label,
124
+ createdAt: performance.now(),
125
+ id: ++this._stats.totalAllocations
126
+ };
127
+
128
+ const bucket = this._resources.get(type) ?? new Set();
129
+ bucket.add(entry);
130
+ this._resources.set(type, bucket);
131
+
132
+ // Update statistics
133
+ this._stats.currentResources++;
134
+ this._stats.currentBytes += bytes;
135
+
136
+ // Update peak tracking
137
+ this._updatePeakStats(type);
138
+
139
+ // Record history
140
+ if (this._trackHistory) {
141
+ this._recordEvent(type, 'alloc', bytes, label);
142
+ }
143
+
144
+ return entry;
145
+ }
146
+
147
+ /**
148
+ * Release a resource without disposing
149
+ * @param {string} type
150
+ * @param {any} handle
151
+ * @returns {boolean}
152
+ */
153
+ release(type, handle) {
154
+ const bucket = this._resources.get(type);
155
+ if (!bucket) return false;
156
+
157
+ for (const entry of bucket) {
158
+ if (entry.handle === handle) {
159
+ bucket.delete(entry);
160
+
161
+ // Update statistics
162
+ this._stats.currentResources--;
163
+ this._stats.currentBytes -= entry.bytes;
164
+ this._stats.totalDeallocations++;
165
+
166
+ // Record history
167
+ if (this._trackHistory) {
168
+ this._recordEvent(type, 'free', entry.bytes, entry.label);
169
+ }
170
+
171
+ if (bucket.size === 0) {
172
+ this._resources.delete(type);
173
+ }
174
+ return true;
175
+ }
176
+ }
177
+ return false;
178
+ }
179
+
180
+ /**
181
+ * Dispose a resource (call disposer and release)
182
+ * @param {string} type
183
+ * @param {any} handle
184
+ * @returns {boolean}
185
+ */
186
+ dispose(type, handle) {
187
+ const bucket = this._resources.get(type);
188
+ if (!bucket) return false;
189
+
190
+ for (const entry of bucket) {
191
+ if (entry.handle === handle) {
192
+ if (entry.disposer) {
193
+ try {
194
+ entry.disposer();
195
+ } catch (e) {
196
+ console.warn(`RenderResourceRegistry: dispose error for ${type}:`, e);
197
+ }
198
+ }
199
+
200
+ bucket.delete(entry);
201
+
202
+ // Update statistics
203
+ this._stats.currentResources--;
204
+ this._stats.currentBytes -= entry.bytes;
205
+ this._stats.totalDeallocations++;
206
+
207
+ // Record history
208
+ if (this._trackHistory) {
209
+ this._recordEvent(type, 'free', entry.bytes, entry.label);
210
+ }
211
+
212
+ if (bucket.size === 0) {
213
+ this._resources.delete(type);
214
+ }
215
+ return true;
216
+ }
217
+ }
218
+ return false;
219
+ }
220
+
221
+ /**
222
+ * Dispose all resources of a type
223
+ * @param {string} type
224
+ * @returns {number} Number of resources disposed
225
+ */
226
+ disposeType(type) {
227
+ const bucket = this._resources.get(type);
228
+ if (!bucket) return 0;
229
+
230
+ let count = 0;
231
+ for (const entry of bucket) {
232
+ if (entry.disposer) {
233
+ try {
234
+ entry.disposer();
235
+ } catch (e) {
236
+ console.warn(`RenderResourceRegistry: dispose error for ${type}:`, e);
237
+ }
238
+ }
239
+
240
+ this._stats.currentResources--;
241
+ this._stats.currentBytes -= entry.bytes;
242
+ this._stats.totalDeallocations++;
243
+
244
+ if (this._trackHistory) {
245
+ this._recordEvent(type, 'free', entry.bytes, entry.label);
246
+ }
247
+
248
+ count++;
249
+ }
250
+
251
+ this._resources.delete(type);
252
+ this._disposedTypes.add(type);
253
+
254
+ return count;
255
+ }
256
+
257
+ /**
258
+ * Dispose all resources
259
+ */
260
+ disposeAll() {
261
+ for (const [type, bucket] of this._resources.entries()) {
262
+ for (const entry of bucket) {
263
+ if (entry.disposer) {
264
+ try {
265
+ entry.disposer();
266
+ } catch (e) {
267
+ console.warn(`RenderResourceRegistry: dispose error for ${type}:`, e);
268
+ }
269
+ }
270
+
271
+ this._stats.totalDeallocations++;
272
+
273
+ if (this._trackHistory) {
274
+ this._recordEvent(type, 'free', entry.bytes, entry.label);
275
+ }
276
+ }
277
+ this._disposedTypes.add(type);
278
+ }
279
+
280
+ this._stats.currentResources = 0;
281
+ this._stats.currentBytes = 0;
282
+ this._resources.clear();
283
+ }
284
+
285
+ /**
286
+ * Update peak statistics
287
+ * @private
288
+ */
289
+ _updatePeakStats(type) {
290
+ // Global peaks
291
+ if (this._stats.currentResources > this._peakResources) {
292
+ this._peakResources = this._stats.currentResources;
293
+ }
294
+ if (this._stats.currentBytes > this._peakBytes) {
295
+ this._peakBytes = this._stats.currentBytes;
296
+ }
297
+
298
+ // Per-type peaks
299
+ const bucket = this._resources.get(type);
300
+ if (bucket) {
301
+ const current = bucket.size;
302
+ const peak = this._peakByType.get(type) || 0;
303
+ if (current > peak) {
304
+ this._peakByType.set(type, current);
305
+ }
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Record history event
311
+ * @private
312
+ */
313
+ _recordEvent(type, action, bytes, label) {
314
+ this._history.push(new ResourceEvent(type, action, bytes, label));
315
+
316
+ // Trim history if over limit
317
+ if (this._history.length > this._historyLimit) {
318
+ this._history = this._history.slice(-this._historyLimit);
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Get basic statistics
324
+ * @returns {object}
325
+ */
326
+ getStats() {
327
+ const stats = {
328
+ totalResources: this._stats.currentResources,
329
+ totalBytes: this._stats.currentBytes,
330
+ byType: {}
331
+ };
332
+
333
+ for (const [type, bucket] of this._resources.entries()) {
334
+ let bytes = 0;
335
+ for (const entry of bucket) {
336
+ bytes += entry.bytes;
337
+ }
338
+ stats.byType[type] = {
339
+ count: bucket.size,
340
+ bytes
341
+ };
342
+ }
343
+
344
+ return stats;
345
+ }
346
+
347
+ /**
348
+ * Get detailed diagnostics
349
+ * @returns {object}
350
+ */
351
+ getDiagnostics() {
352
+ const basicStats = this.getStats();
353
+
354
+ return {
355
+ ...basicStats,
356
+
357
+ // Peak usage
358
+ peak: {
359
+ resources: this._peakResources,
360
+ bytes: this._peakBytes,
361
+ byType: Object.fromEntries(this._peakByType)
362
+ },
363
+
364
+ // Frame delta
365
+ frameDelta: { ...this._frameDelta },
366
+
367
+ // Lifetime statistics
368
+ lifetime: {
369
+ totalAllocations: this._stats.totalAllocations,
370
+ totalDeallocations: this._stats.totalDeallocations,
371
+ netAllocations: this._stats.totalAllocations - this._stats.totalDeallocations
372
+ },
373
+
374
+ // Memory efficiency
375
+ efficiency: {
376
+ utilizationPercent: this._peakBytes > 0
377
+ ? (this._stats.currentBytes / this._peakBytes * 100).toFixed(1)
378
+ : 100,
379
+ averageBytesPerResource: this._stats.currentResources > 0
380
+ ? Math.round(this._stats.currentBytes / this._stats.currentResources)
381
+ : 0
382
+ }
383
+ };
384
+ }
385
+
386
+ /**
387
+ * Get allocation history
388
+ * @param {object} [options]
389
+ * @param {string} [options.type] - Filter by resource type
390
+ * @param {string} [options.action] - Filter by action ('alloc' or 'free')
391
+ * @param {number} [options.limit] - Max entries to return
392
+ * @returns {ResourceEvent[]}
393
+ */
394
+ getHistory(options = {}) {
395
+ let history = this._history;
396
+
397
+ if (options.type) {
398
+ history = history.filter(e => e.type === options.type);
399
+ }
400
+ if (options.action) {
401
+ history = history.filter(e => e.action === options.action);
402
+ }
403
+ if (options.limit) {
404
+ history = history.slice(-options.limit);
405
+ }
406
+
407
+ return history;
408
+ }
409
+
410
+ /**
411
+ * Get resources by type
412
+ * @param {string} type
413
+ * @returns {Array<object>}
414
+ */
415
+ getResourcesByType(type) {
416
+ const bucket = this._resources.get(type);
417
+ if (!bucket) return [];
418
+
419
+ return Array.from(bucket).map(entry => ({
420
+ label: entry.label,
421
+ bytes: entry.bytes,
422
+ createdAt: entry.createdAt,
423
+ age: performance.now() - entry.createdAt,
424
+ id: entry.id
425
+ }));
426
+ }
427
+
428
+ /**
429
+ * Check for potential leaks (resources held too long)
430
+ * @param {number} [ageThreshold] - Age in ms to consider as potential leak (default 60000)
431
+ * @returns {Array<object>}
432
+ */
433
+ detectLeaks(ageThreshold = 60000) {
434
+ const now = performance.now();
435
+ const potentialLeaks = [];
436
+
437
+ for (const [type, bucket] of this._resources.entries()) {
438
+ for (const entry of bucket) {
439
+ const age = now - entry.createdAt;
440
+ if (age > ageThreshold) {
441
+ potentialLeaks.push({
442
+ type,
443
+ label: entry.label,
444
+ bytes: entry.bytes,
445
+ age: Math.round(age),
446
+ id: entry.id
447
+ });
448
+ }
449
+ }
450
+ }
451
+
452
+ return potentialLeaks;
453
+ }
454
+
455
+ /**
456
+ * Reset peak statistics
457
+ */
458
+ resetPeakStats() {
459
+ this._peakResources = this._stats.currentResources;
460
+ this._peakBytes = this._stats.currentBytes;
461
+ this._peakByType.clear();
462
+
463
+ for (const [type, bucket] of this._resources.entries()) {
464
+ this._peakByType.set(type, bucket.size);
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Clear allocation history
470
+ */
471
+ clearHistory() {
472
+ this._history = [];
473
+ }
474
+
475
+ /**
476
+ * Export diagnostics as JSON
477
+ * @returns {string}
478
+ */
479
+ exportDiagnosticsJSON() {
480
+ return JSON.stringify({
481
+ diagnostics: this.getDiagnostics(),
482
+ history: this._history.map(e => ({
483
+ timestamp: e.timestamp,
484
+ type: e.type,
485
+ action: e.action,
486
+ bytes: e.bytes,
487
+ label: e.label
488
+ }))
489
+ }, null, 2);
490
+ }
491
+
492
+ /**
493
+ * Get summary string for debug overlay
494
+ * @returns {string}
495
+ */
496
+ getSummaryString() {
497
+ const d = this.getDiagnostics();
498
+ const lines = [
499
+ `Resources: ${d.totalResources} (peak: ${d.peak.resources})`,
500
+ `Memory: ${this._formatBytes(d.totalBytes)} (peak: ${this._formatBytes(d.peak.bytes)})`,
501
+ `Frame Δ: ${d.frameDelta.resources >= 0 ? '+' : ''}${d.frameDelta.resources} resources`
502
+ ];
503
+
504
+ // Add per-type breakdown
505
+ for (const [type, data] of Object.entries(d.byType)) {
506
+ lines.push(` ${type}: ${data.count} (${this._formatBytes(data.bytes)})`);
507
+ }
508
+
509
+ return lines.join('\n');
510
+ }
511
+
512
+ /**
513
+ * Format bytes for display
514
+ * @private
515
+ */
516
+ _formatBytes(bytes) {
517
+ if (bytes < 1024) return `${bytes}B`;
518
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
519
+ return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
520
+ }
521
+ }
522
+
523
+ export default RenderResourceRegistry;