Skip to content

Releases: colyseus/react-tools

0.18.2

Choose a tag to compare

@github-actions github-actions released this 25 Aug 18:59
4f9733c
  • Pairs with @colyseus/sdk 0.18.2, which merges the smoothing/damping options into one smoothMs (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

Choose a tag to compare

@github-actions github-actions released this 18 Aug 02:43

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

Choose a tag to compare

@github-actions github-actions released this 17 Aug 12:48

Fixes

  • Server-rendering a component that reads room state no longer crashes with Missing getServerSnapshot, which is required for server-rendered content. useRoomState, useColyseusState and the createRoomContext / createLobbyContext hooks 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

Choose a tag to compare

@github-actions github-actions released this 21 Jun 18:27

Fixes

  • Nested ArraySchema values inside a MapSchema (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

Choose a tag to compare

@github-actions github-actions released this 19 Jun 20:36

Fixes

  • Nested ArraySchema values inside a MapSchema (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

Choose a tag to compare

@github-actions github-actions released this 22 Apr 22:20

Performance

  • Dropped the per-decode objectToRefId reverse-lookup Map rebuild. The decoder already tags every Schema/ArraySchema/MapSchema instance with ~refId, and DataChange carries refId directly — both are used instead. Eliminates ~137 KB/op of garbage per decode on a 200-player state.
  • Unified previousResultsByRefId / currentResultsByRefId into a single persistent cache plus a reused visitedThisPass set. Removes a per-render Map allocation and copy loop in useColyseusState.
  • Memoized getSchemaFieldNames per Schema constructor (was Object.values(metadata).map(...) on every visit).
  • Replaced Object.keys(prev).length !== Object.keys(next).length MapSchema size check with a count vs node.size comparison (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, Schema reference reassignment, MapSchema.clear(), multiple hooks sharing a subscription, late-binding state/decoder, useRoomMessage, useLobbyRoom, useQueueRoom, createRoomContext, createLobbyContext, and coexistence with getDecoderStateCallbacks (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

Choose a tag to compare

@github-actions github-actions released this 26 Feb 05:38
fix useRoomState() types to accept either a Schema or Room.

0.1.13

Choose a tag to compare

@github-actions github-actions released this 26 Feb 05:25
use InferState on useRoomState(). #2

0.1.12

Choose a tag to compare

@github-actions github-actions released this 26 Feb 05:13
add @colyseus/shared-types as peerDependency

0.1.10

Choose a tag to compare

@github-actions github-actions released this 26 Feb 03:32
useRoomState() types: remove strict 'extends Schema' as it may confli…