Skip to content

feat(react): support connecting to actors by id in useActor - #5602

Closed
abcxff wants to merge 1 commit into
stack/fix-rivetkit-expose-engine-ray-ids-on-errors-for-debug-kzmlwrllfrom
stack/feat-react-support-connecting-to-actors-by-id-in-useactor-vlrlwlow
Closed

feat(react): support connecting to actors by id in useActor#5602
abcxff wants to merge 1 commit into
stack/fix-rivetkit-expose-engine-ray-ids-on-errors-for-debug-kzmlwrllfrom
stack/feat-react-support-connecting-to-actors-by-id-in-useactor-vlrlwlow

Conversation

@abcxff

@abcxff abcxff commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@abcxff

abcxff commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

@claude

claude Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Review

Clean, well-scoped change that adds id-based actor resolution to useActor alongside the existing key-based path. The implementation is consistent with Client.getForId, which already existed and supports this exact use case, and the discriminated-union approach (ActorByKeyOptions | ActorByIdOptions) is a good fit since id and key are mutually exclusive ways to identify an actor.

Potential issue: key + id both provided compiles without error

ActorOptions is a union of two object types (ActorByKeyOptions / ActorByIdOptions) with no shared discriminant literal tag. TypeScript's excess-property checking on object literals assigned to a union only flags a property if it doesn't exist on any constituent, so since key is valid on one member and id is valid on the other, an object literal supplying both compiles cleanly:

rivet.useActor({ name: "counter", key: ["a"], id: "some-id" }); // no type error

At runtime, create() in rivetkit-typescript/packages/framework-base/src/mod.ts:470 checks "id" in actor.opts first, so id silently wins and key is dropped with no warning. This is a common discriminated-union gotcha (TS doesn't excess-check across union members) and worth guarding against, e.g. by adding a runtime dev-time check that throws/warns if both key and id are present, or by giving the two variants a literal discriminant (type: "key" | "id") instead of relying on structural "id" in opts/"key" in opts narrowing. Low severity since it's a misuse case, but silent-wrong-behavior is worse than a thrown error here.

Minor / nits

  • StoredActorOptions in mod.ts:21-52 duplicates the shape of ActorByKeyOptions/ActorByIdOptions field-for-field (with name/params erased to string/unknown). This mirrors the pre-existing pattern (the old inline opts type was also hand-duplicated), so it's not a regression, but the duplication surface just doubled with the second variant; future option fields need to be added in three places (ActorOptionsBase/ActorByKeyOptions/ActorByIdOptions and StoredActorOptions). Consider deriving StoredActorOptions with a mapped/Omit type over the public options to keep them in sync automatically.
  • defaultHashFunction's return line (mod.ts:556) is fairly long; not a blocker, just flagging in case agent-format.mjs reformats it.

Test coverage

The new id path is covered by rivetkit-typescript/packages/react/src/mod.typecheck.ts, matching the existing type-check-only convention for this hook (there's no runtime/unit test harness for framework-base currently, consistent with pre-existing state). The typecheck additions look good: they verify the connection/event surface for id-based actors matches the key-based form, and assert { name } alone (no key/id) is rejected. Given the finding above, it might be worth adding a @ts-expect-error case for { name, key, id } together to document (and pin) the current type-level gap, even if it can't be fixed at the type level.

Other

  • client.getForId (used here) is a pre-existing, already-tested client API, good reuse, no engine/runner changes needed.
  • No other frontend package consumes @rivetkit/framework-base besides react, so no parity gap there.
  • No docs reference useActor currently, so no docs-sync update needed.

Overall this is a solid, low-risk addition. The main thing I'd want addressed (or consciously accepted) is the silent key+id co-occurrence behavior.

@abcxff
abcxff force-pushed the stack/feat-react-support-connecting-to-actors-by-id-in-useactor-vlrlwlow branch from d970b2d to 5c84ed9 Compare August 25, 2026 19:27
@abcxff
abcxff changed the base branch from stack/fix-rivetkit-expose-engine-ray-ids-on-errors-kzmlwrll to stack/fix-rivetkit-expose-engine-ray-ids-on-errors-for-debug-kzmlwrll August 25, 2026 19:27
@abcxff abcxff closed this Aug 25, 2026
@abcxff
abcxff deleted the stack/feat-react-support-connecting-to-actors-by-id-in-useactor-vlrlwlow branch August 25, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant