Skip to content

docs: expand cloudflare worker playground#800

Merged
dinwwwh merged 2 commits intomainfrom
docs/expand-cloudflare-worker-playground
Jul 24, 2025
Merged

docs: expand cloudflare worker playground#800
dinwwwh merged 2 commits intomainfrom
docs/expand-cloudflare-worker-playground

Conversation

@dinwwwh
Copy link
Copy Markdown
Member

@dinwwwh dinwwwh commented Jul 24, 2025

Summary by CodeRabbit

  • New Features

    • Added interactive API reference UI accessible at /api.
    • Introduced new forms and views for creating and listing planets with pagination.
    • Enabled real-time chat messaging with improved message handling.
    • Added Server-Sent Events endpoint emitting periodic timestamps.
    • Implemented authentication routes for signup, signin, and user profile retrieval.
    • Introduced retry middleware to improve request reliability.
  • Improvements

    • Integrated React Query for efficient data fetching and caching.
    • Enhanced error handling with typed errors and specific unauthorized error responses.
    • Added middleware for authentication enforcement and database access with a fake in-memory DB.
    • Refined API routing with modular handlers for RPC and OpenAPI endpoints.
    • Updated development dependencies to support schema validation, OpenAPI integration, and query management.
  • Bug Fixes

    • Improved message subscription and sending logic in chat component for stability.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jul 24, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
orpc ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 24, 2025 7:17am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 24, 2025

Walkthrough

This change introduces a comprehensive full-stack example in the Cloudflare Worker playground. It adds new middleware, schemas, and route handlers for authentication, planet management, messaging, and SSE, using Zod for validation and oRPC for RPC and OpenAPI integration. The frontend is updated to use React Query, display API documentation, and provide interactive UI components for planets and chat.

Changes

