@downdraft/engine 0.0.0 → 0.1.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/README.md +33 -0
- package/app/src/index.ts +10 -0
- package/app/src/renderer/bootstrap.ts +271 -0
- package/app/src/renderer/downdraft-base.css +93 -0
- package/app/src/renderer/feature-log.ts +200 -0
- package/app/src/renderer/game-module.ts +923 -0
- package/app/src/renderer/hooks.ts +88 -0
- package/app/src/renderer/hot-reload.ts +178 -0
- package/app/src/renderer/import-cache.ts +88 -0
- package/app/src/renderer/index.ts +206 -0
- package/app/src/renderer/mcp-harness.ts +144 -0
- package/app/src/renderer/save-store-factory.ts +239 -0
- package/app/src/renderer/sim-bridge.ts +183 -0
- package/app/src/renderer/standard-automation-tools.ts +771 -0
- package/app/src/shared/feature-log.ts +71 -0
- package/app/src/shared/gpu-info.ts +82 -0
- package/app/src/shared/import-cache-store.ts +142 -0
- package/app/src/shared/index.ts +6 -0
- package/app/src/shared/mcp-discovery.ts +47 -0
- package/app/src/shared/mcp-proxy.ts +82 -0
- package/app/src/shared/types.ts +324 -0
- package/asset-bake/src/bake-audio.ts +119 -0
- package/asset-bake/src/bake-gltf.ts +172 -0
- package/asset-bake/src/bake.ts +78 -0
- package/asset-bake/src/cache.ts +188 -0
- package/asset-bake/src/config.ts +186 -0
- package/asset-bake/src/index.ts +36 -0
- package/core/src/animation/animation-event.ts +41 -0
- package/core/src/animation/bone-mask.ts +122 -0
- package/core/src/animation/clip.ts +252 -0
- package/core/src/animation/index.ts +22 -0
- package/core/src/animation/mixamo.ts +113 -0
- package/core/src/animation/morph-target.ts +69 -0
- package/core/src/animation/player.ts +697 -0
- package/core/src/animation/retarget.ts +158 -0
- package/core/src/animation/skeleton-animator.ts +1399 -0
- package/core/src/animation/skeleton.ts +214 -0
- package/core/src/animation/state-machine.ts +280 -0
- package/core/src/assets/blob-store.ts +66 -0
- package/core/src/assets/cache.ts +186 -0
- package/core/src/assets/cubemap-converter.ts +155 -0
- package/core/src/assets/environment-manager.ts +121 -0
- package/core/src/assets/import-cache.ts +65 -0
- package/core/src/assets/import-settings.ts +72 -0
- package/core/src/assets/importer.ts +108 -0
- package/core/src/assets/index.ts +74 -0
- package/core/src/assets/irradiance-generator.ts +198 -0
- package/core/src/assets/loader-audio.ts +86 -0
- package/core/src/assets/loader-cubemap.ts +211 -0
- package/core/src/assets/loader-dds.ts +236 -0
- package/core/src/assets/loader-hdr.ts +474 -0
- package/core/src/assets/loader-mesh.ts +143 -0
- package/core/src/assets/loader-shader.ts +73 -0
- package/core/src/assets/loader-texture.ts +349 -0
- package/core/src/assets/lod.ts +198 -0
- package/core/src/assets/manager.ts +480 -0
- package/core/src/assets/manifest.ts +81 -0
- package/core/src/assets/material-bridge.ts +186 -0
- package/core/src/assets/model-importer.ts +72 -0
- package/core/src/assets/model-normalizer.ts +248 -0
- package/core/src/assets/model-to-gpu.ts +70 -0
- package/core/src/assets/model-to-mesh.ts +237 -0
- package/core/src/assets/prefilter-generator.ts +250 -0
- package/core/src/audio/engine.ts +177 -0
- package/core/src/audio/interface.ts +130 -0
- package/core/src/audio/listener.ts +32 -0
- package/core/src/audio/mixer.ts +141 -0
- package/core/src/audio/registry.ts +52 -0
- package/core/src/audio/sab.ts +87 -0
- package/core/src/audio/source.ts +89 -0
- package/core/src/change-detection/atomics.ts +1 -0
- package/core/src/change-detection/tracker.ts +47 -0
- package/core/src/debug-draw/lines.ts +64 -0
- package/core/src/debug-draw/points.ts +17 -0
- package/core/src/debug-draw/queue.ts +124 -0
- package/core/src/debug-draw/text.ts +25 -0
- package/core/src/ecs/archetype.ts +323 -0
- package/core/src/ecs/component.ts +188 -0
- package/core/src/ecs/entity.ts +25 -0
- package/core/src/ecs/events.ts +93 -0
- package/core/src/ecs/hierarchy.ts +124 -0
- package/core/src/ecs/hmr-swap-registry.ts +22 -0
- package/core/src/ecs/index.ts +25 -0
- package/core/src/ecs/query.ts +141 -0
- package/core/src/ecs/resource.ts +8 -0
- package/core/src/ecs/schedule.ts +181 -0
- package/core/src/ecs/system-params.ts +99 -0
- package/core/src/ecs/system.ts +42 -0
- package/core/src/ecs/world.ts +348 -0
- package/core/src/index.ts +352 -0
- package/core/src/input/context.ts +73 -0
- package/core/src/input/dom-handler.ts +380 -0
- package/core/src/input/local-player-manager.ts +218 -0
- package/core/src/input/mapping.ts +40 -0
- package/core/src/input/multi-sab-bridge.ts +276 -0
- package/core/src/input/multi-state.ts +54 -0
- package/core/src/input/sab-bridge.ts +71 -0
- package/core/src/input/state.ts +132 -0
- package/core/src/input/ui-router.ts +87 -0
- package/core/src/library/host.ts +317 -0
- package/core/src/library/index.ts +16 -0
- package/core/src/library/library.ts +292 -0
- package/core/src/material/compiler.ts +80 -0
- package/core/src/material/graph-bridge.ts +172 -0
- package/core/src/material/index.ts +9 -0
- package/core/src/material/library.ts +442 -0
- package/core/src/material/material.ts +156 -0
- package/core/src/material/variants.ts +61 -0
- package/core/src/math/mat4.ts +202 -0
- package/core/src/math/perlin-noise-2d.ts +77 -0
- package/core/src/math/perlin-noise-3d.ts +110 -0
- package/core/src/math/quat.ts +33 -0
- package/core/src/math/rng.ts +29 -0
- package/core/src/math/trig.ts +47 -0
- package/core/src/math/value-noise.ts +67 -0
- package/core/src/mesh/builder.ts +177 -0
- package/core/src/mesh/csg.ts +312 -0
- package/core/src/mesh/greased-line.ts +145 -0
- package/core/src/mesh/mesh.ts +17 -0
- package/core/src/mesh/parametric.ts +501 -0
- package/core/src/mesh/skinning.ts +67 -0
- package/core/src/mesh/vertex-layout.ts +91 -0
- package/core/src/module/cross-thread.ts +163 -0
- package/core/src/module/diagnostics.ts +123 -0
- package/core/src/module/host.ts +451 -0
- package/core/src/module/index.ts +22 -0
- package/core/src/module/module.ts +109 -0
- package/core/src/module/registry.ts +94 -0
- package/core/src/module/renderer-module.ts +247 -0
- package/core/src/module/ts-loader.ts +26 -0
- package/core/src/particles/compute-pass.ts +378 -0
- package/core/src/particles/emitter.ts +156 -0
- package/core/src/particles/index.ts +11 -0
- package/core/src/particles/particle-data.ts +47 -0
- package/core/src/particles/render-pass.ts +365 -0
- package/core/src/particles/simulator.ts +264 -0
- package/core/src/particles/system.ts +193 -0
- package/core/src/physics/body.ts +59 -0
- package/core/src/physics/ccd-heuristic.ts +55 -0
- package/core/src/physics/character.ts +282 -0
- package/core/src/physics/collider.ts +55 -0
- package/core/src/physics/collision-system.ts +91 -0
- package/core/src/physics/events.ts +133 -0
- package/core/src/physics/index.ts +34 -0
- package/core/src/physics/interface.ts +473 -0
- package/core/src/physics/interpolation-buffer.ts +192 -0
- package/core/src/physics/lifecycle.ts +87 -0
- package/core/src/physics/load-shedder.ts +164 -0
- package/core/src/physics/physics-accumulator.ts +101 -0
- package/core/src/physics/physics-system.ts +240 -0
- package/core/src/physics/ragdoll-presets.ts +272 -0
- package/core/src/physics/ragdoll-system.ts +220 -0
- package/core/src/physics/ragdoll.ts +182 -0
- package/core/src/physics/raycast.ts +143 -0
- package/core/src/physics/realm-manager.ts +499 -0
- package/core/src/physics/realm-worker-pool.ts +191 -0
- package/core/src/physics/realm-worker.ts +102 -0
- package/core/src/physics/realm.ts +189 -0
- package/core/src/physics/registry.ts +52 -0
- package/core/src/physics/safety.ts +247 -0
- package/core/src/physics/snapshot-manager.ts +141 -0
- package/core/src/physics/worker-protocol.ts +30 -0
- package/core/src/platform/bun-preload.ts +169 -0
- package/core/src/platform/css-stub.ts +4 -0
- package/core/src/platform/glob-polyfill.ts +124 -0
- package/core/src/platform/hidpi.ts +57 -0
- package/core/src/platform/render-surface.ts +77 -0
- package/core/src/platform/rpc.ts +98 -0
- package/core/src/platform/runtime.ts +132 -0
- package/core/src/plugin/context.ts +364 -0
- package/core/src/plugin/diagnostics.ts +61 -0
- package/core/src/plugin/discovery.ts +186 -0
- package/core/src/plugin/extension-loaders.ts +172 -0
- package/core/src/plugin/host.ts +659 -0
- package/core/src/plugin/index.ts +106 -0
- package/core/src/plugin/loader-asset.ts +124 -0
- package/core/src/plugin/loader-quickjs.ts +84 -0
- package/core/src/plugin/loader-wasm.ts +411 -0
- package/core/src/plugin/loader-worker.ts +261 -0
- package/core/src/plugin/manifest.ts +653 -0
- package/core/src/plugin/material-registry.ts +65 -0
- package/core/src/plugin/mcp-tools.ts +165 -0
- package/core/src/plugin/permissions.ts +175 -0
- package/core/src/plugin/quickjs-bridge.ts +294 -0
- package/core/src/plugin/registry.ts +107 -0
- package/core/src/plugin/sandbox-shim.ts +86 -0
- package/core/src/plugin/sandbox-worker.ts +215 -0
- package/core/src/plugin/wasm-abi.ts +152 -0
- package/core/src/plugin/wasm-worker.ts +229 -0
- package/core/src/plugin/workshop.ts +169 -0
- package/core/src/profiling/event-loop.ts +180 -0
- package/core/src/profiling/index.ts +69 -0
- package/core/src/profiling/iops/idb-patch.ts +242 -0
- package/core/src/profiling/iops/opfs-patch.ts +276 -0
- package/core/src/profiling/profiling-sab.ts +839 -0
- package/core/src/profiling/task-latency.ts +134 -0
- package/core/src/profiling/thread-metrics.ts +126 -0
- package/core/src/profiling/trace-event-writer.ts +205 -0
- package/core/src/profiling/warnings.ts +423 -0
- package/core/src/profiling/worker-prelude.ts +376 -0
- package/core/src/render/bind-group.ts +38 -0
- package/core/src/render/bindless/bindless-struct.ts +42 -0
- package/core/src/render/bindless/bindless.wgsl.ts +167 -0
- package/core/src/render/bindless/frame-bindings.ts +176 -0
- package/core/src/render/bindless/index.ts +10 -0
- package/core/src/render/bindless/material-manager.ts +257 -0
- package/core/src/render/bindless/texture-registry.ts +609 -0
- package/core/src/render/buffer.ts +82 -0
- package/core/src/render/camera-2d.ts +217 -0
- package/core/src/render/camera-controller.ts +440 -0
- package/core/src/render/camera.ts +409 -0
- package/core/src/render/canvas-resize-watcher.ts +46 -0
- package/core/src/render/compute-kernel.ts +172 -0
- package/core/src/render/constants.ts +2 -0
- package/core/src/render/device.ts +111 -0
- package/core/src/render/frame-graph.ts +768 -0
- package/core/src/render/frustum.ts +185 -0
- package/core/src/render/fullscreen-vs.ts +25 -0
- package/core/src/render/g-buffer.ts +186 -0
- package/core/src/render/game-renderer.ts +1452 -0
- package/core/src/render/gpu-driven/cull-pass.ts +394 -0
- package/core/src/render/gpu-driven/hzb.ts +215 -0
- package/core/src/render/gpu-driven/index.ts +7 -0
- package/core/src/render/gpu-driven/indirect-draw-pass.ts +324 -0
- package/core/src/render/gpu-driven/instance-buffer.ts +178 -0
- package/core/src/render/gpu-driven/mesh-table.ts +175 -0
- package/core/src/render/gpu-driven/passes/hzb-build-pass.ts +47 -0
- package/core/src/render/gpu-utils.ts +96 -0
- package/core/src/render/hdr.ts +88 -0
- package/core/src/render/hot-reload.ts +295 -0
- package/core/src/render/ibl-bind-group.ts +266 -0
- package/core/src/render/ibl.ts +180 -0
- package/core/src/render/index.ts +163 -0
- package/core/src/render/input-manager.ts +259 -0
- package/core/src/render/lighting/area-light.ts +196 -0
- package/core/src/render/lighting/cluster-grid.ts +288 -0
- package/core/src/render/lighting/cluster-types.ts +193 -0
- package/core/src/render/lighting/ies-parser.ts +162 -0
- package/core/src/render/lighting.ts +454 -0
- package/core/src/render/material-types/depth.wgsl +44 -0
- package/core/src/render/material-types/line.wgsl +50 -0
- package/core/src/render/material-types/matcap.wgsl +51 -0
- package/core/src/render/material-types/normal.wgsl +41 -0
- package/core/src/render/material-types/physical.wgsl +152 -0
- package/core/src/render/material-types/sprite.wgsl +46 -0
- package/core/src/render/material-types/sss.wgsl +79 -0
- package/core/src/render/material-types/toon.wgsl +79 -0
- package/core/src/render/passes/README.md +121 -0
- package/core/src/render/passes/atmosphere.ts +152 -0
- package/core/src/render/passes/cluster-lighting-pass.ts +476 -0
- package/core/src/render/passes/csm.ts +408 -0
- package/core/src/render/passes/cubemap-capture.ts +114 -0
- package/core/src/render/passes/debug-viz.ts +278 -0
- package/core/src/render/passes/debug.ts +538 -0
- package/core/src/render/passes/decal-mesh.ts +111 -0
- package/core/src/render/passes/decal-pass.ts +377 -0
- package/core/src/render/passes/deferred-lighting.ts +434 -0
- package/core/src/render/passes/depth-prepass.ts +163 -0
- package/core/src/render/passes/dome-360.ts +83 -0
- package/core/src/render/passes/fluid-render.ts +137 -0
- package/core/src/render/passes/gi-types.ts +118 -0
- package/core/src/render/passes/graph-compute.ts +300 -0
- package/core/src/render/passes/greased-line-pass.ts +232 -0
- package/core/src/render/passes/morph-target.ts +40 -0
- package/core/src/render/passes/opaque.ts +1028 -0
- package/core/src/render/passes/point-light-shadow.ts +266 -0
- package/core/src/render/passes/procedural-texture.ts +185 -0
- package/core/src/render/passes/reflection-probe.ts +140 -0
- package/core/src/render/passes/rsm-pass.ts +248 -0
- package/core/src/render/passes/sdf-text.ts +155 -0
- package/core/src/render/passes/shadow-map.ts +163 -0
- package/core/src/render/passes/shadow.ts +220 -0
- package/core/src/render/passes/skinning-vs.ts +121 -0
- package/core/src/render/passes/skinning.ts +326 -0
- package/core/src/render/passes/sky-dome.ts +404 -0
- package/core/src/render/passes/skybox.ts +162 -0
- package/core/src/render/passes/spot-light-shadow.ts +273 -0
- package/core/src/render/passes/terrain.ts +326 -0
- package/core/src/render/passes/transparent.ts +353 -0
- package/core/src/render/passes/underwater-fog.ts +185 -0
- package/core/src/render/passes/video-texture.ts +79 -0
- package/core/src/render/passes/volumetric-pass.ts +312 -0
- package/core/src/render/passes/volumetric-types.ts +171 -0
- package/core/src/render/passes/water.ts +753 -0
- package/core/src/render/pbr.ts +296 -0
- package/core/src/render/pipeline.ts +52 -0
- package/core/src/render/render-pass.ts +30 -0
- package/core/src/render/renderer-input-bus.ts +220 -0
- package/core/src/render/renderer-module-host.ts +623 -0
- package/core/src/render/resource-tracker.ts +67 -0
- package/core/src/render/sab-canvas-overlay.ts +122 -0
- package/core/src/render/shader-validator.ts +200 -0
- package/core/src/render/shaders/debug/debug-line.wgsl +27 -0
- package/core/src/render/shaders/debug/debug-point.wgsl +30 -0
- package/core/src/render/shaders/debug/debug-text.wgsl +42 -0
- package/core/src/render/shaders/debug-viz/aabb.wgsl +20 -0
- package/core/src/render/shaders/debug-viz/depth.wgsl +29 -0
- package/core/src/render/shaders/debug-viz/lod.wgsl +38 -0
- package/core/src/render/shaders/debug-viz/normals.wgsl +30 -0
- package/core/src/render/shaders/debug-viz/overdraw.wgsl +21 -0
- package/core/src/render/shaders/debug-viz/tangents.wgsl +29 -0
- package/core/src/render/shaders/debug-viz/wireframe.wgsl +33 -0
- package/core/src/render/shaders/shadow-chunks.ts +135 -0
- package/core/src/render/skybox.ts +146 -0
- package/core/src/render/splitscreen.ts +85 -0
- package/core/src/render/surface.ts +78 -0
- package/core/src/render/tonemap.ts +180 -0
- package/core/src/render/tracked-render-pass.ts +158 -0
- package/core/src/render/viewport.ts +109 -0
- package/core/src/render/wgsl-hmr.ts +70 -0
- package/core/src/sab/core-input-channel.ts +23 -0
- package/core/src/sab/define.ts +239 -0
- package/core/src/sab/errors.ts +76 -0
- package/core/src/sab/game-input.ts +343 -0
- package/core/src/sab/gamepad-devices.ts +259 -0
- package/core/src/sab/grid-buffer.ts +117 -0
- package/core/src/sab/input.ts +55 -0
- package/core/src/sab/layout.ts +219 -0
- package/core/src/sab/multi-input-channel.ts +50 -0
- package/core/src/sab/record-buffer.ts +155 -0
- package/core/src/sab/sab-polyfill.ts +56 -0
- package/core/src/sab/sim-channel.ts +453 -0
- package/core/src/sab/slot-buffer.ts +190 -0
- package/core/src/sab/types.ts +158 -0
- package/core/src/safety/bounds.ts +76 -0
- package/core/src/safety/json.ts +80 -0
- package/core/src/safety/path.ts +167 -0
- package/core/src/save/binary-format.ts +117 -0
- package/core/src/save/game-save-system.ts +161 -0
- package/core/src/save/grid-save-system.ts +158 -0
- package/core/src/save/migrate.ts +44 -0
- package/core/src/save/migration-registry.ts +94 -0
- package/core/src/save/persist-types.ts +208 -0
- package/core/src/save/schema.ts +46 -0
- package/core/src/save/serializer.ts +180 -0
- package/core/src/scene/builder.ts +65 -0
- package/core/src/scene/camera.ts +142 -0
- package/core/src/scene/checkpoint.ts +109 -0
- package/core/src/scene/game-loop.ts +198 -0
- package/core/src/scene/index.ts +24 -0
- package/core/src/scene/layer.ts +6 -0
- package/core/src/scene/prefab.ts +145 -0
- package/core/src/scene/scene-manager.ts +157 -0
- package/core/src/scene/scene.ts +192 -0
- package/core/src/scene/sky.ts +256 -0
- package/core/src/scene/spatial-grid.ts +176 -0
- package/core/src/scene/streaming.ts +304 -0
- package/core/src/scene/vegetation.ts +163 -0
- package/core/src/scene/world.ts +89 -0
- package/core/src/scripting/binding.ts +129 -0
- package/core/src/scripting/hot-reload.ts +144 -0
- package/core/src/scripting/script.ts +99 -0
- package/core/src/sim/hot-reload-pipeline.ts +49 -0
- package/core/src/sim/sim-state-helper.ts +47 -0
- package/core/src/sim/transient-state-registry.ts +77 -0
- package/core/src/sim/types.ts +113 -0
- package/core/src/sim/worker-loop.ts +222 -0
- package/core/src/stores/game-store.ts +158 -0
- package/core/src/stores/hot-reload-store.ts +44 -0
- package/core/src/telemetry/collector.ts +410 -0
- package/core/src/telemetry/gc-controller.ts +453 -0
- package/core/src/telemetry/gc-profiler.ts +126 -0
- package/core/src/telemetry/gc-tracker.ts +69 -0
- package/core/src/telemetry/gpu-profiler.ts +703 -0
- package/core/src/telemetry/gpu-resource-tracker.ts +285 -0
- package/core/src/telemetry/gpu-timer-pool.ts +234 -0
- package/core/src/telemetry/gpu-timer.ts +123 -0
- package/core/src/telemetry/gpu-timestamp-gate.ts +21 -0
- package/core/src/telemetry/reporter.ts +62 -0
- package/core/src/types/engine-types.ts +129 -0
- package/core/src/ui-font-scale.ts +112 -0
- package/core/src/util/broad-phase-grid.ts +82 -0
- package/core/src/util/feature-log.ts +220 -0
- package/core/src/util/index.ts +17 -0
- package/core/src/util/logger.ts +604 -0
- package/core/src/webgpu-destroy-augmentation.d.ts +25 -0
- package/core/src/worker/base-worker-host.ts +183 -0
- package/core/src/worker/buffer-sync.ts +550 -0
- package/core/src/worker/crash-recovery.ts +201 -0
- package/core/src/worker/entity-sim-worker-host.ts +190 -0
- package/core/src/worker/instrumented-worker-host.ts +171 -0
- package/core/src/worker/rpc.ts +253 -0
- package/core/src/worker/sim-worker-base.ts +913 -0
- package/core/src/worker/sim-worker-host.ts +358 -0
- package/core/src/worker/task-pool.ts +256 -0
- package/core/src/worker/task-worker.ts +83 -0
- package/libraries/asset-browser/src/index.ts +11 -0
- package/libraries/asset-browser/src/software-thumbnails.ts +949 -0
- package/libraries/audio-kira/README.md +17 -0
- package/libraries/audio-kira/native/Cargo.toml +14 -0
- package/libraries/audio-kira/native/src/engine.rs +27 -0
- package/libraries/audio-kira/native/src/lib.rs +185 -0
- package/libraries/audio-kira/native/src/mixer.rs +11 -0
- package/libraries/audio-kira/native/src/source.rs +80 -0
- package/libraries/audio-kira/src/backend.ts +469 -0
- package/libraries/audio-kira/src/index.ts +8 -0
- package/libraries/audio-kira/src/library.ts +82 -0
- package/libraries/blitz-ui/native/Cargo.toml +33 -0
- package/libraries/blitz-ui/native/assets/DejaVuSans.woff2 +0 -0
- package/libraries/blitz-ui/native/src/bridge.rs +100 -0
- package/libraries/blitz-ui/native/src/fonts.rs +20 -0
- package/libraries/blitz-ui/native/src/input.rs +80 -0
- package/libraries/blitz-ui/native/src/lib.rs +96 -0
- package/libraries/blitz-ui/native/src/shell.rs +301 -0
- package/libraries/blitz-ui/native-osr/Cargo.toml +24 -0
- package/libraries/blitz-ui/native-osr/src/events.rs +237 -0
- package/libraries/blitz-ui/native-osr/src/lib.rs +846 -0
- package/libraries/blitz-ui/native-osr/src/mutate.rs +385 -0
- package/libraries/blitz-ui/native-osr/src/resources.rs +45 -0
- package/libraries/blitz-ui/native-osr-spike.ts +70 -0
- package/libraries/blitz-ui/src/index.ts +15 -0
- package/libraries/blitz-ui/src/native-module.ts +221 -0
- package/libraries/blitz-ui/src/native-osr-ffi.ts +423 -0
- package/libraries/blitz-ui/src/router.ts +101 -0
- package/libraries/blitz-ui/src/shaders/ui-blit.wgsl.ts +35 -0
- package/libraries/blitz-ui/src/ui-blit-pass.ts +116 -0
- package/libraries/character/README.md +25 -0
- package/libraries/character/src/character-animator.ts +374 -0
- package/libraries/character/src/index.ts +24 -0
- package/libraries/character/src/loader.ts +375 -0
- package/libraries/character/src/locomotion.ts +124 -0
- package/libraries/character/src/preview.ts +287 -0
- package/libraries/devtools/README.md +51 -0
- package/libraries/devtools/native/Cargo.toml +12 -0
- package/libraries/devtools/native/src/lib.rs +1646 -0
- package/libraries/devtools/native/src/panels/console.rs +338 -0
- package/libraries/devtools/native/src/panels/dom_tree.rs +47 -0
- package/libraries/devtools/native/src/panels/generic.rs +317 -0
- package/libraries/devtools/native/src/panels/gpu.rs +107 -0
- package/libraries/devtools/native/src/panels/input.rs +88 -0
- package/libraries/devtools/native/src/panels/mod.rs +154 -0
- package/libraries/devtools/native/src/panels/perf_metrics.rs +91 -0
- package/libraries/devtools/native/src/panels/perf_recorder.rs +158 -0
- package/libraries/devtools/native/src/panels/scene.rs +72 -0
- package/libraries/devtools/native/src/state.rs +394 -0
- package/libraries/devtools/src/cdp-bridge.ts +349 -0
- package/libraries/devtools/src/collectors.ts +346 -0
- package/libraries/devtools/src/egui-ffi.ts +804 -0
- package/libraries/devtools/src/egui-renderer.ts +407 -0
- package/libraries/devtools/src/host.ts +363 -0
- package/libraries/devtools/src/index.ts +40 -0
- package/libraries/devtools/src/mirror.ts +794 -0
- package/libraries/devtools/src/native-providers.ts +744 -0
- package/libraries/devtools/src/verify.ts +167 -0
- package/libraries/devtools/src/web/browser.ts +102 -0
- package/libraries/devtools/src/web/host.ts +212 -0
- package/libraries/devtools/src/web/mirror.ts +430 -0
- package/libraries/devtools/src/web/server.ts +198 -0
- package/libraries/entities/README.md +17 -0
- package/libraries/entities/src/index.ts +4 -0
- package/libraries/entities/src/library.ts +64 -0
- package/libraries/entities/src/model-renderer.ts +1345 -0
- package/libraries/entities/src/shaders/model.wgsl +375 -0
- package/libraries/gamepad/src/feed-input.ts +83 -0
- package/libraries/gamepad/src/filters.ts +49 -0
- package/libraries/gamepad/src/glyphs.ts +93 -0
- package/libraries/gamepad/src/hub.ts +206 -0
- package/libraries/gamepad/src/index.ts +22 -0
- package/libraries/gamepad/src/library.ts +68 -0
- package/libraries/gamepad/src/source-sab.ts +70 -0
- package/libraries/gamepad/src/sysfs-enrich.ts +138 -0
- package/libraries/gaussian-splats/README.md +25 -0
- package/libraries/gaussian-splats/src/gpu-sort.ts +595 -0
- package/libraries/gaussian-splats/src/index.ts +31 -0
- package/libraries/gaussian-splats/src/library.ts +60 -0
- package/libraries/gaussian-splats/src/parser.ts +382 -0
- package/libraries/gaussian-splats/src/renderer.ts +427 -0
- package/libraries/gaussian-splats/src/sh-eval.ts +211 -0
- package/libraries/gaussian-splats/src/sorter.ts +110 -0
- package/libraries/gaussian-splats/src/tile-raster.ts +473 -0
- package/libraries/gpu-kernels/README.md +154 -0
- package/libraries/gpu-kernels/src/index.ts +11 -0
- package/libraries/gpu-kernels/src/kernel.ts +696 -0
- package/libraries/gpu-kernels/src/transpile.ts +958 -0
- package/libraries/html-ui-kit/src/behaviors.ts +250 -0
- package/libraries/html-ui-kit/src/components.ts +309 -0
- package/libraries/html-ui-kit/src/index.ts +30 -0
- package/libraries/html-ui-kit/src/nav/nav-controller.ts +238 -0
- package/libraries/html-ui-kit/src/nav/nav-input.ts +145 -0
- package/libraries/html-ui-kit/src/nav/osk.ts +153 -0
- package/libraries/html-ui-kit/src/nav/router.ts +167 -0
- package/libraries/html-ui-kit/src/nav/vcursor.ts +203 -0
- package/libraries/html-ui-kit/src/ten-foot.ts +182 -0
- package/libraries/html-ui-kit/src/theme.ts +238 -0
- package/libraries/lighting/README.md +20 -0
- package/libraries/lighting/src/index.ts +5 -0
- package/libraries/lighting/src/library.ts +66 -0
- package/libraries/lighting/src/light-system.ts +452 -0
- package/libraries/lighting/src/lighting-system.ts +68 -0
- package/libraries/lighting/src/shaders/light-debug.wgsl +30 -0
- package/libraries/marching-cubes/README.md +25 -0
- package/libraries/marching-cubes/src/chunked-field.ts +177 -0
- package/libraries/marching-cubes/src/deformation.ts +63 -0
- package/libraries/marching-cubes/src/generator.ts +407 -0
- package/libraries/marching-cubes/src/index.ts +32 -0
- package/libraries/marching-cubes/src/library.ts +80 -0
- package/libraries/marching-cubes/src/lod.ts +122 -0
- package/libraries/marching-cubes/src/marching-tetrahedra.ts +252 -0
- package/libraries/marching-cubes/src/sab.ts +45 -0
- package/libraries/marching-cubes/src/streaming-config.ts +48 -0
- package/libraries/marching-cubes/src/streaming-manager.ts +686 -0
- package/libraries/marching-cubes/src/tables.ts +323 -0
- package/libraries/marching-cubes/src/types.ts +18 -0
- package/libraries/models/README.md +25 -0
- package/libraries/models/src/bake-node-transforms.ts +171 -0
- package/libraries/models/src/codecs/basisu-codec.ts +180 -0
- package/libraries/models/src/codecs/draco-codec.ts +372 -0
- package/libraries/models/src/codecs/draco3dgltf.d.ts +40 -0
- package/libraries/models/src/codecs/index.ts +22 -0
- package/libraries/models/src/codecs/meshopt-codec.ts +91 -0
- package/libraries/models/src/codecs/registry.ts +221 -0
- package/libraries/models/src/dae.ts +753 -0
- package/libraries/models/src/default-part-selection.ts +56 -0
- package/libraries/models/src/dxf.ts +200 -0
- package/libraries/models/src/fbx/index.ts +457 -0
- package/libraries/models/src/fbx/interpreter/animation.ts +431 -0
- package/libraries/models/src/fbx/interpreter/blend-shapes.ts +323 -0
- package/libraries/models/src/fbx/interpreter/connections.ts +166 -0
- package/libraries/models/src/fbx/interpreter/diagnostics.ts +65 -0
- package/libraries/models/src/fbx/interpreter/geometry.ts +535 -0
- package/libraries/models/src/fbx/interpreter/global-settings.ts +92 -0
- package/libraries/models/src/fbx/interpreter/materials.ts +265 -0
- package/libraries/models/src/fbx/interpreter/nodes.ts +197 -0
- package/libraries/models/src/fbx/interpreter/skeleton.ts +476 -0
- package/libraries/models/src/fbx/parsers/binary-parser.ts +244 -0
- package/libraries/models/src/fbx/types.ts +119 -0
- package/libraries/models/src/gltf-extensions.ts +196 -0
- package/libraries/models/src/gltf.ts +935 -0
- package/libraries/models/src/index.ts +87 -0
- package/libraries/models/src/library.ts +75 -0
- package/libraries/models/src/loader.ts +265 -0
- package/libraries/models/src/material-adapter.ts +108 -0
- package/libraries/models/src/mini-xml.ts +174 -0
- package/libraries/models/src/normalize.ts +216 -0
- package/libraries/models/src/obj.ts +264 -0
- package/libraries/models/src/off.ts +95 -0
- package/libraries/models/src/ply.ts +348 -0
- package/libraries/models/src/pose-sampler.ts +219 -0
- package/libraries/models/src/sidecar/blender-extras.ts +37 -0
- package/libraries/models/src/sidecar/ddmeta.ts +114 -0
- package/libraries/models/src/sidecar/godot-import.ts +86 -0
- package/libraries/models/src/sidecar/resolver.ts +145 -0
- package/libraries/models/src/sidecar/types.ts +11 -0
- package/libraries/models/src/sidecar/unity-meta.ts +61 -0
- package/libraries/models/src/skeleton-synthesis.ts +132 -0
- package/libraries/models/src/stl.ts +149 -0
- package/libraries/models/src/threeds.ts +363 -0
- package/libraries/models/src/threemf.ts +201 -0
- package/libraries/models/src/types.ts +188 -0
- package/libraries/models/src/vtk.ts +218 -0
- package/libraries/models/test-fixtures/fbx/LICENSE-notice.txt +24 -0
- package/libraries/models/test-fixtures/fbx/README.md +46 -0
- package/libraries/models/test-fixtures/fbx/m01_cube_phong.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m02_geo_ngons.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m03_normals.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m04_material_properties.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m05_external_diffuse.png +0 -0
- package/libraries/models/test-fixtures/fbx/m05_textures.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m06_uv_transform.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m07_multimaterial.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m08_transforms.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m09_skinning.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m10_morph.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m11_node_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m12_skeletal_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m13_morph_anim.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m14_multiclip.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m15_camera_lights.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_axis_yup.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_axis_zup.fbx +0 -0
- package/libraries/models/test-fixtures/fbx/m16_units_254.fbx +0 -0
- package/libraries/navmesh/README.md +23 -0
- package/libraries/navmesh/src/crowd-system.ts +240 -0
- package/libraries/navmesh/src/debug-viz.ts +74 -0
- package/libraries/navmesh/src/index.ts +15 -0
- package/libraries/navmesh/src/library.ts +64 -0
- package/libraries/navmesh/src/navmesh-generator.ts +407 -0
- package/libraries/navmesh/src/navmesh.ts +159 -0
- package/libraries/navmesh/src/pathfinder.ts +252 -0
- package/libraries/navmesh/src/types.ts +63 -0
- package/libraries/networking/README.md +25 -0
- package/libraries/networking/src/authority.ts +121 -0
- package/libraries/networking/src/connection.ts +139 -0
- package/libraries/networking/src/discovery.ts +373 -0
- package/libraries/networking/src/enhanced-replication.ts +355 -0
- package/libraries/networking/src/epic-adapter.ts +129 -0
- package/libraries/networking/src/index.ts +45 -0
- package/libraries/networking/src/library.ts +69 -0
- package/libraries/networking/src/lobby.ts +108 -0
- package/libraries/networking/src/platform-adapter.ts +163 -0
- package/libraries/networking/src/rcs-adapter.ts +127 -0
- package/libraries/networking/src/remote-input.ts +188 -0
- package/libraries/networking/src/replication.ts +327 -0
- package/libraries/networking/src/rpc.ts +188 -0
- package/libraries/networking/src/session.ts +173 -0
- package/libraries/networking/src/transport.ts +201 -0
- package/libraries/networking/src/webrtc.ts +323 -0
- package/libraries/pathfinding-2d/README.md +15 -0
- package/libraries/pathfinding-2d/src/astar-grid.ts +312 -0
- package/libraries/pathfinding-2d/src/index.ts +11 -0
- package/libraries/persistence/README.md +25 -0
- package/libraries/persistence/src/autosave-manager.ts +112 -0
- package/libraries/persistence/src/binary-record-store.ts +244 -0
- package/libraries/persistence/src/browser.ts +51 -0
- package/libraries/persistence/src/file-save-store.ts +553 -0
- package/libraries/persistence/src/hash-utils.ts +59 -0
- package/libraries/persistence/src/index.ts +57 -0
- package/libraries/persistence/src/library.ts +74 -0
- package/libraries/persistence/src/mock-opfs.ts +141 -0
- package/libraries/persistence/src/node-fs-directory-handle.ts +161 -0
- package/libraries/persistence/src/opfs-save-store.ts +745 -0
- package/libraries/persistence/src/save-worker-proxy.ts +127 -0
- package/libraries/persistence/src/save-worker.ts +99 -0
- package/libraries/persistence/src/xxh3-ts.d.ts +10 -0
- package/libraries/physics-native/README.md +21 -0
- package/libraries/physics-native/native/Cargo.toml +11 -0
- package/libraries/physics-native/native/src/body.rs +403 -0
- package/libraries/physics-native/native/src/character.rs +226 -0
- package/libraries/physics-native/native/src/collider.rs +299 -0
- package/libraries/physics-native/native/src/joint.rs +81 -0
- package/libraries/physics-native/native/src/lib.rs +830 -0
- package/libraries/physics-native/native/src/query.rs +261 -0
- package/libraries/physics-native/native/src/realm.rs +33 -0
- package/libraries/physics-native/native/src/step.rs +54 -0
- package/libraries/physics-native/native/src/world.rs +148 -0
- package/libraries/physics-native/src/backend.ts +1046 -0
- package/libraries/physics-native/src/broadphase.ts +101 -0
- package/libraries/physics-native/src/ffi-spike-worker.ts +71 -0
- package/libraries/physics-native/src/index.ts +11 -0
- package/libraries/physics-native/src/library.ts +79 -0
- package/libraries/physics-native/src/narrowphase-shapes.ts +420 -0
- package/libraries/physics-native/src/narrowphase.ts +123 -0
- package/libraries/physics-native/src/solver.ts +141 -0
- package/libraries/physics-native/src/types.ts +76 -0
- package/libraries/physics-rapier/README.md +21 -0
- package/libraries/physics-rapier/bench/ffi-bench.ts +79 -0
- package/libraries/physics-rapier/bench/wasm-baseline.ts +90 -0
- package/libraries/physics-rapier/src/api.ts +452 -0
- package/libraries/physics-rapier/src/auto-backend.ts +59 -0
- package/libraries/physics-rapier/src/backend.ts +1207 -0
- package/libraries/physics-rapier/src/bulk-ops.ts +68 -0
- package/libraries/physics-rapier/src/ffi-backend.ts +21 -0
- package/libraries/physics-rapier/src/ffi-lib.ts +597 -0
- package/libraries/physics-rapier/src/index.ts +12 -0
- package/libraries/physics-rapier/src/library.ts +107 -0
- package/libraries/physics-rapier/src/rapier-backend.ts +1052 -0
- package/libraries/physics-rapier/src/realm-worker-script.ts +237 -0
- package/libraries/postfx/README.md +17 -0
- package/libraries/postfx/src/index.ts +19 -0
- package/libraries/postfx/src/library.ts +337 -0
- package/libraries/postfx/src/post-process-stack.ts +1752 -0
- package/libraries/postfx/src/shaders/post-process/afterimage.wgsl +14 -0
- package/libraries/postfx/src/shaders/post-process/ascii.wgsl +24 -0
- package/libraries/postfx/src/shaders/post-process/blit.wgsl +12 -0
- package/libraries/postfx/src/shaders/post-process/bloom-blur.wgsl +21 -0
- package/libraries/postfx/src/shaders/post-process/bloom-bright.wgsl +15 -0
- package/libraries/postfx/src/shaders/post-process/bloom-composite.wgsl +14 -0
- package/libraries/postfx/src/shaders/post-process/bloom-downsample.wgsl +60 -0
- package/libraries/postfx/src/shaders/post-process/bloom-soft.wgsl +46 -0
- package/libraries/postfx/src/shaders/post-process/bloom-upsample.wgsl +51 -0
- package/libraries/postfx/src/shaders/post-process/channel-mixer.wgsl +36 -0
- package/libraries/postfx/src/shaders/post-process/chromatic-aberration.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/dithering.wgsl +64 -0
- package/libraries/postfx/src/shaders/post-process/dof.wgsl +131 -0
- package/libraries/postfx/src/shaders/post-process/edges.wgsl +45 -0
- package/libraries/postfx/src/shaders/post-process/fullscreen-vs.wgsl +15 -0
- package/libraries/postfx/src/shaders/post-process/fxaa.wgsl +102 -0
- package/libraries/postfx/src/shaders/post-process/gaussian-blur.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/glow-blur.wgsl +33 -0
- package/libraries/postfx/src/shaders/post-process/glow-composite.wgsl +25 -0
- package/libraries/postfx/src/shaders/post-process/grain.wgsl +37 -0
- package/libraries/postfx/src/shaders/post-process/halftone.wgsl +80 -0
- package/libraries/postfx/src/shaders/post-process/highlight-blur.wgsl +33 -0
- package/libraries/postfx/src/shaders/post-process/highlight-composite.wgsl +32 -0
- package/libraries/postfx/src/shaders/post-process/lens-distortion.wgsl +43 -0
- package/libraries/postfx/src/shaders/post-process/lens-flare.wgsl +68 -0
- package/libraries/postfx/src/shaders/post-process/lut.wgsl +30 -0
- package/libraries/postfx/src/shaders/post-process/motion-blur.wgsl +55 -0
- package/libraries/postfx/src/shaders/post-process/occluder-chunk.wgsl +28 -0
- package/libraries/postfx/src/shaders/post-process/outline.wgsl +51 -0
- package/libraries/postfx/src/shaders/post-process/pixelation.wgsl +47 -0
- package/libraries/postfx/src/shaders/post-process/sharpen.wgsl +32 -0
- package/libraries/postfx/src/shaders/post-process/sobel.wgsl +26 -0
- package/libraries/postfx/src/shaders/post-process/split-tone.wgsl +36 -0
- package/libraries/postfx/src/shaders/post-process/ssao-blur.wgsl +38 -0
- package/libraries/postfx/src/shaders/post-process/ssao-composite.wgsl +25 -0
- package/libraries/postfx/src/shaders/post-process/ssao.wgsl +147 -0
- package/libraries/postfx/src/shaders/post-process/ssr.wgsl +155 -0
- package/libraries/postfx/src/shaders/post-process/taa.wgsl +98 -0
- package/libraries/postfx/src/shaders/post-process/tonemap.wgsl +40 -0
- package/libraries/postfx/src/shaders/post-process/watercolor.wgsl +82 -0
- package/libraries/postfx/src/shaders/post-process/white-balance.wgsl +41 -0
- package/libraries/recast/README.md +21 -0
- package/libraries/recast/src/backend.ts +150 -0
- package/libraries/recast/src/crowd-system.ts +352 -0
- package/libraries/recast/src/index.ts +12 -0
- package/libraries/recast/src/library.ts +91 -0
- package/libraries/recast/src/types.ts +86 -0
- package/libraries/sand/README.md +25 -0
- package/libraries/sand/src/cell.ts +43 -0
- package/libraries/sand/src/fields.ts +29 -0
- package/libraries/sand/src/fluid-grid.ts +261 -0
- package/libraries/sand/src/grid-dims.ts +74 -0
- package/libraries/sand/src/grid-sim-buffer.ts +271 -0
- package/libraries/sand/src/index.ts +81 -0
- package/libraries/sand/src/library.ts +92 -0
- package/libraries/sand/src/materials.ts +492 -0
- package/libraries/sand/src/palette.ts +93 -0
- package/libraries/sand/src/particles.ts +185 -0
- package/libraries/sand/src/render/sand-grid-pass.ts +430 -0
- package/libraries/sand/src/rng.ts +51 -0
- package/libraries/sand/src/rules/builtin-rules.ts +132 -0
- package/libraries/sand/src/rules/rule-compiler.ts +162 -0
- package/libraries/sand/src/rules/rule-engine.ts +231 -0
- package/libraries/sand/src/rules/rule-types.ts +87 -0
- package/libraries/sand/src/sand-step-pool.ts +484 -0
- package/libraries/sand/src/sand-step-worker.ts +97 -0
- package/libraries/sand/src/sand-world.ts +3227 -0
- package/libraries/stickman/README.md +25 -0
- package/libraries/stickman/src/index.ts +25 -0
- package/libraries/stickman/src/library.ts +61 -0
- package/libraries/stickman/src/proportions.ts +45 -0
- package/libraries/stickman/src/shader.ts +117 -0
- package/libraries/stickman/src/skeleton.ts +197 -0
- package/libraries/stickman/src/stickman-pass.ts +255 -0
- package/libraries/stickman/src/thick-line.ts +123 -0
- package/libraries/surface-nets/README.md +25 -0
- package/libraries/surface-nets/src/chunked-field.ts +14 -0
- package/libraries/surface-nets/src/deformation.ts +45 -0
- package/libraries/surface-nets/src/index.ts +36 -0
- package/libraries/surface-nets/src/library.ts +59 -0
- package/libraries/surface-nets/src/lod.ts +7 -0
- package/libraries/surface-nets/src/sab.ts +4 -0
- package/libraries/surface-nets/src/streaming-config.ts +5 -0
- package/libraries/surface-nets/src/streaming-manager.ts +15 -0
- package/libraries/surface-nets/src/surface-nets.ts +334 -0
- package/libraries/surface-nets/src/types.ts +23 -0
- package/libraries/water/README.md +25 -0
- package/libraries/water/src/buoyancy.ts +103 -0
- package/libraries/water/src/index.ts +43 -0
- package/libraries/water/src/library.ts +85 -0
- package/libraries/water/src/shore-damping.ts +93 -0
- package/libraries/water/src/water-buffer.ts +89 -0
- package/libraries/water/src/water-chunks.ts +13 -0
- package/libraries/water/src/water-physics.ts +376 -0
- package/libraries/water/src/water-renderer.ts +809 -0
- package/libraries/water/src/water-sab.ts +161 -0
- package/libraries/water/src/wave-sources.ts +84 -0
- package/libraries/weather/README.md +20 -0
- package/libraries/weather/src/index.ts +9 -0
- package/libraries/weather/src/library.ts +72 -0
- package/libraries/weather/src/types.ts +64 -0
- package/libraries/weather/src/weather-blend.ts +112 -0
- package/libraries/weather/src/weather-system.ts +271 -0
- package/libraries/weatherfx/README.md +24 -0
- package/libraries/weatherfx/src/cloud-provider.ts +31 -0
- package/libraries/weatherfx/src/cloud-system.ts +372 -0
- package/libraries/weatherfx/src/index.ts +9 -0
- package/libraries/weatherfx/src/library.ts +58 -0
- package/libraries/weatherfx/src/particle-system.ts +434 -0
- package/libraries/weatherfx/src/shaders/cloud.wgsl +111 -0
- package/libraries/weatherfx/src/shaders/particle-compute.wgsl +187 -0
- package/libraries/weatherfx/src/shaders/particle-render.wgsl +95 -0
- package/lint-plugin.mjs +41 -0
- package/mcp/src/client.ts +703 -0
- package/mcp/src/engine-context.ts +186 -0
- package/mcp/src/http-transport.ts +471 -0
- package/mcp/src/index.ts +13 -0
- package/mcp/src/prompts/add-entity.ts +42 -0
- package/mcp/src/prompts/create-scene.ts +44 -0
- package/mcp/src/prompts/debug-frame.ts +39 -0
- package/mcp/src/prompts/index.ts +12 -0
- package/mcp/src/resources/asset-list.ts +32 -0
- package/mcp/src/resources/checkpoint-list.ts +33 -0
- package/mcp/src/resources/entity-state.ts +55 -0
- package/mcp/src/resources/gpu-info.ts +103 -0
- package/mcp/src/resources/index.ts +57 -0
- package/mcp/src/resources/performance.ts +37 -0
- package/mcp/src/resources/scene-tree.ts +43 -0
- package/mcp/src/server.ts +375 -0
- package/mcp/src/tools/animation.ts +118 -0
- package/mcp/src/tools/asset.ts +161 -0
- package/mcp/src/tools/audio.ts +96 -0
- package/mcp/src/tools/build.ts +143 -0
- package/mcp/src/tools/camera.ts +167 -0
- package/mcp/src/tools/checkpoint.ts +100 -0
- package/mcp/src/tools/component.ts +199 -0
- package/mcp/src/tools/debug.ts +300 -0
- package/mcp/src/tools/entity.ts +361 -0
- package/mcp/src/tools/inspect.ts +210 -0
- package/mcp/src/tools/lighting.ts +263 -0
- package/mcp/src/tools/material.ts +243 -0
- package/mcp/src/tools/mesh.ts +239 -0
- package/mcp/src/tools/physics.ts +266 -0
- package/mcp/src/tools/scene.ts +153 -0
- package/mcp/src/tools/script.ts +122 -0
- package/mcp/src/types.ts +92 -0
- package/mcp/src/undo-redo.ts +77 -0
- package/modules/camera-controls/README.md +20 -0
- package/modules/camera-controls/src/index.ts +161 -0
- package/modules/controller-ui/src/index.ts +164 -0
- package/modules/devtools/README.md +25 -0
- package/modules/devtools/src/api.ts +461 -0
- package/modules/devtools/src/asset-utils.ts +105 -0
- package/modules/devtools/src/bind-debug-store.ts +48 -0
- package/modules/devtools/src/data-bridge.ts +286 -0
- package/modules/devtools/src/debug-overlay.ts +238 -0
- package/modules/devtools/src/debug-raycast.ts +328 -0
- package/modules/devtools/src/debug-store.ts +92 -0
- package/modules/devtools/src/debug-view-descriptors.ts +59 -0
- package/modules/devtools/src/doctor-panel.ts +182 -0
- package/modules/devtools/src/gizmo-module.ts +136 -0
- package/modules/devtools/src/graph-model.ts +509 -0
- package/modules/devtools/src/grid-renderer.ts +157 -0
- package/modules/devtools/src/height-ruler-renderer.ts +216 -0
- package/modules/devtools/src/index.ts +81 -0
- package/modules/devtools/src/init.ts +261 -0
- package/modules/devtools/src/label-overlay.ts +154 -0
- package/modules/devtools/src/material-stats-panel.ts +188 -0
- package/modules/devtools/src/profiling-bridge.ts +377 -0
- package/modules/devtools/src/profiling-hooks.ts +98 -0
- package/modules/devtools/src/renderer-adapter.ts +76 -0
- package/modules/devtools/src/scene-inspector.ts +637 -0
- package/modules/devtools/src/scene-store.ts +320 -0
- package/modules/devtools/src/scene-sync.ts +116 -0
- package/modules/devtools/src/shaders/transform-gizmo.wgsl +38 -0
- package/modules/devtools/src/sim-stats-panel.ts +272 -0
- package/modules/devtools/src/sim-stats-provider.ts +105 -0
- package/modules/devtools/src/skeleton-renderer.ts +351 -0
- package/modules/devtools/src/transform-gizmo.ts +928 -0
- package/modules/devtools/src/types.ts +290 -0
- package/modules/devtools/src/worker-expose.ts +67 -0
- package/modules/devtools/src/worker-sync.ts +137 -0
- package/modules/editor/src/commands/component.ts +156 -0
- package/modules/editor/src/commands/entity.ts +287 -0
- package/modules/editor/src/commands/hierarchy.ts +83 -0
- package/modules/editor/src/commands/index.ts +61 -0
- package/modules/editor/src/commands/prefab.ts +163 -0
- package/modules/editor/src/commands/registry.ts +331 -0
- package/modules/editor/src/commands/scene-io.ts +211 -0
- package/modules/editor/src/commands/selection.ts +73 -0
- package/modules/editor/src/commands/transform.ts +91 -0
- package/modules/editor/src/ddscene.ts +267 -0
- package/modules/editor/src/document.ts +123 -0
- package/modules/editor/src/editor-context.ts +172 -0
- package/modules/editor/src/index.ts +41 -0
- package/modules/editor/src/mcp.ts +103 -0
- package/modules/editor/src/module.ts +148 -0
- package/modules/editor/src/selection.ts +70 -0
- package/modules/editor/src/shell.ts +456 -0
- package/modules/editor/src/viewport.ts +199 -0
- package/modules/html-ui/src/composite.ts +135 -0
- package/modules/html-ui/src/create-html-ui.ts +188 -0
- package/modules/html-ui/src/doc-backend.ts +343 -0
- package/modules/html-ui/src/host.ts +646 -0
- package/modules/html-ui/src/index.ts +13 -0
- package/modules/html-ui/src/jsx-dev-runtime.ts +12 -0
- package/modules/html-ui/src/jsx-runtime.ts +126 -0
- package/modules/html-ui/src/protocol.ts +88 -0
- package/modules/html-ui/src/ui-worker.ts +16 -0
- package/modules/mcp/README.md +18 -0
- package/modules/mcp/src/index.ts +27 -0
- package/modules/movement-2d/README.md +19 -0
- package/modules/movement-2d/src/grid-character.ts +455 -0
- package/modules/movement-2d/src/index.ts +45 -0
- package/modules/movement-3d/README.md +21 -0
- package/modules/movement-3d/src/character-motor.ts +230 -0
- package/modules/movement-3d/src/index.ts +46 -0
- package/modules/native-osr/src/index.ts +22 -0
- package/modules/native-osr/src/input-router.ts +401 -0
- package/modules/native-osr/src/native-osr-manager.ts +247 -0
- package/modules/native-osr/src/native-texture-source.ts +86 -0
- package/modules/native-osr/src/types.ts +112 -0
- package/modules/native-osr/src/world-space-ui-pass.ts +351 -0
- package/modules/sailing/README.md +18 -0
- package/modules/sailing/src/index.ts +51 -0
- package/modules/terrain/README.md +18 -0
- package/modules/terrain/src/index.ts +78 -0
- package/modules/vitals/README.md +17 -0
- package/modules/vitals/src/index.ts +43 -0
- package/modules/vitals/src/vitals.ts +265 -0
- package/modules/xr/README.md +25 -0
- package/modules/xr/src/camera-rig.ts +146 -0
- package/modules/xr/src/debug.ts +59 -0
- package/modules/xr/src/frame-loop.ts +197 -0
- package/modules/xr/src/index.ts +16 -0
- package/modules/xr/src/input.ts +208 -0
- package/modules/xr/src/layer.ts +140 -0
- package/modules/xr/src/session.ts +156 -0
- package/modules/xr/src/sim-module.ts +23 -0
- package/modules/xr/src/types.ts +32 -0
- package/modules/xr/src/webxr.d.ts +182 -0
- package/modules/xr/src/xr-module.ts +179 -0
- package/package.json +232 -3
- package/shader-graph/src/chunks.ts +349 -0
- package/shader-graph/src/compiler.ts +732 -0
- package/shader-graph/src/compute-compiler.ts +453 -0
- package/shader-graph/src/compute-graph.ts +112 -0
- package/shader-graph/src/compute-profiles.ts +54 -0
- package/shader-graph/src/graph.ts +52 -0
- package/shader-graph/src/index.ts +53 -0
- package/shader-graph/src/profiles.ts +407 -0
- package/shader-graph/src/validator.ts +48 -0
- package/shader-graph/src/wgsl-binding-validator.ts +143 -0
- package/shader-graph/src/wgsl-struct-validator.ts +245 -0
- package/shader-graph/src/wgsl-struct.ts +397 -0
- package/test/src/index.ts +7 -0
- package/test/src/vision-test.ts +369 -0
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// ProfilingSAB — SharedArrayBuffer layout for the in-game profiling system.
|
|
3
|
+
//
|
|
4
|
+
// One global SAB allocated by the renderer, shared to all workers + the
|
|
5
|
+
// devtools host. Contains:
|
|
6
|
+
// - Header (magic, version, counts, global tick, warning seq)
|
|
7
|
+
// - Slot table (per-worker metadata)
|
|
8
|
+
// - Per-slot regions (ThreadMetrics + EventLoop block + IOPS ring + string table)
|
|
9
|
+
// - Global warning ring (worker-fired warnings)
|
|
10
|
+
//
|
|
11
|
+
// All multi-byte fields use little-endian. Ring buffers use atomic head/count
|
|
12
|
+
// via Atomics for lock-free single-producer (worker) / single-consumer (reader).
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/** Maximum number of worker slots in the SAB. */
|
|
16
|
+
export const PROFILING_MAX_SLOTS = 32;
|
|
17
|
+
/** IOPS ring buffer capacity per slot. */
|
|
18
|
+
export const PROFILING_IOPS_RING_CAP = 256;
|
|
19
|
+
/** Warning ring buffer capacity (global). */
|
|
20
|
+
export const PROFILING_WARNING_RING_CAP = 128;
|
|
21
|
+
/** String table capacity per slot (entries). */
|
|
22
|
+
export const PROFILING_STRING_TABLE_CAP = 64;
|
|
23
|
+
/** Max string length per interned tag (chars). */
|
|
24
|
+
export const PROFILING_STRING_MAX_LEN = 128;
|
|
25
|
+
|
|
26
|
+
/** Runtime type tag. */
|
|
27
|
+
export const RUNTIME_JS = 0;
|
|
28
|
+
export const RUNTIME_QUICKJS = 1;
|
|
29
|
+
export const RUNTIME_WASM = 2;
|
|
30
|
+
export type RuntimeKind = typeof RUNTIME_JS | typeof RUNTIME_QUICKJS | typeof RUNTIME_WASM;
|
|
31
|
+
|
|
32
|
+
/** IOPS storage type. */
|
|
33
|
+
export const STORE_OPFS = 0;
|
|
34
|
+
export const STORE_IDB = 1;
|
|
35
|
+
|
|
36
|
+
/** Warning severity levels. */
|
|
37
|
+
export const SEVERITY_INFO = 0;
|
|
38
|
+
export const SEVERITY_WARN = 1;
|
|
39
|
+
export const SEVERITY_ERROR = 2;
|
|
40
|
+
export const SEVERITY_CRITICAL = 3;
|
|
41
|
+
export type SeverityLevel = typeof SEVERITY_INFO | typeof SEVERITY_WARN | typeof SEVERITY_ERROR | typeof SEVERITY_CRITICAL;
|
|
42
|
+
|
|
43
|
+
/** Metric kinds for warning records. */
|
|
44
|
+
export const METRIC_TICK_LATENCY = 0;
|
|
45
|
+
export const METRIC_TASK_LATENCY = 1;
|
|
46
|
+
export const METRIC_IOPS_LATENCY = 2;
|
|
47
|
+
export const METRIC_HEAP_USAGE = 3;
|
|
48
|
+
export const METRIC_HEAP_PERCENT = 4;
|
|
49
|
+
export const METRIC_CPU_PERCENT = 5;
|
|
50
|
+
export const METRIC_GC_PAUSE = 6;
|
|
51
|
+
export const METRIC_RAF_JITTER = 7;
|
|
52
|
+
export const METRIC_LONGTASK = 8;
|
|
53
|
+
export const METRIC_GPU_TIME = 9;
|
|
54
|
+
export const METRIC_CUSTOM = 10;
|
|
55
|
+
|
|
56
|
+
// ─── Sizes (bytes) ──────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
const U32 = 4;
|
|
59
|
+
const F32 = 4;
|
|
60
|
+
const U16 = 2;
|
|
61
|
+
const U8 = 1;
|
|
62
|
+
|
|
63
|
+
/** Header size — 32 bytes. */
|
|
64
|
+
export const HEADER_SIZE = 32;
|
|
65
|
+
|
|
66
|
+
/** SlotHeader size — 24 bytes (6 × u32). */
|
|
67
|
+
export const SLOT_HEADER_SIZE = 6 * U32;
|
|
68
|
+
|
|
69
|
+
/** ThreadMetrics block size — 15 fields, 60 bytes. */
|
|
70
|
+
export const THREAD_METRICS_SIZE = 15 * U32; // all u32/f32 = 4 bytes each
|
|
71
|
+
|
|
72
|
+
/** EventLoop block size — 9 fields, 36 bytes. */
|
|
73
|
+
export const EVENT_LOOP_SIZE = 9 * U32;
|
|
74
|
+
|
|
75
|
+
/** IopsRecord size — 22 bytes, padded to 24 for alignment. */
|
|
76
|
+
export const IOPS_RECORD_SIZE = 24;
|
|
77
|
+
|
|
78
|
+
/** WarningRecord size — 20 bytes, padded to 24 for alignment. */
|
|
79
|
+
export const WARNING_RECORD_SIZE = 24;
|
|
80
|
+
|
|
81
|
+
/** String table entry: hash(u32) + len(u16) + chars (up to 128 × 2 bytes).
|
|
82
|
+
* Padded to 4-byte alignment for correct Uint32Array indexing. */
|
|
83
|
+
export const STRING_ENTRY_SIZE = Math.ceil((U32 + U16 + PROFILING_STRING_MAX_LEN * 2) / 4) * 4; // 262 → 264
|
|
84
|
+
|
|
85
|
+
// ─── Header field offsets ───────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
export const HDR = {
|
|
88
|
+
MAGIC: 0, // u32 — 0x50524f46 ("PROF")
|
|
89
|
+
VERSION: 1, // u32
|
|
90
|
+
MAX_SLOTS: 2, // u32
|
|
91
|
+
ACTIVE_SLOTS: 3, // u32
|
|
92
|
+
EPOCH: 4, // u32 — bumped when slot table changes
|
|
93
|
+
GLOBAL_TICK: 5, // u32 — incremented each frame by renderer
|
|
94
|
+
WARNING_SEQ: 6, // u32 — bumped when a new warning is pushed
|
|
95
|
+
PADDING: 7, // u32 — reserved
|
|
96
|
+
} as const;
|
|
97
|
+
|
|
98
|
+
export const PROFILING_MAGIC = 0x50524f46;
|
|
99
|
+
export const PROFILING_VERSION = 1;
|
|
100
|
+
|
|
101
|
+
// ─── SlotHeader field offsets (relative to slot table start + slotIndex * SLOT_HEADER_SIZE) ──
|
|
102
|
+
|
|
103
|
+
export const SH = {
|
|
104
|
+
WORKER_TAG: 0, // u32 — interned worker tag hash
|
|
105
|
+
RUNTIME: 1, // u32 — RuntimeKind
|
|
106
|
+
SLOT_INDEX: 2, // u32 — this slot's index
|
|
107
|
+
NAME_OFFSET: 3, // u32 — offset into the slot's string table for the worker name
|
|
108
|
+
NAME_LEN: 4, // u32 — length of the worker name
|
|
109
|
+
ALIVE: 5, // u32 — 0 = free, 1 = claimed (atomic CAS)
|
|
110
|
+
} as const;
|
|
111
|
+
|
|
112
|
+
// ─── ThreadMetrics field offsets (relative to slot region metrics start) ────
|
|
113
|
+
|
|
114
|
+
export const TM = {
|
|
115
|
+
HEAP_USED: 0, // u32 — bytes
|
|
116
|
+
HEAP_TOTAL: 1, // u32 — bytes
|
|
117
|
+
RSS: 2, // u32 — bytes
|
|
118
|
+
CPU_TIME_MS: 3, // f32 — ms
|
|
119
|
+
CPU_PERCENT: 4, // f32 — %
|
|
120
|
+
GC_PAUSE_TOTAL: 5, // u32 — us
|
|
121
|
+
GC_PAUSE_COUNT: 6, // u32
|
|
122
|
+
GC_PAUSE_MAX: 7, // u32 — us
|
|
123
|
+
TICK: 8, // u32 — tick counter
|
|
124
|
+
TASK_COUNT: 9, // u32
|
|
125
|
+
TASK_LATENCY_P50: 10, // f32 — us
|
|
126
|
+
TASK_LATENCY_P95: 11, // f32 — us
|
|
127
|
+
TASK_LATENCY_P99: 12, // f32 — us
|
|
128
|
+
TASK_LATENCY_MAX: 13, // u32 — us
|
|
129
|
+
LAST_UPDATE_MS: 14, // f32 — performance.now() at last write
|
|
130
|
+
} as const;
|
|
131
|
+
|
|
132
|
+
// ─── EventLoop block field offsets (relative to slot region event-loop start) ──
|
|
133
|
+
|
|
134
|
+
export const EL = {
|
|
135
|
+
RAF_JITTER_P50: 0, // f32 — us
|
|
136
|
+
RAF_JITTER_P95: 1, // f32 — us
|
|
137
|
+
RAF_JITTER_MAX: 2, // u32 — us
|
|
138
|
+
LONGTASK_COUNT: 3, // u32
|
|
139
|
+
LONGTASK_TOTAL_MS: 4, // u32 — ms
|
|
140
|
+
LONGTASK_MAX_MS: 5, // u32 — ms
|
|
141
|
+
IDLE_HEADROOM_MS: 6, // u32 — ms
|
|
142
|
+
EXPECTED_FRAME_MS: 7, // f32 — ms
|
|
143
|
+
LAST_UPDATE_MS: 8, // f32 — performance.now() at last write
|
|
144
|
+
} as const;
|
|
145
|
+
|
|
146
|
+
// ─── IopsRecord field offsets (relative to ring entry start) ────────────────
|
|
147
|
+
|
|
148
|
+
export const IR = {
|
|
149
|
+
OP_KIND: 0, // u16
|
|
150
|
+
STORE: 2, // u8
|
|
151
|
+
_PAD: 3, // u8
|
|
152
|
+
TAG_HASH: 4, // u32
|
|
153
|
+
BYTES: 8, // u32
|
|
154
|
+
LATENCY_US: 12, // u32
|
|
155
|
+
TS: 16, // u32 — performance.now() truncated to u32
|
|
156
|
+
WORKER_TAG: 20, // u32
|
|
157
|
+
} as const;
|
|
158
|
+
|
|
159
|
+
// ─── IOPS ring control (head + count atomics, at the start of the IOPS region) ──
|
|
160
|
+
|
|
161
|
+
export const IOPS_CTRL = {
|
|
162
|
+
HEAD: 0, // u32 — atomic write index
|
|
163
|
+
COUNT: 1, // u32 — atomic number of entries
|
|
164
|
+
} as const;
|
|
165
|
+
const IOPS_CTRL_SIZE = 2 * U32;
|
|
166
|
+
|
|
167
|
+
// ─── WarningRecord field offsets (relative to warning ring entry start) ─────
|
|
168
|
+
|
|
169
|
+
export const WR = {
|
|
170
|
+
RULE_ID_HASH: 0, // u32
|
|
171
|
+
SEVERITY: 4, // u8
|
|
172
|
+
METRIC_KIND: 5, // u8
|
|
173
|
+
_PAD: 6, // u16
|
|
174
|
+
VALUE: 8, // f32
|
|
175
|
+
THRESHOLD: 12, // f32
|
|
176
|
+
WORKER_TAG: 16, // u32
|
|
177
|
+
TS: 20, // u32
|
|
178
|
+
// byte 23: autoTraceFired is packed into the high bit of TS for compactness
|
|
179
|
+
} as const;
|
|
180
|
+
|
|
181
|
+
// ─── Warning ring control (global, after all slot regions) ──────────────────
|
|
182
|
+
|
|
183
|
+
export const WARN_CTRL = {
|
|
184
|
+
HEAD: 0, // u32 — atomic write index
|
|
185
|
+
COUNT: 1, // u32 — atomic number of entries
|
|
186
|
+
SEQ: 2, // u32 — atomic sequence (also mirrored in header WARNING_SEQ)
|
|
187
|
+
} as const;
|
|
188
|
+
const WARN_CTRL_SIZE = 3 * U32;
|
|
189
|
+
|
|
190
|
+
// ─── String table control (per slot, at the start of the string-table region) ──
|
|
191
|
+
|
|
192
|
+
export const STR_CTRL = {
|
|
193
|
+
HEAD: 0, // u32 — next write index (entry count)
|
|
194
|
+
COUNT: 1, // u32 — number of entries
|
|
195
|
+
} as const;
|
|
196
|
+
const STR_CTRL_SIZE = 2 * U32;
|
|
197
|
+
|
|
198
|
+
// ─── Layout computation ─────────────────────────────────────────────────────
|
|
199
|
+
|
|
200
|
+
export interface ProfilingSABLayout {
|
|
201
|
+
byteLength: number;
|
|
202
|
+
headerOffset: number;
|
|
203
|
+
slotTableOffset: number;
|
|
204
|
+
slotRegionSize: number;
|
|
205
|
+
/** Offset of a slot's region from the buffer start. */
|
|
206
|
+
slotRegionOffset: (slotIndex: number) => number;
|
|
207
|
+
/** Offset of a slot's ThreadMetrics block from the buffer start. */
|
|
208
|
+
metricsOffset: (slotIndex: number) => number;
|
|
209
|
+
/** Offset of a slot's EventLoop block from the buffer start. */
|
|
210
|
+
eventLoopOffset: (slotIndex: number) => number;
|
|
211
|
+
/** Offset of a slot's IOPS ring control from the buffer start. */
|
|
212
|
+
iopsCtrlOffset: (slotIndex: number) => number;
|
|
213
|
+
/** Offset of a slot's IOPS ring data (first entry) from the buffer start. */
|
|
214
|
+
iopsDataOffset: (slotIndex: number) => number;
|
|
215
|
+
/** Offset of a slot's string table control from the buffer start. */
|
|
216
|
+
strCtrlOffset: (slotIndex: number) => number;
|
|
217
|
+
/** Offset of a slot's string table data (first entry) from the buffer start. */
|
|
218
|
+
strDataOffset: (slotIndex: number) => number;
|
|
219
|
+
/** Offset of the global warning ring control from the buffer start. */
|
|
220
|
+
warnCtrlOffset: number;
|
|
221
|
+
/** Offset of the global warning ring data (first entry) from the buffer start. */
|
|
222
|
+
warnDataOffset: number;
|
|
223
|
+
maxSlots: number;
|
|
224
|
+
iopsRingCap: number;
|
|
225
|
+
warningRingCap: number;
|
|
226
|
+
stringTableCap: number;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Compute the byte layout of the ProfilingSAB.
|
|
231
|
+
* The layout is deterministic given the capacity parameters.
|
|
232
|
+
*/
|
|
233
|
+
export function computeProfilingSABLayout(
|
|
234
|
+
maxSlots: number = PROFILING_MAX_SLOTS,
|
|
235
|
+
iopsRingCap: number = PROFILING_IOPS_RING_CAP,
|
|
236
|
+
warningRingCap: number = PROFILING_WARNING_RING_CAP,
|
|
237
|
+
stringTableCap: number = PROFILING_STRING_TABLE_CAP,
|
|
238
|
+
): ProfilingSABLayout {
|
|
239
|
+
const headerOffset = 0;
|
|
240
|
+
const slotTableOffset = HEADER_SIZE;
|
|
241
|
+
const slotTableSize = maxSlots * SLOT_HEADER_SIZE;
|
|
242
|
+
|
|
243
|
+
// Each slot region: metrics + event-loop + IOPS (ctrl + data) + string table (ctrl + data)
|
|
244
|
+
const slotRegionSize =
|
|
245
|
+
THREAD_METRICS_SIZE +
|
|
246
|
+
EVENT_LOOP_SIZE +
|
|
247
|
+
IOPS_CTRL_SIZE +
|
|
248
|
+
iopsRingCap * IOPS_RECORD_SIZE +
|
|
249
|
+
STR_CTRL_SIZE +
|
|
250
|
+
stringTableCap * STRING_ENTRY_SIZE;
|
|
251
|
+
|
|
252
|
+
const slotRegionsStart = slotTableOffset + slotTableSize;
|
|
253
|
+
|
|
254
|
+
const slotRegionOffset = (si: number) => slotRegionsStart + si * slotRegionSize;
|
|
255
|
+
const metricsOffset = (si: number) => slotRegionOffset(si);
|
|
256
|
+
const eventLoopOffset = (si: number) => slotRegionOffset(si) + THREAD_METRICS_SIZE;
|
|
257
|
+
const iopsCtrlOffset = (si: number) => slotRegionOffset(si) + THREAD_METRICS_SIZE + EVENT_LOOP_SIZE;
|
|
258
|
+
const iopsDataOffset = (si: number) => iopsCtrlOffset(si) + IOPS_CTRL_SIZE;
|
|
259
|
+
const strCtrlOffset = (si: number) =>
|
|
260
|
+
iopsDataOffset(si) + iopsRingCap * IOPS_RECORD_SIZE;
|
|
261
|
+
const strDataOffset = (si: number) => strCtrlOffset(si) + STR_CTRL_SIZE;
|
|
262
|
+
|
|
263
|
+
const warnCtrlOffset = slotRegionsStart + maxSlots * slotRegionSize;
|
|
264
|
+
const warnDataOffset = warnCtrlOffset + WARN_CTRL_SIZE;
|
|
265
|
+
const byteLength = warnDataOffset + warningRingCap * WARNING_RECORD_SIZE;
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
byteLength,
|
|
269
|
+
headerOffset,
|
|
270
|
+
slotTableOffset,
|
|
271
|
+
slotRegionSize,
|
|
272
|
+
slotRegionOffset,
|
|
273
|
+
metricsOffset,
|
|
274
|
+
eventLoopOffset,
|
|
275
|
+
iopsCtrlOffset,
|
|
276
|
+
iopsDataOffset,
|
|
277
|
+
strCtrlOffset,
|
|
278
|
+
strDataOffset,
|
|
279
|
+
warnCtrlOffset,
|
|
280
|
+
warnDataOffset,
|
|
281
|
+
maxSlots,
|
|
282
|
+
iopsRingCap,
|
|
283
|
+
warningRingCap,
|
|
284
|
+
stringTableCap,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Allocate a new ProfilingSAB and initialize the header.
|
|
290
|
+
* Returns the SharedArrayBuffer + its layout.
|
|
291
|
+
*/
|
|
292
|
+
export function allocateProfilingSAB(
|
|
293
|
+
maxSlots: number = PROFILING_MAX_SLOTS,
|
|
294
|
+
iopsRingCap: number = PROFILING_IOPS_RING_CAP,
|
|
295
|
+
warningRingCap: number = PROFILING_WARNING_RING_CAP,
|
|
296
|
+
stringTableCap: number = PROFILING_STRING_TABLE_CAP,
|
|
297
|
+
): { sab: SharedArrayBuffer; layout: ProfilingSABLayout } {
|
|
298
|
+
const layout = computeProfilingSABLayout(maxSlots, iopsRingCap, warningRingCap, stringTableCap);
|
|
299
|
+
const sab = new SharedArrayBuffer(layout.byteLength);
|
|
300
|
+
const view = new Uint32Array(sab);
|
|
301
|
+
|
|
302
|
+
// Initialize header
|
|
303
|
+
view[HDR.MAGIC] = PROFILING_MAGIC;
|
|
304
|
+
view[HDR.VERSION] = PROFILING_VERSION;
|
|
305
|
+
view[HDR.MAX_SLOTS] = maxSlots;
|
|
306
|
+
view[HDR.ACTIVE_SLOTS] = 0;
|
|
307
|
+
view[HDR.EPOCH] = 0;
|
|
308
|
+
view[HDR.GLOBAL_TICK] = 0;
|
|
309
|
+
view[HDR.WARNING_SEQ] = 0;
|
|
310
|
+
|
|
311
|
+
// Initialize slot table — all slots free (alive = 0)
|
|
312
|
+
for (let i = 0; i < maxSlots; i++) {
|
|
313
|
+
const base = (layout.slotTableOffset / U32) + i * (SLOT_HEADER_SIZE / U32);
|
|
314
|
+
view[base + SH.WORKER_TAG] = 0;
|
|
315
|
+
view[base + SH.RUNTIME] = RUNTIME_JS;
|
|
316
|
+
view[base + SH.SLOT_INDEX] = i;
|
|
317
|
+
view[base + SH.NAME_OFFSET] = 0;
|
|
318
|
+
view[base + SH.NAME_LEN] = 0;
|
|
319
|
+
view[base + SH.ALIVE] = 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return { sab, layout };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ─── ProfilingSABWriter (worker side) ───────────────────────────────────────
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Writer for a single worker slot. Each worker claims a slot via claimSlot()
|
|
329
|
+
* then uses the writer to update metrics, push IOPS records, and intern tags.
|
|
330
|
+
*/
|
|
331
|
+
export class ProfilingSABWriter {
|
|
332
|
+
private u32: Uint32Array;
|
|
333
|
+
private f32: Float32Array;
|
|
334
|
+
private u16: Uint16Array;
|
|
335
|
+
private u8: Uint8Array;
|
|
336
|
+
private layout: ProfilingSABLayout;
|
|
337
|
+
private slotIndex: number;
|
|
338
|
+
|
|
339
|
+
constructor(sab: SharedArrayBuffer, layout: ProfilingSABLayout, slotIndex: number) {
|
|
340
|
+
this.u32 = new Uint32Array(sab);
|
|
341
|
+
this.f32 = new Float32Array(sab);
|
|
342
|
+
this.u16 = new Uint16Array(sab);
|
|
343
|
+
this.u8 = new Uint8Array(sab);
|
|
344
|
+
this.layout = layout;
|
|
345
|
+
this.slotIndex = slotIndex;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
getSlotIndex(): number {
|
|
349
|
+
return this.slotIndex;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Write the ThreadMetrics block for this slot. */
|
|
353
|
+
writeThreadMetrics(m: {
|
|
354
|
+
heapUsed: number;
|
|
355
|
+
heapTotal: number;
|
|
356
|
+
rss: number;
|
|
357
|
+
cpuTimeMs: number;
|
|
358
|
+
cpuPercent: number;
|
|
359
|
+
gcPauseTotalUs: number;
|
|
360
|
+
gcPauseCount: number;
|
|
361
|
+
gcPauseMaxUs: number;
|
|
362
|
+
tick: number;
|
|
363
|
+
taskCount: number;
|
|
364
|
+
taskLatencyP50Us: number;
|
|
365
|
+
taskLatencyP95Us: number;
|
|
366
|
+
taskLatencyP99Us: number;
|
|
367
|
+
taskLatencyMaxUs: number;
|
|
368
|
+
}): void {
|
|
369
|
+
const base = this.layout.metricsOffset(this.slotIndex) / U32;
|
|
370
|
+
this.u32[base + TM.HEAP_USED] = m.heapUsed;
|
|
371
|
+
this.u32[base + TM.HEAP_TOTAL] = m.heapTotal;
|
|
372
|
+
this.u32[base + TM.RSS] = m.rss;
|
|
373
|
+
this.f32[base + TM.CPU_TIME_MS] = m.cpuTimeMs;
|
|
374
|
+
this.f32[base + TM.CPU_PERCENT] = m.cpuPercent;
|
|
375
|
+
this.u32[base + TM.GC_PAUSE_TOTAL] = m.gcPauseTotalUs;
|
|
376
|
+
this.u32[base + TM.GC_PAUSE_COUNT] = m.gcPauseCount;
|
|
377
|
+
this.u32[base + TM.GC_PAUSE_MAX] = m.gcPauseMaxUs;
|
|
378
|
+
this.u32[base + TM.TICK] = m.tick;
|
|
379
|
+
this.u32[base + TM.TASK_COUNT] = m.taskCount;
|
|
380
|
+
this.f32[base + TM.TASK_LATENCY_P50] = m.taskLatencyP50Us;
|
|
381
|
+
this.f32[base + TM.TASK_LATENCY_P95] = m.taskLatencyP95Us;
|
|
382
|
+
this.f32[base + TM.TASK_LATENCY_P99] = m.taskLatencyP99Us;
|
|
383
|
+
this.u32[base + TM.TASK_LATENCY_MAX] = m.taskLatencyMaxUs;
|
|
384
|
+
this.f32[base + TM.LAST_UPDATE_MS] = performance.now();
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Write the EventLoop block for this slot. */
|
|
388
|
+
writeEventLoop(e: {
|
|
389
|
+
rafJitterP50Us: number;
|
|
390
|
+
rafJitterP95Us: number;
|
|
391
|
+
rafJitterMaxUs: number;
|
|
392
|
+
longtaskCount: number;
|
|
393
|
+
longtaskTotalMs: number;
|
|
394
|
+
longtaskMaxMs: number;
|
|
395
|
+
idleHeadroomMs: number;
|
|
396
|
+
expectedFrameMs: number;
|
|
397
|
+
}): void {
|
|
398
|
+
const base = this.layout.eventLoopOffset(this.slotIndex) / U32;
|
|
399
|
+
this.f32[base + EL.RAF_JITTER_P50] = e.rafJitterP50Us;
|
|
400
|
+
this.f32[base + EL.RAF_JITTER_P95] = e.rafJitterP95Us;
|
|
401
|
+
this.u32[base + EL.RAF_JITTER_MAX] = e.rafJitterMaxUs;
|
|
402
|
+
this.u32[base + EL.LONGTASK_COUNT] = e.longtaskCount;
|
|
403
|
+
this.u32[base + EL.LONGTASK_TOTAL_MS] = e.longtaskTotalMs;
|
|
404
|
+
this.u32[base + EL.LONGTASK_MAX_MS] = e.longtaskMaxMs;
|
|
405
|
+
this.u32[base + EL.IDLE_HEADROOM_MS] = e.idleHeadroomMs;
|
|
406
|
+
this.f32[base + EL.EXPECTED_FRAME_MS] = e.expectedFrameMs;
|
|
407
|
+
this.f32[base + EL.LAST_UPDATE_MS] = performance.now();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Push an IOPS record to this slot's ring buffer.
|
|
412
|
+
* Lock-free: uses Atomics on head/count. If the ring is full, the oldest
|
|
413
|
+
* entry is overwritten (the consumer must handle this).
|
|
414
|
+
*/
|
|
415
|
+
pushIopsRecord(rec: {
|
|
416
|
+
opKind: number;
|
|
417
|
+
store: number;
|
|
418
|
+
tagHash: number;
|
|
419
|
+
bytes: number;
|
|
420
|
+
latencyUs: number;
|
|
421
|
+
ts: number;
|
|
422
|
+
workerTag: number;
|
|
423
|
+
}): void {
|
|
424
|
+
const ctrlBase = this.layout.iopsCtrlOffset(this.slotIndex) / U32;
|
|
425
|
+
const cap = this.layout.iopsRingCap;
|
|
426
|
+
const head = Atomics.add(this.u32, ctrlBase + IOPS_CTRL.HEAD, 1) % cap;
|
|
427
|
+
// Increment count up to cap
|
|
428
|
+
const curCount = Atomics.load(this.u32, ctrlBase + IOPS_CTRL.COUNT);
|
|
429
|
+
if (curCount < cap) {
|
|
430
|
+
Atomics.add(this.u32, ctrlBase + IOPS_CTRL.COUNT, 1);
|
|
431
|
+
}
|
|
432
|
+
const entryBase = this.layout.iopsDataOffset(this.slotIndex) + head * IOPS_RECORD_SIZE;
|
|
433
|
+
this.u16[entryBase / U16 + IR.OP_KIND / U16] = rec.opKind;
|
|
434
|
+
this.u8[entryBase + IR.STORE] = rec.store;
|
|
435
|
+
this.u32[(entryBase + IR.TAG_HASH) / U32] = rec.tagHash;
|
|
436
|
+
this.u32[(entryBase + IR.BYTES) / U32] = rec.bytes;
|
|
437
|
+
this.u32[(entryBase + IR.LATENCY_US) / U32] = rec.latencyUs;
|
|
438
|
+
this.u32[(entryBase + IR.TS) / U32] = rec.ts;
|
|
439
|
+
this.u32[(entryBase + IR.WORKER_TAG) / U32] = rec.workerTag;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Intern a string tag into this slot's string table.
|
|
444
|
+
* Returns the hash of the string (used as tagHash in IOPS records).
|
|
445
|
+
* If the string is already in the table, returns its existing hash.
|
|
446
|
+
* Uses FNV-1a hashing for compact, collision-resistant 32-bit hashes.
|
|
447
|
+
*/
|
|
448
|
+
internTag(str: string): number {
|
|
449
|
+
const hash = fnv1a32(str);
|
|
450
|
+
// Check if already interned
|
|
451
|
+
const ctrlBase = this.layout.strCtrlOffset(this.slotIndex) / U32;
|
|
452
|
+
const count = Atomics.load(this.u32, ctrlBase + STR_CTRL.COUNT);
|
|
453
|
+
const dataBase = this.layout.strDataOffset(this.slotIndex);
|
|
454
|
+
for (let i = 0; i < count; i++) {
|
|
455
|
+
const entryBase = dataBase + i * STRING_ENTRY_SIZE;
|
|
456
|
+
const existingHash = this.u32[entryBase / U32];
|
|
457
|
+
if (existingHash === hash) return hash;
|
|
458
|
+
}
|
|
459
|
+
// Add new entry
|
|
460
|
+
const idx = Atomics.add(this.u32, ctrlBase + STR_CTRL.HEAD, 1);
|
|
461
|
+
if (idx >= this.layout.stringTableCap) {
|
|
462
|
+
// Table full — return hash anyway (reader won't resolve, but record is still useful)
|
|
463
|
+
return hash;
|
|
464
|
+
}
|
|
465
|
+
Atomics.add(this.u32, ctrlBase + STR_CTRL.COUNT, 1);
|
|
466
|
+
const entryBase = dataBase + idx * STRING_ENTRY_SIZE;
|
|
467
|
+
this.u32[entryBase / U32] = hash;
|
|
468
|
+
const chars = str.slice(0, PROFILING_STRING_MAX_LEN);
|
|
469
|
+
this.u16[(entryBase + U32) / U16] = chars.length;
|
|
470
|
+
// Write UTF-16 chars directly (matches JS string internal encoding)
|
|
471
|
+
for (let i = 0; i < chars.length; i++) {
|
|
472
|
+
this.u16[(entryBase + U32 + U16) / U16 + i] = chars.charCodeAt(i);
|
|
473
|
+
}
|
|
474
|
+
return hash;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Push a warning record to the global warning ring.
|
|
479
|
+
* Called from any worker or the renderer.
|
|
480
|
+
*/
|
|
481
|
+
pushWarningRecord(rec: {
|
|
482
|
+
ruleIdHash: number;
|
|
483
|
+
severity: number;
|
|
484
|
+
metricKind: number;
|
|
485
|
+
value: number;
|
|
486
|
+
threshold: number;
|
|
487
|
+
workerTag: number;
|
|
488
|
+
ts: number;
|
|
489
|
+
autoTraceFired: boolean;
|
|
490
|
+
}): void {
|
|
491
|
+
const ctrlBase = this.layout.warnCtrlOffset / U32;
|
|
492
|
+
const cap = this.layout.warningRingCap;
|
|
493
|
+
const head = Atomics.add(this.u32, ctrlBase + WARN_CTRL.HEAD, 1) % cap;
|
|
494
|
+
const curCount = Atomics.load(this.u32, ctrlBase + WARN_CTRL.COUNT);
|
|
495
|
+
if (curCount < cap) {
|
|
496
|
+
Atomics.add(this.u32, ctrlBase + WARN_CTRL.COUNT, 1);
|
|
497
|
+
}
|
|
498
|
+
// Bump the sequence number
|
|
499
|
+
Atomics.add(this.u32, ctrlBase + WARN_CTRL.SEQ, 1);
|
|
500
|
+
// Also bump the header's WARNING_SEQ for fast polling
|
|
501
|
+
Atomics.add(this.u32, HDR.WARNING_SEQ, 1);
|
|
502
|
+
|
|
503
|
+
const entryBase = this.layout.warnDataOffset + head * WARNING_RECORD_SIZE;
|
|
504
|
+
this.u32[(entryBase + WR.RULE_ID_HASH) / U32] = rec.ruleIdHash;
|
|
505
|
+
this.u8[entryBase + WR.SEVERITY] = rec.severity;
|
|
506
|
+
this.u8[entryBase + WR.METRIC_KIND] = rec.metricKind;
|
|
507
|
+
this.f32[(entryBase + WR.VALUE) / U32] = rec.value;
|
|
508
|
+
this.f32[(entryBase + WR.THRESHOLD) / U32] = rec.threshold;
|
|
509
|
+
this.u32[(entryBase + WR.WORKER_TAG) / U32] = rec.workerTag;
|
|
510
|
+
// Pack autoTraceFired into the high bit of TS
|
|
511
|
+
const ts = (rec.ts & 0x7fffffff) | (rec.autoTraceFired ? 0x80000000 : 0);
|
|
512
|
+
this.u32[(entryBase + WR.TS) / U32] = ts;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// ─── Slot claiming (worker side) ────────────────────────────────────────────
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Attempt to claim a free slot in the SAB.
|
|
520
|
+
* Uses atomic CAS on the slot's ALIVE field. Returns the slot index or -1
|
|
521
|
+
* if all slots are taken.
|
|
522
|
+
*/
|
|
523
|
+
export function claimSlot(
|
|
524
|
+
sab: SharedArrayBuffer,
|
|
525
|
+
layout: ProfilingSABLayout,
|
|
526
|
+
workerTagHash: number,
|
|
527
|
+
runtime: RuntimeKind,
|
|
528
|
+
name: string,
|
|
529
|
+
): number {
|
|
530
|
+
const u32 = new Uint32Array(sab);
|
|
531
|
+
const u16 = new Uint16Array(sab);
|
|
532
|
+
for (let i = 0; i < layout.maxSlots; i++) {
|
|
533
|
+
const base = (layout.slotTableOffset / U32) + i * (SLOT_HEADER_SIZE / U32);
|
|
534
|
+
const expected = 0;
|
|
535
|
+
const got = Atomics.compareExchange(u32, base + SH.ALIVE, expected, 1);
|
|
536
|
+
if (got === expected) {
|
|
537
|
+
// Claimed! Fill in the slot header.
|
|
538
|
+
u32[base + SH.WORKER_TAG] = workerTagHash;
|
|
539
|
+
u32[base + SH.RUNTIME] = runtime;
|
|
540
|
+
u32[base + SH.SLOT_INDEX] = i;
|
|
541
|
+
// Write the name into the slot's string table (first entry)
|
|
542
|
+
const strDataBase = layout.strDataOffset(i);
|
|
543
|
+
const nameHash = fnv1a32(name);
|
|
544
|
+
u32[strDataBase / U32] = nameHash;
|
|
545
|
+
const chars = name.slice(0, PROFILING_STRING_MAX_LEN);
|
|
546
|
+
u16[(strDataBase + U32) / U16] = chars.length;
|
|
547
|
+
for (let j = 0; j < chars.length; j++) {
|
|
548
|
+
u16[(strDataBase + U32 + U16) / U16 + j] = chars.charCodeAt(j);
|
|
549
|
+
}
|
|
550
|
+
u32[base + SH.NAME_OFFSET] = 0; // name is at string table index 0
|
|
551
|
+
u32[base + SH.NAME_LEN] = chars.length;
|
|
552
|
+
// Set string table count to 1
|
|
553
|
+
const strCtrlBase = layout.strCtrlOffset(i) / U32;
|
|
554
|
+
Atomics.store(u32, strCtrlBase + STR_CTRL.HEAD, 1);
|
|
555
|
+
Atomics.store(u32, strCtrlBase + STR_CTRL.COUNT, 1);
|
|
556
|
+
// Bump epoch + active slots
|
|
557
|
+
Atomics.add(u32, HDR.EPOCH, 1);
|
|
558
|
+
Atomics.add(u32, HDR.ACTIVE_SLOTS, 1);
|
|
559
|
+
return i;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return -1;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/** Release a slot (mark it as free). Called on worker shutdown. */
|
|
566
|
+
export function releaseSlot(sab: SharedArrayBuffer, layout: ProfilingSABLayout, slotIndex: number): void {
|
|
567
|
+
const u32 = new Uint32Array(sab);
|
|
568
|
+
const base = (layout.slotTableOffset / U32) + slotIndex * (SLOT_HEADER_SIZE / U32);
|
|
569
|
+
Atomics.store(u32, base + SH.ALIVE, 0);
|
|
570
|
+
Atomics.add(u32, HDR.EPOCH, 1);
|
|
571
|
+
Atomics.sub(u32, HDR.ACTIVE_SLOTS, 1);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// ─── ProfilingSABReader (renderer / devtools side) ──────────────────────────
|
|
575
|
+
|
|
576
|
+
export interface SlotSnapshot {
|
|
577
|
+
slotIndex: number;
|
|
578
|
+
alive: boolean;
|
|
579
|
+
workerTag: number;
|
|
580
|
+
runtime: RuntimeKind;
|
|
581
|
+
name: string;
|
|
582
|
+
metrics: ThreadMetricsSnapshot;
|
|
583
|
+
eventLoop: EventLoopSnapshot;
|
|
584
|
+
iopsRecords: IopsRecordSnapshot[];
|
|
585
|
+
tagTable: Map<number, string>;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export interface ThreadMetricsSnapshot {
|
|
589
|
+
heapUsed: number;
|
|
590
|
+
heapTotal: number;
|
|
591
|
+
rss: number;
|
|
592
|
+
cpuTimeMs: number;
|
|
593
|
+
cpuPercent: number;
|
|
594
|
+
gcPauseTotalUs: number;
|
|
595
|
+
gcPauseCount: number;
|
|
596
|
+
gcPauseMaxUs: number;
|
|
597
|
+
tick: number;
|
|
598
|
+
taskCount: number;
|
|
599
|
+
taskLatencyP50Us: number;
|
|
600
|
+
taskLatencyP95Us: number;
|
|
601
|
+
taskLatencyP99Us: number;
|
|
602
|
+
taskLatencyMaxUs: number;
|
|
603
|
+
lastUpdateMs: number;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export interface EventLoopSnapshot {
|
|
607
|
+
rafJitterP50Us: number;
|
|
608
|
+
rafJitterP95Us: number;
|
|
609
|
+
rafJitterMaxUs: number;
|
|
610
|
+
longtaskCount: number;
|
|
611
|
+
longtaskTotalMs: number;
|
|
612
|
+
longtaskMaxMs: number;
|
|
613
|
+
idleHeadroomMs: number;
|
|
614
|
+
expectedFrameMs: number;
|
|
615
|
+
lastUpdateMs: number;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export interface IopsRecordSnapshot {
|
|
619
|
+
opKind: number;
|
|
620
|
+
store: number;
|
|
621
|
+
tagHash: number;
|
|
622
|
+
bytes: number;
|
|
623
|
+
latencyUs: number;
|
|
624
|
+
ts: number;
|
|
625
|
+
workerTag: number;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
export interface WarningRecordSnapshot {
|
|
629
|
+
ruleIdHash: number;
|
|
630
|
+
severity: number;
|
|
631
|
+
metricKind: number;
|
|
632
|
+
value: number;
|
|
633
|
+
threshold: number;
|
|
634
|
+
workerTag: number;
|
|
635
|
+
ts: number;
|
|
636
|
+
autoTraceFired: boolean;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export interface ProfilingSnapshot {
|
|
640
|
+
slots: SlotSnapshot[];
|
|
641
|
+
warnings: WarningRecordSnapshot[];
|
|
642
|
+
globalTick: number;
|
|
643
|
+
warningSeq: number;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Reader for the ProfilingSAB. Used by the renderer's ProfilingBridge and
|
|
648
|
+
* the devtools profiling views to read all slots + drain the warning ring.
|
|
649
|
+
*/
|
|
650
|
+
export class ProfilingSABReader {
|
|
651
|
+
private u32: Uint32Array;
|
|
652
|
+
private f32: Float32Array;
|
|
653
|
+
private u16: Uint16Array;
|
|
654
|
+
private u8: Uint8Array;
|
|
655
|
+
private layout: ProfilingSABLayout;
|
|
656
|
+
private lastWarningCount: number = 0;
|
|
657
|
+
|
|
658
|
+
constructor(sab: SharedArrayBuffer, layout: ProfilingSABLayout) {
|
|
659
|
+
this.u32 = new Uint32Array(sab);
|
|
660
|
+
this.f32 = new Float32Array(sab);
|
|
661
|
+
this.u16 = new Uint16Array(sab);
|
|
662
|
+
this.u8 = new Uint8Array(sab);
|
|
663
|
+
this.layout = layout;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
getLayout(): ProfilingSABLayout {
|
|
667
|
+
return this.layout;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/** Read a full snapshot of all alive slots + new warnings. */
|
|
671
|
+
readSnapshot(): ProfilingSnapshot {
|
|
672
|
+
const slots: SlotSnapshot[] = [];
|
|
673
|
+
for (let i = 0; i < this.layout.maxSlots; i++) {
|
|
674
|
+
const base = (this.layout.slotTableOffset / U32) + i * (SLOT_HEADER_SIZE / U32);
|
|
675
|
+
const alive = Atomics.load(this.u32, base + SH.ALIVE) === 1;
|
|
676
|
+
if (!alive) continue;
|
|
677
|
+
const workerTag = this.u32[base + SH.WORKER_TAG];
|
|
678
|
+
const runtime = this.u32[base + SH.RUNTIME] as RuntimeKind;
|
|
679
|
+
const name = this.readSlotName(i);
|
|
680
|
+
const metrics = this.readMetrics(i);
|
|
681
|
+
const eventLoop = this.readEventLoop(i);
|
|
682
|
+
const iopsRecords = this.drainIops(i);
|
|
683
|
+
const tagTable = this.readTagTable(i);
|
|
684
|
+
slots.push({ slotIndex: i, alive, workerTag, runtime, name, metrics, eventLoop, iopsRecords, tagTable });
|
|
685
|
+
}
|
|
686
|
+
const warnings = this.drainWarnings();
|
|
687
|
+
const globalTick = Atomics.load(this.u32, HDR.GLOBAL_TICK);
|
|
688
|
+
const warningSeq = Atomics.load(this.u32, HDR.WARNING_SEQ);
|
|
689
|
+
return { slots, warnings, globalTick, warningSeq };
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/** Increment the global tick counter (renderer calls this each frame). */
|
|
693
|
+
bumpGlobalTick(): void {
|
|
694
|
+
Atomics.add(this.u32, HDR.GLOBAL_TICK, 1);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
private readSlotName(slotIndex: number): string {
|
|
698
|
+
const base = (this.layout.slotTableOffset / U32) + slotIndex * (SLOT_HEADER_SIZE / U32);
|
|
699
|
+
const nameLen = this.u32[base + SH.NAME_LEN];
|
|
700
|
+
if (nameLen === 0) return "";
|
|
701
|
+
const strDataBase = this.layout.strDataOffset(slotIndex);
|
|
702
|
+
let s = "";
|
|
703
|
+
for (let j = 0; j < nameLen; j++) {
|
|
704
|
+
s += String.fromCharCode(this.u16[(strDataBase + U32 + U16) / U16 + j]);
|
|
705
|
+
}
|
|
706
|
+
return s;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
private readMetrics(slotIndex: number): ThreadMetricsSnapshot {
|
|
710
|
+
const base = this.layout.metricsOffset(slotIndex) / U32;
|
|
711
|
+
return {
|
|
712
|
+
heapUsed: this.u32[base + TM.HEAP_USED],
|
|
713
|
+
heapTotal: this.u32[base + TM.HEAP_TOTAL],
|
|
714
|
+
rss: this.u32[base + TM.RSS],
|
|
715
|
+
cpuTimeMs: this.f32[base + TM.CPU_TIME_MS],
|
|
716
|
+
cpuPercent: this.f32[base + TM.CPU_PERCENT],
|
|
717
|
+
gcPauseTotalUs: this.u32[base + TM.GC_PAUSE_TOTAL],
|
|
718
|
+
gcPauseCount: this.u32[base + TM.GC_PAUSE_COUNT],
|
|
719
|
+
gcPauseMaxUs: this.u32[base + TM.GC_PAUSE_MAX],
|
|
720
|
+
tick: this.u32[base + TM.TICK],
|
|
721
|
+
taskCount: this.u32[base + TM.TASK_COUNT],
|
|
722
|
+
taskLatencyP50Us: this.f32[base + TM.TASK_LATENCY_P50],
|
|
723
|
+
taskLatencyP95Us: this.f32[base + TM.TASK_LATENCY_P95],
|
|
724
|
+
taskLatencyP99Us: this.f32[base + TM.TASK_LATENCY_P99],
|
|
725
|
+
taskLatencyMaxUs: this.u32[base + TM.TASK_LATENCY_MAX],
|
|
726
|
+
lastUpdateMs: this.f32[base + TM.LAST_UPDATE_MS],
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
private readEventLoop(slotIndex: number): EventLoopSnapshot {
|
|
731
|
+
const base = this.layout.eventLoopOffset(slotIndex) / U32;
|
|
732
|
+
return {
|
|
733
|
+
rafJitterP50Us: this.f32[base + EL.RAF_JITTER_P50],
|
|
734
|
+
rafJitterP95Us: this.f32[base + EL.RAF_JITTER_P95],
|
|
735
|
+
rafJitterMaxUs: this.u32[base + EL.RAF_JITTER_MAX],
|
|
736
|
+
longtaskCount: this.u32[base + EL.LONGTASK_COUNT],
|
|
737
|
+
longtaskTotalMs: this.u32[base + EL.LONGTASK_TOTAL_MS],
|
|
738
|
+
longtaskMaxMs: this.u32[base + EL.LONGTASK_MAX_MS],
|
|
739
|
+
idleHeadroomMs: this.u32[base + EL.IDLE_HEADROOM_MS],
|
|
740
|
+
expectedFrameMs: this.f32[base + EL.EXPECTED_FRAME_MS],
|
|
741
|
+
lastUpdateMs: this.f32[base + EL.LAST_UPDATE_MS],
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Drain IOPS records from a slot's ring.
|
|
747
|
+
* Returns all available records and resets the count to 0.
|
|
748
|
+
* The head continues to advance (we read from 0..count).
|
|
749
|
+
*/
|
|
750
|
+
private drainIops(slotIndex: number): IopsRecordSnapshot[] {
|
|
751
|
+
const ctrlBase = this.layout.iopsCtrlOffset(slotIndex) / U32;
|
|
752
|
+
const count = Atomics.load(this.u32, ctrlBase + IOPS_CTRL.COUNT);
|
|
753
|
+
if (count === 0) return [];
|
|
754
|
+
const cap = this.layout.iopsRingCap;
|
|
755
|
+
const head = Atomics.load(this.u32, ctrlBase + IOPS_CTRL.HEAD);
|
|
756
|
+
// Read the last `count` entries (they wrap around the ring)
|
|
757
|
+
const records: IopsRecordSnapshot[] = [];
|
|
758
|
+
const readCount = Math.min(count, cap);
|
|
759
|
+
for (let i = 0; i < readCount; i++) {
|
|
760
|
+
// Most recent entries are at (head - 1 - i) mod cap
|
|
761
|
+
const idx = (head - 1 - i + cap * 2) % cap;
|
|
762
|
+
const entryBase = this.layout.iopsDataOffset(slotIndex) + idx * IOPS_RECORD_SIZE;
|
|
763
|
+
records.push({
|
|
764
|
+
opKind: this.u16[entryBase / U16 + IR.OP_KIND / U16],
|
|
765
|
+
store: this.u8[entryBase + IR.STORE],
|
|
766
|
+
tagHash: this.u32[(entryBase + IR.TAG_HASH) / U32],
|
|
767
|
+
bytes: this.u32[(entryBase + IR.BYTES) / U32],
|
|
768
|
+
latencyUs: this.u32[(entryBase + IR.LATENCY_US) / U32],
|
|
769
|
+
ts: this.u32[(entryBase + IR.TS) / U32],
|
|
770
|
+
workerTag: this.u32[(entryBase + IR.WORKER_TAG) / U32],
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
// Reset count (we've consumed them)
|
|
774
|
+
Atomics.store(this.u32, ctrlBase + IOPS_CTRL.COUNT, 0);
|
|
775
|
+
return records;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
private readTagTable(slotIndex: number): Map<number, string> {
|
|
779
|
+
const ctrlBase = this.layout.strCtrlOffset(slotIndex) / U32;
|
|
780
|
+
const count = Atomics.load(this.u32, ctrlBase + STR_CTRL.COUNT);
|
|
781
|
+
const table = new Map<number, string>();
|
|
782
|
+
const dataBase = this.layout.strDataOffset(slotIndex);
|
|
783
|
+
for (let i = 0; i < count; i++) {
|
|
784
|
+
const entryBase = dataBase + i * STRING_ENTRY_SIZE;
|
|
785
|
+
const hash = this.u32[entryBase / U32];
|
|
786
|
+
const len = this.u16[(entryBase + U32) / U16];
|
|
787
|
+
let s = "";
|
|
788
|
+
for (let j = 0; j < len; j++) {
|
|
789
|
+
s += String.fromCharCode(this.u16[(entryBase + U32 + U16) / U16 + j]);
|
|
790
|
+
}
|
|
791
|
+
table.set(hash, s);
|
|
792
|
+
}
|
|
793
|
+
return table;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Drain new warnings from the global warning ring.
|
|
798
|
+
* Tracks how many we've already consumed; returns only new entries.
|
|
799
|
+
*/
|
|
800
|
+
drainWarnings(): WarningRecordSnapshot[] {
|
|
801
|
+
const ctrlBase = this.layout.warnCtrlOffset / U32;
|
|
802
|
+
const count = Atomics.load(this.u32, ctrlBase + WARN_CTRL.COUNT);
|
|
803
|
+
if (count <= this.lastWarningCount) return [];
|
|
804
|
+
const cap = this.layout.warningRingCap;
|
|
805
|
+
const head = Atomics.load(this.u32, ctrlBase + WARN_CTRL.HEAD);
|
|
806
|
+
const newCount = count - this.lastWarningCount;
|
|
807
|
+
const warnings: WarningRecordSnapshot[] = [];
|
|
808
|
+
for (let i = 0; i < newCount; i++) {
|
|
809
|
+
const idx = (head - 1 - i + cap * 2) % cap;
|
|
810
|
+
const entryBase = this.layout.warnDataOffset + idx * WARNING_RECORD_SIZE;
|
|
811
|
+
const ts = this.u32[(entryBase + WR.TS) / U32];
|
|
812
|
+
warnings.push({
|
|
813
|
+
ruleIdHash: this.u32[(entryBase + WR.RULE_ID_HASH) / U32],
|
|
814
|
+
severity: this.u8[entryBase + WR.SEVERITY],
|
|
815
|
+
metricKind: this.u8[entryBase + WR.METRIC_KIND],
|
|
816
|
+
value: this.f32[(entryBase + WR.VALUE) / U32],
|
|
817
|
+
threshold: this.f32[(entryBase + WR.THRESHOLD) / U32],
|
|
818
|
+
workerTag: this.u32[(entryBase + WR.WORKER_TAG) / U32],
|
|
819
|
+
ts: ts & 0x7fffffff,
|
|
820
|
+
autoTraceFired: (ts & 0x80000000) !== 0,
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
this.lastWarningCount = count;
|
|
824
|
+
return warnings;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// ─── Hashing ────────────────────────────────────────────────────────────────
|
|
829
|
+
|
|
830
|
+
/** FNV-1a 32-bit hash. Fast, good distribution for short strings. */
|
|
831
|
+
export function fnv1a32(str: string): number {
|
|
832
|
+
let hash = 0x811c9dc5;
|
|
833
|
+
for (let i = 0; i < str.length; i++) {
|
|
834
|
+
hash ^= str.charCodeAt(i);
|
|
835
|
+
hash = Math.imul(hash, 0x01000193);
|
|
836
|
+
}
|
|
837
|
+
// Force unsigned
|
|
838
|
+
return hash >>> 0;
|
|
839
|
+
}
|