Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 10, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
rivet-site Ready Ready Preview Comment Nov 13, 2025 8:57pm
rivetkit-serverless Ready Ready Preview Comment Nov 13, 2025 8:57pm
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Nov 13, 2025 8:57pm
rivet-inspector Ignored Ignored Preview Nov 13, 2025 8:57pm

Copy link
Member Author

NathanFlurry commented Nov 10, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 10, 2025

More templates

@rivetkit/actor

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/actor@3428

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3428

@rivetkit/core

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/core@3428

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3428

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3428

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3428

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3428

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3428

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3428

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3428

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3428

commit: 714660b

@claude
Copy link

claude bot commented Nov 10, 2025

Code Review: Connection Lifecycle Context Restructuring

Summary

This PR refactors the connection lifecycle context handling in RivetKit by:

  1. Introducing a cleaner context hierarchy with dedicated classes for different lifecycle hooks
  2. Moving request access from function parameters to context properties
  3. Simplifying API signatures by reducing parameter counts

Positive Aspects

Architecture & Design

Excellent use of inheritance hierarchy: The new ConnInitContext and ConnContext base classes create a clear and logical separation between connection initialization phases and active connection phases.

Context hierarchy:

  • ConnInitContext (has request, no conn)
    • CreateConnStateContext
    • OnBeforeConnectContext
    • OnConnectContext
  • ConnContext (has conn)
    • ActionContext
    • RequestContext (also has request)
    • WebSocketContext (also has request)

Cleaner API: Moving request from an opts parameter to a context property (c.request) is more ergonomic and consistent with the rest of the API.

Type safety: The request?: Request | undefined typing correctly reflects that requests may not always be present in all connection scenarios.

Implementation Quality

Consistent refactoring: All lifecycle hooks have been updated consistently across the codebase.

Backward compatibility considerations: The migration path is clear, as evidenced by the fixture updates.

Issues & Concerns

🔴 Critical: Incomplete Migration (Blocking)

Location: rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/raw-websocket.ts:54

The getRequestInfo handler is commented out with a throw "TODO" statement. This is a runtime bomb that will fail if any test calls this code path.

Recommendation: Either:

  1. Complete the migration by accessing c.request from the context
  2. Remove the getRequestInfo feature entirely if no longer needed
  3. Return a clear error message instead of throwing a bare string

Suggested fix: Access ctx.request to get the request URL info, similar to how it's done in request-access.ts fixture.

⚠️ Minor Issues

1. Empty Type Definition

Location: rivetkit-typescript/packages/rivetkit/src/actor/conn/drivers/websocket.ts:8

export type ConnDriverWebSocketState = Record<never, never>;

While technically correct, this is slightly unusual. Could use Record<string, never> or {} instead.

Impact: Low - it works correctly but is unconventional.

2. Documentation Completeness

The new context classes have basic JSDoc comments, but could benefit from more detailed documentation:

  • Examples of when each context is used
  • Lifecycle ordering diagram
  • Clear explanation of when request will be undefined

3. Type Parameter Verbosity

The generic type parameters are quite verbose across multiple context classes. Consider if some could be simplified, though this may be unavoidable given TypeScript limitations.

Testing Considerations

Good test coverage: The fixture updates show that the migration has been tested across multiple scenarios (conn-params, conn-state, lifecycle, request-access, etc.)

⚠️ Missing: Explicit tests for the request === undefined case to ensure the code handles optional requests gracefully.

Performance Impact

Negligible: The refactoring primarily changes how data is accessed (via context properties vs parameters), with no material performance impact.

Security Review

No concerns: The changes do not introduce new security vulnerabilities. Request access is properly controlled through the context.

Documentation Updates

📚 Action needed: The website/public/llms-full.txt and website/public/llms.txt files were updated, which suggests documentation was addressed. Verify these changes accurately reflect the new API.

Recommendations

Before Merge (Required)

  1. Fix the throw "TODO" in raw-websocket.ts:54 (see detailed suggestion above)
  2. Run the full test suite, especially driver tests, to ensure the TODO does not break tests
  3. Consider adding a test case that explicitly validates request === undefined handling

