@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.
- package/CHANGELOG.md +118 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
- package/DOCS/CI_TESTING.md +38 -0
- package/DOCS/CLI_ONBOARDING.md +75 -0
- package/DOCS/CONTROL_REFERENCE.md +64 -0
- package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
- package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
- package/DOCS/ENV_SETUP.md +189 -0
- package/DOCS/EXPORT_FORMATS.md +417 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
- package/DOCS/LICENSING_TIERS.md +275 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
- package/DOCS/OBS_SETUP_GUIDE.md +98 -0
- package/DOCS/PROJECT_SETUP.md +66 -0
- package/DOCS/RENDERER_LIFECYCLE.md +40 -0
- package/DOCS/REPO_MANIFEST.md +121 -0
- package/DOCS/SESSION_014_PLAN.md +195 -0
- package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
- package/DOCS/SYSTEM_INVENTORY.md +520 -0
- package/DOCS/TELEMETRY_EXPORTS.md +34 -0
- package/DOCS/WEBGPU_STATUS.md +38 -0
- package/DOCS/XR_BENCHMARKS.md +608 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/docs/.nojekyll +0 -0
- package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/02-hyperspatial_ego_death.html +346 -0
- package/docs/03-post_cartesian_sublime.html +346 -0
- package/docs/04-crystalline_void_meditation.html +346 -0
- package/docs/05-quantum_decoherence_ballet.html +346 -0
- package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/07-hyperspatial_ego_death.html +346 -0
- package/docs/08-post_cartesian_sublime.html +346 -0
- package/docs/09-crystalline_void_meditation.html +346 -0
- package/docs/10-quantum_decoherence_ballet.html +346 -0
- package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/12-hyperspatial_ego_death.html +346 -0
- package/docs/13-post_cartesian_sublime.html +346 -0
- package/docs/index.html +794 -0
- package/docs/test-hub.html +441 -0
- package/docs/url-state.js +102 -0
- package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
- package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
- package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
- package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
- package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
- package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
- package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
- package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
- package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
- package/docs/vib3-exports/index.html +238 -0
- package/docs/webgpu-live.html +702 -0
- package/package.json +367 -0
- package/src/advanced/AIPresetGenerator.js +777 -0
- package/src/advanced/MIDIController.js +703 -0
- package/src/advanced/OffscreenWorker.js +1051 -0
- package/src/advanced/WebGPUCompute.js +1051 -0
- package/src/advanced/WebXRRenderer.js +680 -0
- package/src/agent/cli/AgentCLI.js +615 -0
- package/src/agent/cli/index.js +14 -0
- package/src/agent/index.js +73 -0
- package/src/agent/mcp/MCPServer.js +950 -0
- package/src/agent/mcp/index.js +9 -0
- package/src/agent/mcp/tools.js +548 -0
- package/src/agent/telemetry/EventStream.js +669 -0
- package/src/agent/telemetry/Instrumentation.js +618 -0
- package/src/agent/telemetry/TelemetryExporters.js +427 -0
- package/src/agent/telemetry/TelemetryService.js +464 -0
- package/src/agent/telemetry/index.js +52 -0
- package/src/benchmarks/BenchmarkRunner.js +381 -0
- package/src/benchmarks/MetricsCollector.js +299 -0
- package/src/benchmarks/index.js +9 -0
- package/src/benchmarks/scenes.js +259 -0
- package/src/cli/index.js +675 -0
- package/src/config/ApiConfig.js +88 -0
- package/src/core/CanvasManager.js +217 -0
- package/src/core/ErrorReporter.js +117 -0
- package/src/core/ParameterMapper.js +333 -0
- package/src/core/Parameters.js +396 -0
- package/src/core/RendererContracts.js +200 -0
- package/src/core/UnifiedResourceManager.js +370 -0
- package/src/core/VIB3Engine.js +636 -0
- package/src/core/renderers/FacetedRendererAdapter.js +32 -0
- package/src/core/renderers/HolographicRendererAdapter.js +29 -0
- package/src/core/renderers/QuantumRendererAdapter.js +29 -0
- package/src/core/renderers/RendererLifecycleManager.js +63 -0
- package/src/creative/ColorPresetsSystem.js +980 -0
- package/src/creative/ParameterTimeline.js +1061 -0
- package/src/creative/PostProcessingPipeline.js +1113 -0
- package/src/creative/TransitionAnimator.js +683 -0
- package/src/export/CSSExporter.js +226 -0
- package/src/export/CardGeneratorBase.js +279 -0
- package/src/export/ExportManager.js +580 -0
- package/src/export/FacetedCardGenerator.js +279 -0
- package/src/export/HolographicCardGenerator.js +543 -0
- package/src/export/LottieExporter.js +552 -0
- package/src/export/QuantumCardGenerator.js +315 -0
- package/src/export/SVGExporter.js +519 -0
- package/src/export/ShaderExporter.js +903 -0
- package/src/export/TradingCardGenerator.js +3055 -0
- package/src/export/TradingCardManager.js +181 -0
- package/src/export/VIB3PackageExporter.js +559 -0
- package/src/export/index.js +14 -0
- package/src/export/systems/TradingCardSystemFaceted.js +494 -0
- package/src/export/systems/TradingCardSystemHolographic.js +452 -0
- package/src/export/systems/TradingCardSystemQuantum.js +411 -0
- package/src/faceted/FacetedSystem.js +963 -0
- package/src/features/CollectionManager.js +433 -0
- package/src/gallery/CollectionManager.js +240 -0
- package/src/gallery/GallerySystem.js +485 -0
- package/src/geometry/GeometryFactory.js +314 -0
- package/src/geometry/GeometryLibrary.js +72 -0
- package/src/geometry/buffers/BufferBuilder.js +338 -0
- package/src/geometry/buffers/index.js +18 -0
- package/src/geometry/generators/Crystal.js +420 -0
- package/src/geometry/generators/Fractal.js +298 -0
- package/src/geometry/generators/KleinBottle.js +197 -0
- package/src/geometry/generators/Sphere.js +192 -0
- package/src/geometry/generators/Tesseract.js +160 -0
- package/src/geometry/generators/Tetrahedron.js +225 -0
- package/src/geometry/generators/Torus.js +304 -0
- package/src/geometry/generators/Wave.js +341 -0
- package/src/geometry/index.js +142 -0
- package/src/geometry/warp/HypersphereCore.js +211 -0
- package/src/geometry/warp/HypertetraCore.js +386 -0
- package/src/geometry/warp/index.js +57 -0
- package/src/holograms/HolographicVisualizer.js +1073 -0
- package/src/holograms/RealHolographicSystem.js +966 -0
- package/src/holograms/variantRegistry.js +69 -0
- package/src/integrations/FigmaPlugin.js +854 -0
- package/src/integrations/OBSMode.js +754 -0
- package/src/integrations/ThreeJsPackage.js +660 -0
- package/src/integrations/TouchDesignerExport.js +552 -0
- package/src/integrations/frameworks/Vib3React.js +591 -0
- package/src/integrations/frameworks/Vib3Svelte.js +654 -0
- package/src/integrations/frameworks/Vib3Vue.js +628 -0
- package/src/llm/LLMParameterInterface.js +240 -0
- package/src/llm/LLMParameterUI.js +577 -0
- package/src/math/Mat4x4.js +708 -0
- package/src/math/Projection.js +341 -0
- package/src/math/Rotor4D.js +637 -0
- package/src/math/Vec4.js +476 -0
- package/src/math/constants.js +164 -0
- package/src/math/index.js +68 -0
- package/src/math/projections.js +54 -0
- package/src/math/rotations.js +196 -0
- package/src/quantum/QuantumEngine.js +906 -0
- package/src/quantum/QuantumVisualizer.js +1103 -0
- package/src/reactivity/ReactivityConfig.js +499 -0
- package/src/reactivity/ReactivityManager.js +586 -0
- package/src/reactivity/SpatialInputSystem.js +1783 -0
- package/src/reactivity/index.js +93 -0
- package/src/render/CommandBuffer.js +465 -0
- package/src/render/MultiCanvasBridge.js +340 -0
- package/src/render/RenderCommand.js +514 -0
- package/src/render/RenderResourceRegistry.js +523 -0
- package/src/render/RenderState.js +552 -0
- package/src/render/RenderTarget.js +512 -0
- package/src/render/ShaderLoader.js +253 -0
- package/src/render/ShaderProgram.js +599 -0
- package/src/render/UnifiedRenderBridge.js +496 -0
- package/src/render/backends/WebGLBackend.js +1108 -0
- package/src/render/backends/WebGPUBackend.js +1409 -0
- package/src/render/commands/CommandBufferExecutor.js +607 -0
- package/src/render/commands/RenderCommandBuffer.js +661 -0
- package/src/render/commands/index.js +17 -0
- package/src/render/index.js +367 -0
- package/src/scene/Disposable.js +498 -0
- package/src/scene/MemoryPool.js +618 -0
- package/src/scene/Node4D.js +697 -0
- package/src/scene/ResourceManager.js +599 -0
- package/src/scene/Scene4D.js +540 -0
- package/src/scene/index.js +98 -0
- package/src/schemas/error.schema.json +84 -0
- package/src/schemas/extension.schema.json +88 -0
- package/src/schemas/index.js +214 -0
- package/src/schemas/parameters.schema.json +142 -0
- package/src/schemas/tool-pack.schema.json +44 -0
- package/src/schemas/tool-response.schema.json +127 -0
- package/src/shaders/common/fullscreen.vert.glsl +5 -0
- package/src/shaders/common/fullscreen.vert.wgsl +17 -0
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +85 -0
- package/src/shaders/common/rotation4d.wgsl +86 -0
- package/src/shaders/common/uniforms.glsl +44 -0
- package/src/shaders/common/uniforms.wgsl +48 -0
- package/src/shaders/faceted/faceted.frag.glsl +129 -0
- package/src/shaders/faceted/faceted.frag.wgsl +164 -0
- package/src/shaders/holographic/holographic.frag.glsl +406 -0
- package/src/shaders/holographic/holographic.frag.wgsl +185 -0
- package/src/shaders/quantum/quantum.frag.glsl +513 -0
- package/src/shaders/quantum/quantum.frag.wgsl +361 -0
- package/src/testing/ParallelTestFramework.js +519 -0
- package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
- package/src/testing/exportFormats.test.js +8 -0
- package/src/testing/projections.test.js +14 -0
- package/src/testing/rotations.test.js +37 -0
- package/src/ui/InteractivityMenu.js +516 -0
- package/src/ui/StatusManager.js +96 -0
- package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
- package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
- package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
- package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
- package/src/variations/VariationManager.js +431 -0
- package/src/viewer/AudioReactivity.js +505 -0
- package/src/viewer/CardBending.js +481 -0
- package/src/viewer/GalleryUI.js +832 -0
- package/src/viewer/ReactivityManager.js +590 -0
- package/src/viewer/TradingCardExporter.js +600 -0
- package/src/viewer/ViewerPortal.js +374 -0
- package/src/viewer/index.js +12 -0
- package/src/wasm/WasmLoader.js +296 -0
- package/src/wasm/index.js +132 -0
- package/tools/agentic/mcpTools.js +88 -0
- package/tools/cli/agent-cli.js +92 -0
- package/tools/export/formats.js +24 -0
- package/tools/math/rotation-baseline.mjs +64 -0
- package/tools/shader-sync-verify.js +937 -0
- package/tools/telemetry/manifestPipeline.js +141 -0
- package/tools/telemetry/telemetryEvents.js +35 -0
- package/types/adaptive-sdk.d.ts +185 -0
- package/types/advanced/AIPresetGenerator.d.ts +81 -0
- package/types/advanced/MIDIController.d.ts +100 -0
- package/types/advanced/OffscreenWorker.d.ts +82 -0
- package/types/advanced/WebGPUCompute.d.ts +52 -0
- package/types/advanced/WebXRRenderer.d.ts +77 -0
- package/types/advanced/index.d.ts +46 -0
- package/types/core/ErrorReporter.d.ts +50 -0
- package/types/core/VIB3Engine.d.ts +204 -0
- package/types/creative/ColorPresetsSystem.d.ts +91 -0
- package/types/creative/ParameterTimeline.d.ts +74 -0
- package/types/creative/PostProcessingPipeline.d.ts +109 -0
- package/types/creative/TransitionAnimator.d.ts +71 -0
- package/types/creative/index.d.ts +35 -0
- package/types/integrations/FigmaPlugin.d.ts +46 -0
- package/types/integrations/OBSMode.d.ts +74 -0
- package/types/integrations/ThreeJsPackage.d.ts +62 -0
- package/types/integrations/TouchDesignerExport.d.ts +36 -0
- package/types/integrations/Vib3React.d.ts +74 -0
- package/types/integrations/Vib3Svelte.d.ts +63 -0
- package/types/integrations/Vib3Vue.d.ts +55 -0
- package/types/integrations/index.d.ts +52 -0
- package/types/reactivity/SpatialInputSystem.d.ts +173 -0
- package/types/reactivity/index.d.ts +394 -0
- package/types/render/CommandBuffer.d.ts +169 -0
- package/types/render/RenderCommand.d.ts +312 -0
- package/types/render/RenderState.d.ts +279 -0
- package/types/render/RenderTarget.d.ts +254 -0
- package/types/render/ShaderProgram.d.ts +277 -0
- package/types/render/UnifiedRenderBridge.d.ts +143 -0
- package/types/render/WebGLBackend.d.ts +168 -0
- package/types/render/WebGPUBackend.d.ts +186 -0
- package/types/render/index.d.ts +141 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instrumentation.js - Auto-tracing Decorators and Wrappers
|
|
3
|
+
*
|
|
4
|
+
* Provides decorators and utilities for automatic instrumentation
|
|
5
|
+
* of functions, classes, and async operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { SpanStatus } from './TelemetryService.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Default telemetry service reference (set via configure)
|
|
12
|
+
* @type {object|null}
|
|
13
|
+
*/
|
|
14
|
+
let defaultTelemetry = null;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Configure the default telemetry service
|
|
18
|
+
* @param {object} telemetryService
|
|
19
|
+
*/
|
|
20
|
+
export function configureTelemetry(telemetryService) {
|
|
21
|
+
defaultTelemetry = telemetryService;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the current telemetry service
|
|
26
|
+
*/
|
|
27
|
+
export function getTelemetry() {
|
|
28
|
+
return defaultTelemetry;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Trace decorator factory for methods
|
|
33
|
+
*
|
|
34
|
+
* Usage:
|
|
35
|
+
* class MyClass {
|
|
36
|
+
* @trace('myOperation')
|
|
37
|
+
* async doSomething() { ... }
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* @param {string} spanName - Name for the span
|
|
41
|
+
* @param {object} options - Tracing options
|
|
42
|
+
*/
|
|
43
|
+
export function trace(spanName, options = {}) {
|
|
44
|
+
return function(target, propertyKey, descriptor) {
|
|
45
|
+
const originalMethod = descriptor.value;
|
|
46
|
+
const name = spanName || `${target.constructor?.name}.${propertyKey}`;
|
|
47
|
+
|
|
48
|
+
descriptor.value = function(...args) {
|
|
49
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
50
|
+
if (!telemetry) {
|
|
51
|
+
return originalMethod.apply(this, args);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const attributes = {
|
|
55
|
+
'code.function': propertyKey,
|
|
56
|
+
'code.namespace': target.constructor?.name,
|
|
57
|
+
...options.attributes
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Add argument info if enabled
|
|
61
|
+
if (options.traceArgs) {
|
|
62
|
+
attributes['code.args.count'] = args.length;
|
|
63
|
+
if (options.traceArgValues) {
|
|
64
|
+
args.forEach((arg, i) => {
|
|
65
|
+
attributes[`code.args.${i}`] = summarizeValue(arg);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const span = telemetry.startSpan(name, attributes);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const result = originalMethod.apply(this, args);
|
|
74
|
+
|
|
75
|
+
// Handle promises
|
|
76
|
+
if (result && typeof result.then === 'function') {
|
|
77
|
+
return result.then(
|
|
78
|
+
(value) => {
|
|
79
|
+
if (options.traceResult) {
|
|
80
|
+
telemetry.addSpanEvent(span.spanId, 'result', {
|
|
81
|
+
value: summarizeValue(value)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
85
|
+
return value;
|
|
86
|
+
},
|
|
87
|
+
(error) => {
|
|
88
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
89
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR, error.message);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Sync result
|
|
96
|
+
if (options.traceResult) {
|
|
97
|
+
telemetry.addSpanEvent(span.spanId, 'result', {
|
|
98
|
+
value: summarizeValue(result)
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
102
|
+
return result;
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
106
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR, error.message);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return descriptor;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Wrap a function with tracing
|
|
117
|
+
*
|
|
118
|
+
* Usage:
|
|
119
|
+
* const tracedFn = traceFunction(myFunction, 'myOperation');
|
|
120
|
+
*
|
|
121
|
+
* @param {Function} fn - Function to wrap
|
|
122
|
+
* @param {string} name - Span name
|
|
123
|
+
* @param {object} options - Tracing options
|
|
124
|
+
*/
|
|
125
|
+
export function traceFunction(fn, name, options = {}) {
|
|
126
|
+
const spanName = name || fn.name || 'anonymous';
|
|
127
|
+
|
|
128
|
+
return function tracedFunction(...args) {
|
|
129
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
130
|
+
if (!telemetry) {
|
|
131
|
+
return fn.apply(this, args);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const attributes = {
|
|
135
|
+
'code.function': fn.name || 'anonymous',
|
|
136
|
+
...options.attributes
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const span = telemetry.startSpan(spanName, attributes);
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const result = fn.apply(this, args);
|
|
143
|
+
|
|
144
|
+
if (result && typeof result.then === 'function') {
|
|
145
|
+
return result.then(
|
|
146
|
+
(value) => {
|
|
147
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
148
|
+
return value;
|
|
149
|
+
},
|
|
150
|
+
(error) => {
|
|
151
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
152
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
159
|
+
return result;
|
|
160
|
+
|
|
161
|
+
} catch (error) {
|
|
162
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
163
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Trace async generator/iterator
|
|
171
|
+
*
|
|
172
|
+
* @param {AsyncIterable} iterable - Async iterable to trace
|
|
173
|
+
* @param {string} name - Span name
|
|
174
|
+
* @param {object} options - Options
|
|
175
|
+
*/
|
|
176
|
+
export async function* traceAsyncIterable(iterable, name, options = {}) {
|
|
177
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
178
|
+
if (!telemetry) {
|
|
179
|
+
yield* iterable;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const span = telemetry.startSpan(name, {
|
|
184
|
+
'iteration.type': 'async',
|
|
185
|
+
...options.attributes
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
let count = 0;
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
for await (const item of iterable) {
|
|
192
|
+
count++;
|
|
193
|
+
if (options.traceItems) {
|
|
194
|
+
telemetry.addSpanEvent(span.spanId, 'yield', {
|
|
195
|
+
index: count,
|
|
196
|
+
value: summarizeValue(item)
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
yield item;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
telemetry.setSpanAttribute(span.spanId, 'iteration.count', count);
|
|
203
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
204
|
+
|
|
205
|
+
} catch (error) {
|
|
206
|
+
telemetry.setSpanAttribute(span.spanId, 'iteration.count', count);
|
|
207
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
208
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Instrument all methods of a class
|
|
215
|
+
*
|
|
216
|
+
* @param {Function} ClassConstructor - Class to instrument
|
|
217
|
+
* @param {object} options - Options
|
|
218
|
+
*/
|
|
219
|
+
export function instrumentClass(ClassConstructor, options = {}) {
|
|
220
|
+
const prototype = ClassConstructor.prototype;
|
|
221
|
+
const className = ClassConstructor.name;
|
|
222
|
+
const exclude = new Set(options.exclude || ['constructor']);
|
|
223
|
+
const include = options.include ? new Set(options.include) : null;
|
|
224
|
+
|
|
225
|
+
// Get all method names
|
|
226
|
+
const methodNames = Object.getOwnPropertyNames(prototype)
|
|
227
|
+
.filter(name => {
|
|
228
|
+
if (exclude.has(name)) return false;
|
|
229
|
+
if (include && !include.has(name)) return false;
|
|
230
|
+
const desc = Object.getOwnPropertyDescriptor(prototype, name);
|
|
231
|
+
return typeof desc?.value === 'function';
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Wrap each method
|
|
235
|
+
for (const methodName of methodNames) {
|
|
236
|
+
const original = prototype[methodName];
|
|
237
|
+
const spanName = options.namePrefix
|
|
238
|
+
? `${options.namePrefix}.${methodName}`
|
|
239
|
+
: `${className}.${methodName}`;
|
|
240
|
+
|
|
241
|
+
prototype[methodName] = traceFunction(original, spanName, {
|
|
242
|
+
...options,
|
|
243
|
+
attributes: {
|
|
244
|
+
'code.class': className,
|
|
245
|
+
'code.method': methodName,
|
|
246
|
+
...options.attributes
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return ClassConstructor;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Create a traced proxy around an object
|
|
256
|
+
*
|
|
257
|
+
* @param {object} target - Object to proxy
|
|
258
|
+
* @param {string} name - Base name for spans
|
|
259
|
+
* @param {object} options - Options
|
|
260
|
+
*/
|
|
261
|
+
export function traceObject(target, name, options = {}) {
|
|
262
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
263
|
+
|
|
264
|
+
return new Proxy(target, {
|
|
265
|
+
get(obj, prop) {
|
|
266
|
+
const value = obj[prop];
|
|
267
|
+
|
|
268
|
+
if (typeof value !== 'function') {
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Return traced function
|
|
273
|
+
return function(...args) {
|
|
274
|
+
if (!telemetry) {
|
|
275
|
+
return value.apply(obj, args);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const spanName = `${name}.${String(prop)}`;
|
|
279
|
+
const span = telemetry.startSpan(spanName, {
|
|
280
|
+
'code.function': String(prop),
|
|
281
|
+
...options.attributes
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
const result = value.apply(obj, args);
|
|
286
|
+
|
|
287
|
+
if (result && typeof result.then === 'function') {
|
|
288
|
+
return result.then(
|
|
289
|
+
(v) => {
|
|
290
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
291
|
+
return v;
|
|
292
|
+
},
|
|
293
|
+
(e) => {
|
|
294
|
+
telemetry.recordSpanError(span.spanId, e);
|
|
295
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
296
|
+
throw e;
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
telemetry.endSpan(span.spanId, SpanStatus.OK);
|
|
302
|
+
return result;
|
|
303
|
+
|
|
304
|
+
} catch (error) {
|
|
305
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
306
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
307
|
+
throw error;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Timing wrapper - measures execution time without full tracing
|
|
316
|
+
*
|
|
317
|
+
* @param {Function} fn - Function to time
|
|
318
|
+
* @param {Function} callback - Called with duration in ms
|
|
319
|
+
*/
|
|
320
|
+
export function withTiming(fn, callback) {
|
|
321
|
+
return function(...args) {
|
|
322
|
+
const start = performance.now();
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
const result = fn.apply(this, args);
|
|
326
|
+
|
|
327
|
+
if (result && typeof result.then === 'function') {
|
|
328
|
+
return result.then(
|
|
329
|
+
(value) => {
|
|
330
|
+
callback(performance.now() - start, null, value);
|
|
331
|
+
return value;
|
|
332
|
+
},
|
|
333
|
+
(error) => {
|
|
334
|
+
callback(performance.now() - start, error, null);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
callback(performance.now() - start, null, result);
|
|
341
|
+
return result;
|
|
342
|
+
|
|
343
|
+
} catch (error) {
|
|
344
|
+
callback(performance.now() - start, error, null);
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Meter decorator for counting invocations
|
|
352
|
+
*
|
|
353
|
+
* @param {string} metricName - Metric name
|
|
354
|
+
* @param {object} options - Options
|
|
355
|
+
*/
|
|
356
|
+
export function meter(metricName, options = {}) {
|
|
357
|
+
return function(target, propertyKey, descriptor) {
|
|
358
|
+
const originalMethod = descriptor.value;
|
|
359
|
+
let count = 0;
|
|
360
|
+
let errors = 0;
|
|
361
|
+
let totalDuration = 0;
|
|
362
|
+
|
|
363
|
+
descriptor.value = function(...args) {
|
|
364
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
365
|
+
const start = performance.now();
|
|
366
|
+
count++;
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
const result = originalMethod.apply(this, args);
|
|
370
|
+
|
|
371
|
+
if (result && typeof result.then === 'function') {
|
|
372
|
+
return result.then(
|
|
373
|
+
(value) => {
|
|
374
|
+
totalDuration += performance.now() - start;
|
|
375
|
+
recordMetrics();
|
|
376
|
+
return value;
|
|
377
|
+
},
|
|
378
|
+
(error) => {
|
|
379
|
+
errors++;
|
|
380
|
+
totalDuration += performance.now() - start;
|
|
381
|
+
recordMetrics();
|
|
382
|
+
throw error;
|
|
383
|
+
}
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
totalDuration += performance.now() - start;
|
|
388
|
+
recordMetrics();
|
|
389
|
+
return result;
|
|
390
|
+
|
|
391
|
+
} catch (error) {
|
|
392
|
+
errors++;
|
|
393
|
+
totalDuration += performance.now() - start;
|
|
394
|
+
recordMetrics();
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function recordMetrics() {
|
|
399
|
+
if (telemetry?.recordEvent) {
|
|
400
|
+
telemetry.recordEvent('meter', {
|
|
401
|
+
metric: metricName,
|
|
402
|
+
count,
|
|
403
|
+
errors,
|
|
404
|
+
errorRate: count > 0 ? errors / count : 0,
|
|
405
|
+
totalDurationMs: totalDuration,
|
|
406
|
+
avgDurationMs: count > 0 ? totalDuration / count : 0
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
// Expose metrics
|
|
413
|
+
descriptor.value.getMetrics = () => ({
|
|
414
|
+
count,
|
|
415
|
+
errors,
|
|
416
|
+
errorRate: count > 0 ? errors / count : 0,
|
|
417
|
+
totalDurationMs: totalDuration,
|
|
418
|
+
avgDurationMs: count > 0 ? totalDuration / count : 0
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
return descriptor;
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Batch multiple operations into a single span
|
|
427
|
+
*
|
|
428
|
+
* @param {string} name - Batch span name
|
|
429
|
+
* @param {Function} fn - Async function that performs batch operations
|
|
430
|
+
* @param {object} options - Options
|
|
431
|
+
*/
|
|
432
|
+
export async function traceBatch(name, fn, options = {}) {
|
|
433
|
+
const telemetry = options.telemetry || defaultTelemetry;
|
|
434
|
+
if (!telemetry) {
|
|
435
|
+
return fn();
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const span = telemetry.startSpan(name, {
|
|
439
|
+
'batch.type': 'grouped',
|
|
440
|
+
...options.attributes
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
const operations = [];
|
|
444
|
+
|
|
445
|
+
// Create context for batch
|
|
446
|
+
const ctx = {
|
|
447
|
+
/**
|
|
448
|
+
* Add operation to batch
|
|
449
|
+
*/
|
|
450
|
+
operation(opName, opFn) {
|
|
451
|
+
operations.push({ name: opName, fn: opFn });
|
|
452
|
+
},
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Record progress
|
|
456
|
+
*/
|
|
457
|
+
progress(current, total) {
|
|
458
|
+
telemetry.addSpanEvent(span.spanId, 'progress', {
|
|
459
|
+
current,
|
|
460
|
+
total,
|
|
461
|
+
percentage: total > 0 ? (current / total * 100).toFixed(1) : 0
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
// Execute the batch setup
|
|
468
|
+
await fn(ctx);
|
|
469
|
+
|
|
470
|
+
// Execute all operations
|
|
471
|
+
telemetry.setSpanAttribute(span.spanId, 'batch.operation_count', operations.length);
|
|
472
|
+
|
|
473
|
+
let completed = 0;
|
|
474
|
+
let failed = 0;
|
|
475
|
+
|
|
476
|
+
for (const op of operations) {
|
|
477
|
+
try {
|
|
478
|
+
await op.fn();
|
|
479
|
+
completed++;
|
|
480
|
+
telemetry.addSpanEvent(span.spanId, 'operation_complete', {
|
|
481
|
+
name: op.name,
|
|
482
|
+
index: completed
|
|
483
|
+
});
|
|
484
|
+
} catch (err) {
|
|
485
|
+
failed++;
|
|
486
|
+
telemetry.addSpanEvent(span.spanId, 'operation_failed', {
|
|
487
|
+
name: op.name,
|
|
488
|
+
error: err.message
|
|
489
|
+
});
|
|
490
|
+
if (!options.continueOnError) throw err;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
telemetry.setSpanAttribute(span.spanId, 'batch.completed', completed);
|
|
495
|
+
telemetry.setSpanAttribute(span.spanId, 'batch.failed', failed);
|
|
496
|
+
telemetry.endSpan(span.spanId, failed > 0 ? SpanStatus.ERROR : SpanStatus.OK);
|
|
497
|
+
|
|
498
|
+
return { completed, failed };
|
|
499
|
+
|
|
500
|
+
} catch (error) {
|
|
501
|
+
telemetry.recordSpanError(span.spanId, error);
|
|
502
|
+
telemetry.endSpan(span.spanId, SpanStatus.ERROR);
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Context manager for scoped tracing
|
|
509
|
+
*/
|
|
510
|
+
export class TraceContext {
|
|
511
|
+
constructor(name, options = {}) {
|
|
512
|
+
this.name = name;
|
|
513
|
+
this.options = options;
|
|
514
|
+
this.telemetry = options.telemetry || defaultTelemetry;
|
|
515
|
+
this.span = null;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Enter context (start span)
|
|
520
|
+
*/
|
|
521
|
+
enter() {
|
|
522
|
+
if (this.telemetry) {
|
|
523
|
+
this.span = this.telemetry.startSpan(this.name, this.options.attributes);
|
|
524
|
+
}
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Add event to current span
|
|
530
|
+
*/
|
|
531
|
+
event(name, attributes = {}) {
|
|
532
|
+
if (this.span && this.telemetry) {
|
|
533
|
+
this.telemetry.addSpanEvent(this.span.spanId, name, attributes);
|
|
534
|
+
}
|
|
535
|
+
return this;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Set attribute on current span
|
|
540
|
+
*/
|
|
541
|
+
setAttribute(key, value) {
|
|
542
|
+
if (this.span && this.telemetry) {
|
|
543
|
+
this.telemetry.setSpanAttribute(this.span.spanId, key, value);
|
|
544
|
+
}
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Exit context (end span)
|
|
550
|
+
*/
|
|
551
|
+
exit(status = SpanStatus.OK, message) {
|
|
552
|
+
if (this.span && this.telemetry) {
|
|
553
|
+
this.telemetry.endSpan(this.span.spanId, status, message);
|
|
554
|
+
}
|
|
555
|
+
return this;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Exit with error
|
|
560
|
+
*/
|
|
561
|
+
error(err) {
|
|
562
|
+
if (this.span && this.telemetry) {
|
|
563
|
+
this.telemetry.recordSpanError(this.span.spanId, err);
|
|
564
|
+
this.telemetry.endSpan(this.span.spanId, SpanStatus.ERROR, err.message);
|
|
565
|
+
}
|
|
566
|
+
return this;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Helper to summarize a value for logging
|
|
572
|
+
* @private
|
|
573
|
+
*/
|
|
574
|
+
function summarizeValue(value, maxLength = 100) {
|
|
575
|
+
if (value === null) return 'null';
|
|
576
|
+
if (value === undefined) return 'undefined';
|
|
577
|
+
|
|
578
|
+
const type = typeof value;
|
|
579
|
+
|
|
580
|
+
if (type === 'string') {
|
|
581
|
+
return value.length > maxLength
|
|
582
|
+
? value.substring(0, maxLength) + '...'
|
|
583
|
+
: value;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
if (type === 'number' || type === 'boolean') {
|
|
587
|
+
return String(value);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (Array.isArray(value)) {
|
|
591
|
+
return `Array(${value.length})`;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (type === 'object') {
|
|
595
|
+
const name = value.constructor?.name || 'Object';
|
|
596
|
+
return `${name}{}`;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (type === 'function') {
|
|
600
|
+
return `Function(${value.name || 'anonymous'})`;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return String(value).substring(0, maxLength);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export default {
|
|
607
|
+
configureTelemetry,
|
|
608
|
+
getTelemetry,
|
|
609
|
+
trace,
|
|
610
|
+
traceFunction,
|
|
611
|
+
traceAsyncIterable,
|
|
612
|
+
instrumentClass,
|
|
613
|
+
traceObject,
|
|
614
|
+
withTiming,
|
|
615
|
+
meter,
|
|
616
|
+
traceBatch,
|
|
617
|
+
TraceContext
|
|
618
|
+
};
|