murow 0.0.60 → 0.0.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -37
- package/dist/cjs/core/binary-codec/binary-codec.js +1 -0
- package/dist/cjs/core/binary-codec/index.js +1 -0
- package/dist/cjs/core/driver/driver.js +1 -0
- package/dist/cjs/core/driver/drivers/immediate.js +1 -0
- package/dist/cjs/core/driver/drivers/index.js +1 -0
- package/dist/cjs/core/driver/drivers/raf.js +1 -0
- package/dist/cjs/core/driver/drivers/timeout.js +1 -0
- package/dist/cjs/core/driver/index.js +1 -0
- package/dist/cjs/core/events/event-system.js +1 -0
- package/dist/cjs/core/events/index.js +1 -0
- package/dist/cjs/core/fixed-ticker/fixed-ticker.js +1 -0
- package/dist/cjs/core/fixed-ticker/index.js +1 -0
- package/dist/cjs/core/free-list/free-list.js +1 -0
- package/dist/cjs/core/free-list/index.js +1 -0
- package/dist/cjs/core/generate-id/generate-id.js +1 -0
- package/dist/cjs/core/generate-id/index.js +1 -0
- package/dist/cjs/core/index.js +1 -0
- package/dist/cjs/core/input/index.js +1 -0
- package/dist/cjs/core/input/manager.js +1 -0
- package/dist/cjs/core/input/sources/browser.js +1 -0
- package/dist/cjs/core/input/sources/index.js +1 -0
- package/dist/cjs/core/input/types.js +1 -0
- package/dist/cjs/core/lerp/index.js +1 -0
- package/dist/cjs/core/lerp/lerp.js +1 -0
- package/dist/cjs/core/navmesh/index.js +1 -0
- package/dist/cjs/core/navmesh/navmesh-worker-pool.js +1 -0
- package/dist/cjs/core/navmesh/navmesh.js +1 -0
- package/dist/cjs/core/navmesh/navmesh.worker.js +1 -0
- package/dist/cjs/core/pooled-codec/index.js +1 -0
- package/dist/cjs/core/pooled-codec/pooled-codec.js +1 -0
- package/dist/cjs/core/prediction/index.js +1 -0
- package/dist/cjs/core/prediction/prediction.js +1 -0
- package/dist/cjs/core/ray/index.js +1 -0
- package/dist/cjs/core/ray/ray-2d.js +1 -0
- package/dist/cjs/core/ray/ray-3d.js +1 -0
- package/dist/cjs/core/simple-rng/index.js +1 -0
- package/dist/cjs/core/simple-rng/simple-rng.js +1 -0
- package/dist/cjs/core/sparse-batcher/index.js +1 -0
- package/dist/cjs/core/sparse-batcher/sparse-batcher.js +1 -0
- package/dist/cjs/ecs/component-store.js +1 -0
- package/dist/cjs/ecs/component.js +1 -0
- package/dist/cjs/ecs/entity-handle.js +1 -0
- package/dist/cjs/ecs/index.js +1 -0
- package/dist/cjs/ecs/system-builder.js +1 -0
- package/dist/cjs/ecs/world-systems.js +1 -0
- package/dist/cjs/ecs/world.js +1 -0
- package/dist/cjs/game/index.js +1 -0
- package/dist/cjs/game/loop/index.js +1 -0
- package/dist/cjs/game/loop/loop.js +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/net/adapters/browser-websocket.js +1 -0
- package/dist/cjs/net/adapters/bun-websocket.js +1 -0
- package/dist/cjs/net/buffer-pool.js +1 -0
- package/dist/cjs/net/client.js +1 -0
- package/dist/cjs/net/index.js +1 -0
- package/dist/cjs/net/server.js +1 -0
- package/dist/cjs/net/types.js +1 -0
- package/dist/cjs/net/validators.js +1 -0
- package/dist/cjs/protocol/index.js +1 -0
- package/dist/cjs/protocol/intent/define-intent.js +1 -0
- package/dist/cjs/protocol/intent/index.js +1 -0
- package/dist/cjs/protocol/intent/intent-registry.js +1 -0
- package/dist/cjs/protocol/intent/intent.js +1 -0
- package/dist/cjs/protocol/rpc/define-rpc.js +1 -0
- package/dist/cjs/protocol/rpc/index.js +1 -0
- package/dist/cjs/protocol/rpc/rpc-registry.js +1 -0
- package/dist/cjs/protocol/rpc/rpc.js +1 -0
- package/dist/cjs/protocol/snapshot/index.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot-codec.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot-registry.js +1 -0
- package/dist/cjs/protocol/snapshot/snapshot.js +1 -0
- package/dist/cjs/renderer/base-2d-renderer.js +1 -0
- package/dist/cjs/renderer/base-3d-renderer.js +1 -0
- package/dist/cjs/renderer/base-renderer.js +1 -0
- package/dist/cjs/renderer/index.js +1 -0
- package/dist/cjs/renderer/types.js +1 -0
- package/dist/esm/core/binary-codec/binary-codec.js +1 -0
- package/dist/esm/core/binary-codec/index.js +1 -0
- package/dist/esm/core/driver/driver.js +1 -0
- package/dist/esm/core/driver/drivers/immediate.js +1 -0
- package/dist/esm/core/driver/drivers/index.js +1 -0
- package/dist/esm/core/driver/drivers/raf.js +1 -0
- package/dist/esm/core/driver/drivers/timeout.js +1 -0
- package/dist/esm/core/driver/index.js +1 -0
- package/dist/esm/core/events/event-system.js +1 -0
- package/dist/esm/core/events/index.js +1 -0
- package/dist/esm/core/fixed-ticker/fixed-ticker.js +1 -0
- package/dist/esm/core/fixed-ticker/index.js +1 -0
- package/dist/esm/core/free-list/free-list.js +1 -0
- package/dist/esm/core/free-list/index.js +1 -0
- package/dist/esm/core/generate-id/generate-id.js +1 -0
- package/dist/esm/core/generate-id/index.js +1 -0
- package/dist/esm/core/index.js +1 -0
- package/dist/esm/core/input/index.js +1 -0
- package/dist/esm/core/input/manager.js +1 -0
- package/dist/esm/core/input/sources/browser.js +1 -0
- package/dist/esm/core/input/sources/index.js +1 -0
- package/dist/esm/core/input/types.js +0 -0
- package/dist/esm/core/lerp/index.js +1 -0
- package/dist/esm/core/lerp/lerp.js +1 -0
- package/dist/esm/core/navmesh/index.js +1 -0
- package/dist/esm/core/navmesh/navmesh-worker-pool.js +1 -0
- package/dist/esm/core/navmesh/navmesh.js +1 -0
- package/dist/esm/core/navmesh/navmesh.worker.js +1 -0
- package/dist/esm/core/pooled-codec/index.js +1 -0
- package/dist/esm/core/pooled-codec/pooled-codec.js +1 -0
- package/dist/esm/core/prediction/index.js +1 -0
- package/dist/esm/core/prediction/prediction.js +1 -0
- package/dist/esm/core/ray/index.js +1 -0
- package/dist/esm/core/ray/ray-2d.js +1 -0
- package/dist/esm/core/ray/ray-3d.js +1 -0
- package/dist/esm/core/simple-rng/index.js +1 -0
- package/dist/esm/core/simple-rng/simple-rng.js +1 -0
- package/dist/esm/core/sparse-batcher/index.js +1 -0
- package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -0
- package/dist/esm/ecs/component-store.js +1 -0
- package/dist/esm/ecs/component.js +1 -0
- package/dist/esm/ecs/entity-handle.js +1 -0
- package/dist/esm/ecs/index.js +1 -0
- package/dist/esm/ecs/system-builder.js +1 -0
- package/dist/esm/ecs/world-systems.js +1 -0
- package/dist/esm/ecs/world.js +1 -0
- package/dist/esm/game/index.js +1 -0
- package/dist/esm/game/loop/index.js +1 -0
- package/dist/esm/game/loop/loop.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/net/adapters/browser-websocket.js +1 -0
- package/dist/esm/net/adapters/bun-websocket.js +1 -0
- package/dist/esm/net/buffer-pool.js +1 -0
- package/dist/esm/net/client.js +1 -0
- package/dist/esm/net/index.js +1 -0
- package/dist/esm/net/server.js +1 -0
- package/dist/esm/net/types.js +1 -0
- package/dist/esm/net/validators.js +1 -0
- package/dist/esm/protocol/index.js +1 -0
- package/dist/esm/protocol/intent/define-intent.js +1 -0
- package/dist/esm/protocol/intent/index.js +1 -0
- package/dist/esm/protocol/intent/intent-registry.js +1 -0
- package/dist/esm/protocol/intent/intent.js +0 -0
- package/dist/esm/protocol/rpc/define-rpc.js +1 -0
- package/dist/esm/protocol/rpc/index.js +1 -0
- package/dist/esm/protocol/rpc/rpc-registry.js +1 -0
- package/dist/esm/protocol/rpc/rpc.js +0 -0
- package/dist/esm/protocol/snapshot/index.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot-codec.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot-registry.js +1 -0
- package/dist/esm/protocol/snapshot/snapshot.js +1 -0
- package/dist/esm/renderer/base-2d-renderer.js +1 -0
- package/dist/esm/renderer/base-3d-renderer.js +1 -0
- package/dist/esm/renderer/base-renderer.js +1 -0
- package/dist/esm/renderer/index.js +1 -0
- package/dist/esm/renderer/types.js +0 -0
- package/dist/{core → types/core}/binary-codec/binary-codec.d.ts +4 -0
- package/dist/{core/loop → types/core/driver}/drivers/immediate.d.ts +1 -1
- package/dist/{core/loop → types/core/driver}/drivers/raf.d.ts +1 -1
- package/dist/{core/loop → types/core/driver}/drivers/timeout.d.ts +1 -1
- package/dist/{core/loop → types/core/driver}/index.d.ts +1 -1
- package/dist/{core → types/core}/events/event-system.d.ts +14 -33
- package/dist/{core → types/core}/fixed-ticker/fixed-ticker.d.ts +1 -1
- package/dist/types/core/free-list/free-list.d.ts +31 -0
- package/dist/types/core/free-list/index.d.ts +1 -0
- package/dist/{core → types/core}/index.d.ts +7 -1
- package/dist/types/core/input/index.d.ts +3 -0
- package/dist/types/core/input/manager.d.ts +56 -0
- package/dist/types/core/input/sources/browser.d.ts +9 -0
- package/dist/types/core/input/sources/index.d.ts +1 -0
- package/dist/types/core/input/types.d.ts +36 -0
- package/dist/{core → types/core}/navmesh/navmesh.d.ts +1 -21
- package/dist/types/core/ray/index.d.ts +2 -0
- package/dist/types/core/ray/ray-2d.d.ts +37 -0
- package/dist/types/core/ray/ray-3d.d.ts +42 -0
- package/dist/types/core/simple-rng/index.d.ts +1 -0
- package/dist/types/core/simple-rng/simple-rng.d.ts +36 -0
- package/dist/types/core/sparse-batcher/index.d.ts +1 -0
- package/dist/types/core/sparse-batcher/sparse-batcher.d.ts +55 -0
- package/dist/{ecs → types/ecs}/system-builder.d.ts +20 -9
- package/dist/{ecs → types/ecs}/world.d.ts +11 -0
- package/dist/types/game/index.d.ts +1 -0
- package/dist/types/game/loop/index.d.ts +1 -0
- package/dist/types/game/loop/loop.d.ts +175 -0
- package/dist/{index.d.ts → types/index.d.ts} +2 -0
- package/dist/{net → types/net}/index.d.ts +2 -2
- package/dist/{net → types/net}/server.d.ts +39 -19
- package/dist/{protocol → types/protocol}/intent/define-intent.d.ts +15 -0
- package/dist/{protocol → types/protocol}/intent/index.d.ts +1 -1
- package/dist/types/renderer/base-2d-renderer.d.ts +13 -0
- package/dist/types/renderer/base-3d-renderer.d.ts +10 -0
- package/dist/types/renderer/base-renderer.d.ts +21 -0
- package/dist/types/renderer/index.d.ts +4 -0
- package/dist/types/renderer/types.d.ts +79 -0
- package/dist/webgpu/cjs/index.js +6004 -0
- package/dist/webgpu/esm/index.js +5972 -0
- package/dist/webgpu/types/2d/animation.d.ts +97 -0
- package/dist/webgpu/types/2d/renderer.d.ts +55 -0
- package/dist/webgpu/types/2d/shader.d.ts +61 -0
- package/dist/webgpu/types/2d/sprite-accessor.d.ts +47 -0
- package/dist/webgpu/types/2d/sprite-accessor.test.d.ts +1 -0
- package/dist/webgpu/types/3d/gltf-skin-parser.d.ts +101 -0
- package/dist/webgpu/types/3d/morph-animation.d.ts +69 -0
- package/dist/webgpu/types/3d/morph-animation.test.d.ts +1 -0
- package/dist/webgpu/types/3d/renderer.d.ts +216 -0
- package/dist/webgpu/types/3d/shader.d.ts +136 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +2 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +8 -0
- package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +32 -0
- package/dist/webgpu/types/3d/skeletal-animation.d.ts +90 -0
- package/dist/webgpu/types/camera/camera-2d.d.ts +53 -0
- package/dist/webgpu/types/camera/camera-2d.test.d.ts +1 -0
- package/dist/webgpu/types/camera/camera-3d.d.ts +81 -0
- package/dist/webgpu/types/camera/camera-3d.test.d.ts +1 -0
- package/dist/webgpu/types/camera/index.d.ts +2 -0
- package/dist/webgpu/types/compute/compute-builder.d.ts +123 -0
- package/dist/webgpu/types/compute/compute-builder.test.d.ts +1 -0
- package/dist/webgpu/types/core/constants.d.ts +59 -0
- package/dist/webgpu/types/core/constants.test.d.ts +1 -0
- package/dist/webgpu/types/core/index.d.ts +2 -0
- package/dist/webgpu/types/core/math.d.ts +37 -0
- package/dist/webgpu/types/core/types.d.ts +125 -0
- package/dist/webgpu/types/core/types.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/built-in.d.ts +58 -0
- package/dist/webgpu/types/geometry/built-in.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/geometry-builder.d.ts +281 -0
- package/dist/webgpu/types/geometry/geometry-builder.test.d.ts +1 -0
- package/dist/webgpu/types/geometry/index.d.ts +2 -0
- package/dist/webgpu/types/index.d.ts +32 -0
- package/dist/webgpu/types/particle/emitter.d.ts +36 -0
- package/dist/webgpu/types/shaders/index.d.ts +2 -0
- package/dist/webgpu/types/shaders/runtime-transpile.d.ts +18 -0
- package/dist/webgpu/types/shaders/sprite-2d.wgsl.d.ts +10 -0
- package/dist/webgpu/types/shaders/typegpu.d.ts +9 -0
- package/dist/webgpu/types/shaders/utils.d.ts +28 -0
- package/dist/webgpu/types/shaders/utils.test.d.ts +1 -0
- package/dist/webgpu/types/spritesheet/index.d.ts +1 -0
- package/dist/webgpu/types/spritesheet/spritesheet.d.ts +57 -0
- package/dist/webgpu/types/spritesheet/spritesheet.test.d.ts +1 -0
- package/package.json +96 -26
- package/dist/core/binary-codec/binary-codec.js +0 -354
- package/dist/core/binary-codec/index.js +0 -1
- package/dist/core/events/event-system.js +0 -88
- package/dist/core/events/index.js +0 -1
- package/dist/core/fixed-ticker/fixed-ticker.js +0 -101
- package/dist/core/fixed-ticker/index.js +0 -1
- package/dist/core/generate-id/generate-id.js +0 -25
- package/dist/core/generate-id/index.js +0 -1
- package/dist/core/index.js +0 -9
- package/dist/core/lerp/index.js +0 -1
- package/dist/core/lerp/lerp.js +0 -42
- package/dist/core/loop/drivers/immediate.js +0 -61
- package/dist/core/loop/drivers/index.js +0 -3
- package/dist/core/loop/drivers/raf.js +0 -62
- package/dist/core/loop/drivers/timeout.js +0 -71
- package/dist/core/loop/index.js +0 -2
- package/dist/core/loop/loop.js +0 -47
- package/dist/core/navmesh/index.js +0 -1
- package/dist/core/navmesh/navmesh-worker-pool.js +0 -180
- package/dist/core/navmesh/navmesh.js +0 -799
- package/dist/core/navmesh/navmesh.worker.js +0 -79
- package/dist/core/pooled-codec/index.js +0 -1
- package/dist/core/pooled-codec/pooled-codec.js +0 -410
- package/dist/core/prediction/index.js +0 -1
- package/dist/core/prediction/prediction.js +0 -99
- package/dist/core.esm.js +0 -1
- package/dist/core.js +0 -1
- package/dist/ecs/component-store.js +0 -175
- package/dist/ecs/component.js +0 -43
- package/dist/ecs/entity-handle.js +0 -515
- package/dist/ecs/example.js +0 -125
- package/dist/ecs/index.js +0 -4
- package/dist/ecs/system-builder.js +0 -180
- package/dist/ecs/system.d.ts +0 -63
- package/dist/ecs/system.js +0 -92
- package/dist/ecs/world-systems.js +0 -79
- package/dist/ecs/world.js +0 -684
- package/dist/index.js +0 -24
- package/dist/net/adapters/browser-websocket.js +0 -74
- package/dist/net/adapters/bun-websocket.js +0 -245
- package/dist/net/buffer-pool.js +0 -89
- package/dist/net/client.js +0 -586
- package/dist/net/index.js +0 -58
- package/dist/net/server.js +0 -938
- package/dist/net/types.js +0 -31
- package/dist/net/validators.js +0 -88
- package/dist/protocol/index.js +0 -92
- package/dist/protocol/intent/define-intent.js +0 -125
- package/dist/protocol/intent/index.js +0 -91
- package/dist/protocol/intent/intent-registry.js +0 -91
- package/dist/protocol/rpc/define-rpc.js +0 -84
- package/dist/protocol/rpc/index.js +0 -3
- package/dist/protocol/rpc/rpc-registry.js +0 -159
- package/dist/protocol/rpc/rpc.js +0 -12
- package/dist/protocol/snapshot/index.js +0 -43
- package/dist/protocol/snapshot/snapshot-codec.js +0 -67
- package/dist/protocol/snapshot/snapshot-registry.js +0 -168
- package/dist/protocol/snapshot/snapshot.js +0 -30
- package/src/core/binary-codec/README.md +0 -60
- package/src/core/binary-codec/binary-codec.test.ts +0 -300
- package/src/core/binary-codec/binary-codec.ts +0 -448
- package/src/core/binary-codec/index.ts +0 -1
- package/src/core/events/README.md +0 -47
- package/src/core/events/event-system.test.ts +0 -243
- package/src/core/events/event-system.ts +0 -140
- package/src/core/events/index.ts +0 -1
- package/src/core/fixed-ticker/README.md +0 -77
- package/src/core/fixed-ticker/fixed-ticker.test.ts +0 -151
- package/src/core/fixed-ticker/fixed-ticker.ts +0 -169
- package/src/core/fixed-ticker/index.ts +0 -1
- package/src/core/generate-id/README.md +0 -18
- package/src/core/generate-id/generate-id.test.ts +0 -79
- package/src/core/generate-id/generate-id.ts +0 -37
- package/src/core/generate-id/index.ts +0 -1
- package/src/core/index.ts +0 -9
- package/src/core/lerp/README.md +0 -79
- package/src/core/lerp/index.ts +0 -1
- package/src/core/lerp/lerp.test.ts +0 -90
- package/src/core/lerp/lerp.ts +0 -42
- package/src/core/loop/README.md +0 -97
- package/src/core/loop/drivers/immediate.ts +0 -66
- package/src/core/loop/drivers/index.ts +0 -3
- package/src/core/loop/drivers/raf.ts +0 -67
- package/src/core/loop/drivers/timeout.ts +0 -77
- package/src/core/loop/index.ts +0 -2
- package/src/core/loop/loop.test.ts +0 -414
- package/src/core/loop/loop.ts +0 -71
- package/src/core/navmesh/README.md +0 -164
- package/src/core/navmesh/index.ts +0 -1
- package/src/core/navmesh/navmesh-worker-pool.ts +0 -236
- package/src/core/navmesh/navmesh-workers.test.ts +0 -356
- package/src/core/navmesh/navmesh.test.ts +0 -344
- package/src/core/navmesh/navmesh.ts +0 -1047
- package/src/core/navmesh/navmesh.worker.ts +0 -147
- package/src/core/pooled-codec/README.md +0 -70
- package/src/core/pooled-codec/index.ts +0 -1
- package/src/core/pooled-codec/pooled-codec.test.ts +0 -862
- package/src/core/pooled-codec/pooled-codec.ts +0 -504
- package/src/core/prediction/README.md +0 -64
- package/src/core/prediction/index.ts +0 -1
- package/src/core/prediction/prediction.test.ts +0 -423
- package/src/core/prediction/prediction.ts +0 -112
- package/src/ecs/README.md +0 -427
- package/src/ecs/benchmark.test.ts +0 -1645
- package/src/ecs/component-store.ts +0 -198
- package/src/ecs/component.ts +0 -90
- package/src/ecs/entity-handle.test.ts +0 -393
- package/src/ecs/entity-handle.ts +0 -563
- package/src/ecs/example.ts +0 -152
- package/src/ecs/index.ts +0 -4
- package/src/ecs/system-builder.ts +0 -309
- package/src/ecs/system.ts +0 -111
- package/src/ecs/world-systems.ts +0 -83
- package/src/ecs/world.test.ts +0 -310
- package/src/ecs/world.ts +0 -828
- package/src/index.ts +0 -28
- package/src/net/README.md +0 -474
- package/src/net/adapters/browser-websocket.ts +0 -86
- package/src/net/adapters/bun-websocket.ts +0 -292
- package/src/net/buffer-pool.ts +0 -106
- package/src/net/client.test.ts +0 -807
- package/src/net/client.ts +0 -695
- package/src/net/index.ts +0 -60
- package/src/net/server.test.ts +0 -799
- package/src/net/server.ts +0 -1116
- package/src/net/types.ts +0 -228
- package/src/net/validators.ts +0 -104
- package/src/protocol/README.md +0 -469
- package/src/protocol/index.ts +0 -93
- package/src/protocol/intent/define-intent.test.ts +0 -397
- package/src/protocol/intent/define-intent.ts +0 -182
- package/src/protocol/intent/index.ts +0 -94
- package/src/protocol/intent/intent-registry.test.ts +0 -198
- package/src/protocol/intent/intent-registry.ts +0 -112
- package/src/protocol/intent/intent.ts +0 -12
- package/src/protocol/rpc/define-rpc.test.ts +0 -141
- package/src/protocol/rpc/define-rpc.ts +0 -113
- package/src/protocol/rpc/index.ts +0 -3
- package/src/protocol/rpc/rpc-registry.test.ts +0 -168
- package/src/protocol/rpc/rpc-registry.ts +0 -176
- package/src/protocol/rpc/rpc.ts +0 -37
- package/src/protocol/snapshot/index.ts +0 -45
- package/src/protocol/snapshot/snapshot-codec.test.ts +0 -138
- package/src/protocol/snapshot/snapshot-codec.ts +0 -87
- package/src/protocol/snapshot/snapshot-registry.test.ts +0 -310
- package/src/protocol/snapshot/snapshot-registry.ts +0 -201
- package/src/protocol/snapshot/snapshot.test.ts +0 -76
- package/src/protocol/snapshot/snapshot.ts +0 -41
- /package/dist/{core → types/core}/binary-codec/index.d.ts +0 -0
- /package/dist/{core/loop/loop.d.ts → types/core/driver/driver.d.ts} +0 -0
- /package/dist/{core/loop → types/core/driver}/drivers/index.d.ts +0 -0
- /package/dist/{core → types/core}/events/index.d.ts +0 -0
- /package/dist/{core → types/core}/fixed-ticker/index.d.ts +0 -0
- /package/dist/{core → types/core}/generate-id/generate-id.d.ts +0 -0
- /package/dist/{core → types/core}/generate-id/index.d.ts +0 -0
- /package/dist/{core → types/core}/lerp/index.d.ts +0 -0
- /package/dist/{core → types/core}/lerp/lerp.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/index.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/navmesh-worker-pool.d.ts +0 -0
- /package/dist/{core → types/core}/navmesh/navmesh.worker.d.ts +0 -0
- /package/dist/{core → types/core}/pooled-codec/index.d.ts +0 -0
- /package/dist/{core → types/core}/pooled-codec/pooled-codec.d.ts +0 -0
- /package/dist/{core → types/core}/prediction/index.d.ts +0 -0
- /package/dist/{core → types/core}/prediction/prediction.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/component-store.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/component.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/entity-handle.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/example.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/index.d.ts +0 -0
- /package/dist/{ecs → types/ecs}/world-systems.d.ts +0 -0
- /package/dist/{net → types/net}/adapters/browser-websocket.d.ts +0 -0
- /package/dist/{net → types/net}/adapters/bun-websocket.d.ts +0 -0
- /package/dist/{net → types/net}/buffer-pool.d.ts +0 -0
- /package/dist/{net → types/net}/client.d.ts +0 -0
- /package/dist/{net → types/net}/types.d.ts +0 -0
- /package/dist/{net → types/net}/validators.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/intent-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/intent/intent.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/define-rpc.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/rpc-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/rpc/rpc.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/index.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot-codec.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot-registry.d.ts +0 -0
- /package/dist/{protocol → types/protocol}/snapshot/snapshot.d.ts +0 -0
- /package/dist/{protocol/intent/intent.js → webgpu/types/2d/animation.test.d.ts} +0 -0
|
@@ -1,862 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import {
|
|
3
|
-
ObjectPool,
|
|
4
|
-
PooledDecoder,
|
|
5
|
-
PooledEncoder,
|
|
6
|
-
PooledCodec,
|
|
7
|
-
PooledArrayDecoder,
|
|
8
|
-
} from "./pooled-codec";
|
|
9
|
-
import { BinaryCodec, BinaryPrimitives, Schema } from "../binary-codec";
|
|
10
|
-
|
|
11
|
-
describe("ObjectPool", () => {
|
|
12
|
-
test("should create new object when pool is empty", () => {
|
|
13
|
-
const pool = new ObjectPool(() => ({ value: 0 }));
|
|
14
|
-
const obj = pool.acquire();
|
|
15
|
-
expect(obj).toEqual({ value: 0 });
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test("should reuse released objects", () => {
|
|
19
|
-
const pool = new ObjectPool(() => ({ value: 0 }));
|
|
20
|
-
const obj1 = pool.acquire();
|
|
21
|
-
obj1.value = 42;
|
|
22
|
-
pool.release(obj1);
|
|
23
|
-
|
|
24
|
-
const obj2 = pool.acquire();
|
|
25
|
-
expect(obj2.value).toBe(42);
|
|
26
|
-
expect(obj2).toBe(obj1); // Same object reference
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("should handle multiple acquire/release cycles", () => {
|
|
30
|
-
const pool = new ObjectPool(() => ({ count: 0 }));
|
|
31
|
-
|
|
32
|
-
const obj1 = pool.acquire();
|
|
33
|
-
obj1.count = 1;
|
|
34
|
-
pool.release(obj1);
|
|
35
|
-
|
|
36
|
-
const obj2 = pool.acquire();
|
|
37
|
-
obj2.count = 2;
|
|
38
|
-
pool.release(obj2);
|
|
39
|
-
|
|
40
|
-
const obj3 = pool.acquire();
|
|
41
|
-
expect(obj3.count).toBe(2); // Gets the last released object
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test("should release multiple objects at once", () => {
|
|
45
|
-
const pool = new ObjectPool(() => ({ id: 0 }));
|
|
46
|
-
|
|
47
|
-
const objs = [
|
|
48
|
-
pool.acquire(),
|
|
49
|
-
pool.acquire(),
|
|
50
|
-
pool.acquire(),
|
|
51
|
-
];
|
|
52
|
-
|
|
53
|
-
objs.forEach((obj, i) => (obj.id = i));
|
|
54
|
-
pool.releaseAll(objs);
|
|
55
|
-
|
|
56
|
-
const reused1 = pool.acquire();
|
|
57
|
-
const reused2 = pool.acquire();
|
|
58
|
-
const reused3 = pool.acquire();
|
|
59
|
-
|
|
60
|
-
expect([reused1.id, reused2.id, reused3.id].sort()).toEqual([0, 1, 2]);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe("PooledDecoder", () => {
|
|
65
|
-
test("should decode data into pooled objects", () => {
|
|
66
|
-
const schema: Schema<{ value: number }> = {
|
|
67
|
-
value: BinaryPrimitives.f32,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const decoder = new PooledDecoder(schema);
|
|
71
|
-
|
|
72
|
-
// Use BinaryCodec to encode the data first
|
|
73
|
-
const data = { value: 10.5 };
|
|
74
|
-
const buffer = BinaryCodec.encode(schema, data);
|
|
75
|
-
|
|
76
|
-
const obj = decoder.decode(buffer);
|
|
77
|
-
expect(obj.value).toBeCloseTo(10.5, 5);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test("should reuse released objects", () => {
|
|
81
|
-
const schema: Schema<{ value: number }> = {
|
|
82
|
-
value: BinaryPrimitives.u32,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const decoder = new PooledDecoder(schema);
|
|
86
|
-
|
|
87
|
-
const buffer = new Uint8Array(4);
|
|
88
|
-
const view = new DataView(buffer.buffer);
|
|
89
|
-
view.setUint32(0, 42, false);
|
|
90
|
-
|
|
91
|
-
const obj1 = decoder.decode(buffer);
|
|
92
|
-
expect(obj1.value).toBe(42);
|
|
93
|
-
|
|
94
|
-
decoder.release(obj1);
|
|
95
|
-
|
|
96
|
-
view.setUint32(0, 100, false);
|
|
97
|
-
const obj2 = decoder.decode(buffer);
|
|
98
|
-
expect(obj2.value).toBe(100);
|
|
99
|
-
expect(obj2).toBe(obj1); // Same object reference
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test("should decode into existing target object", () => {
|
|
103
|
-
const schema: Schema<{ value: number }> = {
|
|
104
|
-
value: BinaryPrimitives.u8,
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const decoder = new PooledDecoder(schema);
|
|
108
|
-
|
|
109
|
-
// Use BinaryCodec to encode the data first
|
|
110
|
-
const data = { value: 10 };
|
|
111
|
-
const buffer = BinaryCodec.encode(schema, data);
|
|
112
|
-
const target = { value: 0 };
|
|
113
|
-
|
|
114
|
-
decoder.decodeInto(buffer, target);
|
|
115
|
-
expect(target.value).toBe(10);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe("PooledArrayDecoder", () => {
|
|
120
|
-
test("should decode multiple buffers into pooled objects", () => {
|
|
121
|
-
const schema: Schema<{ id: number }> = {
|
|
122
|
-
id: BinaryPrimitives.u32,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const arrayDecoder = new PooledArrayDecoder(schema);
|
|
126
|
-
|
|
127
|
-
const buffers = [
|
|
128
|
-
new Uint8Array([0, 0, 0, 1]),
|
|
129
|
-
new Uint8Array([0, 0, 0, 2]),
|
|
130
|
-
new Uint8Array([0, 0, 0, 3]),
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
const objs = arrayDecoder.decodeAll(buffers);
|
|
134
|
-
expect(objs.length).toBe(3);
|
|
135
|
-
expect(objs[0].id).toBe(1);
|
|
136
|
-
expect(objs[1].id).toBe(2);
|
|
137
|
-
expect(objs[2].id).toBe(3);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test("should release multiple objects", () => {
|
|
141
|
-
const schema: Schema<{ value: number }> = {
|
|
142
|
-
value: BinaryPrimitives.u8,
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const arrayDecoder = new PooledArrayDecoder(schema);
|
|
146
|
-
|
|
147
|
-
// Use BinaryCodec to encode the data first
|
|
148
|
-
const buffers = [
|
|
149
|
-
BinaryCodec.encode(schema, { value: 10 }),
|
|
150
|
-
BinaryCodec.encode(schema, { value: 20 }),
|
|
151
|
-
BinaryCodec.encode(schema, { value: 30 }),
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
const objs = arrayDecoder.decodeAll(buffers);
|
|
155
|
-
const objValues = objs.map(o => o.value);
|
|
156
|
-
expect(objValues).toEqual([10, 20, 30]);
|
|
157
|
-
|
|
158
|
-
arrayDecoder.releaseAll(objs);
|
|
159
|
-
|
|
160
|
-
// Decode again and verify objects are reused (checking references)
|
|
161
|
-
const newObjs = arrayDecoder.decodeAll(buffers);
|
|
162
|
-
// Objects should be reused (same references)
|
|
163
|
-
let reuseCount = 0;
|
|
164
|
-
for (const newObj of newObjs) {
|
|
165
|
-
if (objs.includes(newObj)) reuseCount++;
|
|
166
|
-
}
|
|
167
|
-
expect(reuseCount).toBeGreaterThan(0);
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
describe("PooledEncoder", () => {
|
|
172
|
-
test("should encode objects into pooled buffers", () => {
|
|
173
|
-
const schema: Schema<{ x: number; y: number }> = {
|
|
174
|
-
x: BinaryPrimitives.f32,
|
|
175
|
-
y: BinaryPrimitives.f32,
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const encoder = new PooledEncoder(schema);
|
|
179
|
-
const data = { x: 5.5, y: 10.5 };
|
|
180
|
-
|
|
181
|
-
const buffer = encoder.encode(data);
|
|
182
|
-
expect(buffer.length).toBe(8);
|
|
183
|
-
|
|
184
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
185
|
-
expect(view.getFloat32(0, false)).toBeCloseTo(5.5, 5);
|
|
186
|
-
expect(view.getFloat32(4, false)).toBeCloseTo(10.5, 5);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
test("should reuse released buffers", () => {
|
|
190
|
-
const schema: Schema<{ value: number }> = {
|
|
191
|
-
value: BinaryPrimitives.u32,
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
const encoder = new PooledEncoder(schema, 16);
|
|
195
|
-
const data1 = { value: 42 };
|
|
196
|
-
|
|
197
|
-
const buffer1 = encoder.encode(data1);
|
|
198
|
-
encoder.release(buffer1);
|
|
199
|
-
|
|
200
|
-
const data2 = { value: 100 };
|
|
201
|
-
const buffer2 = encoder.encode(data2);
|
|
202
|
-
|
|
203
|
-
// Should reuse the same underlying buffer
|
|
204
|
-
expect(buffer2.buffer).toBe(buffer1.buffer);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
test("should handle custom buffer size", () => {
|
|
208
|
-
const schema: Schema<{ id: number }> = {
|
|
209
|
-
id: BinaryPrimitives.u8,
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const encoder = new PooledEncoder(schema, 64);
|
|
213
|
-
const data = { id: 5 };
|
|
214
|
-
|
|
215
|
-
const buffer = encoder.encode(data);
|
|
216
|
-
expect(buffer.length).toBe(1); // Only actual data
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
describe("PooledCodec", () => {
|
|
221
|
-
test("should encode and decode with pooling", () => {
|
|
222
|
-
const schema: Schema<{ id: number }> = {
|
|
223
|
-
id: BinaryPrimitives.u32,
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
const codec = new PooledCodec(schema);
|
|
227
|
-
const data = { id: 123 };
|
|
228
|
-
|
|
229
|
-
const encoded = codec.encode(data);
|
|
230
|
-
const decoded = codec.decode(encoded);
|
|
231
|
-
|
|
232
|
-
expect(decoded.id).toBe(123);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
test("should reuse objects after release", () => {
|
|
236
|
-
const schema: Schema<{ value: number }> = {
|
|
237
|
-
value: BinaryPrimitives.u32,
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
const codec = new PooledCodec(schema);
|
|
241
|
-
|
|
242
|
-
const encoded1 = codec.encode({ value: 42 });
|
|
243
|
-
const decoded1 = codec.decode(encoded1);
|
|
244
|
-
expect(decoded1.value).toBe(42);
|
|
245
|
-
|
|
246
|
-
codec.release(decoded1);
|
|
247
|
-
|
|
248
|
-
const encoded2 = codec.encode({ value: 100 });
|
|
249
|
-
const decoded2 = codec.decode(encoded2);
|
|
250
|
-
expect(decoded2.value).toBe(100);
|
|
251
|
-
expect(decoded2).toBe(decoded1); // Same object
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
test("should handle multiple encode/decode cycles", () => {
|
|
255
|
-
const schema: Schema<{ value: number }> = {
|
|
256
|
-
value: BinaryPrimitives.u16,
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const codec = new PooledCodec(schema);
|
|
260
|
-
|
|
261
|
-
for (let i = 0; i < 100; i++) {
|
|
262
|
-
const data = { value: i * 10 };
|
|
263
|
-
const encoded = codec.encode(data);
|
|
264
|
-
const decoded = codec.decode(encoded);
|
|
265
|
-
|
|
266
|
-
expect(decoded.value).toBe(i * 10);
|
|
267
|
-
|
|
268
|
-
codec.release(decoded);
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test("should work with single field schemas", () => {
|
|
273
|
-
const schema: Schema<{
|
|
274
|
-
id: number;
|
|
275
|
-
}> = {
|
|
276
|
-
id: BinaryPrimitives.u32,
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const codec = new PooledCodec(schema);
|
|
280
|
-
const data = {
|
|
281
|
-
id: 999,
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const encoded = codec.encode(data);
|
|
285
|
-
const decoded = codec.decode(encoded);
|
|
286
|
-
|
|
287
|
-
expect(decoded.id).toBe(999);
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
describe("PooledCodec - Memory Efficiency", () => {
|
|
292
|
-
test("should reduce allocations with pooling", () => {
|
|
293
|
-
const schema: Schema<{ value: number }> = {
|
|
294
|
-
value: BinaryPrimitives.u32,
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
const codec = new PooledCodec(schema);
|
|
298
|
-
const objects: any[] = [];
|
|
299
|
-
|
|
300
|
-
const times = 10000;
|
|
301
|
-
|
|
302
|
-
// Encode and decode {times} times
|
|
303
|
-
for (let i = 0; i < times; i++) {
|
|
304
|
-
const encoded = codec.encode({ value: i });
|
|
305
|
-
const decoded = codec.decode(encoded);
|
|
306
|
-
objects.push(decoded);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Release all
|
|
310
|
-
objects.forEach((obj) => codec.release(obj));
|
|
311
|
-
|
|
312
|
-
// Decode again - should reuse objects
|
|
313
|
-
const newObjects: any[] = [];
|
|
314
|
-
for (let i = 0; i < times; i++) {
|
|
315
|
-
const encoded = codec.encode({ value: i });
|
|
316
|
-
const decoded = codec.decode(encoded);
|
|
317
|
-
newObjects.push(decoded);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// At least some objects should be reused
|
|
321
|
-
let reusedCount = 0;
|
|
322
|
-
for (const newObj of newObjects) {
|
|
323
|
-
if (objects.includes(newObj)) {
|
|
324
|
-
reusedCount++;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
expect(reusedCount).toBeGreaterThan(0);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
test("should handle concurrent encode/decode without release", () => {
|
|
332
|
-
const schema: Schema<{ id: number }> = {
|
|
333
|
-
id: BinaryPrimitives.u16,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const codec = new PooledCodec(schema);
|
|
337
|
-
const objects: any[] = [];
|
|
338
|
-
|
|
339
|
-
// Create many objects without releasing
|
|
340
|
-
for (let i = 0; i < 50; i++) {
|
|
341
|
-
const encoded = codec.encode({ id: i });
|
|
342
|
-
const decoded = codec.decode(encoded);
|
|
343
|
-
objects.push(decoded);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
expect(objects.length).toBe(50);
|
|
347
|
-
objects.forEach((obj, i) => expect(obj.id).toBe(i));
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
describe("PooledCodec.array", () => {
|
|
352
|
-
test("should encode and decode arrays of objects", () => {
|
|
353
|
-
const PlayerSchema = {
|
|
354
|
-
entityId: BinaryPrimitives.u32,
|
|
355
|
-
x: BinaryPrimitives.f32,
|
|
356
|
-
y: BinaryPrimitives.f32,
|
|
357
|
-
} satisfies Schema<{ entityId: number; x: number; y: number }>;
|
|
358
|
-
|
|
359
|
-
const UpdateSchema = {
|
|
360
|
-
tick: BinaryPrimitives.u32,
|
|
361
|
-
players: PooledCodec.array(PlayerSchema),
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
365
|
-
|
|
366
|
-
// Encode
|
|
367
|
-
const buffer = codec.encode({
|
|
368
|
-
tick: 42,
|
|
369
|
-
players: [
|
|
370
|
-
{ entityId: 1, x: 10.5, y: 20.5 },
|
|
371
|
-
{ entityId: 2, x: 30.5, y: 40.5 },
|
|
372
|
-
],
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
// Decode
|
|
376
|
-
const snapshot = codec.decode(buffer);
|
|
377
|
-
|
|
378
|
-
expect(snapshot.tick).toBe(42);
|
|
379
|
-
expect(snapshot.players.length).toBe(2);
|
|
380
|
-
expect(snapshot.players[0].entityId).toBe(1);
|
|
381
|
-
expect(snapshot.players[0].x).toBeCloseTo(10.5, 5);
|
|
382
|
-
expect(snapshot.players[0].y).toBeCloseTo(20.5, 5);
|
|
383
|
-
expect(snapshot.players[1].entityId).toBe(2);
|
|
384
|
-
expect(snapshot.players[1].x).toBeCloseTo(30.5, 5);
|
|
385
|
-
expect(snapshot.players[1].y).toBeCloseTo(40.5, 5);
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
test("should handle empty arrays", () => {
|
|
389
|
-
const ItemSchema = {
|
|
390
|
-
id: BinaryPrimitives.u32,
|
|
391
|
-
} satisfies Schema<{ id: number }>;
|
|
392
|
-
|
|
393
|
-
const UpdateSchema = {
|
|
394
|
-
tick: BinaryPrimitives.u16,
|
|
395
|
-
items: PooledCodec.array(ItemSchema),
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
399
|
-
|
|
400
|
-
// Encode with empty array
|
|
401
|
-
const buffer = codec.encode({
|
|
402
|
-
tick: 100,
|
|
403
|
-
items: [],
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
// Decode
|
|
407
|
-
const snapshot = codec.decode(buffer);
|
|
408
|
-
|
|
409
|
-
expect(snapshot.tick).toBe(100);
|
|
410
|
-
expect(snapshot.items).toEqual([]);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
test("should handle arrays with many items", () => {
|
|
414
|
-
const PositionSchema = {
|
|
415
|
-
x: BinaryPrimitives.f32,
|
|
416
|
-
y: BinaryPrimitives.f32,
|
|
417
|
-
} satisfies Schema<{ x: number; y: number }>;
|
|
418
|
-
|
|
419
|
-
const UpdateSchema = {
|
|
420
|
-
positions: PooledCodec.array(PositionSchema),
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
424
|
-
|
|
425
|
-
// Create 100 positions
|
|
426
|
-
const positions = Array.from({ length: 100 }, (_, i) => ({
|
|
427
|
-
x: i * 1.5,
|
|
428
|
-
y: i * 2.5,
|
|
429
|
-
}));
|
|
430
|
-
|
|
431
|
-
// Encode
|
|
432
|
-
const buffer = codec.encode({ positions });
|
|
433
|
-
|
|
434
|
-
// Decode
|
|
435
|
-
const snapshot = codec.decode(buffer);
|
|
436
|
-
|
|
437
|
-
expect(snapshot.positions.length).toBe(100);
|
|
438
|
-
for (let i = 0; i < 100; i++) {
|
|
439
|
-
expect(snapshot.positions[i].x).toBeCloseTo(i * 1.5, 5);
|
|
440
|
-
expect(snapshot.positions[i].y).toBeCloseTo(i * 2.5, 5);
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
test("should work with multiple array fields", () => {
|
|
445
|
-
const PlayerSchema = {
|
|
446
|
-
id: BinaryPrimitives.u32,
|
|
447
|
-
health: BinaryPrimitives.u8,
|
|
448
|
-
} satisfies Schema<{ id: number; health: number }>;
|
|
449
|
-
|
|
450
|
-
const EnemySchema = {
|
|
451
|
-
id: BinaryPrimitives.u32,
|
|
452
|
-
type: BinaryPrimitives.u8,
|
|
453
|
-
} satisfies Schema<{ id: number; type: number }>;
|
|
454
|
-
|
|
455
|
-
const UpdateSchema = {
|
|
456
|
-
tick: BinaryPrimitives.u32,
|
|
457
|
-
players: PooledCodec.array(PlayerSchema),
|
|
458
|
-
enemies: PooledCodec.array(EnemySchema),
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
462
|
-
|
|
463
|
-
// Encode
|
|
464
|
-
const buffer = codec.encode({
|
|
465
|
-
tick: 50,
|
|
466
|
-
players: [
|
|
467
|
-
{ id: 1, health: 100 },
|
|
468
|
-
{ id: 2, health: 75 },
|
|
469
|
-
],
|
|
470
|
-
enemies: [
|
|
471
|
-
{ id: 10, type: 1 },
|
|
472
|
-
{ id: 11, type: 2 },
|
|
473
|
-
{ id: 12, type: 1 },
|
|
474
|
-
],
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
// Decode
|
|
478
|
-
const snapshot = codec.decode(buffer);
|
|
479
|
-
|
|
480
|
-
expect(snapshot.tick).toBe(50);
|
|
481
|
-
expect(snapshot.players.length).toBe(2);
|
|
482
|
-
expect(snapshot.players[0]).toEqual({ id: 1, health: 100 });
|
|
483
|
-
expect(snapshot.players[1]).toEqual({ id: 2, health: 75 });
|
|
484
|
-
expect(snapshot.enemies.length).toBe(3);
|
|
485
|
-
expect(snapshot.enemies[0]).toEqual({ id: 10, type: 1 });
|
|
486
|
-
expect(snapshot.enemies[1]).toEqual({ id: 11, type: 2 });
|
|
487
|
-
expect(snapshot.enemies[2]).toEqual({ id: 12, type: 1 });
|
|
488
|
-
});
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
describe("PooledCodec - Zero-Copy Encoding", () => {
|
|
492
|
-
test("calculateSize should return correct size for simple schema", () => {
|
|
493
|
-
const schema = {
|
|
494
|
-
id: BinaryPrimitives.u32,
|
|
495
|
-
x: BinaryPrimitives.f32,
|
|
496
|
-
y: BinaryPrimitives.f32,
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
const codec = new PooledCodec(schema);
|
|
500
|
-
const data = { id: 1, x: 10.5, y: 20.5 };
|
|
501
|
-
|
|
502
|
-
const size = codec.calculateSize(data);
|
|
503
|
-
expect(size).toBe(4 + 4 + 4); // u32 + f32 + f32 = 12 bytes
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
test("calculateSize should return correct size for schema with arrays", () => {
|
|
507
|
-
const PlayerSchema = {
|
|
508
|
-
entityId: BinaryPrimitives.u32,
|
|
509
|
-
x: BinaryPrimitives.f32,
|
|
510
|
-
y: BinaryPrimitives.f32,
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
const UpdateSchema = {
|
|
514
|
-
tick: BinaryPrimitives.u32,
|
|
515
|
-
players: PooledCodec.array(PlayerSchema),
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
519
|
-
const data = {
|
|
520
|
-
tick: 42,
|
|
521
|
-
players: [
|
|
522
|
-
{ entityId: 1, x: 10.5, y: 20.5 },
|
|
523
|
-
{ entityId: 2, x: 30.5, y: 40.5 },
|
|
524
|
-
],
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
const size = codec.calculateSize(data);
|
|
528
|
-
// tick(4) + array_length(2) + 2 * (entityId(4) + x(4) + y(4))
|
|
529
|
-
expect(size).toBe(4 + 2 + 2 * 12); // 30 bytes
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
test("encodeInto should write directly to buffer without allocations", () => {
|
|
533
|
-
const schema = {
|
|
534
|
-
id: BinaryPrimitives.u32,
|
|
535
|
-
value: BinaryPrimitives.f32,
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
const codec = new PooledCodec(schema);
|
|
539
|
-
const data = { id: 123, value: 45.67 };
|
|
540
|
-
|
|
541
|
-
const buffer = new Uint8Array(100);
|
|
542
|
-
const bytesWritten = codec.encodeInto(data, buffer, 10);
|
|
543
|
-
|
|
544
|
-
expect(bytesWritten).toBe(8); // 4 + 4
|
|
545
|
-
|
|
546
|
-
// Verify the data was written at the correct offset (using big-endian like BinaryPrimitives)
|
|
547
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset);
|
|
548
|
-
expect(view.getUint32(10, false)).toBe(123);
|
|
549
|
-
expect(view.getFloat32(14, false)).toBeCloseTo(45.67, 2);
|
|
550
|
-
});
|
|
551
|
-
|
|
552
|
-
test("encodeInto should produce same result as encode", () => {
|
|
553
|
-
const PlayerSchema = {
|
|
554
|
-
entityId: BinaryPrimitives.u32,
|
|
555
|
-
x: BinaryPrimitives.f32,
|
|
556
|
-
y: BinaryPrimitives.f32,
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
const UpdateSchema = {
|
|
560
|
-
tick: BinaryPrimitives.u32,
|
|
561
|
-
players: PooledCodec.array(PlayerSchema),
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
565
|
-
const data = {
|
|
566
|
-
tick: 42,
|
|
567
|
-
players: [
|
|
568
|
-
{ entityId: 1, x: 10.5, y: 20.5 },
|
|
569
|
-
{ entityId: 2, x: 30.5, y: 40.5 },
|
|
570
|
-
],
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// Encode using the old method
|
|
574
|
-
const encodedOld = codec.encode(data);
|
|
575
|
-
|
|
576
|
-
// Encode using encodeInto
|
|
577
|
-
const size = codec.calculateSize(data);
|
|
578
|
-
const buffer = new Uint8Array(size);
|
|
579
|
-
const bytesWritten = codec.encodeInto(data, buffer, 0);
|
|
580
|
-
|
|
581
|
-
expect(bytesWritten).toBe(size);
|
|
582
|
-
expect(Array.from(buffer)).toEqual(Array.from(encodedOld));
|
|
583
|
-
});
|
|
584
|
-
|
|
585
|
-
test("encodeInto should work with offset in target buffer", () => {
|
|
586
|
-
const schema = {
|
|
587
|
-
a: BinaryPrimitives.u16,
|
|
588
|
-
b: BinaryPrimitives.u16,
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
const codec = new PooledCodec(schema);
|
|
592
|
-
const data1 = { a: 100, b: 200 };
|
|
593
|
-
const data2 = { a: 300, b: 400 };
|
|
594
|
-
|
|
595
|
-
const buffer = new Uint8Array(20);
|
|
596
|
-
|
|
597
|
-
// Write first object at offset 0
|
|
598
|
-
const bytes1 = codec.encodeInto(data1, buffer, 0);
|
|
599
|
-
expect(bytes1).toBe(4);
|
|
600
|
-
|
|
601
|
-
// Write second object at offset 4
|
|
602
|
-
const bytes2 = codec.encodeInto(data2, buffer, 4);
|
|
603
|
-
expect(bytes2).toBe(4);
|
|
604
|
-
|
|
605
|
-
// Verify both objects are in the buffer (using big-endian)
|
|
606
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset);
|
|
607
|
-
expect(view.getUint16(0, false)).toBe(100);
|
|
608
|
-
expect(view.getUint16(2, false)).toBe(200);
|
|
609
|
-
expect(view.getUint16(4, false)).toBe(300);
|
|
610
|
-
expect(view.getUint16(6, false)).toBe(400);
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
test("array field encodeInto should write directly without intermediate allocations", () => {
|
|
614
|
-
const PlayerSchema = {
|
|
615
|
-
id: BinaryPrimitives.u32,
|
|
616
|
-
health: BinaryPrimitives.u8,
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
const arrayField = PooledCodec.array(PlayerSchema);
|
|
620
|
-
const players = [
|
|
621
|
-
{ id: 1, health: 100 },
|
|
622
|
-
{ id: 2, health: 75 },
|
|
623
|
-
{ id: 3, health: 50 },
|
|
624
|
-
];
|
|
625
|
-
|
|
626
|
-
const buffer = new Uint8Array(100);
|
|
627
|
-
const bytesWritten = arrayField.encodeInto(players, buffer, 5);
|
|
628
|
-
|
|
629
|
-
// 2 (length) + 3 * 5 (id:4 + health:1) = 17 bytes
|
|
630
|
-
expect(bytesWritten).toBe(17);
|
|
631
|
-
|
|
632
|
-
// Verify array length was written
|
|
633
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset);
|
|
634
|
-
expect(view.getUint16(5, false)).toBe(3);
|
|
635
|
-
|
|
636
|
-
// Verify first player (using big-endian)
|
|
637
|
-
expect(view.getUint32(7, false)).toBe(1);
|
|
638
|
-
expect(view.getUint8(11)).toBe(100);
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
test("calculateSize and encodeInto should work with multiple arrays", () => {
|
|
642
|
-
const PlayerSchema = {
|
|
643
|
-
id: BinaryPrimitives.u32,
|
|
644
|
-
health: BinaryPrimitives.u8,
|
|
645
|
-
};
|
|
646
|
-
|
|
647
|
-
const EnemySchema = {
|
|
648
|
-
id: BinaryPrimitives.u32,
|
|
649
|
-
type: BinaryPrimitives.u8,
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
const UpdateSchema = {
|
|
653
|
-
tick: BinaryPrimitives.u32,
|
|
654
|
-
players: PooledCodec.array(PlayerSchema),
|
|
655
|
-
enemies: PooledCodec.array(EnemySchema),
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
const codec = new PooledCodec(UpdateSchema);
|
|
659
|
-
const data = {
|
|
660
|
-
tick: 100,
|
|
661
|
-
players: [
|
|
662
|
-
{ id: 1, health: 100 },
|
|
663
|
-
{ id: 2, health: 75 },
|
|
664
|
-
],
|
|
665
|
-
enemies: [
|
|
666
|
-
{ id: 10, type: 1 },
|
|
667
|
-
{ id: 11, type: 2 },
|
|
668
|
-
{ id: 12, type: 3 },
|
|
669
|
-
],
|
|
670
|
-
};
|
|
671
|
-
|
|
672
|
-
const size = codec.calculateSize(data);
|
|
673
|
-
// tick(4) + players_len(2) + 2*5 + enemies_len(2) + 3*5 = 4 + 2 + 10 + 2 + 15 = 33
|
|
674
|
-
expect(size).toBe(33);
|
|
675
|
-
|
|
676
|
-
const buffer = new Uint8Array(size);
|
|
677
|
-
const bytesWritten = codec.encodeInto(data, buffer, 0);
|
|
678
|
-
expect(bytesWritten).toBe(33);
|
|
679
|
-
|
|
680
|
-
// Verify it can be decoded correctly
|
|
681
|
-
const decoded = codec.decode(buffer);
|
|
682
|
-
expect(decoded.tick).toBe(100);
|
|
683
|
-
expect(decoded.players.length).toBe(2);
|
|
684
|
-
expect(decoded.enemies.length).toBe(3);
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* Tests for DataView reuse optimization in PooledCodec.array()
|
|
690
|
-
*
|
|
691
|
-
* These tests verify that the shared encodeView/decodeView optimization
|
|
692
|
-
* is safe under various usage patterns that might seem problematic.
|
|
693
|
-
*/
|
|
694
|
-
describe("PooledCodec.array() - DataView Reuse Safety", () => {
|
|
695
|
-
const playerSchema = {
|
|
696
|
-
id: BinaryCodec.u32,
|
|
697
|
-
health: BinaryCodec.u8,
|
|
698
|
-
};
|
|
699
|
-
test("same ArrayField instance used in nested schema (sequential)", () => {
|
|
700
|
-
// Scenario: Reusing same ArrayField in multiple schema fields
|
|
701
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
702
|
-
const teamSchema = {
|
|
703
|
-
teamA: playerArray, // Same instance
|
|
704
|
-
teamB: playerArray, // Same instance
|
|
705
|
-
};
|
|
706
|
-
const codec = new PooledCodec(teamSchema);
|
|
707
|
-
const data = {
|
|
708
|
-
teamA: [
|
|
709
|
-
{ id: 1, health: 100 },
|
|
710
|
-
{ id: 2, health: 80 },
|
|
711
|
-
],
|
|
712
|
-
teamB: [
|
|
713
|
-
{ id: 3, health: 90 },
|
|
714
|
-
{ id: 4, health: 70 },
|
|
715
|
-
],
|
|
716
|
-
};
|
|
717
|
-
const encoded = codec.encode(data);
|
|
718
|
-
const decoded = codec.decode(encoded);
|
|
719
|
-
// Verify no corruption
|
|
720
|
-
expect(decoded.teamA[0].id).toBe(1);
|
|
721
|
-
expect(decoded.teamA[0].health).toBe(100);
|
|
722
|
-
expect(decoded.teamA[1].id).toBe(2);
|
|
723
|
-
expect(decoded.teamA[1].health).toBe(80);
|
|
724
|
-
expect(decoded.teamB[0].id).toBe(3);
|
|
725
|
-
expect(decoded.teamB[0].health).toBe(90);
|
|
726
|
-
expect(decoded.teamB[1].id).toBe(4);
|
|
727
|
-
expect(decoded.teamB[1].health).toBe(70);
|
|
728
|
-
});
|
|
729
|
-
test("rapid sequential encode/decode (simulates game loop)", () => {
|
|
730
|
-
// Scenario: High-frequency encoding like multiplayer snapshots
|
|
731
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
732
|
-
const iterations = 1000;
|
|
733
|
-
for (let i = 0; i < iterations; i++) {
|
|
734
|
-
const data = [
|
|
735
|
-
{ id: i, health: 100 },
|
|
736
|
-
{ id: i + 1, health: 80 },
|
|
737
|
-
];
|
|
738
|
-
const encoded = playerArray.encode(data);
|
|
739
|
-
const decoded = playerArray.decode(encoded);
|
|
740
|
-
expect(decoded[0].id).toBe(i);
|
|
741
|
-
expect(decoded[0].health).toBe(100);
|
|
742
|
-
expect(decoded[1].id).toBe(i + 1);
|
|
743
|
-
expect(decoded[1].health).toBe(80);
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
test("async encode/decode with Promise.all (no corruption)", async () => {
|
|
747
|
-
// Scenario: Multiple async operations using same ArrayField
|
|
748
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
749
|
-
async function encodeTask(taskId: number) {
|
|
750
|
-
return playerArray.encode([
|
|
751
|
-
{ id: taskId * 10, health: 100 },
|
|
752
|
-
{ id: taskId * 10 + 1, health: 80 },
|
|
753
|
-
]);
|
|
754
|
-
}
|
|
755
|
-
// Run 10 encode operations "concurrently"
|
|
756
|
-
const results = await Promise.all([
|
|
757
|
-
encodeTask(1),
|
|
758
|
-
encodeTask(2),
|
|
759
|
-
encodeTask(3),
|
|
760
|
-
encodeTask(4),
|
|
761
|
-
encodeTask(5),
|
|
762
|
-
encodeTask(6),
|
|
763
|
-
encodeTask(7),
|
|
764
|
-
encodeTask(8),
|
|
765
|
-
encodeTask(9),
|
|
766
|
-
encodeTask(10),
|
|
767
|
-
]);
|
|
768
|
-
// Decode and verify each result
|
|
769
|
-
for (let i = 0; i < results.length; i++) {
|
|
770
|
-
const decoded = playerArray.decode(results[i]);
|
|
771
|
-
const expectedId = (i + 1) * 10;
|
|
772
|
-
expect(decoded[0].id).toBe(expectedId);
|
|
773
|
-
expect(decoded[0].health).toBe(100);
|
|
774
|
-
expect(decoded[1].id).toBe(expectedId + 1);
|
|
775
|
-
expect(decoded[1].health).toBe(80);
|
|
776
|
-
}
|
|
777
|
-
});
|
|
778
|
-
test("encode while decode is queued (microtask interleaving)", async () => {
|
|
779
|
-
// Scenario: Encode and decode queued as microtasks
|
|
780
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
781
|
-
let encoded1: Uint8Array | null = null;
|
|
782
|
-
let encoded2: Uint8Array | null = null;
|
|
783
|
-
queueMicrotask(() => {
|
|
784
|
-
encoded1 = playerArray.encode([{ id: 1, health: 100 }]);
|
|
785
|
-
});
|
|
786
|
-
queueMicrotask(() => {
|
|
787
|
-
encoded2 = playerArray.encode([{ id: 2, health: 200 }]);
|
|
788
|
-
});
|
|
789
|
-
// Wait for microtasks to complete
|
|
790
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
791
|
-
expect(encoded1).not.toBeNull();
|
|
792
|
-
expect(encoded2).not.toBeNull();
|
|
793
|
-
const decoded1 = playerArray.decode(encoded1!);
|
|
794
|
-
const decoded2 = playerArray.decode(encoded2!);
|
|
795
|
-
expect(decoded1[0].id).toBe(1);
|
|
796
|
-
expect(decoded1[0].health).toBe(100);
|
|
797
|
-
expect(decoded2[0].id).toBe(2);
|
|
798
|
-
expect(decoded2[0].health).toBe(200);
|
|
799
|
-
});
|
|
800
|
-
test("buffer pool with different-sized arrays (reuse correctness)", () => {
|
|
801
|
-
// Scenario: Encoding arrays of different sizes (buffer pool behavior)
|
|
802
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
803
|
-
// Small array
|
|
804
|
-
const small = playerArray.encode([{ id: 1, health: 100 }]);
|
|
805
|
-
const decodedSmall = playerArray.decode(small);
|
|
806
|
-
expect(decodedSmall).toHaveLength(1);
|
|
807
|
-
expect(decodedSmall[0].id).toBe(1);
|
|
808
|
-
// Large array
|
|
809
|
-
const largeData = Array.from({ length: 100 }, (_, i) => ({
|
|
810
|
-
id: i,
|
|
811
|
-
health: 100,
|
|
812
|
-
}));
|
|
813
|
-
const large = playerArray.encode(largeData);
|
|
814
|
-
const decodedLarge = playerArray.decode(large);
|
|
815
|
-
expect(decodedLarge).toHaveLength(100);
|
|
816
|
-
expect(decodedLarge[0].id).toBe(0);
|
|
817
|
-
expect(decodedLarge[99].id).toBe(99);
|
|
818
|
-
// Small again (verifies buffer pool reuse doesn't corrupt)
|
|
819
|
-
const small2 = playerArray.encode([{ id: 999, health: 50 }]);
|
|
820
|
-
const decodedSmall2 = playerArray.decode(small2);
|
|
821
|
-
expect(decodedSmall2).toHaveLength(1);
|
|
822
|
-
expect(decodedSmall2[0].id).toBe(999);
|
|
823
|
-
expect(decodedSmall2[0].health).toBe(50);
|
|
824
|
-
});
|
|
825
|
-
test("encodeInto with different buffers (zero-copy safety)", () => {
|
|
826
|
-
// Scenario: Using encodeInto with external buffers
|
|
827
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
828
|
-
const data = [
|
|
829
|
-
{ id: 1, health: 100 },
|
|
830
|
-
{ id: 2, health: 80 },
|
|
831
|
-
];
|
|
832
|
-
// Calculate size and allocate buffer
|
|
833
|
-
const size = playerArray.calculateSize(data);
|
|
834
|
-
const buffer = new Uint8Array(size);
|
|
835
|
-
// Encode directly into buffer
|
|
836
|
-
const bytesWritten = playerArray.encodeInto(data, buffer, 0);
|
|
837
|
-
expect(bytesWritten).toBe(size);
|
|
838
|
-
// Decode and verify
|
|
839
|
-
const decoded = playerArray.decode(buffer);
|
|
840
|
-
expect(decoded[0].id).toBe(1);
|
|
841
|
-
expect(decoded[0].health).toBe(100);
|
|
842
|
-
expect(decoded[1].id).toBe(2);
|
|
843
|
-
expect(decoded[1].health).toBe(80);
|
|
844
|
-
});
|
|
845
|
-
test("stress test: 10k rapid encode/decode cycles", () => {
|
|
846
|
-
// Scenario: Extreme throughput test
|
|
847
|
-
const playerArray = PooledCodec.array(playerSchema);
|
|
848
|
-
for (let i = 0; i < 10000; i++) {
|
|
849
|
-
const data = [
|
|
850
|
-
{ id: i % 256, health: 100 },
|
|
851
|
-
{ id: (i + 1) % 256, health: 80 },
|
|
852
|
-
];
|
|
853
|
-
const encoded = playerArray.encode(data);
|
|
854
|
-
const decoded = playerArray.decode(encoded);
|
|
855
|
-
// Spot check every 1000th iteration
|
|
856
|
-
if (i % 1000 === 0) {
|
|
857
|
-
expect(decoded[0].id).toBe(i % 256);
|
|
858
|
-
expect(decoded[0].health).toBe(100);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
});
|
|
862
|
-
});
|