Skip to content

fix(studio): allow replacing the whole state, catch unhandled promises #1122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jog1t
Copy link
Collaborator

@jog1t jog1t commented Jul 23, 2025

TL;DR

Removed database dependencies from the counter example and simplified the actor state structure.

What changed?

  • Removed database integration from the counter example:
    • Deleted dizzle.config.ts and schema.ts files
    • Removed database-related dependencies from package.json (drizzle-orm, better-sqlite3, drizzle-kit)
    • Removed @rivetkit/db dependency
  • Simplified the counter example's actor state to only include the essential count property
  • Removed the database initialization and unused code in the registry
  • Updated the file system global state implementation to improve actor state loading
  • Enhanced the inspector API to support both patching and replacing state
  • Updated Zod import to use v4
  • Added error handling for actor fetching in the manager inspector

How to test?

  1. Run the counter example to verify it works without database dependencies:
    cd examples/counter
    pnpm install
    pnpm start
    
  2. Test the inspector API's new state replacement functionality by making a PATCH request with a replace property
  3. Verify that actor state loading works correctly with the updated implementation

Why make this change?

This change simplifies the counter example by removing unnecessary database dependencies, making it more focused on demonstrating the core actor functionality. It also improves the state management implementation and enhances the inspector API with better error handling and the ability to completely replace state, providing more flexibility for debugging and development.

Copy link

claude bot commented Jul 23, 2025

Claude finished @jog1t's task —— View job


PR Review: fix(studio): allow replacing the whole state, catch unhandled promises

Review Checklist:

  • Read and understand all changed files
  • Analyze code quality and adherence to project standards
  • Check for potential bugs and issues
  • Evaluate performance considerations
  • Review security concerns
  • Assess test coverage implications
  • Provide comprehensive feedback

Overview

This PR introduces two main improvements:

  1. Enhanced state replacement functionality in the studio inspector
  2. Better promise handling and error catching in various components
  3. Example cleanup removing database dependencies from the counter example

Detailed Review

Code Quality & Best Practices

Good practices observed:

  • Proper use of Zod schema validation for input validation
  • Consistent error handling patterns
  • Following project logging conventions with logger().error(...)
  • Atomic file operations maintained in file system driver

Areas for improvement:

  • Consider adding JSDoc comments for the new state replacement functionality
  • The || "" fallback in actor.ts:96 could benefit from a comment explaining the edge case

Bug Fixes & Improvements

Fixed Issues:

  1. Promise handling improvement (global-state.ts:40,205-212): Simplified from manual PromiseWithResolvers to direct Promise return, reducing complexity and potential race conditions
  2. Unhandled promise rejection (manager.ts:29-38): Added proper try-catch around getAllActors
  3. Stringify safety (actor.ts:96): Added || "" fallback for JSON.stringify to prevent potential undefined issues

New Functionality:

  • Whole state replacement (actor.ts:48-83): New endpoint accepts either { patch: PatchSchema } or { replace: any } - well implemented with proper validation

⚠️ Potential Issues

  1. Type Safety Concern (actor.ts:52):

    z.object({ replace: z.any() })

    Using z.any() bypasses type safety. Consider:

    • Using z.unknown() for better type safety
    • Adding runtime validation for critical state properties
    • Documenting expected state structure
  2. Error Handling (manager.ts:37):

    return c.json("Failed to fetch actors", 500);

    Should return a proper error object structure instead of a string:

    return c.json({ error: "Failed to fetch actors" }, 500);
  3. Missing Validation (actor.ts:61):
    The replace functionality doesn't validate if the new state is compatible with the actor's expected state structure.

🔒 Security Considerations

Low Risk Areas:

  • State replacement is properly authenticated through existing inspector middleware
  • No direct user input exposure to system functions
  • File operations remain atomic and safe

Recommendations:

  • Consider adding size limits for state replacement to prevent memory exhaustion
  • Log state replacement operations for audit purposes