Files / Groups Change Summary
package.json Added devDependencies: oRPC-related packages, OpenAPI, Zod, Tanstack Query, and API reference UI.
src/App.tsx, src/main.tsx, src/components/*, src/lib/orpc.ts Integrated React Query, added API reference UI, planet mutation/query forms, and chat UI updates.
worker/index.ts Refactored handler: split into RPC and OpenAPI handlers, modularized routing, added plugins.
worker/middlewares/auth.ts, worker/middlewares/db.ts, worker/middlewares/retry.ts Added new middlewares: authentication, database provider, and retry logic.
worker/orpc.ts Set up oRPC contexts with database and authentication middleware.
worker/router/auth.ts, worker/router/planet.ts, worker/router/message.ts, worker/router/sse.ts Added new route handlers for auth, planets, messaging, and SSE, with Zod validation and error types.
worker/router/index.ts Centralized router export, organizing all route handlers.
worker/schemas/auth.ts, worker/schemas/planet.ts, worker/schemas/user.ts Added Zod schemas and TypeScript types for users, planets, and authentication.
playgrounds/astro/src/middlewares/auth.ts, playgrounds/browser-extension/entrypoints/background/middlewares/auth.ts, playgrounds/electron/src/main/middlewares/auth.ts, playgrounds/next/src/middlewares/auth.ts, playgrounds/tanstack-start/src/middlewares/auth.ts Changed error throwing in auth middlewares to use ORPCError with message 'UNAUTHORIZED'.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App (React)
    participant orpc client
    participant Cloudflare Worker
    participant DB (Fake/In-memory)

    User->>App (React): Interacts (view, submit forms, chat)
    App (React)->>orpc client: Calls mutation/query (e.g., createPlanet, listPlanets)
    orpc client->>Cloudflare Worker: Sends RPC request (/rpc)
    Cloudflare Worker->>DB (Fake/In-memory): Handles via middleware (auth, db)
    DB (Fake/In-memory)-->>Cloudflare Worker: Returns data/result
    Cloudflare Worker-->>orpc client: Responds with result
    orpc client-->>App (React): Updates UI state

    User->>App (React): Navigates to /api
    App (React)->>Cloudflare Worker: Requests /api/spec.json
    Cloudflare Worker-->>App (React): Returns OpenAPI spec
    App (React)-->>User: Renders API Reference UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • unnoq/orpc#748: Adds the @orpc/json-schema package and implements a smart coercion plugin, which is directly used in this PR's OpenAPI handler setup.
  • unnoq/orpc#442: Integrates the OpenAPI Reference Plugin, which this PR configures for API documentation under /api.
  • unnoq/orpc#668: Implements durable event iterator feature used here for chat message streaming in the Cloudflare Worker playground.

Suggested labels

size:L

Poem

In a Worker’s cloud, new planets spin,
With Zod and oRPC, the fun begins!
Auth and chat, planets galore,
React Query caches, schemas at the core.
API docs sparkle, SSE streams flow—
A playground where cosmic rabbits grow!
🪐🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 215f58f and dec537b.

📒 Files selected for processing (6)
  • playgrounds/astro/src/middlewares/auth.ts (1 hunks)
  • playgrounds/browser-extension/entrypoints/background/middlewares/auth.ts (2 hunks)
  • playgrounds/cloudflare-worker/worker/middlewares/auth.ts (1 hunks)
  • playgrounds/electron/src/main/middlewares/auth.ts (2 hunks)
  • playgrounds/next/src/middlewares/auth.ts (2 hunks)
  • playgrounds/tanstack-start/src/middlewares/auth.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • playgrounds/cloudflare-worker/worker/middlewares/auth.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: publish-commit
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (10)
playgrounds/astro/src/middlewares/auth.ts (2)

2-2: LGTM: Import statement updated correctly.

The addition of ORPCError to the import is necessary for the improved error handling below.


8-8: LGTM: Improved error handling with typed errors.

The change from generic Error to ORPCError('UNAUTHORIZED') provides better error typing and consistency with the oRPC framework. This aligns with the standardization effort mentioned in the summary across multiple playgrounds.

playgrounds/browser-extension/entrypoints/background/middlewares/auth.ts (2)

2-2: LGTM: Import addition for improved error handling.

Adding ORPCError to the imports enables the use of framework-specific error types for better error handling consistency.


15-15: LGTM: Improved error handling with ORPCError.

Replacing the generic Error with ORPCError provides better error categorization and consistency across the oRPC framework. The 'UNAUTHORIZED' error code will be properly handled by the framework's error handling mechanisms.

playgrounds/electron/src/main/middlewares/auth.ts (2)

2-2: LGTM! Import standardization improves framework integration.

Adding ORPCError to the import statement aligns with the framework-specific error handling pattern being standardized across playgrounds.


15-15: LGTM! Enhanced error handling with framework-specific error type.

Replacing the generic Error with ORPCError provides better integration with the oRPC framework and enables more sophisticated error handling downstream. This change aligns with the standardization effort mentioned in the summary across multiple playgrounds.

playgrounds/tanstack-start/src/middlewares/auth.ts (2)

2-2: LGTM! Import statement properly updated.

The addition of ORPCError to the import statement is necessary for the improved error handling and follows proper ES6 import conventions.


15-15: Excellent improvement to error handling consistency.

Replacing the generic Error with ORPCError provides better integration with the oRPC framework and improves type safety. This standardization across playgrounds enhances maintainability and follows oRPC best practices.

playgrounds/next/src/middlewares/auth.ts (2)

2-2: LGTM! Import correctly updated for ORPC error handling.

The addition of ORPCError to the import statement is necessary for the improved error handling and follows the ORPC framework conventions.


15-15: Excellent improvement to error handling!

Replacing the generic Error with ORPCError('UNAUTHORIZED') aligns with the ORPC framework's error handling patterns and provides better structured error responses. This change improves consistency across the codebase and enables proper error handling by the framework.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/expand-cloudflare-worker-playground

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jul 24, 2025
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the Cloudflare Worker playground by integrating advanced ORPC features, including OpenAPI documentation generation, client-side data management with Tanstack Query, and new API endpoints for authentication and planet management. It also introduces modular middleware for authentication, database access, and retries, enhancing the example's realism and demonstrating best practices for building robust serverless applications.

Highlights

  • Enhanced API Documentation: I've integrated the Scalar API Reference into the Cloudflare Worker playground. This allows for automatic OpenAPI documentation generation, accessible via the /api route, providing a clear and interactive overview of the available API endpoints.
  • Client-Side Data Management with Tanstack Query: The frontend now leverages Tanstack Query for efficient data fetching, caching, and state management. I've added new components (CreatePlanetMutationForm and ListPlanetsQuery) to demonstrate both ORPC queries (including infinite scrolling) and mutations with robust error handling and data invalidation.
  • New API Endpoints and Modular Worker Architecture: I've significantly expanded the backend API with new endpoints for authentication (signup, signin, current user details) and comprehensive CRUD operations for 'planets'. The worker's architecture has been refactored to be more modular, introducing dedicated middleware for authentication, a fake database provider, and retry logic, all organized under a structured ORPC router.
  • Schema-Driven Development with Zod: To ensure type safety and robust validation across the stack, I've extensively used Zod for defining input and output schemas for all new API endpoints. These schemas are also leveraged for OpenAPI documentation generation, providing a single source of truth for API contracts.
  • ORPC Client Refinements: The ORPC client calls have been updated to use a more organized, namespaced approach (e.g., client.message.on instead of client.onMessage), improving code readability and maintainability for future expansions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 24, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

📢 Thoughts on this report? Let us know!

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jul 24, 2025

More templates

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@800

@orpc/client

npm i https://pkg.pr.new/@orpc/client@800

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@800

@orpc/experimental-durable-event-iterator

npm i https://pkg.pr.new/@orpc/experimental-durable-event-iterator@800

@orpc/hey-api

npm i https://pkg.pr.new/@orpc/hey-api@800

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@800

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@800

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@800

@orpc/openapi-client

npm i https://pkg.pr.new/@orpc/openapi-client@800

@orpc/react

npm i https://pkg.pr.new/@orpc/react@800

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@800

@orpc/server

npm i https://pkg.pr.new/@orpc/server@800

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@800

@orpc/solid-query

npm i https://pkg.pr.new/@orpc/solid-query@800

@orpc/standard-server

npm i https://pkg.pr.new/@orpc/standard-server@800

@orpc/standard-server-aws-lambda

npm i https://pkg.pr.new/@orpc/standard-server-aws-lambda@800

@orpc/standard-server-fetch

npm i https://pkg.pr.new/@orpc/standard-server-fetch@800

@orpc/standard-server-node

npm i https://pkg.pr.new/@orpc/standard-server-node@800

@orpc/standard-server-peer

npm i https://pkg.pr.new/@orpc/standard-server-peer@800

@orpc/svelte-query

npm i https://pkg.pr.new/@orpc/svelte-query@800

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@800

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@800

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@800

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@800

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@800

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@800

commit: dec537b

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request expands the Cloudflare worker playground, adding features like Tanstack Query integration, OpenAPI spec generation, and a modular worker-side router with middlewares. I've found one critical issue in the retry middleware and a few medium-severity suggestions related to code duplication and readability.

Comment thread playgrounds/cloudflare-worker/worker/middlewares/retry.ts
Comment thread playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx
Comment thread playgrounds/cloudflare-worker/worker/index.ts
Comment thread playgrounds/cloudflare-worker/worker/index.ts
Comment thread playgrounds/cloudflare-worker/worker/schemas/planet.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🔭 Outside diff range comments (2)
playgrounds/cloudflare-worker/src/components/chat-room.tsx (2)

8-23: Add error handling for message streaming.

The async operations lack error handling, which could lead to unhandled promise rejections or silent failures.

   useEffect(() => {
     const controller = new AbortController()

     void (async () => {
-      const iterator = await client.message.on(undefined, { signal: controller.signal })
-      setIterator(iterator)
-
-      for await (const message of iterator) {
-        setMessages(messages => [...messages, message.message])
+      try {
+        const iterator = await client.message.on(undefined, { signal: controller.signal })
+        setIterator(iterator)
+
+        for await (const message of iterator) {
+          setMessages(messages => [...messages, message.message])
+        }
+      } catch (error) {
+        if (!controller.signal.aborted) {
+          console.error('Error in message streaming:', error)
+        }
       }
     })()

     return () => {
       controller.abort()
+      setIterator(null)
     }
   }, [])

25-34: Add error handling and form reset for message sending.

The message sending function lacks error handling and doesn't reset the form after successful send.

   const sendMessage = async (e: React.FormEvent<HTMLFormElement>) => {
     e.preventDefault()

     const form = new FormData(e.target as HTMLFormElement)
     const message = form.get('message') as string

-    await client.message.send({ message })
-    // or ---
-    // await iterator?.publishMessageRPC({ message })
+    try {
+      await client.message.send({ message })
+      // Reset form after successful send
+      ;(e.target as HTMLFormElement).reset()
+    } catch (error) {
+      console.error('Error sending message:', error)
+    }
   }
🧹 Nitpick comments (15)
playgrounds/cloudflare-worker/src/main.tsx (1)

10-12: Consider adding QueryClient configuration for production use.

While the default QueryClient configuration works well for development, consider adding custom configuration for production scenarios:

-const queryClient = new QueryClient()
+const queryClient = new QueryClient({
+  defaultOptions: {
+    queries: {
+      staleTime: 1000 * 60 * 5, // 5 minutes
+      retry: 2,
+    },
+  },
+})
playgrounds/cloudflare-worker/src/App.tsx (2)

8-16: Consider using React Router for navigation.

While the direct location.pathname check works for this simple case, consider using React Router for more robust routing as the application grows:

// Alternative approach with React Router
import { BrowserRouter, Routes, Route } from 'react-router-dom'

// Then use Route components instead of conditional rendering

29-33: Consider adding error boundaries for component resilience.

Since these components likely make API calls, consider wrapping them in error boundaries for better error handling:

<ErrorBoundary fallback={<div>Error loading planets</div>}>
  <CreatePlanetMutationForm />
</ErrorBoundary>
playgrounds/cloudflare-worker/worker/schemas/auth.ts (1)

4-5: Consider enhanced password validation for production use.

For production environments, consider adding password strength requirements:

-  password: z.string(),
+  password: z.string()
+    .min(8, "Password must be at least 8 characters")
+    .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, "Password must contain uppercase, lowercase, and number"),
playgrounds/cloudflare-worker/worker/middlewares/retry.ts (1)

17-34: Consider adding configurable retry delay and error filtering.

The current implementation retries immediately without delay and retries all errors. For production use, consider adding exponential backoff and selective error retry logic.

-export function retry(options: { times: number }) {
+export function retry(options: { 
+  times: number
+  delay?: number
+  shouldRetry?: (error: unknown) => boolean 
+}) {
   /**
    * Best practices for dedupe-middlewares
    * {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware}
    */
   return os
     .$context<{ canRetry?: boolean }>()
     .middleware(({ context, next }) => {
       const canRetry = context.canRetry ?? true

       if (!canRetry) {
         return next()
       }

       let times = 0
       while (true) {
         try {
           return next({
             context: {
               canRetry: false,
             },
           })
         }
         catch (e) {
+          if (options.shouldRetry && !options.shouldRetry(e)) {
+            throw e
+          }
+          
           if (times >= options.times) {
             throw e
           }

           times++
+          
+          if (options.delay) {
+            await new Promise(resolve => setTimeout(resolve, options.delay * Math.pow(2, times)))
+          }
         }
       }
     })
 }
