Releases: colyseus/react-tools
Releases · colyseus/react-tools
Release list
0.18.2
- Pairs with
@colyseus/sdk0.18.2, which merges thesmoothing/dampingoptions into onesmoothMs(time constant in ms;smoothMs = 1000 / old value). No API change in the hooks themselves — option types flow through from the SDK.
0.1.19
Fixes
- Selectors that build their own container no longer crash the component with
Maximum update depth exceeded.useRoomState(room, (s) => Array.from(s.players.values()))and(s) => ({ message: s.myString })now hold a stable reference between renders. (#13, reported by @under-undefined, who also contributed the regression tests — thank you!) - Object-literal selectors return plain snapshot data, the way array selectors already did.
(s) => ({ player: s.players.get(id) })previously handed back the live schema node.
0.1.18
Fixes
- Server-rendering a component that reads room state no longer crashes with
Missing getServerSnapshot, which is required for server-rendered content.useRoomState,useColyseusStateand thecreateRoomContext/createLobbyContexthooks now render on the server as if no room were connected — rooms and decoder state are client-side objects, never serialized for hydration — and pick up the live room right after hydration. (#12 by @under-undefined)
0.1.17
Fixes
- Nested
ArraySchemavalues inside aMapSchema(e.g.items.get(key).tags) could still go stale during normal, mounted gameplay — not only across remounts as 0.1.16 addressed. 0.1.16 accumulated the dirty set until a snapshot consumed it, but with several hooks sharing one room subscription, an unrelated hook re-rendering between two decodes could let the next decode clear a mark another hook had not yet consumed, leaving that hook's nested value stale. The dirty set is no longer bulk-cleared on any schedule: a ref's mark is removed only when a snapshot actually rebuilds that ref, so it survives across any number of decodes and unrelated re-renders until the owning hook re-renders and consumes it. Marks are tracked only for refs that already have a cached result (dirtyRefIds ⊆ resultsByRefId), which keeps the set bounded by the cache with no extra bookkeeping. Re-render counts and snapshot performance are unchanged. (#10, follow-up repro by @konistehrad)
0.1.16
Fixes
- Nested
ArraySchemavalues inside aMapSchema(e.g.items.get(key).tags) could stay stale — the live decoded state was correct, but the snapshot kept the old value. Dirty tracking cleared its set at the start of every decode, so when two or more decodes arrived with no snapshot in between — which happens whenever the hook is not subscribed while patches arrive (the component is unmounted on a route/tab switch, behind a conditional, virtualized out of a list, …) and then remounts — the second decode wiped the first's marks and the snapshot short-circuited the stale subtree. The dirty set now accumulates across decodes and is cleared only once a snapshot has consumed it. (#10, reported by @konistehrad)
0.1.15
Performance
- Dropped the per-decode
objectToRefIdreverse-lookupMaprebuild. The decoder already tags every Schema/ArraySchema/MapSchema instance with~refId, andDataChangecarriesrefIddirectly — both are used instead. Eliminates ~137 KB/op of garbage per decode on a 200-player state. - Unified
previousResultsByRefId/currentResultsByRefIdinto a single persistent cache plus a reusedvisitedThisPassset. Removes a per-renderMapallocation and copy loop inuseColyseusState. - Memoized
getSchemaFieldNamesper Schema constructor (wasObject.values(metadata).map(...)on every visit). - Replaced
Object.keys(prev).length !== Object.keys(next).lengthMapSchema size check with a count vsnode.sizecomparison (no array allocations). - Parent-chain dirty walk now short-circuits once it hits an already-dirty ancestor.
Measured on a synthetic "50 of 200 players mutate each tick" benchmark: ~25% faster, ~99% less allocation per tick.
Tests
- +60 tests covering: selectors, primitive
ArraySchema/MapSchema,Schemareference reassignment,MapSchema.clear(), multiple hooks sharing a subscription, late-binding state/decoder,useRoomMessage,useLobbyRoom,useQueueRoom,createRoomContext,createLobbyContext, and coexistence withgetDecoderStateCallbacks(onAdd/onRemove/onChange/listen). - New opt-in microbenchmark at
src/tests/bench.test.ts(BENCH=1 NODE_OPTIONS=--expose-gc npx vitest run src/tests/bench.test.ts).
0.1.14
fix useRoomState() types to accept either a Schema or Room.
0.1.13
use InferState on useRoomState(). #2
0.1.12
add @colyseus/shared-types as peerDependency
0.1.10
useRoomState() types: remove strict 'extends Schema' as it may confli…