Future Improvements (Optional)

  1. Add more comprehensive JSDoc examples to the new context classes
  2. Consider creating a migration guide for users updating their actors
  3. Document the lifecycle ordering and when each context type is used

Verdict

Status: ⚠️ Needs Changes

The refactoring is well-designed and improves the API significantly, but the incomplete migration in raw-websocket.ts must be addressed before merging. Once the TODO is resolved and tests pass, this should be good to merge.

Estimated effort to fix: ~5-10 minutes

@claude
Copy link

claude bot commented Nov 10, 2025

Code Review: Connection Lifecycle Context Restructuring

This PR refactors the RivetKit connection lifecycle contexts to improve type safety and reduce code duplication. Overall, the changes are well-structured and follow good architectural patterns.

Strengths

  1. Excellent Use of Inheritance Hierarchy: The new context class hierarchy is well-designed with ConnInitContext as the base for initialization hooks and ConnContext as the base for established connections.

  2. Reduced Code Duplication: The refactoring eliminates approximately 300+ lines of duplicated code across ActionContext, RequestContext, and WebSocketContext by using inheritance from ActorContext.

  3. Improved API Consistency: Removing the opts parameter and moving request to the context object creates a cleaner, more intuitive API.

  4. Better Type Safety: The inheritance structure ensures that request is only available where it makes sense.

  5. Good Documentation: New context classes have clear JSDoc comments explaining their purpose.

Issues and Concerns

1. Breaking Change with TODO Comment (HIGH PRIORITY)

In rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/raw-websocket.ts:54, the code now has throw TODO where request info should be returned. This test fixture now throws an error instead of providing working functionality.

Recommendation: Either complete the implementation using c.request, remove this test case if no longer relevant, or add a proper error message.

2. Request Availability Not Clear (MEDIUM PRIORITY)

The request field is marked as Request | undefined in multiple contexts, but the documentation does not clearly explain when it will be undefined and what users should check before using it.

Recommendation: Add clearer documentation explaining that request will be defined for connections initiated via HTTP/WebSocket upgrade requests, but undefined for connections restored from hibernation.

3. Empty Type Definition (LOW PRIORITY)

In websocket.ts:8, changed from empty object to Record never never. While more explicit, the old empty object was clearer for representing an empty object type.

4. Type Safety in ConnectionManager (LOW PRIORITY)

In connection-manager.ts, there are several as any casts at lines 153, 275, and 286. Consider adding proper type definitions to avoid type assertions.

Questions

  1. Are there breaking changes for existing users? Should there be migration notes?
  2. Are there tests that verify request is properly passed through all contexts?

Performance and Security

  • Performance: No concerns. The inheritance-based approach should have minimal overhead.
  • Security: No issues identified. The request object handling appears safe.

Recommendations Summary

Before Merge:

  1. Fix or remove the throw TODO in raw-websocket.ts
  2. Improve documentation for when request is undefined
  3. Verify all tests pass

Nice to Have:
4. Add type safety to avoid as any casts in ConnectionManager
5. Consider keeping empty object instead of Record never never for clarity

Overall Assessment

This is a solid refactoring that improves code quality and API design. The inheritance hierarchy is well-thought-out and the reduction in code duplication is significant. The main blocker is the incomplete TODO implementation.

Recommendation: Request changes for the TODO issue, then approve.

@NathanFlurry NathanFlurry force-pushed the 11-09-chore_rivetkit_add_websocketcontext_and_requestcontext_ branch from b1ac4de to 9878acc Compare November 13, 2025 02:47
@NathanFlurry NathanFlurry force-pushed the 11-09-refactor_rivetkit_restructure_connection_lifecycle_contexts branch from 7de7488 to 27c352a Compare November 13, 2025 02:47
@vercel
Copy link

vercel bot commented Nov 13, 2025

Deployment failed with the following error:

Too many requests - try again in 5 minutes (more than 120, code: "api-deployments-flood-pro").

