Skip to content

feat(effect): add getToken client option and schema-typed events - #5809

Open
Abhikansh3 wants to merge 1 commit into
rivet-dev:mainfrom
Abhikansh3:feat/effect-events-and-get-token
Open

Abhikansh3 wants to merge 1 commit into
rivet-dev:mainfrom
Abhikansh3:feat/effect-events-and-get-token

Conversation

@Abhikansh3

@Abhikansh3 Abhikansh3 commented Sep 29, 2026 •

Copy link
Copy Markdown

Description

Addresses part of #5806, which asks for first-class, Schema-typed support for the connection/events lifecycle in @rivetkit/effect. That issue's full scope (connections, authorize, CurrentConnection, a scoped client connect() with typed event streams) is a large, multi-PR effort with genuine open design questions inherited from the original SDK design (issue #4703). This PR ships the two independently well-scoped, low-risk pieces first:

  1. Client.Options.getToken passthrough. Client.Options was a Pick of rivetkit's ClientConfigInput that excluded getToken, so there was no way to supply a short-lived, scoped token that's fetched (and refreshed on reconnect) on demand instead of a single static token. Client.make already forwarded the whole options object to the underlying createClient(options) unchanged, so this was a type-only gap: getToken reached the wire fine once the type allowed it through.

  2. Schema-typed events (broadcast only). Adds Event.make (mirrors Action.make's pattern: a value-level definition with an effect/Schema payload) and an events option on Actor.make. Actor.toLayer's wake options now include events: EventBroadcaster<Events>, whose broadcast(tag, payload) encodes the payload through the declared event's schema before calling RivetKit's raw broadcast, mirroring how ActionDispatcher already encodes/decodes action payloads. RivetKit's own event schema validation is bypassed the same way action validation already is (a bare Rivetkit.event() token registers the event name without RivetKit re-validating it), so @rivetkit/effect is the single source of truth for the schema.

Typed client-side subscription (connect(...).events.<Tag>: Stream<...>) is explicitly not included here — receiving events is naturally part of the connections/client work, and building a new client-side Stream-from-callback bridge without the rest of that design in place isn't worth the risk. Today, a client subscribes to a broadcast event the same way it would for any RivetKit actor, through the raw connection's .on("EventName", ...).

Type of change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • pnpm exec vitest --typecheck run in rivetkit-typescript/packages/effect: 146/146 tests pass across all 10 test files, zero type errors, including:
    • Client.test-d.ts (new): type-level proof Client.Options now accepts a getToken callback.
    • test/e2e.test.ts (new test + fixture): a new Broadcaster actor with a Chime event, exercised end-to-end against a real rivet-engine — a raw client connects, subscribes via .on("Chime", ...), and asserts the received payload is the event's JSON-codec encoding (proving the payload went through schema encoding, not a raw pass-through).
  • Full package suite (Actor.test.ts, Actor.test-d.ts, Registry.test.ts, etc.) re-verified green after the change to confirm no regressions to existing actor/action/state/client behavior.
  • Updated docs/actors/content/docs/quickstart/effect.mdx's feature-support table and added a "Typed Events" section with a runnable-shaped example.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Follow-up (not in this PR)

The remainder of #5806 — connection params/state schemas, an authorize hook with typed refusal errors, CurrentConnection in action handlers, and a scoped client connect() with typed event streams — is a larger, coupled effort with open design questions (e.g. how an Effect-typed authorize refusal should interact with RivetKit's synchronous createConnState timeout model). Left for a follow-up PR/design discussion rather than bundled here.

Copilot AI balanced review requested due to automatic review settings September 29, 2026 20:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@the-company-company the-company-company Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 1 medium-severity finding

Reviewed commit edd78fb.

```ts src/actors/counter/api.ts @nocheck
import { Action, Actor, Event } from "@rivetkit/effect";
import { Schema } from "effect";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Medium · Move the TypeScript example into a checked snippet

This inline TypeScript block bypasses the docs bundle's required CodeSnippet type-checking, and @nocheck additionally hides API drift. The repository's docs/CLAUDE.md explicitly forbids inline TypeScript examples for this reason. Move the complete example (including imports and actor registration) under examples/ and embed it with <CodeSnippet>; use regions if only this section should render.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page's five other examples (api.ts, live.ts, main.ts, client.ts) already use inline @nocheck TypeScript blocks on main, predating this PR. The new Typed Events section follows that same existing pattern for consistency with the rest of the page. Converting the whole quickstart to examples/-backed <CodeSnippet>s would be a good cleanup but is a larger, unrelated change touching content outside this PR's scope (getToken + typed events). Happy to file that as a follow-up if maintainers want it done.

This branch has not been deployed

No deployments
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.

2 participants