Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 21, 2025

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

Project Deployment Preview Comments Updated (UTC)
rivetkit-serverless Ready Ready Preview Comment Dec 1, 2025 11:53pm
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Dec 1, 2025 11:53pm
rivet-inspector Ignored Ignored Preview Dec 1, 2025 11:53pm
rivet-site Ignored Ignored Preview Dec 1, 2025 11:53pm

Copy link
Member Author


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.

@claude
Copy link

claude bot commented Nov 21, 2025

PR Review: fix(runner-protocol): do not depend on node:assert for generated code

Overview

This PR removes the dependency on Node.js's node:assert module from the generated TypeScript runner protocol code by post-processing the output to replace it with a custom assert function. This is a good fix for ensuring the generated code is more portable and doesn't rely on Node.js-specific modules.


✅ Strengths

  1. Clean solution: Post-processing approach is appropriate for modifying generated code
  2. Maintains functionality: The custom assert function preserves the TypeScript assertion type guard behavior
  3. Minimal changes: Focused change that solves the specific problem

🔍 Issues & Recommendations

1. String replacement fragility (Minor)

Location: build.rs:96

The current implementation uses a simple string replacement:

let content = content.replace("import assert from \"node:assert\"\n", "");

Issue: This assumes the exact format including the newline character. If the BARE compiler changes its formatting (e.g., uses different quotes, adds semicolons, or changes whitespace), this replacement will silently fail.

Recommendation: Use a more robust approach with regex or handle multiple variations:

// Handle both with and without newline, with/without semicolon
let content = content
    .replace("import assert from \"node:assert\";\n", "")
    .replace("import assert from \"node:assert\"\n", "")
    .replace("import assert from 'node:assert';\n", "")
    .replace("import assert from 'node:assert'\n", "");

Or use a regex-based approach for more flexibility.


2. String mutation inefficiency (Minor)

Location: build.rs:96-105

Issue: The code performs string replacement and then creates a new string with format:

let content = content.replace(...); // Creates new String
let content = format\!("{}\n{}", content, assert_function); // Creates another new String

Recommendation: Use a single operation or be more explicit:

let mut content = content.replace("import assert from \"node:assert\"\n", "");
content.push_str("\n");
content.push_str(assert_function);

3. Formatting inconsistency (Minor)

Location: build.rs:99-104

Issue: The custom assert function uses spaces for indentation, but the generated TypeScript likely follows the project's conventions. Looking at the diff output, the generated code doesn't use indentation for top-level functions.

Current:

function assert(condition: boolean, message?: string): asserts condition {
    if (\!condition) throw new Error(message ?? "Assertion failed")
}

Recommendation: Match the generated code style (no indentation for function body in this case, or follow the actual generated pattern).


4. Missing error context (Minor)

Location: build.rs:92-93, 107

Issue: The .expect() calls don't include the file path in the error message, making debugging harder.

Recommendation:

let content = fs::read_to_string(file_path)
    .unwrap_or_else(|e| panic\!("Failed to read TypeScript file at {:?}: {}", file_path, e));

fs::write(file_path, content)
    .unwrap_or_else(|e| panic\!("Failed to write TypeScript file at {:?}: {}", file_path, e));

5. No verification of replacement (Medium)

Location: build.rs:91-108

Issue: The code doesn't verify that the import was actually found and removed. If the BARE compiler changes and stops emitting the assert import, or if it's already using a different pattern, the build will silently succeed but the custom assert function will be added unnecessarily (and might conflict).

Recommendation: Add verification:

fn post_process_typescript(file_path: &Path) {
    let content = fs::read_to_string(file_path)
        .unwrap_or_else(|e| panic\!("Failed to read TypeScript file at {:?}: {}", file_path, e));
    
    // Check if node:assert import exists
    let has_node_assert = content.contains("from \"node:assert\"") || content.contains("from 'node:assert'");
    
    if \!has_node_assert {
        println\!("cargo:warning=No node:assert import found in generated TypeScript. Post-processing may not be necessary.");
    }
    
    // Remove Node.js assert import
    let content = content
        .replace("import assert from \"node:assert\"\n", "")
        .replace("import assert from 'node:assert'\n", "");
    
    // Only add custom assert if we removed the import
    let content = if has_node_assert {
        format\!("{}\n{}", content, assert_function)
    } else {
        content
    };
    
    fs::write(file_path, content)
        .unwrap_or_else(|e| panic\!("Failed to write TypeScript file at {:?}: {}", file_path, e));
}

6. Missing test coverage (Medium)

Issue: There are no tests verifying that:

  • The generated TypeScript compiles correctly
  • The assert function works as expected
  • The import is actually removed

Recommendation: Consider adding integration tests or at minimum, a build-time check that the generated file:

  1. Doesn't contain node:assert
  2. Contains the custom assert function
  3. Compiles without errors

🔒 Security

No security concerns identified. The code is run during build time and doesn't introduce any runtime vulnerabilities.


⚡ Performance

No performance concerns. This is a build-time operation on a single generated file.


📝 Code Style

The Rust code follows the repository's conventions. The TypeScript formatting should be verified to match generated code patterns.


Summary

This is a good fix for the immediate problem. The main concerns are around robustness (handling format variations) and verification (ensuring the replacement actually happened). Consider implementing the recommendations to make this more maintainable long-term, especially recommendation #5 for verification.

Overall Assessment: ✅ Approve with suggestions for improvements

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 21, 2025

More templates

@rivetkit/cloudflare-workers

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

@rivetkit/db

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

@rivetkit/framework-base

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

@rivetkit/next-js

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

@rivetkit/react

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

rivetkit

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

@rivetkit/sql-loader

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

@rivetkit/engine-runner

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

@rivetkit/engine-runner-protocol

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

commit: 9e499e8

@jog1t jog1t force-pushed the 11-21-fix_runner-protocol_do_not_depend_on_node_assert_for_generated_code branch from d899197 to 9e499e8 Compare December 1, 2025 23:51
@LevanKvirkvelia
Copy link

lgtm :D

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