Learn More: https://vercel.com/docs/limits#rate-limits

@claude
Copy link

claude bot commented Nov 13, 2025

PR Review: Restructure Connection Lifecycle Contexts

Thank you for this refactoring! This is a well-thought-out restructuring that improves type safety and API consistency.

Strengths

1. Excellent Type Hierarchy

The new context hierarchy is clean and logical:

  • ConnInitContext for initialization phases (no connection yet)
  • ConnContext for connection-aware phases
  • Specific contexts for each lifecycle hook

This makes the capabilities available at each stage explicit in the type system.

2. Improved API Consistency

Moving request from the opts parameter to context.request is more consistent with the framework's design patterns.

3. Reduced Boilerplate

Using inheritance eliminates significant code duplication across ActionContext, RequestContext, and WebSocketContext.

Issues & Concerns

1. Breaking Change with TODO Comment (CRITICAL)

In fixtures/driver-test-suite/raw-websocket.ts:54, there's a throw TODO that breaks the getRequestInfo functionality. This will cause runtime errors if any tests rely on this.

Recommendation: Either implement the new way to access request info via ctx.request, remove this code path, or handle the error gracefully.

2. Type Safety Note

The change from {} to Record<never, never> for ConnDriverWebSocketState is more explicit but could be a subtle breaking change in structural typing scenarios.

3. Error Handling

In request-access.ts:105, throw Missing request should use a proper Error object instead of a string.

4. Backwards Compatibility

The signature changes are breaking. Consider providing a migration guide for users.

Suggestions

  1. Add type guard helpers for request since it can be undefined
  2. Consider making conn readonly in ConnContext for consistency
  3. Document the migration path and rationale

Summary

Overall Assessment: Solid refactoring that improves maintainability and type safety. Main blocker is the TODO/throw that needs resolution.

Recommended Actions Before Merge:

  1. Fix or remove the throw TODO in raw-websocket.ts:54
  2. Consider migration guide for users
  3. Verify ConnDriverWebSocketState type change
  4. Use proper Error objects instead of string throws

Great work on this refactoring!

@claude
Copy link

claude bot commented Nov 13, 2025

PR Review: Connection Lifecycle Refactoring

I've reviewed this PR that restructures the connection lifecycle contexts in RivetKit. Overall, this is a well-executed refactoring that improves type safety and code organization. Here's my detailed feedback:

Strengths

1. Excellent Context Hierarchy Design
The new inheritance structure is clean and logical:

  • ActorContext (base) → ConnInitContext → lifecycle-specific contexts (CreateConnStateContext, OnBeforeConnectContext, OnConnectContext)
  • ActorContext (base) → ConnContextActionContext, RequestContext, WebSocketContext

This hierarchy properly models the different stages of connection lifecycle and eliminates code duplication across 150+ lines in request.ts and websocket.ts.

2. Improved API Consistency
The refactoring standardizes how request is accessed:

  • Before: Passed as separate opts parameter (e.g., onWebSocket(c, websocket, { request }))
  • After: Available as c.request property on the context

This is more intuitive and consistent with how other context properties are accessed.

3. Type Safety Improvements

  • ConnDriverWebSocketState changed from {} to Record<never, never> (line driver/websocket.ts:8) - this is more precise TypeScript
  • Proper generic constraints on CreateConnStateContext requiring TDatabase extends AnyDatabaseProvider

4. Good Test Coverage
All test fixtures have been updated to reflect the API changes, ensuring backward compatibility is maintained.

Issues & Concerns

Critical: Incomplete Implementation

