@woosh/meep-engine 3.46.0 → 3.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (827) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
  3. package/editor/actions/concrete/TransformModifyAction.js +10 -2
  4. package/editor/ecs/component/FieldDescriptor.js +15 -0
  5. package/editor/ecs/component/createObjectEditor.js +41 -12
  6. package/editor/ecs/component/editors/ecs/Transform64Editor.d.ts.map +1 -1
  7. package/editor/ecs/component/editors/ecs/Transform64Editor.js +77 -70
  8. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +1 -2
  9. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  10. package/editor/particles/effect/ParticleReferenceSimulation.js +2 -4
  11. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  12. package/editor/tools/TransformToolV2.js +4 -0
  13. package/editor/tools/v2/TransformControls.d.ts.map +1 -1
  14. package/editor/tools/v2/TransformControls.js +7 -0
  15. package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
  16. package/editor/view/ecs/EntityEditor.js +4 -2
  17. package/editor/view/particles/effect/ParticleGraphEditorView.js +1 -1
  18. package/package.json +1 -1
  19. package/src/core/collection/array/array_insert_at.d.ts +16 -0
  20. package/src/core/collection/array/array_insert_at.d.ts.map +1 -0
  21. package/src/core/collection/array/array_insert_at.js +32 -0
  22. package/src/core/collection/array/array_remove_at.d.ts +15 -0
  23. package/src/core/collection/array/array_remove_at.d.ts.map +1 -0
  24. package/src/core/collection/array/array_remove_at.js +30 -0
  25. package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts +37 -0
  26. package/src/core/geom/3d/quaternion/quat3_look_rotation.d.ts.map +1 -0
  27. package/src/core/geom/3d/quaternion/quat3_look_rotation.js +172 -0
  28. package/src/core/geom/Quaternion.d.ts +1 -0
  29. package/src/core/geom/Quaternion.d.ts.map +1 -1
  30. package/src/core/geom/Quaternion.js +12 -48
  31. package/src/engine/Engine.d.ts.map +1 -1
  32. package/src/engine/Engine.js +9 -4
  33. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +27 -11
  34. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  35. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +21 -0
  36. package/src/engine/ecs/transform/t64_look_rotation.d.ts +4 -4
  37. package/src/engine/ecs/transform/t64_look_rotation.d.ts.map +1 -1
  38. package/src/engine/ecs/transform/t64_look_rotation.js +7 -18
  39. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  40. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +30 -1
  41. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +2 -2
  42. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
  43. package/src/engine/graphics/ecs/particles/ParticleEffect.js +7 -7
  44. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +8 -0
  45. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -1
  46. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +11 -3
  47. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts +26 -0
  48. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts.map +1 -0
  49. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.js +91 -0
  50. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -0
  51. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  52. package/src/engine/graphics3/GPUParticleEmitterSystem.js +72 -29
  53. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  54. package/src/engine/graphics3/GraphicsEngine.js +8 -1
  55. package/src/engine/graphics3/ParticipatingMedia.d.ts +84 -1
  56. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
  57. package/src/engine/graphics3/ParticipatingMedia.js +139 -5
  58. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +6 -2
  59. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -1
  60. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +29 -4
  61. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts +10 -0
  62. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts.map +1 -0
  63. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.js +38 -0
  64. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
  65. package/src/engine/graphics3/ParticipatingMediaSystem.js +46 -3
  66. package/src/engine/input/devices/KeyboardDevice.d.ts +1 -0
  67. package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
  68. package/src/engine/input/devices/KeyboardDevice.js +7 -6
  69. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
  70. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +15 -2
  71. package/src/engine/network/CONGESTION_CONTROL.md +9 -9
  72. package/src/engine/network/MESSAGE_TRANSPORT.md +364 -0
  73. package/src/engine/network/NetworkSession.d.ts +47 -16
  74. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  75. package/src/engine/network/NetworkSession.js +556 -292
  76. package/src/engine/network/README.md +104 -28
  77. package/src/engine/network/SMOOTHNESS_DESIGN.md +13 -5
  78. package/src/engine/network/diagnostics/BandwidthMeter.d.ts +1 -1
  79. package/src/engine/network/diagnostics/BandwidthMeter.js +1 -1
  80. package/src/engine/network/orchestrator/HostJoin.d.ts +111 -0
  81. package/src/engine/network/orchestrator/HostJoin.d.ts.map +1 -0
  82. package/src/engine/network/orchestrator/HostJoin.js +271 -0
  83. package/src/engine/network/orchestrator/NetworkPeer.d.ts +151 -112
  84. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  85. package/src/engine/network/orchestrator/NetworkPeer.js +450 -499
  86. package/src/engine/network/orchestrator/PendingSlices.d.ts +30 -0
  87. package/src/engine/network/orchestrator/PendingSlices.d.ts.map +1 -0
  88. package/src/engine/network/orchestrator/PendingSlices.js +83 -0
  89. package/src/engine/network/orchestrator/ReliableFrames.d.ts +34 -0
  90. package/src/engine/network/orchestrator/ReliableFrames.d.ts.map +1 -0
  91. package/src/engine/network/orchestrator/ReliableFrames.js +96 -0
  92. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +77 -10
  93. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  94. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +236 -61
  95. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +59 -23
  96. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  97. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +213 -198
  98. package/src/engine/network/replication/Replicator.d.ts +15 -4
  99. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  100. package/src/engine/network/replication/Replicator.js +57 -17
  101. package/src/engine/network/sim/ActionLog.d.ts +32 -5
  102. package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
  103. package/src/engine/network/sim/ActionLog.js +47 -5
  104. package/src/engine/network/sim/SimActionExecutor.d.ts +42 -2
  105. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  106. package/src/engine/network/sim/SimActionExecutor.js +100 -4
  107. package/src/engine/network/sim/Snapshotter.d.ts +12 -0
  108. package/src/engine/network/sim/Snapshotter.d.ts.map +1 -1
  109. package/src/engine/network/sim/Snapshotter.js +43 -0
  110. package/src/engine/network/state/Baseline.d.ts +1 -1
  111. package/src/engine/network/state/Baseline.js +1 -1
  112. package/src/engine/network/state/FrameBufferRing.d.ts +25 -6
  113. package/src/engine/network/state/FrameBufferRing.d.ts.map +1 -1
  114. package/src/engine/network/state/FrameBufferRing.js +51 -6
  115. package/src/engine/network/state/InputRing.d.ts +4 -0
  116. package/src/engine/network/state/InputRing.d.ts.map +1 -1
  117. package/src/engine/network/state/InputRing.js +7 -0
  118. package/src/engine/network/state/RecordArrivalRing.d.ts +57 -0
  119. package/src/engine/network/state/RecordArrivalRing.d.ts.map +1 -0
  120. package/src/engine/network/state/RecordArrivalRing.js +144 -0
  121. package/src/engine/network/transport/DeferredTransport.d.ts.map +1 -1
  122. package/src/engine/network/transport/DeferredTransport.js +1 -0
  123. package/src/engine/network/transport/LoopbackTransport.d.ts.map +1 -1
  124. package/src/engine/network/transport/LoopbackTransport.js +4 -2
  125. package/src/engine/network/transport/Transport.d.ts +7 -0
  126. package/src/engine/network/transport/Transport.d.ts.map +1 -1
  127. package/src/engine/network/transport/Transport.js +8 -0
  128. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -1
  129. package/src/engine/network/transport/adapters/NodeUDPTransport.js +20 -5
  130. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts.map +1 -1
  131. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +8 -0
  132. package/src/engine/network/transport/adapters/WebTransportTransport.d.ts.map +1 -1
  133. package/src/engine/network/transport/adapters/WebTransportTransport.js +6 -0
  134. package/src/engine/network/transport/connection/Connection.d.ts +191 -0
  135. package/src/engine/network/transport/connection/Connection.d.ts.map +1 -0
  136. package/src/engine/network/transport/connection/Connection.js +1262 -0
  137. package/src/engine/network/transport/connection/RangeSet.d.ts +94 -0
  138. package/src/engine/network/transport/connection/RangeSet.d.ts.map +1 -0
  139. package/src/engine/network/transport/connection/RangeSet.js +260 -0
  140. package/src/engine/network/transport/connection/RxStream.d.ts +48 -0
  141. package/src/engine/network/transport/connection/RxStream.d.ts.map +1 -0
  142. package/src/engine/network/transport/connection/RxStream.js +211 -0
  143. package/src/engine/network/transport/connection/TxStream.d.ts +90 -0
  144. package/src/engine/network/transport/connection/TxStream.d.ts.map +1 -0
  145. package/src/engine/network/transport/connection/TxStream.js +243 -0
  146. package/src/engine/network/transport/connection/bytes_copy.d.ts +17 -0
  147. package/src/engine/network/transport/connection/bytes_copy.d.ts.map +1 -0
  148. package/src/engine/network/transport/connection/bytes_copy.js +34 -0
  149. package/src/engine/network/transport/connection/varint.d.ts +46 -0
  150. package/src/engine/network/transport/connection/varint.d.ts.map +1 -0
  151. package/src/engine/network/transport/connection/varint.js +107 -0
  152. package/src/engine/physics/cloth/MEASUREMENTS.md +354 -0
  153. package/src/engine/physics/cloth/PLAN.md +85 -5
  154. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +0 -12
  155. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  156. package/src/engine/physics/cloth/ecs/ClothInstance.js +0 -13
  157. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +2 -1
  158. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  159. package/src/engine/physics/cloth/ecs/ClothSystem.js +7 -1
  160. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  161. package/src/engine/physics/cloth/ecs/ClothWorld.js +4 -15
  162. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +2 -1
  163. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  164. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +6 -1
  165. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  166. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +20 -10
  167. package/src/engine/physics/cloth/playground/collide.html +5 -3
  168. package/src/engine/physics/cloth/playground/collide_main.js +14 -13
  169. package/src/engine/physics/cloth/solver/ClothState.d.ts +30 -2
  170. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  171. package/src/engine/physics/cloth/solver/ClothState.js +62 -4
  172. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +11 -3
  173. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  174. package/src/engine/physics/cloth/solver/cloth_self_find.js +52 -11
  175. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts +42 -0
  176. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts.map +1 -0
  177. package/src/engine/physics/cloth/solver/cloth_self_radius.js +64 -0
  178. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +99 -24
  179. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  180. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +102 -25
  181. package/src/engine/physics/cloth/solver/cloth_step.d.ts +5 -1
  182. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  183. package/src/engine/physics/cloth/solver/cloth_step.js +13 -3
  184. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +0 -1
  185. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  186. package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -14
  187. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +23 -4
  188. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  189. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +36 -8
  190. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  191. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +4 -2
  192. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  193. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +38 -7
  194. package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -1
  195. package/src/engine/sound/ecs/audio/AudioEmitter.js +35 -7
  196. package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.d.ts.map +1 -1
  197. package/src/engine/sound/ecs/audio/AudioEmitterSerializationAdapter.js +5 -1
  198. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts +18 -0
  199. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.d.ts.map +1 -0
  200. package/src/engine/sound/ecs/audio/AudioEmitterSerializationUpgrader_0_1.js +48 -0
  201. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +12 -2
  202. package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -1
  203. package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +173 -9
  204. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +9 -3
  205. package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -1
  206. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +28 -8
  207. package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts +8 -0
  208. package/src/engine/sound/ecs/trigger/AudioEventTrigger.d.ts.map +1 -1
  209. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.d.ts.map +1 -1
  210. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationAdapter.js +5 -1
  211. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts +18 -0
  212. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.d.ts.map +1 -0
  213. package/src/engine/sound/ecs/trigger/AudioEventTriggerSerializationUpgrader_0_1.js +51 -0
  214. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.d.ts.map +1 -1
  215. package/src/engine/sound/ecs/trigger/AudioEventTriggerSystem.js +15 -1
  216. package/src/engine/sound/sopra/README.md +768 -644
  217. package/src/engine/sound/sopra/SopraEngine.d.ts +104 -8
  218. package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -1
  219. package/src/engine/sound/sopra/SopraEngine.js +327 -12
  220. package/src/engine/sound/sopra/definition/EventDescription.d.ts +28 -2
  221. package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
  222. package/src/engine/sound/sopra/definition/EventDescription.js +55 -5
  223. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +10 -0
  224. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -1
  225. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +77 -55
  226. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts +31 -0
  227. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.d.ts.map +1 -0
  228. package/src/engine/sound/sopra/definition/EventDescriptionSerializationUpgrader_0_1.js +75 -0
  229. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +38 -9
  230. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -1
  231. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +34 -5
  232. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +7 -2
  233. package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -1
  234. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +137 -122
  235. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +3 -1
  236. package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -1
  237. package/src/engine/sound/sopra/definition/effect/EqEffect.js +146 -131
  238. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +1 -0
  239. package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -1
  240. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +6 -1
  241. package/src/engine/sound/sopra/runtime/BusGraph.d.ts +44 -2
  242. package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -1
  243. package/src/engine/sound/sopra/runtime/BusGraph.js +83 -43
  244. package/src/engine/sound/sopra/runtime/EffectChain.d.ts +96 -0
  245. package/src/engine/sound/sopra/runtime/EffectChain.d.ts.map +1 -0
  246. package/src/engine/sound/sopra/runtime/EffectChain.js +286 -0
  247. package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts +123 -0
  248. package/src/engine/sound/sopra/runtime/EffectParamOverrides.d.ts.map +1 -0
  249. package/src/engine/sound/sopra/runtime/EffectParamOverrides.js +320 -0
  250. package/src/engine/sound/sopra/runtime/EventInstance.d.ts +55 -5
  251. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  252. package/src/engine/sound/sopra/runtime/EventInstance.js +201 -26
  253. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +2 -1
  254. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -1
  255. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +6 -1
  256. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +15 -0
  257. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -1
  258. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +32 -0
  259. package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -1
  260. package/src/engine/sound/sopra/util/MockAudioContext.js +3 -0
  261. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +13 -3
  262. package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -1
  263. package/src/engine/sound/sopra/util/fadeOutAndStop.js +25 -13
  264. package/src/shade/RENDERER_CONTRACT.md +6 -3
  265. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts +24 -0
  266. package/src/shade/device/SHADE_DEVICE_FLOOR.d.ts.map +1 -0
  267. package/src/shade/device/SHADE_DEVICE_FLOOR.js +34 -0
  268. package/src/shade/device/ShadeDeviceFailure.d.ts +12 -5
  269. package/src/shade/device/ShadeDeviceFailure.d.ts.map +1 -1
  270. package/src/shade/device/ShadeDeviceFailure.js +17 -8
  271. package/src/shade/device/ShadeDeviceFailureReason.d.ts +1 -1
  272. package/src/shade/device/ShadeDeviceFailureReason.js +2 -2
  273. package/src/shade/device/mock/SoftwareGPUDevice.d.ts +15 -0
  274. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  275. package/src/shade/device/mock/SoftwareGPUDevice.js +21 -0
  276. package/src/shade/device/pipeline/ComputePipelineManager.d.ts +20 -0
  277. package/src/shade/device/pipeline/ComputePipelineManager.d.ts.map +1 -1
  278. package/src/shade/device/pipeline/ComputePipelineManager.js +80 -6
  279. package/src/shade/device/pipeline/PipelineEnquiry.d.ts +52 -0
  280. package/src/shade/device/pipeline/PipelineEnquiry.d.ts.map +1 -0
  281. package/src/shade/device/pipeline/PipelineEnquiry.js +63 -0
  282. package/src/shade/device/pipeline/RenderPipelineManager.d.ts +21 -0
  283. package/src/shade/device/pipeline/RenderPipelineManager.d.ts.map +1 -1
  284. package/src/shade/device/pipeline/RenderPipelineManager.js +84 -4
  285. package/src/shade/device/shade_device_floor_unmet.d.ts +13 -0
  286. package/src/shade/device/shade_device_floor_unmet.d.ts.map +1 -0
  287. package/src/shade/device/shade_device_floor_unmet.js +32 -0
  288. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts +137 -0
  289. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts.map +1 -0
  290. package/src/shade/playground/contact_shadows/ContactShadowLab.js +654 -0
  291. package/src/shade/playground/contact_shadows/README.md +126 -0
  292. package/src/shade/playground/contact_shadows/index.html +191 -0
  293. package/src/shade/playground/contact_shadows/main.d.ts +2 -0
  294. package/src/shade/playground/contact_shadows/main.d.ts.map +1 -0
  295. package/src/shade/playground/contact_shadows/main.js +888 -0
  296. package/src/shade/playground/contact_shadows/scenes.d.ts +48 -0
  297. package/src/shade/playground/contact_shadows/scenes.d.ts.map +1 -0
  298. package/src/shade/playground/contact_shadows/scenes.js +620 -0
  299. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts +36 -0
  300. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts.map +1 -0
  301. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.js +245 -0
  302. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts +15 -0
  303. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts.map +1 -0
  304. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.js +120 -0
  305. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts +55 -0
  306. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts.map +1 -0
  307. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.js +216 -0
  308. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts +20 -0
  309. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts.map +1 -0
  310. package/src/shade/playground/contact_shadows/shader_contact_lab_view.js +114 -0
  311. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts +11 -0
  312. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts.map +1 -0
  313. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.js +90 -0
  314. package/src/shade/playground/contact_shadows/textures.d.ts +16 -0
  315. package/src/shade/playground/contact_shadows/textures.d.ts.map +1 -0
  316. package/src/shade/playground/contact_shadows/textures.js +123 -0
  317. package/src/shade/playground/particle_ecs/README.md +1 -1
  318. package/src/shade/playground/particle_ecs/effects/flame.json +1932 -1881
  319. package/src/shade/playground/particle_ecs/effects/smoke.json +99 -1
  320. package/src/shade/playground/particle_ecs/effects/soot.json +152 -145
  321. package/src/shade/playground/tonemap_sdr/README.md +90 -0
  322. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts +105 -0
  323. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts.map +1 -0
  324. package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +380 -0
  325. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts +32 -0
  326. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts.map +1 -0
  327. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.js +104 -0
  328. package/src/shade/playground/tonemap_sdr/index.html +90 -0
  329. package/src/shade/playground/tonemap_sdr/main.d.ts +2 -0
  330. package/src/shade/playground/tonemap_sdr/main.d.ts.map +1 -0
  331. package/src/shade/playground/tonemap_sdr/main.js +306 -0
  332. package/src/shade/playground/tonemap_sdr/scenes.d.ts +26 -0
  333. package/src/shade/playground/tonemap_sdr/scenes.d.ts.map +1 -0
  334. package/src/shade/playground/tonemap_sdr/scenes.js +404 -0
  335. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  336. package/src/shade/playground/volumetrics_froxel/main.js +85 -4
  337. package/src/shade/playground/water_refraction/README.md +26 -18
  338. package/src/shade/playground/water_refraction/index.html +1 -1
  339. package/src/shade/renderer/Renderer.d.ts +37 -3
  340. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  341. package/src/shade/renderer/Renderer.js +237 -67
  342. package/src/shade/renderer/ShadeToneMappingMode.d.ts +14 -0
  343. package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +1 -0
  344. package/src/shade/renderer/ShadeToneMappingMode.js +30 -0
  345. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +9 -0
  346. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  347. package/src/shade/renderer/animation/GPUAnimationManager.js +14 -0
  348. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  349. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +5 -3
  350. package/src/shade/renderer/buffer/GPUBufferAllocator.d.ts.map +1 -1
  351. package/src/shade/renderer/buffer/GPUBufferAllocator.js +9 -0
  352. package/src/shade/renderer/buffer/buffer_pool_ops.d.ts +21 -12
  353. package/src/shade/renderer/buffer/buffer_pool_ops.d.ts.map +1 -1
  354. package/src/shade/renderer/buffer/buffer_pool_ops.js +18 -19
  355. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +7 -0
  356. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  357. package/src/shade/renderer/buffer/table/GPUDatabase.js +12 -0
  358. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts +8 -0
  359. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  360. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +12 -0
  361. package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
  362. package/src/shade/renderer/camera/GPUCameraContext.js +19 -8
  363. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.d.ts.map +1 -1
  364. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.js +4 -0
  365. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts.map +1 -1
  366. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.js +4 -0
  367. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts.map +1 -1
  368. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.js +4 -0
  369. package/src/shade/renderer/deferred/shader_deferred_main.d.ts.map +1 -1
  370. package/src/shade/renderer/deferred/shader_deferred_main.js +3 -0
  371. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts +6 -0
  372. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  373. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +13 -3
  374. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts +9 -0
  375. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +1 -0
  376. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.js +63 -0
  377. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts +10 -0
  378. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -0
  379. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.js +87 -0
  380. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts +6 -0
  381. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +1 -1
  382. package/src/shade/renderer/deferred/shader_tonemap_LDR.js +23 -5
  383. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts +9 -0
  384. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +1 -0
  385. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.js +68 -0
  386. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts +10 -0
  387. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -0
  388. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.js +73 -0
  389. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  390. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +58 -9
  391. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +35 -25
  392. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  393. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +97 -196
  394. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +1 -1
  395. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +121 -129
  396. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  397. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +3 -0
  398. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  399. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -0
  400. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.d.ts.map +1 -1
  401. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.js +4 -0
  402. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  403. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +3 -0
  404. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  405. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +4 -0
  406. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.d.ts.map +1 -1
  407. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.js +4 -0
  408. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.d.ts.map +1 -1
  409. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.js +4 -0
  410. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +131 -1
  411. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts +7 -0
  412. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts.map +1 -1
  413. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.js +45 -38
  414. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts +2 -0
  415. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts.map +1 -1
  416. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.js +81 -79
  417. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts +2 -0
  418. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts.map +1 -1
  419. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.js +5 -3
  420. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts +21 -0
  421. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts.map +1 -0
  422. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.js +42 -0
  423. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts +19 -0
  424. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts.map +1 -0
  425. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.js +44 -0
  426. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +23 -5
  427. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
  428. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +139 -23
  429. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts +25 -0
  430. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts.map +1 -0
  431. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +179 -0
  432. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +2 -2
  433. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  434. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +7 -16
  435. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts +3 -4
  436. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  437. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +6 -23
  438. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +11 -0
  439. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  440. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +14 -3
  441. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts +10 -0
  442. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts.map +1 -1
  443. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.js +13 -3
  444. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +10 -0
  445. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  446. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +14 -0
  447. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts +26 -0
  448. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts.map +1 -0
  449. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.js +52 -0
  450. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts +32 -0
  451. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts.map +1 -0
  452. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.js +89 -0
  453. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +10 -0
  454. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  455. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +20 -1
  456. package/src/shade/renderer/gpu_primitive/test/gpu_test.d.ts.map +1 -1
  457. package/src/shade/renderer/gpu_primitive/test/gpu_test.js +8 -11
  458. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +10 -0
  459. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  460. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +294 -281
  461. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  462. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  463. package/src/shade/renderer/light/GPULightCollection.js +18 -1
  464. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +8 -0
  465. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  466. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +234 -218
  467. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +7 -0
  468. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  469. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +13 -0
  470. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +7 -0
  471. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
  472. package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +16 -2
  473. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +10 -0
  474. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  475. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +13 -0
  476. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  477. package/src/shade/renderer/lightmap/GPULightMap.js +3 -0
  478. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  479. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +4 -0
  480. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  481. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +4 -0
  482. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  483. package/src/shade/renderer/material/GPUMaterialManager.d.ts +16 -4
  484. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  485. package/src/shade/renderer/material/GPUMaterialManager.js +38 -8
  486. package/src/shade/renderer/particles/DESIGN.md +49 -7
  487. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +453 -0
  488. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +5 -1
  489. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  490. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +13 -5
  491. package/src/shade/renderer/particles/data/particle_emitter_record.js +2 -2
  492. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  493. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +12 -0
  494. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts +60 -0
  495. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  496. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +156 -0
  497. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +2 -2
  498. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  499. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +8 -8
  500. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
  501. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +6 -4
  502. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +7 -6
  503. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  504. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +91 -58
  505. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  506. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +10 -0
  507. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  508. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +5 -1
  509. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  510. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +6 -0
  511. package/src/shade/renderer/pool/TransientResourcePool.d.ts +24 -0
  512. package/src/shade/renderer/pool/TransientResourcePool.d.ts.map +1 -1
  513. package/src/shade/renderer/pool/TransientResourcePool.js +41 -10
  514. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts +7 -0
  515. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts.map +1 -1
  516. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +18 -0
  517. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts.map +1 -1
  518. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.js +1 -0
  519. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.d.ts.map +1 -1
  520. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.js +6 -4
  521. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +11 -0
  522. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  523. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +16 -0
  524. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +10 -0
  525. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  526. package/src/shade/renderer/postprocess/gtao/GTAO.js +16 -0
  527. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  528. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +32 -10
  529. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  530. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  531. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +3 -0
  532. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +1 -1
  533. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.js +6 -3
  534. package/src/shade/renderer/postprocess/taa/TAA.d.ts +12 -0
  535. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  536. package/src/shade/renderer/postprocess/taa/TAA.js +15 -0
  537. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts +7 -0
  538. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  539. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +13 -0
  540. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts +31 -3
  541. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts.map +1 -1
  542. package/src/shade/renderer/rasterize/TemplatePassDescriptor.js +79 -4
  543. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts +17 -0
  544. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts.map +1 -1
  545. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.js +35 -4
  546. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts +7 -0
  547. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  548. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +182 -169
  549. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts +10 -0
  550. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  551. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +20 -1
  552. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts +10 -0
  553. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts.map +1 -1
  554. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.js +18 -1
  555. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts +10 -0
  556. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  557. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +20 -1
  558. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts +7 -0
  559. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  560. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +187 -170
  561. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts +10 -0
  562. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  563. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +19 -1
  564. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts +13 -0
  565. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  566. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +25 -1
  567. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts +10 -0
  568. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  569. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +20 -0
  570. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  571. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -0
  572. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  573. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -0
  574. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  575. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  576. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  577. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +7 -2
  578. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  579. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +12 -4
  580. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -1
  581. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +4 -3
  582. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -1
  583. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +4 -3
  584. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +2 -1
  585. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  586. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +11 -3
  587. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  588. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -3
  589. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts.map +1 -1
  590. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -3
  591. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts +15 -0
  592. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  593. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +35 -2
  594. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts +14 -0
  595. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  596. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +32 -4
  597. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +17 -0
  598. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  599. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +34 -4
  600. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts +5 -3
  601. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
  602. package/src/shade/renderer/restir/di/chunk_restir_resolve.js +8 -3
  603. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  604. package/src/shade/renderer/restir/di/graph_restir_di.js +1 -0
  605. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  606. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +5 -1
  607. package/src/shade/renderer/restir/reservoir/shader.d.ts.map +1 -1
  608. package/src/shade/renderer/restir/reservoir/shader.js +7 -4
  609. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +7 -0
  610. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  611. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +13 -1
  612. package/src/shade/renderer/scene/GPUSceneContext.d.ts +10 -0
  613. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  614. package/src/shade/renderer/scene/GPUSceneContext.js +19 -0
  615. package/src/shade/renderer/scene/SceneManager.d.ts +9 -0
  616. package/src/shade/renderer/scene/SceneManager.d.ts.map +1 -1
  617. package/src/shade/renderer/scene/SceneManager.js +11 -0
  618. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts +11 -0
  619. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts.map +1 -1
  620. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.js +17 -0
  621. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +11 -0
  622. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  623. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +18 -1
  624. package/src/shade/renderer/shader/ComputeShader.d.ts +12 -0
  625. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  626. package/src/shade/renderer/shader/ComputeShader.js +71 -2
  627. package/src/shade/renderer/shader/ImageShader.d.ts +27 -8
  628. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  629. package/src/shade/renderer/shader/ImageShader.js +299 -218
  630. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +21 -0
  631. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  632. package/src/shade/renderer/shader/ShaderDescriptor.js +71 -1
  633. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts +17 -0
  634. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts.map +1 -0
  635. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.js +45 -0
  636. package/src/shade/renderer/shader/chunk/camera/chunk_screen_coordinate_to_view.js +3 -3
  637. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.d.ts +1 -1
  638. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.js +62 -62
  639. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +318 -0
  640. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +237 -0
  641. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts +17 -0
  642. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts.map +1 -0
  643. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js +22 -0
  644. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts +14 -1
  645. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts.map +1 -1
  646. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js +28 -15
  647. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts +12 -0
  648. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts.map +1 -1
  649. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js +128 -110
  650. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts +20 -0
  651. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts.map +1 -0
  652. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.js +33 -0
  653. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts +4 -0
  654. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts.map +1 -1
  655. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.js +12 -1
  656. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.d.ts.map +1 -1
  657. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js +7 -0
  658. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +108 -0
  659. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.d.ts.map +1 -1
  660. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.js +23 -4
  661. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts +18 -0
  662. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts.map +1 -0
  663. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.js +56 -0
  664. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.d.ts.map +1 -1
  665. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.js +2 -0
  666. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts +43 -0
  667. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts.map +1 -0
  668. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.js +319 -0
  669. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +33 -0
  670. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  671. package/src/shade/renderer/shader/compiler/CodeChunk.js +140 -0
  672. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts +74 -0
  673. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts.map +1 -0
  674. package/src/shade/renderer/shader/compiler/CodeChunkChoice.js +166 -0
  675. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +680 -0
  676. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts +86 -0
  677. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts.map +1 -0
  678. package/src/shade/renderer/shader/compiler/ShaderSwitch.js +178 -0
  679. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts +67 -0
  680. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts.map +1 -0
  681. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.js +205 -0
  682. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts +14 -0
  683. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts.map +1 -0
  684. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.js +13 -0
  685. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts +65 -0
  686. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts.map +1 -0
  687. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.js +252 -0
  688. package/src/shade/renderer/shadow/contact/FINDINGS.md +413 -0
  689. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts +29 -0
  690. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts.map +1 -0
  691. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.js +105 -0
  692. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts +29 -0
  693. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts.map +1 -0
  694. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.js +39 -0
  695. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts +29 -0
  696. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts.map +1 -0
  697. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.js +92 -0
  698. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts +29 -0
  699. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts.map +1 -0
  700. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.js +128 -0
  701. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts +52 -0
  702. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts.map +1 -0
  703. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.js +358 -0
  704. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts +10 -0
  705. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts.map +1 -0
  706. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.js +12 -0
  707. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts +13 -0
  708. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts.map +1 -0
  709. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.js +14 -0
  710. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +14 -8
  711. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  712. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +20 -86
  713. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts +14 -0
  714. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts.map +1 -0
  715. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.js +79 -0
  716. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.d.ts.map +1 -1
  717. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.js +12 -12
  718. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  719. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +153 -151
  720. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts +13 -0
  721. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts.map +1 -0
  722. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.js +48 -0
  723. package/src/shade/renderer/texture/GPUTextureContext.d.ts +10 -0
  724. package/src/shade/renderer/texture/GPUTextureContext.d.ts.map +1 -1
  725. package/src/shade/renderer/texture/GPUTextureContext.js +24 -0
  726. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +219 -0
  727. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -0
  728. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +671 -0
  729. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +26 -2
  730. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  731. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +108 -4
  732. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +5 -1
  733. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  734. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +6 -0
  735. package/src/shade/renderer/volumetrics/NOTES.md +50 -0
  736. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.d.ts.map +1 -1
  737. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.js +30 -1
  738. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +51 -13
  739. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  740. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +98 -13
  741. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +9 -0
  742. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  743. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +78 -68
  744. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +326 -0
  745. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts +7 -4
  746. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts.map +1 -1
  747. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.js +21 -9
  748. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts +19 -0
  749. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts.map +1 -0
  750. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.js +53 -0
  751. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +12 -3
  752. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -1
  753. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +85 -48
  754. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +4 -1
  755. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -1
  756. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +4 -1
  757. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +4 -1
  758. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  759. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +21 -1
  760. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts +98 -0
  761. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts.map +1 -0
  762. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js +115 -0
  763. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts +9 -0
  764. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts.map +1 -0
  765. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.js +24 -0
  766. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts +27 -0
  767. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts.map +1 -0
  768. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.js +91 -0
  769. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts +35 -0
  770. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts.map +1 -0
  771. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.js +92 -0
  772. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts +10 -0
  773. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts.map +1 -0
  774. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.js +121 -0
  775. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  776. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +38 -3
  777. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -1
  778. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +311 -290
  779. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.d.ts.map +1 -1
  780. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.js +28 -49
  781. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +3 -1
  782. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  783. package/src/shade/renderer/water/GPUWaterRenderer.js +24 -18
  784. package/src/shade/renderer/water/chunk_water_transport.d.ts +0 -1
  785. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  786. package/src/shade/renderer/water/chunk_water_transport.js +0 -17
  787. package/src/shade/renderer/water/shader_water.d.ts +4 -2
  788. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  789. package/src/shade/renderer/water/shader_water.js +27 -16
  790. package/src/shade/renderer/water/shader_water_avboit.d.ts +0 -4
  791. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  792. package/src/shade/renderer/water/shader_water_avboit.js +0 -63
  793. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  794. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +43 -9
  795. package/src/view/graphics/GraphicsContextFailureView.d.ts +1 -2
  796. package/src/view/graphics/GraphicsContextFailureView.d.ts.map +1 -1
  797. package/src/view/graphics/GraphicsContextFailureView.js +1 -2
  798. package/src/engine/network/transport/Channel.d.ts +0 -85
  799. package/src/engine/network/transport/Channel.d.ts.map +0 -1
  800. package/src/engine/network/transport/Channel.js +0 -336
  801. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +0 -155
  802. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +0 -1
  803. package/src/engine/network/transport/ReliableCommandPipeline.js +0 -335
  804. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts +0 -105
  805. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts.map +0 -1
  806. package/src/engine/network/transport/fragments/FragmentAssembler.js +0 -350
  807. package/src/engine/network/transport/fragments/FragmentRetention.d.ts +0 -103
  808. package/src/engine/network/transport/fragments/FragmentRetention.d.ts.map +0 -1
  809. package/src/engine/network/transport/fragments/FragmentRetention.js +0 -191
  810. package/src/engine/network/transport/fragments/fragment_send.d.ts +0 -61
  811. package/src/engine/network/transport/fragments/fragment_send.d.ts.map +0 -1
  812. package/src/engine/network/transport/fragments/fragment_send.js +0 -157
  813. package/src/engine/network/transport/fragments/packet_size.d.ts +0 -99
  814. package/src/engine/network/transport/fragments/packet_size.d.ts.map +0 -1
  815. package/src/engine/network/transport/fragments/packet_size.js +0 -107
  816. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts +0 -6
  817. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts.map +0 -1
  818. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.js +0 -16
  819. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts +0 -7
  820. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts.map +0 -1
  821. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.js +0 -46
  822. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts +0 -10
  823. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts.map +0 -1
  824. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.js +0 -127
  825. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts +0 -7
  826. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts.map +0 -1
  827. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.js +0 -39
@@ -0,0 +1,1262 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import Signal from "../../../../core/events/signal/Signal.js";
3
+ import { bytes_copy } from "./bytes_copy.js";
4
+ import { RangeSet } from "./RangeSet.js";
5
+ import { RX_ERROR, RX_NONE, RxStream } from "./RxStream.js";
6
+ import { TxStream } from "./TxStream.js";
7
+ import { varint_read, varint_size, varint_write } from "./varint.js";
8
+
9
+ /**
10
+ * Reliable lanes. Each is an ordered stream of messages; the lanes are independent of each other.
11
+ * @readonly
12
+ * @enum {number}
13
+ */
14
+ export const Lane = Object.freeze({
15
+ /** Engine control messages, one datagram each: resume answers, DISCONNECT. Not paced. */
16
+ CONTROL: 0,
17
+ /**
18
+ * Action-stream frames too large for a datagram. Not paced: the stream to the peer waits on
19
+ * them, and it cannot wait longer than its action log's ring.
20
+ */
21
+ FRAMES: 1,
22
+ /** Application messages that must arrive. Paced. */
23
+ USER: 2,
24
+ /** Large transfers: snapshot pages, state bursts. Paced, last. */
25
+ BULK: 3,
26
+ });
27
+
28
+ const LANE_COUNT = 4;
29
+
30
+ /** Lanes the token bucket holds back. */
31
+ const LANE_PACED = [false, false, true, true];
32
+
33
+ /** Protocol version, in the high nibble of every datagram's flags byte. */
34
+ const PROTOCOL_VERSION = 1;
35
+
36
+ /*
37
+ Wire format, one datagram:
38
+
39
+ u8 flags bit0 ACK present, bit1 packet number is 4 bytes (else 2),
40
+ bits 4-7 protocol version
41
+ u16|u32 packet number truncated, big-endian
42
+ [ACK] varint largest acknowledged (full packet number)
43
+ varint ack delay, units of 8 µs
44
+ varint additional range count
45
+ varint first range (packets below largest acknowledged, contiguous)
46
+ count × (varint gap, varint range length) RFC 9000 §19.3
47
+ frames to the end of the datagram:
48
+ 0x01 MESSAGE varint length, bytes unreliable, one datagram at most
49
+ 0x02 PING nothing asks for an ACK
50
+ 0x10|lane STREAM varint offset, varint length, bytes reliable
51
+ */
52
+
53
+ const FLAG_ACK = 0x01;
54
+ const FLAG_PN32 = 0x02;
55
+ const FLAGS_KNOWN = FLAG_ACK | FLAG_PN32 | (PROTOCOL_VERSION << 4);
56
+
57
+ const FRAME_MESSAGE = 0x01;
58
+ const FRAME_PING = 0x02;
59
+ const FRAME_STREAM = 0x10;
60
+ const FRAME_STREAM_LANE_MASK = 0x03;
61
+
62
+ /** flags byte + 4-byte packet number */
63
+ const PACKET_HEADER_MAX = 5;
64
+ /** type byte + 2-byte varint length (datagrams stay under 16,384 bytes) */
65
+ const MESSAGE_FRAME_HEADER_MAX = 3;
66
+ /** type byte + 8-byte offset + 2-byte length */
67
+ const STREAM_FRAME_HEADER_MAX = 11;
68
+ /** a stream frame is not started with less room than this for its bytes */
69
+ const STREAM_FRAME_MIN_PAYLOAD = 16;
70
+
71
+ /** RFC 9002 kPacketThreshold */
72
+ const PACKET_THRESHOLD = 3;
73
+ /** RFC 9002 kInitialRtt, ms */
74
+ const INITIAL_RTT_MS = 333;
75
+
76
+ /** Record kinds: what a packet carried that needs news of its fate. */
77
+ const RECORD_MESSAGE = 1;
78
+ const RECORD_STREAM = 2;
79
+
80
+ /** In-flight packets at most; past this the oldest is given up as lost. */
81
+ const MAX_IN_FLIGHT = 1 << 16;
82
+
83
+ /** Ack delay is sent in units of 8 µs. */
84
+ const ACK_DELAY_UNITS_PER_MS = 125;
85
+
86
+ /** Most ranges one ACK frame may carry: a receiver refuses more. */
87
+ const MAX_ACK_RANGES = 64;
88
+
89
+ /**
90
+ * One connection to one peer over a datagram {@link Transport}: numbered packets acknowledged by
91
+ * ranges, unreliable messages of up to a datagram with a delivery notice each, and reliable lanes
92
+ * that carry messages of any size up to `max_message_bytes`, paced by a token bucket.
93
+ *
94
+ * Everything queued goes out on {@link flush}, packed into as few datagrams as fit. Everything
95
+ * received is handled inside the transport's receive callback. Time is whatever `clock` says; the
96
+ * connection never reads a clock of its own.
97
+ *
98
+ * The design is in `network/MESSAGE_TRANSPORT.md`. Loss detection, RTT and the probe timeout follow
99
+ * QUIC (RFC 9002), packet numbers and ACK ranges RFC 9000.
100
+ *
101
+ * @author Alex Goldring
102
+ * @copyright Company Named Limited (c) 2026
103
+ */
104
+ export class Connection {
105
+ // ---------------------------------------------------------------- configuration
106
+
107
+ /** @type {{ send(bytes: Uint8Array, length: number): void, onReceive: Signal }} */
108
+ #transport;
109
+ /** @type {function(): number} */
110
+ #clock;
111
+ #max_datagram;
112
+ #rate_bytes_per_ms;
113
+ #burst_bytes;
114
+ #max_ack_ranges;
115
+ #max_ack_delay_ms;
116
+ /** RFC 9002 kGranularity: the clock's resolution, one tick */
117
+ #granularity_ms;
118
+ /** acknowledgements say what was delivered; nothing is lost and nothing is probed */
119
+ #lossless;
120
+ #max_queued_bytes;
121
+
122
+ // ---------------------------------------------------------------- send side
123
+
124
+ #next_pn = 0;
125
+ /** largest of our packet numbers the peer has acknowledged */
126
+ #largest_acked = -1;
127
+ /** every packet below this is retired (acked or lost) */
128
+ #oldest_unretired = 0;
129
+
130
+ // in-flight table, indexed by packet number & (capacity - 1)
131
+ #pkt_capacity = 256;
132
+ #pkt_pn = new Float64Array(256).fill(-1);
133
+ #pkt_sent_time = new Float64Array(256);
134
+ #pkt_size = new Uint16Array(256);
135
+ #pkt_rec_start = new Float64Array(256);
136
+ #pkt_rec_count = new Uint16Array(256);
137
+ /** largest packet number this packet's ACK reported, -1 when it carried none */
138
+ #pkt_ack_largest = new Float64Array(256);
139
+ #in_flight_count = 0;
140
+
141
+ // records ring, indexed by absolute record index % capacity
142
+ #rec_capacity = 1024;
143
+ #rec_kind = new Uint8Array(1024);
144
+ #rec_id = new Int32Array(1024);
145
+ #rec_offset = new Float64Array(1024);
146
+ #rec_length = new Int32Array(1024);
147
+ #rec_head = 0;
148
+
149
+ // RTT, RFC 9002 §5
150
+ #has_rtt = false;
151
+ #latest_rtt = 0;
152
+ #smoothed_rtt = INITIAL_RTT_MS;
153
+ #rttvar = INITIAL_RTT_MS / 2;
154
+ #min_rtt = 0;
155
+
156
+ #pto_count = 0;
157
+ #last_ack_eliciting_sent = 0;
158
+ #probe_pending = false;
159
+ /** a probe may send one paced datagram past an empty bucket */
160
+ #probe_credit = false;
161
+ /** bytes of paced lanes sent this flush: they always get one datagram's worth */
162
+ #paced_sent = 0;
163
+
164
+ #tokens;
165
+ #last_refill = -1;
166
+
167
+ /** @type {TxStream[]} */
168
+ #tx = [];
169
+
170
+ // unreliable queue for the next flush
171
+ #uq_bytes = new Uint8Array(2048);
172
+ #uq_used = 0;
173
+ #uq_count = 0;
174
+ #uq_offset = new Int32Array(32);
175
+ #uq_length = new Int32Array(32);
176
+ #uq_token = new Int32Array(32);
177
+
178
+ // datagram being built
179
+ #dgram;
180
+ #dgram_len = 0;
181
+ #dgram_open = false;
182
+ #dgram_pn = 0;
183
+ #dgram_flags = 0;
184
+ #dgram_ack_eliciting = false;
185
+ #dgram_rec_start = 0;
186
+ #dgram_ack_largest = -1;
187
+ #flush_sent_eliciting = false;
188
+ #flush_sent_any = false;
189
+
190
+ // ---------------------------------------------------------------- receive side
191
+
192
+ /** received packet numbers at or above {@link #rx_floor} */
193
+ #rx_ranges = new RangeSet(64);
194
+ /** packets below this are dropped: duplicates, or too old to matter */
195
+ #rx_floor = 0;
196
+ #largest_rx = -1;
197
+ #largest_rx_time = 0;
198
+ /** an ack-eliciting packet arrived since the last ACK went out */
199
+ #ack_pending = false;
200
+
201
+ /** @type {RxStream[]} */
202
+ #rx = [];
203
+
204
+ #cursor = { position: 0 };
205
+ #message_out = new Float64Array(1);
206
+ #peek_out = new Float64Array(2);
207
+ /** parsed ACK ranges of the packet being read, [high, low] inclusive pairs */
208
+ #ack_scratch = new Float64Array(2 * MAX_ACK_RANGES);
209
+
210
+ // Fates of unreliable messages, told once the walk that settled them is over: a handler may
211
+ // send, flush or dispose, and none of that may happen to the tables while they are being walked.
212
+ #notice_token = new Int32Array(64);
213
+ /** 1 acknowledged, 0 lost */
214
+ #notice_acked = new Uint8Array(64);
215
+ #notice_count = 0;
216
+ #notice_head = 0;
217
+
218
+ #disposed = false;
219
+
220
+ // ---------------------------------------------------------------- statistics
221
+
222
+ #stats = {
223
+ packets_sent: 0,
224
+ packets_received: 0,
225
+ packets_lost: 0,
226
+ packets_dropped: 0,
227
+ bytes_sent: 0,
228
+ bytes_received: 0,
229
+ };
230
+
231
+ /**
232
+ * @param {{
233
+ * transport: { send(bytes: Uint8Array, length: number): void, onReceive: Signal, max_datagram_bytes?: number },
234
+ * clock: function(): number,
235
+ * send_rate_bytes_per_second: number,
236
+ * max_message_bytes: number,
237
+ * receive_window_bytes: number,
238
+ * max_queued_bytes: number,
239
+ * max_ack_delay_ms: number,
240
+ * max_ack_ranges?: number,
241
+ * }} options
242
+ * `clock` returns milliseconds and never runs backwards. `send_rate_bytes_per_second` paces
243
+ * the BULK lane. `max_message_bytes` is the largest reliable message either side may send;
244
+ * both ends must agree. `receive_window_bytes` bounds what each reliable lane may have in
245
+ * flight past its acknowledged prefix, and so what a receiver holds out of order. Both ends
246
+ * must agree on these two; a peer that exceeds them is a protocol error.
247
+ * `max_queued_bytes` caps what one lane may hold unacknowledged: past it,
248
+ * {@link send_reliable} throws rather than grow without bound.
249
+ * `max_ack_delay_ms` is how long this side may sit on an ACK and the resolution of its
250
+ * clock: its tick period. `max_ack_ranges` is how many ranges this side's ACKs report, at
251
+ * most 64.
252
+ *
253
+ * A transport that is itself reliable (`transport.reliable`, e.g. a WebSocket) delivers
254
+ * every packet: nothing is declared lost and nothing is probed, or a stalled TCP stream
255
+ * would be fed duplicates behind the originals.
256
+ */
257
+ constructor({
258
+ transport,
259
+ clock,
260
+ send_rate_bytes_per_second,
261
+ max_message_bytes,
262
+ receive_window_bytes,
263
+ max_queued_bytes,
264
+ max_ack_delay_ms,
265
+ max_ack_ranges = 32,
266
+ }) {
267
+ assert.ok(transport && typeof transport.send === 'function', 'transport must implement send()');
268
+ assert.ok(transport.onReceive, 'transport must expose onReceive');
269
+ assert.isFunction(clock, 'clock');
270
+ assert.isPositiveInteger(send_rate_bytes_per_second, 'send_rate_bytes_per_second');
271
+ assert.isPositiveInteger(max_message_bytes, 'max_message_bytes');
272
+ assert.isPositiveInteger(receive_window_bytes, 'receive_window_bytes');
273
+ assert.isPositiveInteger(max_queued_bytes, 'max_queued_bytes');
274
+ assert.isNumber(max_ack_delay_ms, 'max_ack_delay_ms');
275
+ assert.greaterThanOrEqual(max_ack_delay_ms, 0, 'max_ack_delay_ms');
276
+ assert.isPositiveInteger(max_ack_ranges, 'max_ack_ranges');
277
+ assert.lessThanOrEqual(max_ack_ranges, MAX_ACK_RANGES, 'max_ack_ranges');
278
+
279
+ const max_datagram = transport.max_datagram_bytes ?? 1200;
280
+ assert.isPositiveInteger(max_datagram, 'transport.max_datagram_bytes');
281
+ if (max_datagram < 64 || max_datagram > 16383) {
282
+ throw new RangeError(`Connection: transport.max_datagram_bytes ${max_datagram} must be in [64, 16383]`);
283
+ }
284
+
285
+ this.#transport = transport;
286
+ this.#clock = clock;
287
+ this.#max_datagram = max_datagram;
288
+ this.#rate_bytes_per_ms = send_rate_bytes_per_second / 1000;
289
+ this.#max_ack_ranges = max_ack_ranges;
290
+ this.#max_ack_delay_ms = max_ack_delay_ms;
291
+ this.#granularity_ms = Math.max(max_ack_delay_ms, 1);
292
+ this.#lossless = transport.reliable === true;
293
+ this.#max_queued_bytes = max_queued_bytes;
294
+ // sends happen once a tick, so the bucket holds two ticks of rate, and never less than two
295
+ // datagrams
296
+ this.#burst_bytes = Math.max(this.#rate_bytes_per_ms * 2 * this.#granularity_ms, 2 * max_datagram);
297
+ this.#tokens = this.#burst_bytes;
298
+
299
+ /** @type {number} @readonly */
300
+ this.max_message_bytes = max_message_bytes;
301
+
302
+ /**
303
+ * Largest unreliable message: what fits one datagram after the packet and frame headers.
304
+ * @type {number} @readonly
305
+ */
306
+ this.max_unreliable_message_bytes = max_datagram - PACKET_HEADER_MAX - MESSAGE_FRAME_HEADER_MAX;
307
+
308
+ for (let lane = 0; lane < LANE_COUNT; lane++) {
309
+ this.#tx.push(new TxStream(receive_window_bytes));
310
+ this.#rx.push(new RxStream(max_message_bytes, receive_window_bytes));
311
+ }
312
+
313
+ this.#dgram = new Uint8Array(max_datagram);
314
+
315
+ /**
316
+ * A message arrived: `(bytes, offset, length)`. `bytes` is the connection's or the
317
+ * transport's buffer, valid for the duration of the call only.
318
+ * @type {Signal}
319
+ */
320
+ this.onMessage = new Signal();
321
+
322
+ /**
323
+ * An unreliable message sent with a token arrived: `(token)`.
324
+ * @type {Signal}
325
+ */
326
+ this.onMessageAcked = new Signal();
327
+
328
+ /**
329
+ * An unreliable message sent with a token was lost: `(token)`. Lost means not confirmed:
330
+ * a message whose packet arrived but whose acknowledgement never got through — every ACK
331
+ * that could report it lost, or crowded out by newer ranges — is reported lost, as QUIC
332
+ * does.
333
+ * @type {Signal}
334
+ */
335
+ this.onMessageLost = new Signal();
336
+
337
+ /**
338
+ * A datagram that does not parse, or is of another protocol version, was dropped whole and
339
+ * unacknowledged: `(reason)`. The connection carries on; anyone can send a stray datagram.
340
+ * @type {Signal}
341
+ */
342
+ this.onMalformedDatagram = new Signal();
343
+
344
+ /**
345
+ * The connection is no longer whole: `(reason)`. The peer broke the protocol on a reliable
346
+ * lane — a message longer than `max_message_bytes`, bytes past the receive window, more
347
+ * holes than a sender keeping to its window makes — and the lane has stopped, so nothing
348
+ * more will arrive on it; or the peer acknowledged a packet this side never sent, so it
349
+ * took in a datagram that was not this side's and nothing it acknowledges can be trusted.
350
+ * The datagram carrying that ACK is dropped, as is every later one that repeats it.
351
+ *
352
+ * The connection does not authenticate datagrams: its transport must deliver only the
353
+ * peer's (DTLS and TLS do; a UDP socket filters by source address). The cure is a new
354
+ * connection.
355
+ * @type {Signal}
356
+ */
357
+ this.onProtocolError = new Signal();
358
+
359
+ transport.onReceive.add(this.#receive, this);
360
+ }
361
+
362
+ // ================================================================ public: sending
363
+
364
+ /**
365
+ * Queue an unreliable message for the next {@link flush}. With `token >= 0` the connection
366
+ * reports its fate: {@link onMessageAcked} once the packet carrying it is acknowledged, or
367
+ * {@link onMessageLost} once it is declared lost — exactly one of them.
368
+ *
369
+ * @param {Uint8Array} bytes
370
+ * @param {number} offset
371
+ * @param {number} length at most {@link max_unreliable_message_bytes}
372
+ * @param {number} token caller's id for the notice, or -1 for none
373
+ */
374
+ send_unreliable(bytes, offset, length, token) {
375
+ if (length > this.max_unreliable_message_bytes) {
376
+ throw new RangeError(`Connection.send_unreliable: ${length} bytes exceeds the ${this.max_unreliable_message_bytes}-byte datagram limit; send it on a reliable lane`);
377
+ }
378
+ const n = this.#uq_count;
379
+ if (n === this.#uq_offset.length) this.#grow_unreliable_queue();
380
+ if (this.#uq_used + length > this.#uq_bytes.length) {
381
+ let size = this.#uq_bytes.length * 2;
382
+ while (size < this.#uq_used + length) size *= 2;
383
+ const next = new Uint8Array(size);
384
+ next.set(this.#uq_bytes.subarray(0, this.#uq_used));
385
+ this.#uq_bytes = next;
386
+ }
387
+ bytes_copy(bytes, offset, this.#uq_bytes, this.#uq_used, length);
388
+ this.#uq_offset[n] = this.#uq_used;
389
+ this.#uq_length[n] = length;
390
+ this.#uq_token[n] = token;
391
+ this.#uq_used += length;
392
+ this.#uq_count = n + 1;
393
+ }
394
+
395
+ /**
396
+ * Queue a reliable message on `lane`. It arrives, whole and in order with the lane's other
397
+ * messages, unless the connection ends first.
398
+ *
399
+ * @param {number} lane one of {@link Lane}
400
+ * @param {Uint8Array} bytes
401
+ * @param {number} offset
402
+ * @param {number} length at most {@link max_message_bytes}
403
+ * @returns {number} delivery mark: see {@link is_delivered}
404
+ */
405
+ send_reliable(lane, bytes, offset, length) {
406
+ if (length > this.max_message_bytes) {
407
+ throw new RangeError(`Connection.send_reliable: ${length} bytes exceeds max_message_bytes ${this.max_message_bytes}`);
408
+ }
409
+ const tx = this.#tx[lane];
410
+ if (tx.end - tx.acked_prefix + length > this.#max_queued_bytes) {
411
+ throw new RangeError(`Connection.send_reliable: lane ${lane} already holds ${tx.end - tx.acked_prefix} unacknowledged bytes; ${length} more would pass max_queued_bytes ${this.#max_queued_bytes}`);
412
+ }
413
+ return tx.append(bytes, offset, length);
414
+ }
415
+
416
+ /**
417
+ * Whether every message on `lane` up to the one whose mark this is has been acknowledged.
418
+ * @param {number} lane
419
+ * @param {number} mark from {@link send_reliable}
420
+ * @returns {boolean}
421
+ */
422
+ is_delivered(lane, mark) {
423
+ return this.#tx[lane].acked_prefix >= mark;
424
+ }
425
+
426
+ /**
427
+ * Bytes queued on `lane` the peer has not acknowledged.
428
+ * @param {number} lane
429
+ * @returns {number}
430
+ */
431
+ unacked_bytes(lane) {
432
+ const tx = this.#tx[lane];
433
+ return tx.end - tx.acked_prefix;
434
+ }
435
+
436
+ /**
437
+ * Send everything queued that may go now, packed into as few datagrams as fit: the ACK, the
438
+ * CONTROL lane, unreliable messages, then the BULK lane while the token bucket allows. Also
439
+ * runs the loss and probe timers.
440
+ */
441
+ flush() {
442
+ if (this.#disposed) return;
443
+ const now = this.#clock();
444
+
445
+ this.#detect_lost(now);
446
+ this.#check_probe_timeout(now);
447
+ this.#refill(now);
448
+
449
+ this.#flush_sent_eliciting = false;
450
+ this.#flush_sent_any = false;
451
+
452
+ this.#paced_sent = 0;
453
+ this.#send_stream(Lane.CONTROL, now);
454
+ this.#send_unreliable_queue(now);
455
+ this.#send_stream(Lane.FRAMES, now);
456
+ this.#send_stream(Lane.USER, now);
457
+ this.#send_stream(Lane.BULK, now);
458
+ this.#probe_credit = false;
459
+
460
+ if (this.#probe_pending && !this.#flush_sent_eliciting && !this.#dgram_ack_eliciting) {
461
+ this.#ensure_room(1, now);
462
+ this.#dgram[this.#dgram_len++] = FRAME_PING;
463
+ this.#dgram_ack_eliciting = true;
464
+ }
465
+ this.#probe_pending = false;
466
+
467
+ if (this.#ack_pending && !this.#dgram_open && !this.#flush_sent_any) {
468
+ // An ACK with nothing else to carry it. Once a round trip it asks for an ACK itself: a
469
+ // side that only ever acknowledges never hears which of its ACKs arrived, so it could
470
+ // never stop reporting old ranges (RFC 9000 §13.2.4).
471
+ this.#open_packet(now);
472
+ if (now - this.#last_ack_eliciting_sent >= this.#smoothed_rtt) {
473
+ this.#dgram[this.#dgram_len++] = FRAME_PING;
474
+ this.#dgram_ack_eliciting = true;
475
+ }
476
+ }
477
+
478
+ this.#close_packet(now);
479
+ this.#emit_notices();
480
+ }
481
+
482
+ // ================================================================ public: diagnostics
483
+
484
+ /** Smoothed round-trip time, ms; RFC 9002's initial 333 ms until the first sample. */
485
+ get smoothed_rtt() {
486
+ return this.#smoothed_rtt;
487
+ }
488
+
489
+ /** Packets sent and not yet acknowledged or declared lost that asked for an ACK. */
490
+ get in_flight_count() {
491
+ return this.#in_flight_count;
492
+ }
493
+
494
+ /** Most bytes one reliable lane may hold unacknowledged; {@link send_reliable} throws past it. */
495
+ get max_queued_bytes() {
496
+ return this.#max_queued_bytes;
497
+ }
498
+
499
+ /**
500
+ * @returns {{packets_sent: number, packets_received: number, packets_lost: number, packets_dropped: number, bytes_sent: number, bytes_received: number}}
501
+ */
502
+ getStats() {
503
+ return { ...this.#stats };
504
+ }
505
+
506
+ /**
507
+ * Stop: no more receiving, and nothing queued will be sent. Call {@link flush} first for a
508
+ * last send.
509
+ */
510
+ dispose() {
511
+ if (this.#disposed) return;
512
+ this.#disposed = true;
513
+ this.#transport.onReceive.remove(this.#receive, this);
514
+ this.#uq_count = 0;
515
+ this.#uq_used = 0;
516
+ this.#notice_count = 0;
517
+ this.#notice_head = 0;
518
+ for (let lane = 0; lane < LANE_COUNT; lane++) {
519
+ this.#tx[lane].clear();
520
+ this.#rx[lane].clear();
521
+ }
522
+ }
523
+
524
+ // ================================================================ sending internals
525
+
526
+ #refill(now) {
527
+ if (this.#last_refill < 0) {
528
+ this.#last_refill = now;
529
+ return;
530
+ }
531
+ const elapsed = now - this.#last_refill;
532
+ if (elapsed <= 0) return;
533
+ this.#last_refill = now;
534
+ this.#tokens = Math.min(this.#burst_bytes, this.#tokens + elapsed * this.#rate_bytes_per_ms);
535
+ }
536
+
537
+ /**
538
+ * Send what `lane` has: re-sends first, then new bytes up to its window. A paced lane stops
539
+ * when the bucket is empty, except that paced lanes always get one datagram's worth a flush (so
540
+ * unpaced traffic cannot starve them) and a probe always goes.
541
+ */
542
+ #send_stream(lane, now) {
543
+ const tx = this.#tx[lane];
544
+ const paced = LANE_PACED[lane];
545
+ const out = this.#peek_out;
546
+ while (tx.has_sendable()) {
547
+ if (paced && this.#tokens - this.#dgram_len <= 0 && this.#paced_sent >= this.#max_datagram) {
548
+ if (!this.#probe_credit) return;
549
+ this.#probe_credit = false;
550
+ }
551
+ this.#ensure_room(STREAM_FRAME_HEADER_MAX + STREAM_FRAME_MIN_PAYLOAD, now);
552
+ const room = this.#max_datagram - this.#dgram_len - STREAM_FRAME_HEADER_MAX;
553
+ tx.peek(room, out);
554
+ const offset = out[0];
555
+ const length = out[1];
556
+ if (length <= 0) return;
557
+
558
+ const d = this.#dgram;
559
+ let p = this.#dgram_len;
560
+ d[p++] = FRAME_STREAM | lane;
561
+ p = varint_write(d, p, offset);
562
+ p = varint_write(d, p, length);
563
+ tx.copy_out(offset, length, d, p);
564
+ this.#dgram_len = p + length;
565
+ this.#dgram_ack_eliciting = true;
566
+
567
+ tx.mark_sent(offset, length);
568
+ this.#push_record(RECORD_STREAM, lane, offset, length);
569
+ if (paced) this.#paced_sent += length;
570
+ }
571
+ }
572
+
573
+ #send_unreliable_queue(now) {
574
+ const n = this.#uq_count;
575
+ for (let i = 0; i < n; i++) {
576
+ const length = this.#uq_length[i];
577
+ this.#ensure_room(1 + varint_size(length) + length, now);
578
+ const d = this.#dgram;
579
+ let p = this.#dgram_len;
580
+ d[p++] = FRAME_MESSAGE;
581
+ p = varint_write(d, p, length);
582
+ const from = this.#uq_offset[i];
583
+ bytes_copy(this.#uq_bytes, from, d, p, length);
584
+ this.#dgram_len = p + length;
585
+ this.#dgram_ack_eliciting = true;
586
+
587
+ const token = this.#uq_token[i];
588
+ if (token >= 0) this.#push_record(RECORD_MESSAGE, token, 0, 0);
589
+ }
590
+ this.#uq_count = 0;
591
+ this.#uq_used = 0;
592
+ }
593
+
594
+ /**
595
+ * Make sure the open datagram has `bytes` of room, closing it and opening the next if not.
596
+ */
597
+ #ensure_room(bytes, now) {
598
+ if (this.#dgram_open && this.#dgram_len + bytes <= this.#max_datagram) return;
599
+ this.#close_packet(now);
600
+ this.#open_packet(now);
601
+ if (this.#dgram_len + bytes > this.#max_datagram) {
602
+ // the ACK that opens a flush's first datagram leaves too little: it goes alone, and the
603
+ // next datagram carries none
604
+ this.#close_packet(now);
605
+ this.#open_packet(now);
606
+ }
607
+ }
608
+
609
+ #open_packet(now) {
610
+ const pn = this.#next_pn++;
611
+ this.#dgram_pn = pn;
612
+ this.#dgram_open = true;
613
+ this.#dgram_ack_eliciting = false;
614
+ this.#dgram_rec_start = this.#rec_head;
615
+ this.#dgram_ack_largest = -1;
616
+
617
+ // 2 bytes while the receiver can still expand it: RFC 9000 §17.1
618
+ const unacked = pn - this.#largest_acked;
619
+ const long = unacked >= 16384;
620
+ this.#dgram_flags = long ? FLAG_PN32 : 0;
621
+ const d = this.#dgram;
622
+ let p = 1;
623
+ if (long) {
624
+ d[p++] = (pn >>> 24) & 0xFF;
625
+ d[p++] = (pn >>> 16) & 0xFF;
626
+ }
627
+ d[p++] = (pn >>> 8) & 0xFF;
628
+ d[p++] = pn & 0xFF;
629
+ this.#dgram_len = p;
630
+
631
+ // the first datagram of a flush acknowledges what has been received
632
+ if (!this.#rx_ranges.is_empty() && !this.#flush_sent_any) {
633
+ this.#write_ack(now);
634
+ }
635
+ }
636
+
637
+ #write_ack(now) {
638
+ const ranges = this.#rx_ranges;
639
+ const top = ranges.count - 1;
640
+ const largest = ranges.end(top) - 1;
641
+ const delay_ms = Math.max(0, now - this.#largest_rx_time);
642
+ const delay = Math.min(Math.round(delay_ms * ACK_DELAY_UNITS_PER_MS), 1073741823);
643
+ const first = largest - ranges.start(top);
644
+
645
+ // As many ranges as fit half the datagram, newest first: the rest of it is for frames. The
646
+ // ranges left out are older; the peer learns of them from a later ACK, or declares them lost.
647
+ const room = ((this.#max_datagram - PACKET_HEADER_MAX) >> 1) - this.#dgram_len;
648
+ let size = varint_size(largest) + varint_size(delay) + 1 + varint_size(first);
649
+ let reported = 1;
650
+ {
651
+ let previous_start = ranges.start(top);
652
+ const most = Math.min(ranges.count, this.#max_ack_ranges);
653
+ for (let i = top - 1; reported < most; i--, reported++) {
654
+ const s = ranges.start(i);
655
+ const e = ranges.end(i);
656
+ const more = varint_size(previous_start - e - 1) + varint_size(e - 1 - s);
657
+ if (size + more > room) break;
658
+ size += more;
659
+ previous_start = s;
660
+ }
661
+ }
662
+
663
+ const d = this.#dgram;
664
+ let p = this.#dgram_len;
665
+ p = varint_write(d, p, largest);
666
+ p = varint_write(d, p, delay);
667
+ p = varint_write(d, p, reported - 1);
668
+ p = varint_write(d, p, first);
669
+ let previous_start = ranges.start(top);
670
+ for (let i = top - 1; i > top - reported; i--) {
671
+ const s = ranges.start(i);
672
+ const e = ranges.end(i);
673
+ p = varint_write(d, p, previous_start - e - 1);
674
+ p = varint_write(d, p, e - 1 - s);
675
+ previous_start = s;
676
+ }
677
+ this.#dgram_len = p;
678
+ this.#dgram_flags |= FLAG_ACK;
679
+ this.#dgram_ack_largest = largest;
680
+ this.#ack_pending = false;
681
+ }
682
+
683
+ #close_packet(now) {
684
+ if (!this.#dgram_open) return;
685
+ this.#dgram_open = false;
686
+ const d = this.#dgram;
687
+ d[0] = this.#dgram_flags | (PROTOCOL_VERSION << 4);
688
+ const length = this.#dgram_len;
689
+ this.#transport.send(d, length);
690
+
691
+ this.#flush_sent_any = true;
692
+ // unpaced traffic may take the bucket below zero, never more than a burst below
693
+ this.#tokens = Math.max(this.#tokens - length, -this.#burst_bytes);
694
+ this.#stats.packets_sent++;
695
+ this.#stats.bytes_sent += length;
696
+
697
+ if (!this.#dgram_ack_eliciting) return;
698
+ this.#flush_sent_eliciting = true;
699
+
700
+ const pn = this.#dgram_pn;
701
+ this.#ensure_packet_capacity(pn);
702
+ const slot = pn & (this.#pkt_capacity - 1);
703
+ this.#pkt_pn[slot] = pn;
704
+ this.#pkt_sent_time[slot] = now;
705
+ this.#pkt_size[slot] = length;
706
+ this.#pkt_rec_start[slot] = this.#dgram_rec_start;
707
+ this.#pkt_rec_count[slot] = this.#rec_head - this.#dgram_rec_start;
708
+ this.#pkt_ack_largest[slot] = this.#dgram_ack_largest;
709
+ this.#in_flight_count++;
710
+ this.#last_ack_eliciting_sent = now;
711
+ }
712
+
713
+ #push_record(kind, id, offset, length) {
714
+ const oldest = this.#oldest_record_in_use();
715
+ if (this.#rec_head - oldest >= this.#rec_capacity) this.#grow_records(oldest);
716
+ const i = this.#rec_head % this.#rec_capacity;
717
+ this.#rec_kind[i] = kind;
718
+ this.#rec_id[i] = id;
719
+ this.#rec_offset[i] = offset;
720
+ this.#rec_length[i] = length;
721
+ this.#rec_head++;
722
+ }
723
+
724
+ /** Absolute index of the oldest record a packet still in flight (or being built) may own. */
725
+ #oldest_record_in_use() {
726
+ if (this.#in_flight_count > 0) {
727
+ for (let pn = this.#oldest_unretired; pn < this.#next_pn; pn++) {
728
+ const slot = pn & (this.#pkt_capacity - 1);
729
+ if (this.#pkt_pn[slot] === pn) return this.#pkt_rec_start[slot];
730
+ }
731
+ }
732
+ return this.#dgram_open ? this.#dgram_rec_start : this.#rec_head;
733
+ }
734
+
735
+ #grow_records(oldest) {
736
+ const old_capacity = this.#rec_capacity;
737
+ const capacity = old_capacity * 2;
738
+ const kind = new Uint8Array(capacity);
739
+ const id = new Int32Array(capacity);
740
+ const offset = new Float64Array(capacity);
741
+ const length = new Int32Array(capacity);
742
+ for (let r = oldest; r < this.#rec_head; r++) {
743
+ const from = r % old_capacity;
744
+ const to = r % capacity;
745
+ kind[to] = this.#rec_kind[from];
746
+ id[to] = this.#rec_id[from];
747
+ offset[to] = this.#rec_offset[from];
748
+ length[to] = this.#rec_length[from];
749
+ }
750
+ this.#rec_capacity = capacity;
751
+ this.#rec_kind = kind;
752
+ this.#rec_id = id;
753
+ this.#rec_offset = offset;
754
+ this.#rec_length = length;
755
+ }
756
+
757
+ #ensure_packet_capacity(pn) {
758
+ while (pn - this.#oldest_unretired >= this.#pkt_capacity) {
759
+ if (this.#pkt_capacity >= MAX_IN_FLIGHT) {
760
+ // the peer has gone quiet for longer than any link holds packets: give the oldest up
761
+ this.#retire_lost(this.#oldest_unretired);
762
+ // never past `pn`: it is the packet being recorded, not yet in the table
763
+ this.#advance_oldest_unretired(pn);
764
+ continue;
765
+ }
766
+ this.#grow_packets();
767
+ }
768
+ }
769
+
770
+ #grow_packets() {
771
+ const old_capacity = this.#pkt_capacity;
772
+ const capacity = old_capacity * 2;
773
+ const pn_ = new Float64Array(capacity).fill(-1);
774
+ const sent = new Float64Array(capacity);
775
+ const size = new Uint16Array(capacity);
776
+ const rec_start = new Float64Array(capacity);
777
+ const rec_count = new Uint16Array(capacity);
778
+ const ack_largest = new Float64Array(capacity);
779
+ for (let i = 0; i < old_capacity; i++) {
780
+ const pn = this.#pkt_pn[i];
781
+ if (pn < 0) continue;
782
+ const to = pn % capacity;
783
+ pn_[to] = pn;
784
+ sent[to] = this.#pkt_sent_time[i];
785
+ size[to] = this.#pkt_size[i];
786
+ rec_start[to] = this.#pkt_rec_start[i];
787
+ rec_count[to] = this.#pkt_rec_count[i];
788
+ ack_largest[to] = this.#pkt_ack_largest[i];
789
+ }
790
+ this.#pkt_capacity = capacity;
791
+ this.#pkt_pn = pn_;
792
+ this.#pkt_sent_time = sent;
793
+ this.#pkt_size = size;
794
+ this.#pkt_rec_start = rec_start;
795
+ this.#pkt_rec_count = rec_count;
796
+ this.#pkt_ack_largest = ack_largest;
797
+ }
798
+
799
+ // ================================================================ loss, RTT, probe
800
+
801
+ #loss_delay() {
802
+ const rtt = this.#has_rtt ? Math.max(this.#latest_rtt, this.#smoothed_rtt) : INITIAL_RTT_MS;
803
+ return Math.max(rtt * 9 / 8, this.#granularity_ms);
804
+ }
805
+
806
+ /**
807
+ * RFC 9002 §6.1: a packet is lost once a packet {@link PACKET_THRESHOLD} later is acknowledged,
808
+ * or once it is older than the loss delay and something sent after it has been acknowledged.
809
+ */
810
+ #detect_lost(now) {
811
+ const largest = this.#largest_acked;
812
+ if (this.#lossless || largest < 0 || this.#in_flight_count === 0) return;
813
+ const lost_before = now - this.#loss_delay();
814
+ const mask = this.#pkt_capacity - 1;
815
+ const last = Math.min(largest - 1, this.#next_pn - 1);
816
+ for (let pn = this.#oldest_unretired; pn <= last; pn++) {
817
+ const slot = pn & mask;
818
+ if (this.#pkt_pn[slot] !== pn) continue;
819
+ if (largest - pn >= PACKET_THRESHOLD || this.#pkt_sent_time[slot] <= lost_before) {
820
+ this.#retire_lost(pn);
821
+ }
822
+ }
823
+ this.#advance_oldest_unretired();
824
+ }
825
+
826
+ /**
827
+ * RFC 9002 §6.2: with ack-eliciting packets outstanding and no ACK for a probe timeout, send
828
+ * the oldest outstanding reliable bytes again (or a PING when only unreliable messages are
829
+ * outstanding) to draw an ACK. Backs off by doubling.
830
+ */
831
+ #check_probe_timeout(now) {
832
+ if (this.#lossless || this.#in_flight_count === 0) {
833
+ this.#pto_count = 0;
834
+ return;
835
+ }
836
+ const pto = (this.#smoothed_rtt + Math.max(4 * this.#rttvar, this.#granularity_ms) + this.#max_ack_delay_ms)
837
+ * (1 << Math.min(this.#pto_count, 16));
838
+ if (now - this.#last_ack_eliciting_sent < pto) return;
839
+
840
+ this.#pto_count++;
841
+ this.#probe_credit = true;
842
+ const mask = this.#pkt_capacity - 1;
843
+ for (let pn = this.#oldest_unretired; pn < this.#next_pn; pn++) {
844
+ const slot = pn & mask;
845
+ if (this.#pkt_pn[slot] !== pn) continue;
846
+ if (this.#requeue_stream_records(slot)) return;
847
+ }
848
+ this.#probe_pending = true;
849
+ }
850
+
851
+ /**
852
+ * Queue the reliable bytes a packet carried for re-sending, leaving the packet in flight.
853
+ * @returns {boolean} whether any of them is still unacknowledged: a packet whose bytes were
854
+ * all acknowledged by another (an earlier probe's, or the one it re-sent) has nothing to
855
+ * probe with
856
+ */
857
+ #requeue_stream_records(slot) {
858
+ const start = this.#pkt_rec_start[slot];
859
+ const count = this.#pkt_rec_count[slot];
860
+ let any = false;
861
+ for (let r = start; r < start + count; r++) {
862
+ const i = r % this.#rec_capacity;
863
+ if (this.#rec_kind[i] !== RECORD_STREAM) continue;
864
+ if (this.#tx[this.#rec_id[i]].on_lost(this.#rec_offset[i], this.#rec_length[i])) any = true;
865
+ }
866
+ return any;
867
+ }
868
+
869
+ #retire_lost(pn) {
870
+ const slot = pn & (this.#pkt_capacity - 1);
871
+ if (this.#pkt_pn[slot] !== pn) return;
872
+ this.#pkt_pn[slot] = -1;
873
+ this.#in_flight_count--;
874
+ this.#stats.packets_lost++;
875
+
876
+ const start = this.#pkt_rec_start[slot];
877
+ const count = this.#pkt_rec_count[slot];
878
+ for (let r = start; r < start + count; r++) {
879
+ const i = r % this.#rec_capacity;
880
+ const kind = this.#rec_kind[i];
881
+ if (kind === RECORD_STREAM) {
882
+ this.#tx[this.#rec_id[i]].on_lost(this.#rec_offset[i], this.#rec_length[i]);
883
+ } else if (kind === RECORD_MESSAGE) {
884
+ this.#queue_notice(this.#rec_id[i], 0);
885
+ }
886
+ }
887
+ }
888
+
889
+ /**
890
+ * @param {number} token
891
+ * @param {number} acked 1 acknowledged, 0 lost
892
+ */
893
+ #queue_notice(token, acked) {
894
+ const n = this.#notice_count;
895
+ if (n === this.#notice_token.length) {
896
+ const token_next = new Int32Array(n * 2);
897
+ const acked_next = new Uint8Array(n * 2);
898
+ token_next.set(this.#notice_token);
899
+ acked_next.set(this.#notice_acked);
900
+ this.#notice_token = token_next;
901
+ this.#notice_acked = acked_next;
902
+ }
903
+ this.#notice_token[n] = token;
904
+ this.#notice_acked[n] = acked;
905
+ this.#notice_count = n + 1;
906
+ }
907
+
908
+ /**
909
+ * Tell the queued fates, in order. A handler may flush — which tells the rest, and its own —
910
+ * or dispose, after which nothing more is told.
911
+ */
912
+ #emit_notices() {
913
+ while (this.#notice_head < this.#notice_count && !this.#disposed) {
914
+ const i = this.#notice_head++;
915
+ const token = this.#notice_token[i];
916
+ if (this.#notice_acked[i] !== 0) {
917
+ this.onMessageAcked.send1(token);
918
+ } else {
919
+ this.onMessageLost.send1(token);
920
+ }
921
+ }
922
+ this.#notice_head = 0;
923
+ this.#notice_count = 0;
924
+ }
925
+
926
+ #retire_acked(pn) {
927
+ const slot = pn & (this.#pkt_capacity - 1);
928
+ this.#pkt_pn[slot] = -1;
929
+ this.#in_flight_count--;
930
+
931
+ // the peer has seen our ACK up to this: it need not hear of those packets again
932
+ const reported = this.#pkt_ack_largest[slot];
933
+ if (reported >= 0 && reported + 1 > this.#rx_floor) {
934
+ this.#rx_floor = reported + 1;
935
+ this.#rx_ranges.remove_below(this.#rx_floor);
936
+ }
937
+
938
+ const start = this.#pkt_rec_start[slot];
939
+ const count = this.#pkt_rec_count[slot];
940
+ for (let r = start; r < start + count; r++) {
941
+ const i = r % this.#rec_capacity;
942
+ const kind = this.#rec_kind[i];
943
+ if (kind === RECORD_STREAM) {
944
+ this.#tx[this.#rec_id[i]].on_acked(this.#rec_offset[i], this.#rec_length[i]);
945
+ } else if (kind === RECORD_MESSAGE) {
946
+ this.#queue_notice(this.#rec_id[i], 1);
947
+ }
948
+ }
949
+ }
950
+
951
+ /**
952
+ * Move the oldest-unretired mark up to the oldest packet still in flight, or to `limit`.
953
+ * @param {number} [limit]
954
+ */
955
+ #advance_oldest_unretired(limit = this.#next_pn) {
956
+ const mask = this.#pkt_capacity - 1;
957
+ let pn = this.#oldest_unretired;
958
+ while (pn < limit && this.#pkt_pn[pn & mask] !== pn) pn++;
959
+ this.#oldest_unretired = pn;
960
+ }
961
+
962
+ #update_rtt(latest, ack_delay) {
963
+ this.#latest_rtt = latest;
964
+ if (!this.#has_rtt) {
965
+ this.#has_rtt = true;
966
+ this.#min_rtt = latest;
967
+ this.#smoothed_rtt = latest;
968
+ this.#rttvar = latest / 2;
969
+ return;
970
+ }
971
+ this.#min_rtt = Math.min(this.#min_rtt, latest);
972
+ const delay = Math.min(ack_delay, this.#max_ack_delay_ms);
973
+ const adjusted = latest >= this.#min_rtt + delay ? latest - delay : latest;
974
+ this.#rttvar = 0.75 * this.#rttvar + 0.25 * Math.abs(this.#smoothed_rtt - adjusted);
975
+ this.#smoothed_rtt = 0.875 * this.#smoothed_rtt + 0.125 * adjusted;
976
+ }
977
+
978
+ // ================================================================ receiving
979
+
980
+ /**
981
+ * @param {Uint8Array} bytes
982
+ * @param {number} length
983
+ */
984
+ #receive(bytes, length) {
985
+ if (this.#disposed) return;
986
+ const now = this.#clock();
987
+ this.#stats.bytes_received += length;
988
+
989
+ if (length < 3) {
990
+ this.#drop('datagram shorter than a packet header');
991
+ return;
992
+ }
993
+ const flags = bytes[0];
994
+ if ((flags >>> 4) !== PROTOCOL_VERSION) {
995
+ this.#drop(`protocol version ${flags >>> 4}, expected ${PROTOCOL_VERSION}`);
996
+ return;
997
+ }
998
+ if ((flags & ~FLAGS_KNOWN) !== 0) {
999
+ this.#drop('unknown flags');
1000
+ return;
1001
+ }
1002
+ let p = 1;
1003
+ let truncated;
1004
+ let bits;
1005
+ if ((flags & FLAG_PN32) !== 0) {
1006
+ if (length < 5) {
1007
+ this.#drop('datagram shorter than its packet number');
1008
+ return;
1009
+ }
1010
+ truncated = ((bytes[1] << 24) >>> 0) + (bytes[2] << 16) + (bytes[3] << 8) + bytes[4];
1011
+ bits = 32;
1012
+ p = 5;
1013
+ } else {
1014
+ truncated = (bytes[1] << 8) | bytes[2];
1015
+ bits = 16;
1016
+ p = 3;
1017
+ }
1018
+ const pn = this.#expand_packet_number(truncated, bits);
1019
+
1020
+ if (pn < this.#rx_floor || this.#rx_ranges.contains(pn)) {
1021
+ this.#stats.packets_dropped++;
1022
+ return; // a duplicate, or too old to matter
1023
+ }
1024
+
1025
+ // Pass 1: the whole packet must parse before any of it is acted on.
1026
+ const ack_end = this.#validate(bytes, p, length, flags);
1027
+ if (ack_end < 0) return;
1028
+
1029
+ this.#stats.packets_received++;
1030
+ this.#rx_ranges.add(pn, pn + 1);
1031
+ if (pn > this.#largest_rx) {
1032
+ this.#largest_rx = pn;
1033
+ this.#largest_rx_time = now;
1034
+ }
1035
+ if (this.#rx_ranges.count > this.#max_ack_ranges) {
1036
+ this.#rx_ranges.keep_highest(this.#max_ack_ranges);
1037
+ this.#rx_floor = Math.max(this.#rx_floor, this.#rx_ranges.min());
1038
+ }
1039
+
1040
+ // Pass 2.
1041
+ if ((flags & FLAG_ACK) !== 0) {
1042
+ this.#process_ack(bytes, p, ack_end, now);
1043
+ this.#emit_notices();
1044
+ if (this.#disposed) return;
1045
+ }
1046
+ this.#process_frames(bytes, ack_end, length);
1047
+ }
1048
+
1049
+ /**
1050
+ * RFC 9000 Appendix A.3.
1051
+ */
1052
+ #expand_packet_number(truncated, bits) {
1053
+ const expected = this.#largest_rx + 1;
1054
+ const win = 2 ** bits;
1055
+ const hwin = win / 2;
1056
+ let candidate = expected - (expected % win) + truncated;
1057
+ if (candidate <= expected - hwin) {
1058
+ candidate += win;
1059
+ } else if (candidate > expected + hwin && candidate >= win) {
1060
+ candidate -= win;
1061
+ }
1062
+ return candidate;
1063
+ }
1064
+
1065
+ #drop(reason) {
1066
+ this.#stats.packets_dropped++;
1067
+ this.onMalformedDatagram.send1(reason);
1068
+ }
1069
+
1070
+ /**
1071
+ * Check a packet's structure without acting on it.
1072
+ * @returns {number} where the frames start, or -1 when it is malformed (already reported)
1073
+ */
1074
+ #validate(bytes, start, end, flags) {
1075
+ const cursor = this.#cursor;
1076
+ cursor.position = start;
1077
+ let frames_start = start;
1078
+
1079
+ if ((flags & FLAG_ACK) !== 0) {
1080
+ const largest = varint_read(bytes, cursor, end);
1081
+ const delay = varint_read(bytes, cursor, end);
1082
+ const more = varint_read(bytes, cursor, end);
1083
+ const first = varint_read(bytes, cursor, end);
1084
+ if (largest < 0 || delay < 0 || more < 0 || first < 0) {
1085
+ this.#drop('truncated ACK');
1086
+ return -1;
1087
+ }
1088
+ if (first > largest || more + 1 > MAX_ACK_RANGES) {
1089
+ this.#drop('ACK out of range');
1090
+ return -1;
1091
+ }
1092
+ if (largest >= this.#next_pn) {
1093
+ // Not a malformed datagram to shrug off: the peer took in one that was not ours,
1094
+ // and will report it in every ACK it writes (see onProtocolError).
1095
+ this.#stats.packets_dropped++;
1096
+ this.onProtocolError.send1(`ACK of packet ${largest}, which was never sent (${this.#next_pn} sent): the peer took in a datagram that was not this side's`);
1097
+ return -1;
1098
+ }
1099
+ let low = largest - first;
1100
+ for (let i = 0; i < more; i++) {
1101
+ const gap = varint_read(bytes, cursor, end);
1102
+ const run = varint_read(bytes, cursor, end);
1103
+ if (gap < 0 || run < 0) {
1104
+ this.#drop('truncated ACK range');
1105
+ return -1;
1106
+ }
1107
+ const high = low - gap - 2;
1108
+ if (high < 0 || run > high) {
1109
+ this.#drop('ACK range below zero');
1110
+ return -1;
1111
+ }
1112
+ low = high - run;
1113
+ }
1114
+ frames_start = cursor.position;
1115
+ }
1116
+
1117
+ while (cursor.position < end) {
1118
+ const type = bytes[cursor.position++];
1119
+ if (type === FRAME_MESSAGE) {
1120
+ const length = varint_read(bytes, cursor, end);
1121
+ if (length < 0 || cursor.position + length > end) {
1122
+ this.#drop('truncated MESSAGE');
1123
+ return -1;
1124
+ }
1125
+ cursor.position += length;
1126
+ } else if (type === FRAME_PING) {
1127
+ // nothing
1128
+ } else if ((type & ~FRAME_STREAM_LANE_MASK) === FRAME_STREAM) {
1129
+ const lane = type & FRAME_STREAM_LANE_MASK;
1130
+ const offset = varint_read(bytes, cursor, end);
1131
+ const length = varint_read(bytes, cursor, end);
1132
+ if (lane >= LANE_COUNT || offset < 0 || length < 0 || cursor.position + length > end) {
1133
+ this.#drop('malformed STREAM');
1134
+ return -1;
1135
+ }
1136
+ cursor.position += length;
1137
+ } else {
1138
+ this.#drop(`unknown frame type ${type}`);
1139
+ return -1;
1140
+ }
1141
+ }
1142
+ return frames_start;
1143
+ }
1144
+
1145
+ #process_ack(bytes, start, end, now) {
1146
+ const cursor = this.#cursor;
1147
+ cursor.position = start;
1148
+ const largest = varint_read(bytes, cursor, end);
1149
+ const delay = varint_read(bytes, cursor, end);
1150
+ const more = varint_read(bytes, cursor, end);
1151
+ const first = varint_read(bytes, cursor, end);
1152
+
1153
+ const ranges = this.#ack_scratch;
1154
+ let count = 0;
1155
+ let high = largest;
1156
+ let low = largest - first;
1157
+ ranges[count++] = high;
1158
+ ranges[count++] = low;
1159
+ for (let i = 0; i < more; i++) {
1160
+ const gap = varint_read(bytes, cursor, end);
1161
+ const run = varint_read(bytes, cursor, end);
1162
+ high = low - gap - 2;
1163
+ low = high - run;
1164
+ ranges[count++] = high;
1165
+ ranges[count++] = low;
1166
+ }
1167
+
1168
+ const mask = this.#pkt_capacity - 1;
1169
+
1170
+ // RTT from the largest acknowledged, when it is newly acknowledged
1171
+ const largest_slot = largest & mask;
1172
+ let newly_acked_any = false;
1173
+ if (this.#pkt_pn[largest_slot] === largest) {
1174
+ this.#update_rtt(now - this.#pkt_sent_time[largest_slot], delay / ACK_DELAY_UNITS_PER_MS);
1175
+ }
1176
+
1177
+ for (let i = 0; i < count; i += 2) {
1178
+ const range_high = Math.min(ranges[i], this.#next_pn - 1);
1179
+ const range_low = Math.max(ranges[i + 1], this.#oldest_unretired);
1180
+ for (let pn = range_low; pn <= range_high; pn++) {
1181
+ if (this.#pkt_pn[pn & mask] !== pn) continue;
1182
+ newly_acked_any = true;
1183
+ this.#retire_acked(pn);
1184
+ }
1185
+ }
1186
+
1187
+ if (largest > this.#largest_acked) this.#largest_acked = largest;
1188
+ if (newly_acked_any) this.#pto_count = 0;
1189
+
1190
+ this.#advance_oldest_unretired();
1191
+ this.#detect_lost(now);
1192
+ }
1193
+
1194
+ #process_frames(bytes, start, end) {
1195
+ const cursor = this.#cursor;
1196
+ cursor.position = start;
1197
+ let ack_eliciting = false;
1198
+ while (cursor.position < end) {
1199
+ const type = bytes[cursor.position++];
1200
+ if (type === FRAME_MESSAGE) {
1201
+ ack_eliciting = true;
1202
+ const length = varint_read(bytes, cursor, end);
1203
+ const at = cursor.position;
1204
+ cursor.position = at + length;
1205
+ const resume = cursor.position;
1206
+ this.onMessage.send3(bytes, at, length);
1207
+ if (this.#disposed) return;
1208
+ cursor.position = resume;
1209
+ } else if (type === FRAME_PING) {
1210
+ ack_eliciting = true;
1211
+ } else {
1212
+ ack_eliciting = true;
1213
+ const lane = type & FRAME_STREAM_LANE_MASK;
1214
+ const offset = varint_read(bytes, cursor, end);
1215
+ const length = varint_read(bytes, cursor, end);
1216
+ const at = cursor.position;
1217
+ cursor.position = at + length;
1218
+ const resume = cursor.position;
1219
+ const rx = this.#rx[lane];
1220
+ if (rx.failed) continue;
1221
+ if (!rx.receive(offset, bytes, at, length)) {
1222
+ this.onProtocolError.send1(`lane ${lane}: ${rx.failure}`);
1223
+ if (this.#disposed) return;
1224
+ cursor.position = resume;
1225
+ continue;
1226
+ }
1227
+ this.#deliver_lane(lane);
1228
+ if (this.#disposed) return;
1229
+ cursor.position = resume;
1230
+ }
1231
+ }
1232
+ if (ack_eliciting) this.#ack_pending = true;
1233
+ }
1234
+
1235
+ #deliver_lane(lane) {
1236
+ const rx = this.#rx[lane];
1237
+ const out = this.#message_out;
1238
+ for (; ;) {
1239
+ const length = rx.next_message(out);
1240
+ if (length === RX_NONE) return;
1241
+ if (length === RX_ERROR) {
1242
+ this.onProtocolError.send1(`lane ${lane}: ${rx.failure}`);
1243
+ return;
1244
+ }
1245
+ this.onMessage.send3(rx.bytes, out[0], length);
1246
+ if (this.#disposed) return;
1247
+ }
1248
+ }
1249
+
1250
+ #grow_unreliable_queue() {
1251
+ const capacity = this.#uq_offset.length * 2;
1252
+ const offset = new Int32Array(capacity);
1253
+ const length = new Int32Array(capacity);
1254
+ const token = new Int32Array(capacity);
1255
+ offset.set(this.#uq_offset);
1256
+ length.set(this.#uq_length);
1257
+ token.set(this.#uq_token);
1258
+ this.#uq_offset = offset;
1259
+ this.#uq_length = length;
1260
+ this.#uq_token = token;
1261
+ }
1262
+ }