🚀 Performance Considerations

Positive Changes:

  • Simplified promise handling in global-state.ts reduces overhead
  • Removed unnecessary file existence check (global-state.ts:208-217)

Potential Concerns:

  • Large state replacements could impact memory usage - consider adding size validation
  • State streaming could be affected by very large state objects

🧪 Test Coverage

Missing Test Coverage:

  • New state replacement functionality needs tests for both success and error cases
  • Error handling in manager inspector should be tested
  • Promise handling changes in global state should have regression tests

Recommended Tests:

// Test state replacement
describe('state replacement', () => {
  it('should replace entire state', async () => { /* test replace functionality */ });
  it('should handle invalid replacement data', async () => { /* test error cases */ });
  it('should maintain state consistency', async () => { /* test state integrity */ });
});

📝 Example Cleanup Assessment

Positive Changes:

  • Simplified counter example by removing unused database complexity
  • Cleaner, more focused demonstration of core actor functionality
  • Reduced dependencies improves example portability

Recommendation:

  • Consider keeping a separate database example since this removes all database usage patterns

Summary

This is a solid PR with meaningful improvements. The code quality is good and follows project conventions. The main concerns are around type safety and error response formatting.

Approval Recommendation:Approve with minor suggestions

Key Action Items:

  1. Consider changing z.any() to z.unknown() for better type safety
  2. Fix error response format in manager inspector
  3. Add tests for new state replacement functionality
  4. Consider adding size limits for state replacement

Copy link
Collaborator Author

jog1t commented Jul 23, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

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.

@jog1t jog1t marked this pull request as ready for review July 23, 2025 08:39
Copy link

pkg-pr-new bot commented Jul 23, 2025

Open in StackBlitz

@rivetkit/actor

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/actor@1122

@rivetkit/core

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/core@1122

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/db@1122

rivetkit

pnpm add https://pkg.pr.new/rivet-gg/rivetkit@1122

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/cloudflare-workers@1122

@rivetkit/redis

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/redis@1122

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/framework-base@1122

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/react@1122

commit: eecb927

Copy link

graphite-app bot commented Jul 24, 2025

Merge activity

  • Jul 24, 4:25 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Jul 24, 4:26 AM UTC: CI is running for this pull request on a draft pull request (#1124) due to your merge queue CI optimization settings.
  • Jul 24, 4:27 AM UTC: Merged by the Graphite merge queue via draft PR: #1124.

graphite-app bot pushed a commit that referenced this pull request Jul 24, 2025
#1122)

### TL;DR

Removed database dependencies from the counter example and simplified the actor state structure.

### What changed?

- Removed database integration from the counter example:
  - Deleted `dizzle.config.ts` and `schema.ts` files
  - Removed database-related dependencies from `package.json` (drizzle-orm, better-sqlite3, drizzle-kit)
  - Removed `@rivetkit/db` dependency
- Simplified the counter example's actor state to only include the essential `count` property
- Removed the database initialization and unused code in the registry
- Updated the file system global state implementation to improve actor state loading
- Enhanced the inspector API to support both patching and replacing state
- Updated Zod import to use v4
- Added error handling for actor fetching in the manager inspector

### How to test?

1. Run the counter example to verify it works without database dependencies:
   ```
   cd examples/counter
   pnpm install
   pnpm start
   ```
2. Test the inspector API's new state replacement functionality by making a PATCH request with a `replace` property
3. Verify that actor state loading works correctly with the updated implementation

### Why make this change?

This change simplifies the counter example by removing unnecessary database dependencies, making it more focused on demonstrating the core actor functionality. It also improves the state management implementation and enhances the inspector API with better error handling and the ability to completely replace state, providing more flexibility for debugging and development.
@graphite-app graphite-app bot closed this Jul 24, 2025
@graphite-app graphite-app bot deleted the 07-23-fix_studio_allow_replacing_the_whole_state_catch_unhandled_promises branch July 24, 2025 04:27
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