playgrounds/cloudflare-worker/src/components/chat-room.tsx (1)

32-33: Remove commented code or clarify the alternative approach.

The commented alternative suggests uncertainty about the API design. Either remove it or add documentation explaining when to use each approach.

playgrounds/cloudflare-worker/src/components/orpc-query.tsx (1)

13-19: Consider more descriptive error messaging.

The generic error message could be more helpful for debugging and user experience.

   if (status === 'error') {
     return (
       <p>
-        Something went wrong.
+        Failed to load planets. Please try refreshing the page.
       </p>
     )
   }
playgrounds/cloudflare-worker/worker/router/sse.ts (1)

14-22: Consider making the configuration more flexible.

The SSE handler is well-implemented, but the hard-coded values could be made configurable for better reusability.

-const MAX_EVENTS = 5
+const DEFAULT_MAX_EVENTS = 5
+const DEFAULT_INTERVAL = 1000

 export const sse = os
   .route({
     method: 'GET',
     path: '/sse',
     tags: ['SSE'],
     summary: 'Server-Sent Events',
   })
+  .input(z.object({
+    maxEvents: z.number().min(1).max(100).default(DEFAULT_MAX_EVENTS),
+    interval: z.number().min(100).max(10000).default(DEFAULT_INTERVAL),
+  }).optional())
   .output(eventIterator(z.object({ time: z.date() })))