Location: rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/raw-websocket.ts:54

} else if (parsed.type === "getRequestInfo") {
    throw "TODO";
    // Send back the request URL info
    // websocket.send(...)

Issue: The getRequestInfo functionality has been commented out with a TODO, and there's a corresponding test in tests/raw-websocket.ts:434-471 that expects this to work.

Impact: This test will fail when run, as the fixture throws "TODO" instead of returning request info.

Recommendation: Either:

  1. Implement the request access via c.request (if available in that context), or
  2. Remove/skip the test until the implementation is complete

The fix should look something like:

} else if (parsed.type === "getRequestInfo") {
    if (!c.request) {
        websocket.send(JSON.stringify({
            type: "error",
            message: "Request not available"
        }));
    } else {
        websocket.send(JSON.stringify({
            type: "requestInfo",
            url: c.request.url,
            pathname: new URL(c.request.url).pathname,
            search: new URL(c.request.url).search,
        }));
    }

Breaking Changes

Signature Changes (non-breaking for TypeScript but behavioral):

  1. createConnState(c, opts, params)createConnState(c, params) - opts removed
  2. onBeforeConnect(c, opts, params)onBeforeConnect(c, params) - opts removed
  3. onWebSocket(c, websocket, opts)onWebSocket(c, websocket) - opts removed

Migration Path: Users need to change from opts.request to c.request. This is documented in the examples but should be called out in the PR description or changelog.

Type Safety Concern

Location: rivetkit-typescript/packages/rivetkit/src/actor/contexts/conn-init.ts:14

> extends ActorContext<TState, undefined, undefined, TVars, TInput, TDatabase> {

Using undefined for TConnParams and TConnState is technically correct but worth documenting. These contexts are called before connection state exists, which is why these are undefined.

Minor Issues

1. Documentation
The new context classes have minimal JSDoc. Consider adding more detailed documentation about:

  • When each context is used in the lifecycle
  • What properties are available
  • Examples of common use cases

2. Export Organization
Good job adding the new context exports to mod.ts:79-82. The exports are well-organized.

3. Variable Naming
In connection-manager.ts, the pattern of creating contexts is consistent:

const ctx = new OnBeforeConnectContext(this.#actor, request);
await config.onBeforeConnect(ctx, params);

This is clean and readable.

Performance & Security

  • Performance: No concerns. The refactoring reduces code duplication without adding overhead.
  • Security: No concerns. The request object access pattern doesn't introduce vulnerabilities.

Recommendations

  1. High Priority: Fix or remove the TODO in raw-websocket.ts:54 before merging
  2. Medium Priority: Add JSDoc documentation to the new context classes
  3. Low Priority: Consider adding a migration guide in CHANGELOG or docs

Test Coverage

The test fixtures have been comprehensively updated:

  • conn-params.ts - Updated
  • conn-state.ts - Updated
  • lifecycle.ts - Updated
  • request-access.ts - Updated (comprehensive request access tests)
  • sleep.ts - Updated
  • raw-websocket.ts - Has TODO that will cause test failure

Conclusion

This is a solid refactoring that improves code quality and API consistency. The only blocker is the incomplete getRequestInfo implementation. Once that's addressed, this PR is ready to merge.

Recommendation: Request changes to fix the TODO before merging.


Note: Following CLAUDE.md conventions - no formatting was run as per project guidelines.

@claude
Copy link

claude bot commented Nov 13, 2025

PR Review: Refactor RivetKit Connection Lifecycle Contexts

Summary

This PR restructures the connection lifecycle contexts in RivetKit by creating a cleaner inheritance hierarchy and moving the request object from being passed as an opts parameter to being a property on the context objects. This is a well-executed refactoring that improves the API design.

Code Quality & Architecture

✅ Positive Changes

  1. Cleaner Context Hierarchy: The new inheritance structure is well-designed:

    • ActorContext (base)
    • ConnInitContext extends ActorContext (adds request property)
    • ConnContext extends ActorContext (adds conn property)
    • Specific contexts extend these base classes appropriately
  2. Improved API Ergonomics: Moving request from opts parameter to ctx.request is more intuitive:

    // Before
    onWebSocket: (c, websocket, { request }) => { ... }
    
    // After  
    onWebSocket: (c, websocket) => { 
      const url = new URL(c.request.url); // cleaner access
    }
  3. Consistent Type Safety: The new contexts properly type request as Request | undefined, acknowledging that not all connections originate from HTTP requests.

  4. Good Documentation: JSDoc comments clearly explain the purpose of each context class.

  5. Proper Exports: All new context types are properly exported in actor/mod.ts:79-82.

⚠️ Issues & Concerns

1. Broken Feature with TODO Placeholder (Critical)

In raw-websocket.ts:54, there's a throw "TODO" that breaks the getRequestInfo functionality:

} else if (parsed.type === "getRequestInfo") {
    throw "TODO";
    // Send back the request URL info
    // websocket.send(...)

Issue: This breaks existing functionality. The commented code should be updated to use ctx.request instead of opts.request.

Fix needed:

} else if (parsed.type === "getRequestInfo") {
    if (!ctx.request) {
        websocket.send(JSON.stringify({ type: "error", message: "No request available" }));
    } else {
        websocket.send(
            JSON.stringify({
                type: "requestInfo",
                url: ctx.request.url,
                pathname: new URL(ctx.request.url).pathname,
                search: new URL(ctx.request.url).search,
            }),
        );
    }
}

2. Error Handling Pattern (Minor)

In request-access.ts:118, the error is thrown as a string:

if (!c.request) throw "Missing request";

Recommendation: Use proper Error objects for better stack traces:

if (!c.request) throw new Error("Missing request");

3. Type Safety in Connection Manager (Minor)

In connection-manager.ts:329,334,366, the config is typed as any:

async #createConnState(
    config: any,  // Should be properly typed
    params: CP,
    request: Request | undefined,
): Promise<CS | undefined>

Recommendation: Use the proper ActorConfig type instead of any to maintain type safety throughout the codebase.

4. Empty Type Definition (Cosmetic)

In websocket.ts:8, the type definition changed from {} to Record<never, never>:

export type ConnDriverWebSocketState = Record<never, never>;

Note: While Record<never, never> is more explicit, both represent an empty object type. This is fine but consider if a comment explaining why it's empty would be helpful.

Performance Considerations

✅ No performance concerns identified. The refactoring:

  • Doesn't add extra object allocations
  • Maintains the same call patterns
  • Properly uses the existing context objects

Security Concerns

✅ No security issues identified:

  • Request objects are properly typed and handled
  • No exposure of sensitive data
  • Appropriate null-checking for optional request objects

Test Coverage

⚠️ Potential Gap: The TODO in raw-websocket.ts suggests this code path may not have test coverage for the getRequestInfo functionality.

Recommendation:

  1. Add a test case for the getRequestInfo message type
  2. Ensure tests verify proper access to ctx.request in all lifecycle hooks

Breaking Changes

Well-managed breaking changes:

  • All affected fixtures and examples have been updated
  • The signature changes are clear and compile-time safe
  • Migration path is straightforward (remove opts parameter, use ctx.request instead)

Documentation Updates

✅ The llms.txt and llms-full.txt files were updated, which is good for AI-assisted development.

Recommendation: Consider adding a migration guide comment in the PR description for users upgrading from previous versions.

Overall Assessment

This is a solid refactoring that improves the API design and maintainability. The inheritance hierarchy is well-thought-out and the changes are consistently applied across the codebase.

Blockers before merge:

  1. ❌ Fix the broken getRequestInfo functionality in raw-websocket.ts:54

Recommended improvements (non-blocking):

  1. Use proper Error objects instead of string throws
  2. Add proper typing to config parameters instead of any
  3. Add test coverage for the previously broken code path

Score: 8/10 (would be 9/10 after fixing the TODO)

@graphite-app
Copy link
Contributor

graphite-app bot commented Nov 13, 2025

Merge activity

  • Nov 13, 9:15 PM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Nov 13, 9:16 PM UTC: CI is running for this pull request on a draft pull request (#3465) due to your merge queue CI optimization settings.
  • Nov 13, 9:16 PM UTC: Merged by the Graphite merge queue via draft PR: #3465.

@graphite-app graphite-app bot closed this Nov 13, 2025
@graphite-app graphite-app bot deleted the 11-09-refactor_rivetkit_restructure_connection_lifecycle_contexts branch November 13, 2025 21:16
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.

3 participants