Skip to content

Add route handler protocol body helper#2706

Open
mareszhar wants to merge 1 commit into
instantdb:mainfrom
mareszhar:export-instant-route-handler-body-types
Open

Add route handler protocol body helper#2706
mareszhar wants to merge 1 commit into
instantdb:mainfrom
mareszhar:export-instant-route-handler-body-types

Conversation

@mareszhar
Copy link
Copy Markdown

Reference Discord Thread

This PR introduces a unified protocol for utils working with firstPartyPath.

Benefits

Avoids client/server drift — adds a shared routeHandlerProtocol.ts contract used by both Reactor when posting auth sync updates and createInstantRouteHandler when receiving them.

Keeps future payload types easy to add — models request bodies through a payload-by-type map, so new route-handler request types can extend the map and automatically flow into the derived body union.

Provides a consistent body factory — adds createInstantRouteHandlerBody('sync-user', { appId, user }) so protocol bodies are constructed from one helper instead of hand-written object literals.

Improves custom handler DX — exports InstantRouteHandlerBody, InstantRouteHandlerRawBody, InstantRouteHandlerType, and InstantRouteHandlerPayloadByType so custom route handlers can type the payload they receive without duplicating the SDK's internal shape.

Documents intended behavior through tests — adds runtime and type-level coverage for the helper, the existing route handler behavior, unknown request types, and the exported type contract.

Validation

pnpm --dir client/packages/core run check
pnpm --dir client/packages/core run test:types
pnpm --dir client/packages/core exec vitest run __tests__/src/createRouteHandler.test.ts

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6066ce03-1bbb-4371-b8d9-612664f30d5a

📥 Commits

Reviewing files that changed from the base of the PR and between b46704a and 8920e04.

📒 Files selected for processing (13)
  • client/packages/admin/src/index.ts
  • client/packages/core/__tests__/src/createRouteHandler.test.ts
  • client/packages/core/src/Reactor.js
  • client/packages/core/src/__types__/routeHandlerProtocolTypeTest.ts
  • client/packages/core/src/createRouteHandler.ts
  • client/packages/core/src/index.ts
  • client/packages/core/src/routeHandlerProtocol.ts
  • client/packages/react-native/src/index.ts
  • client/packages/react/src/index.ts
  • client/packages/react/src/next-ssr/index.tsx
  • client/packages/solidjs/src/index.ts
  • client/packages/svelte/src/lib/index.ts
  • client/packages/vue/src/index.ts

📝 Walkthrough

Walkthrough

This PR introduces a typed first-party route handler protocol that standardizes request bodies for sync-user operations. A new routeHandlerProtocol.ts file defines strongly-typed contracts, payload mappings, and a createInstantRouteHandlerBody factory. The protocol is integrated into core request handling and Reactor user sync, validated with type-level and runtime tests, and then re-exported across all framework packages.

Changes

Route Handler Protocol

Layer / File(s) Summary
Route handler protocol definition
client/packages/core/src/routeHandlerProtocol.ts
Payload shape map defines sync-user body structure with appId and user fields; InstantRouteHandlerType is derived as a union of known types; InstantRouteHandlerBody<Type> is a generic keyed by handler type; InstantRouteHandlerRawBody represents untrusted incoming request JSON; createInstantRouteHandlerBody merges a validated payload with its type into a typed body.
Protocol type validation
client/packages/core/src/__types__/routeHandlerProtocolTypeTest.ts
Compile-time test suite constructs a sync-user body and asserts the type is not any, matches InstantRouteHandlerBody<'sync-user'>, and payload mappings resolve correctly; includes // @ts-expect-error`` checks that reject unknown types and enforce the official User shape.
Core request handler and reactor integration
client/packages/core/src/createRouteHandler.ts, client/packages/core/src/Reactor.js
Route handler types the parsed request body as InstantRouteHandlerRawBody and casts body.user to User | null | undefined before normalizing to null; Reactor imports createInstantRouteHandlerBody and uses it to construct the sync-user payload when POSTing to firstPartyPath.
Runtime protocol tests
client/packages/core/__tests__/src/createRouteHandler.test.ts
Vitest suite confirms createInstantRouteHandlerBody('sync-user', ...) returns correctly typed objects; validates the route handler returns 200 with { ok: true } and sets an instant_user_<appId> cookie with Max-Age=604800; confirms unknown types are rejected with 400 and an error message.
Core package public API expansion
client/packages/core/src/index.ts
Core entrypoint imports and re-exports createInstantRouteHandlerBody plus the InstantRouteHandler* protocol types.
Framework packages public API expansion
client/packages/admin/src/index.ts, client/packages/react/src/index.ts, client/packages/react/src/next-ssr/index.tsx, client/packages/react-native/src/index.ts, client/packages/solidjs/src/index.ts, client/packages/svelte/src/lib/index.ts, client/packages/vue/src/index.ts
Admin, React, React Native, SolidJS, Svelte, and Vue packages re-export the factory and protocol types from core; React Next SSR expands its route handler export to include the full protocol API.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • nezaj
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add route handler protocol body helper' accurately and concisely summarizes the main change—introducing a helper function and protocol for route handler bodies. It matches the primary objective of the changeset.
Description check ✅ Passed The description provides a comprehensive explanation of the PR's purpose, benefits, and implementation details, clearly relating to the changeset which adds route handler protocol infrastructure and exports.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@drew-harris drew-harris left a comment

Choose a reason for hiding this comment

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

Thanks for taking initiative to submit this PR. I think currently this diff does a bit too much and instead we would prefer to export the bare minimum typescript type if we can get away with that.

export type InstantRouteHandlerPayloadByType = {
  'sync-user': {
    appId: string;
    user: User | null;
  };
};


/** A valid request body for Instant's first-party route handler protocol. */
export type InstantRouteHandlerBody<
  Type extends InstantRouteHandlerType = InstantRouteHandlerType,
> = {
  [KnownType in Type]: {
    type: KnownType;
  } & InstantRouteHandlerPayloadByType[KnownType];
}[Type];

Would exporting these 2 types from all packages be enough for your specific usecase / reasoning for opening the PR?

We don't feel the need for any tests on this code and we prefer to use the satisfies keyword over a constructor method. For the raw body type, we think end users creating a zod / validator schema for a body is a better alternative.

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