-  .handler(async function* () {
+  .handler(async function* (input) {
+    const { maxEvents = DEFAULT_MAX_EVENTS, interval = DEFAULT_INTERVAL } = input || {}
     let count = 0

-    while (count < MAX_EVENTS) {
+    while (count < maxEvents) {
       count++
       yield { time: new Date() }
-      await new Promise(resolve => setTimeout(resolve, 1000))
+      await new Promise(resolve => setTimeout(resolve, interval))
     }
   })
playgrounds/cloudflare-worker/worker/schemas/user.ts (1)

7-11: Consider adding basic password validation for security best practices.

While this is a playground example, adding basic password validation (minimum length, etc.) would demonstrate security best practices that users might reference for real implementations.

  password: z.string(),
+  password: z.string().min(8, 'Password must be at least 8 characters'),
playgrounds/cloudflare-worker/worker/router/message.ts (1)

7-7: Hardcoded room name limits scalability.

While acceptable for a playground demo, consider documenting that real implementations should support dynamic room names, possibly as input parameters.

playgrounds/cloudflare-worker/worker/router/auth.ts (1)

31-33: Authentication stub needs security disclaimer

The signin handler returns a hardcoded token without validating credentials. While acceptable for a playground, consider:

  • Adding a comment indicating this is a stub
  • Using a more realistic token format (e.g., JWT-like string) to better demonstrate the expected response structure
-    return { token: 'token' }
+    // TODO: Implement actual authentication
+    // This is a stub implementation for demonstration purposes
+    return { token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.stub.signature' }
playgrounds/cloudflare-worker/worker/schemas/planet.ts (1)

8-19: Reduce schema duplication with shared fields

Consider extracting common fields to reduce duplication between NewPlanetSchema and UpdatePlanetSchema:

+const PlanetFieldsSchema = z.object({
+  name: z.string(),
+  description: z.string().optional(),
+  image: z.file().mime(['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml', 'image/gif']).optional(),
+})
+
-export const NewPlanetSchema = z.object({
-  name: z.string(),
-  description: z.string().optional(),
-  image: z.file().mime(['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml', 'image/gif']).optional(),
-})
+export const NewPlanetSchema = PlanetFieldsSchema

-export const UpdatePlanetSchema = z.object({
-  id: z.number().int().min(1),
-  name: z.string(),
-  description: z.string().optional(),
-  image: z.file().mime(['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml', 'image/gif']).optional(),
-})
+export const UpdatePlanetSchema = PlanetFieldsSchema.extend({
+  id: z.number().int().min(1),
+})
playgrounds/cloudflare-worker/worker/index.ts (1)

68-76: Consider making default token configurable

The hardcoded default token in the OpenAPI docs configuration could be made configurable via environment variables for better flexibility across environments.

       authentication: {
         securitySchemes: {
           bearerAuth: {
-            token: 'default-token',
+            token: env.DEFAULT_API_TOKEN || 'default-token',
           },
         },
       },
playgrounds/cloudflare-worker/worker/middlewares/db.ts (1)

31-65: Consider data isolation for concurrent requests

The shared mutable planets array could lead to race conditions in a real environment. While this is a fake implementation, consider documenting this limitation or using a copy-on-write pattern for better demonstration of production patterns.

playgrounds/cloudflare-worker/worker/router/planet.ts (1)

78-98: Redundant planet lookup in update handler

The handler fetches the planet to check existence but doesn't use it. Since db.planets.update will handle the not-found case, consider removing the redundant lookup or passing the found planet to avoid double fetching.

   .handler(async ({ input, context, errors }) => {
-    const planet = await context.db.planets.find(input.id)
-
-    if (!planet) {
-      /**
-       *  1. Type-Safe Error Handling
-       *
-       * {@link https://orpc.unnoq.com/docs/error-handling#type%E2%80%90safe-error-handling}
-       */
-      throw errors.NOT_FOUND({ data: { id: input.id } })
-
-      /**
-       * 2. Normal Approach
-       *
-       * {@link https://orpc.unnoq.com/docs/error-handling#normal-approach}
-       */
-      // throw new ORPCError('NOT_FOUND', { message: 'Planet not found' })
-    }
-
-    return context.db.planets.update(input)
+    try {
+      return await context.db.planets.update(input)
+    } catch (error) {
+      if (error instanceof Error && error.message === 'Planet not found') {
+        throw errors.NOT_FOUND({ data: { id: input.id } })
+      }
+      throw error
+    }
   })
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9686570 and 215f58f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • playgrounds/cloudflare-worker/package.json (1 hunks)
  • playgrounds/cloudflare-worker/src/App.tsx (1 hunks)
  • playgrounds/cloudflare-worker/src/components/chat-room.tsx (2 hunks)
  • playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx (1 hunks)
  • playgrounds/cloudflare-worker/src/components/orpc-query.tsx (1 hunks)
  • playgrounds/cloudflare-worker/src/lib/orpc.ts (2 hunks)
  • playgrounds/cloudflare-worker/src/main.tsx (1 hunks)
  • playgrounds/cloudflare-worker/worker/index.ts (2 hunks)
  • playgrounds/cloudflare-worker/worker/middlewares/auth.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/middlewares/db.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/middlewares/retry.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/orpc.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/router/auth.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/router/index.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/router/message.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/router/planet.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/router/sse.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/schemas/auth.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/schemas/planet.ts (1 hunks)
  • playgrounds/cloudflare-worker/worker/schemas/user.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
playgrounds/cloudflare-worker/src/main.tsx (1)
playgrounds/cloudflare-worker/src/App.tsx (1)
  • App (7-36)
playgrounds/cloudflare-worker/src/components/chat-room.tsx (1)
playgrounds/cloudflare-worker/src/lib/orpc.ts (1)
  • client (17-17)
playgrounds/cloudflare-worker/worker/schemas/planet.ts (1)
playgrounds/cloudflare-worker/worker/schemas/user.ts (1)
  • UserSchema (23-27)
playgrounds/cloudflare-worker/worker/router/sse.ts (1)
packages/server/src/builder.ts (1)
  • os (336-352)
playgrounds/cloudflare-worker/worker/router/auth.ts (3)
playgrounds/cloudflare-worker/worker/orpc.ts (2)
  • pub (5-7)
  • authed (9-10)
playgrounds/cloudflare-worker/worker/schemas/user.ts (2)
  • NewUserSchema (7-11)
  • UserSchema (23-27)
playgrounds/cloudflare-worker/worker/schemas/auth.ts (2)
  • CredentialSchema (3-6)
  • TokenSchema (8-10)
playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx (1)
playgrounds/cloudflare-worker/src/lib/orpc.ts (1)
  • orpc (19-19)
playgrounds/cloudflare-worker/src/components/orpc-query.tsx (1)
playgrounds/cloudflare-worker/src/lib/orpc.ts (1)
  • orpc (19-19)
playgrounds/cloudflare-worker/worker/router/index.ts (2)
playgrounds/cloudflare-worker/worker/router/planet.ts (4)
  • listPlanets (7-24)
  • createPlanet (26-37)
  • findPlanet (39-61)
  • updatePlanet (63-98)
playgrounds/cloudflare-worker/worker/router/message.ts (2)
  • onMessage (6-12)
  • sendMessage (14-21)
playgrounds/cloudflare-worker/worker/schemas/user.ts (1)
packages/zod/src/zod4/registries.ts (1)
  • JSON_SCHEMA_REGISTRY (22-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: publish-commit
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (23)
playgrounds/cloudflare-worker/src/main.tsx (1)

4-6: LGTM! Clean React Query integration.

The implementation correctly sets up React Query at the application root with proper imports and client instantiation.

playgrounds/cloudflare-worker/src/lib/orpc.ts (3)

5-6: LGTM! Improved import specificity and React Query integration.

The more specific import path from ../../worker/router is cleaner, and the createTanstackQueryUtils import enables the React Query integration used by the new components.


19-19: Excellent addition of Tanstack Query utilities.

The orpc export using createTanstackQueryUtils provides a clean interface for the React Query integration used in the new components.


9-9: RPC endpoint correctly aligned

The worker’s RPC handler in playgrounds/cloudflare‐worker/worker/index.ts is configured with prefix: '/rpc', which matches the client’s url: ${window.location.origin}/rpc``. No further changes are required.

playgrounds/cloudflare-worker/src/App.tsx (2)

2-5: Clean component imports and API reference integration.

The new component imports and Scalar API reference setup look well-structured and align with the enhanced playground functionality.


19-34: Excellent semantic HTML and component structure.

The change from <div> to <main> improves semantic HTML, and the structured layout with clear separators provides good UX for the playground components.

playgrounds/cloudflare-worker/package.json (1)

18-24: Appropriate dependency additions for enhanced functionality.

The new dependencies correctly support the added features:

  • oRPC packages enable schema validation, OpenAPI integration, and React Query utilities
  • Scalar API reference provides the documentation UI
  • Tanstack React Query enables data fetching and caching

Version choices are appropriate with "next" for oRPC packages and stable versions for established libraries.

playgrounds/cloudflare-worker/worker/schemas/auth.ts (2)

3-6: Clean and appropriate credential schema definition.

The CredentialSchema correctly uses Zod's email validation and basic string validation for passwords. This is suitable for the playground environment.


8-10: Simple and effective token schema.

The TokenSchema provides clean validation for authentication tokens with appropriate simplicity for the demo use case.

playgrounds/cloudflare-worker/worker/middlewares/retry.ts (1)

3-35: LGTM! Well-implemented retry middleware.

The retry middleware is well-structured and follows oRPC best practices. The infinite loop prevention using the canRetry context flag is a solid pattern, and the reference to documentation is helpful.

playgrounds/cloudflare-worker/src/components/orpc-query.tsx (2)

5-11: LGTM! Well-implemented infinite query with cursor pagination.

The infinite query setup is excellent with proper cursor-based pagination logic. The getNextPageParam correctly checks for full pages to determine if there are more items to load.


35-44: Good use of page index in keys for proper React reconciliation.

The key generation ${planet.id}-${i} correctly includes the page index to handle potential duplicate IDs across pages and ensure proper React list reconciliation.

playgrounds/cloudflare-worker/worker/router/sse.ts (1)

6-22: LGTM! Clean SSE implementation.

The Server-Sent Events route is well-structured with proper schema validation, appropriate rate limiting, and clean async generator usage. The implementation follows oRPC patterns correctly.

playgrounds/cloudflare-worker/worker/orpc.ts (1)

1-11: Well-structured middleware composition pattern.

The layered context setup follows oRPC best practices by composing middleware incrementally. The pub context provides database access for public routes, while authed extends it with authentication requirements. This design allows selective middleware application across different route types.

playgrounds/cloudflare-worker/worker/middlewares/auth.ts (2)

23-35: Hardcoded user data is appropriate for playground demo.

The hardcoded user data and commented Next.js integration code is suitable for a playground example. The comments effectively explain the limitations and provide guidance for real-world implementation.


12-12: Excellent use of nullish coalescing for performance optimization.

The use of ?? operator to avoid unnecessary getSession() calls when a session already exists in context is a great performance optimization pattern, as referenced in the oRPC documentation.

playgrounds/cloudflare-worker/worker/router/index.ts (1)

1-27: Excellent router organization and API design.

The router consolidation provides a clean, semantic API structure:

  • Logical grouping of related functionality (auth, planet, message)
  • Intuitive naming conventions (e.g., list vs listPlanets for external API)
  • Clear separation of concerns
  • Easy to understand and maintain

This follows API design best practices by providing a clean external interface while maintaining descriptive internal implementation names.

playgrounds/cloudflare-worker/worker/schemas/user.ts (2)

13-21: Well-structured schema registry integration.

The JSON schema registry setup with examples is excellent for API documentation generation. The example data is realistic and helpful for understanding the expected format.


23-37: Good separation of concerns between NewUser and User schemas.

The distinction between NewUser (for creation) and User (with id) follows proper API design patterns and prevents id injection attacks during user creation.

playgrounds/cloudflare-worker/worker/router/message.ts (1)

14-21: Consider authentication requirements for message sending.

The sendMessage handler uses the pub context, allowing unauthenticated message sending. Consider if this aligns with your intended security model, especially since message receiving via onMessage is also public.

For a complete security review, should message sending require authentication? If so, consider using the authed context instead of pub.

playgrounds/cloudflare-worker/worker/router/auth.ts (1)

35-45: Clean implementation of authenticated endpoint

The me endpoint correctly leverages the authentication middleware to return the current user. This is a good example of separation of concerns.

playgrounds/cloudflare-worker/worker/index.ts (1)

15-25: Well-structured RPC handler configuration

Good implementation with error logging and plugin configuration. The batch handling and durable event iterator support are properly integrated.

playgrounds/cloudflare-worker/worker/router/planet.ts (1)

7-24: Well-implemented pagination with proper constraints

Good implementation of pagination with sensible limits and defaults. The retry middleware for read operations is appropriately applied.

Comment thread playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx
Comment thread playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx
Comment thread playgrounds/cloudflare-worker/src/components/orpc-mutation.tsx
Comment thread playgrounds/cloudflare-worker/worker/middlewares/auth.ts
Comment thread playgrounds/cloudflare-worker/worker/middlewares/db.ts
Comment thread playgrounds/cloudflare-worker/worker/router/auth.ts
Comment thread playgrounds/cloudflare-worker/worker/router/message.ts
@dinwwwh dinwwwh merged commit 24085bc into main Jul 24, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant