-
Notifications
You must be signed in to change notification settings - Fork 371
feat(clerk-js,clerk-react,types): Introduce state signals #6450
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
🦋 Changeset detectedLatest commit: bc8457b The changes in this PR will be included in the next version bump. This PR includes changesets to release 22 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/elements
@clerk/clerk-expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/clerk-react
@clerk/react-router
@clerk/remix
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/themes
@clerk/types
@clerk/upgrade
@clerk/vue
commit: |
📝 WalkthroughWalkthroughThis change introduces a new experimental Signals API throughout the Clerk codebase. It adds the Estimated code review effort🎯 4 (Complex) | ⏱️ ~35–50 minutes
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (4)
packages/react/src/experimental.ts (1)
4-5
: Export is fine but consider namespacing under__experimental_
Everything else in this file follows the
__experimental_
prefix convention. ExposinguseSignInSignal
without that prefix could encourage unintended usage in userland before the API stabilises.-export { useSignInSignal } from './hooks/useClerkSignal'; +export { useSignInSignal as __experimental_useSignInSignal } from './hooks/useClerkSignal';If you intentionally skipped the prefix, ignore this note, but please document the rationale.
No unit tests exercise the new hook – add a minimal render/subscribe test to guard against ref regressions.packages/types/src/index.ts (1)
52-53
: Be cautious of barrel exports growth / potential cycles
./state
is now re-exported here.index.ts
is already large and occasionally causes circular-type explosions in downstream builds. Ifstate.ts
pulls in runtime-heavy types or depends on many others, consider a dedicated sub-entry (export * as state from './state'
) to localise surface area.No action required if you’ve verified compilation time remains unaffected.
packages/clerk-js/src/core/signals.ts (1)
1-5
: LGTM! Clean signal implementation.The signal definition is well-structured with proper typing and sensible defaults. Consider adding JSDoc documentation since this is a new public export:
+/** + * Reactive signal for tracking sign-in resource state. + * @internal This API is experimental and subject to change. + */ export const signInSignal = signal<{ resource: SignIn | null }>({ resource: null });packages/types/src/state.ts (1)
4-9
: StrengthensignInSignal
typing and immutability
- Consider declaring the property itself
readonly
to prevent consumers from rebinding it:- signInSignal: { + readonly signInSignal: {
- Return value could be marked
readonly
as well to discourage mutation:- (): { - resource: SignInResource | null; - }; + (): Readonly<{ resource: SignInResource | null }>;These tweaks cost nothing but add a small safety net.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
packages/clerk-js/package.json
(1 hunks)packages/clerk-js/src/core/clerk.ts
(2 hunks)packages/clerk-js/src/core/events.ts
(1 hunks)packages/clerk-js/src/core/resources/SignIn.ts
(2 hunks)packages/clerk-js/src/core/signals.ts
(1 hunks)packages/clerk-js/src/core/state.ts
(1 hunks)packages/react/src/experimental.ts
(1 hunks)packages/react/src/hooks/useClerkSignal.ts
(1 hunks)packages/react/src/isomorphicClerk.ts
(2 hunks)packages/types/src/clerk.ts
(2 hunks)packages/types/src/index.ts
(1 hunks)packages/types/src/state.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/clerk-js/package.json
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/*/package.json
📄 CodeRabbit Inference Engine (.cursor/rules/global.mdc)
All publishable packages should be placed under the packages/ directory
packages/*/package.json
: All publishable packages must be located in the 'packages/' directory.
All packages must be published under the @clerk namespace on npm.
Semantic versioning must be used across all packages.
Files:
packages/clerk-js/package.json
**/*
⚙️ CodeRabbit Configuration File
**/*
: If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.Whenever reviewing a pull request, if there are any changes that could impact security, always tag
@clerk/security
in the PR.Security-impacting changes include, but are not limited to:
- Changes to authentication logic or mechanisms (e.g. login, session handling, token issuance)
- Any modification to access control, authorization checks, or role-based permissions
- Introduction or modification of hashing algorithms, signature verification, or cryptographic primitives
- Handling of sensitive data (e.g. passwords, tokens, secrets, PII)
- Integration with external identity providers (e.g. SSO, OAuth, OpenID Connect)
- Modifications to security headers, cookie flags, CORS policies, or CSRF protections
- Bypass mechanisms (e.g. feature flags, testing overrides) that could weaken protections
- Changes to rate limiting, abuse prevention, or input validation
If you're unsure whether a change is security-relevant, err on the side of caution and tag
@clerk/security
.Any time that you tag
@clerk/security
, please do so explicitly in a code comment, rather than within a collapsed section in a coderabbit comment, such as the "recent review details" section. If you do use the team name in any thinking or non-direct-code-comment content, it can be referred to as "clerk security team" to avoid accidentally printing the tag which sends a notification to the team.
Files:
packages/clerk-js/package.json
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/**/index.{js,ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use tree-shaking friendly exports
Files:
packages/types/src/index.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/types/src/index.ts
packages/react/src/experimental.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/react/src/isomorphicClerk.ts
packages/types/src/clerk.ts
packages/clerk-js/src/core/clerk.ts
packages/clerk-js/src/core/signals.ts
packages/clerk-js/src/core/events.ts
packages/react/src/hooks/useClerkSignal.ts
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
**/index.ts
📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)
Use index.ts files for clean imports but avoid deep barrel exports
Avoid barrel files (index.ts re-exports) as they can cause circular dependencies
Files:
packages/types/src/index.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). (5)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: Build Packages
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (21)
packages/clerk-js/package.json (1)
78-80
: Pin or tighten thealien-signals
version in package.jsonpackages/clerk-js/package.json (lines 78–80):
- "alien-signals": "^2.0.5", + "alien-signals": "2.0.5",Alternatively, if you prefer to keep a floating range, add an automated lock-file diff + bundle-size watch in CI to catch unexpected bumps. Also:
- Verify that
alien-signals
is MIT-licensed- Confirm your bundler tree-shakes this package to avoid pulling in unused code
packages/clerk-js/src/core/clerk.ts (1)
157-158
: Import looks good – watch for treeshaking
State
should be side-effect-free; otherwise this import will always include the signals runtime even when not used (e.g. headless builds). Confirm./state
has"sideEffects": false
in itspackage.json
or annotate the file accordingly.packages/clerk-js/src/core/resources/SignIn.ts (2)
69-69
: LGTM!The import of
eventBus
is correctly implemented and follows established patterns in the codebase.
455-456
: LGTM!The event emission is correctly placed at the end of the
fromJSON
method, ensuring all properties are updated before notifying listeners. The event name and payload structure are appropriate for the reactive state system.packages/types/src/clerk.ts (2)
57-57
: LGTM!The type-only import follows TypeScript best practices and coding guidelines, using
import type
for better tree-shaking.
231-232
: LGTM!The
__internal_state
property is correctly defined with appropriate typing and internal naming convention. The optional type provides backwards compatibility while enabling the new reactive state functionality.packages/react/src/isomorphicClerk.ts (1)
718-720
: LGTM! Well-implemented internal state getter.The implementation correctly follows the established pattern in this class for exposing properties from the underlying clerkjs instance, with proper null safety using optional chaining.
packages/clerk-js/src/core/events.ts (4)
4-4
: LGTM! Proper import addition.The SignIn import is correctly added from the local resources module.
11-11
: LGTM! Consistent event naming.The new
SignInUpdate
event follows the established naming convention in this file.
15-15
: LGTM! Well-defined payload type.The
SignInUpdatePayload
type is properly defined and exported for reuse across the codebase.
22-22
: LGTM! Correct type mapping.The
InternalEvents
type mapping is properly updated to include the new signin:update event with its payload type.packages/clerk-js/src/core/state.ts (4)
1-6
: LGTM! Well-organized imports.All imports are properly typed and sourced from the correct modules.
7-12
: LGTM! Clean state class structure.The State class properly implements the StateInterface and correctly exposes the reactive primitives for internal use.
13-15
: LGTM! Proper event subscription setup.The constructor correctly subscribes to the signin:update event to enable reactive updates.
17-20
: LGTM! Correct signal update implementation.The onSignInUpdated method properly updates the signInSignal with the new resource from the event payload.
packages/react/src/hooks/useClerkSignal.ts (6)
1-6
: LGTM! Proper imports and dependencies.All necessary React hooks and Clerk context utilities are correctly imported.
7-11
: LGTM! Good hook setup with proper assertions.The hook correctly asserts it's used within a ClerkProvider and accesses the clerk instance from context.
12-31
: LGTM! Well-implemented subscription logic.The subscribe callback properly handles edge cases by checking if clerk is loaded and has internal state before setting up the effect subscription. The dependency array is correctly specified.
32-43
: LGTM! Safe snapshot getter implementation.The getSnapshot callback safely handles the case where internal state might not exist and includes proper error handling for unknown signals.
45-51
: LGTM! Correct useSyncExternalStore usage.The hook properly uses
useSyncExternalStore
for React 18+ concurrent features compatibility and returns a well-structured result object.
53-55
: LGTM! Clean convenience wrapper.The
useSignInSignal
export provides a clean, specialized interface for consuming the sign-in signal.
!snapshot |
Hey @dstaley - the snapshot version command generated the following package versions:
Tip: Use the snippet copy button below to quickly install the required packages. npm i @clerk/agent-toolkit@0.1.16-snapshot.v20250731195414 --save-exact
npm i @clerk/astro@2.10.13-snapshot.v20250731195414 --save-exact
npm i @clerk/backend@2.6.2-snapshot.v20250731195414 --save-exact
npm i @clerk/chrome-extension@2.5.15-snapshot.v20250731195414 --save-exact
npm i @clerk/clerk-js@5.79.0-snapshot.v20250731195414 --save-exact
npm i @clerk/elements@0.23.48-snapshot.v20250731195414 --save-exact
npm i @clerk/clerk-expo@2.14.14-snapshot.v20250731195414 --save-exact
npm i @clerk/expo-passkeys@0.3.25-snapshot.v20250731195414 --save-exact
npm i @clerk/express@1.7.15-snapshot.v20250731195414 --save-exact
npm i @clerk/fastify@2.4.15-snapshot.v20250731195414 --save-exact
npm i @clerk/localizations@3.20.6-snapshot.v20250731195414 --save-exact
npm i @clerk/nextjs@6.28.1-snapshot.v20250731195414 --save-exact
npm i @clerk/nuxt@1.8.1-snapshot.v20250731195414 --save-exact
npm i @clerk/clerk-react@5.38.1-snapshot.v20250731195414 --save-exact
npm i @clerk/react-router@1.8.9-snapshot.v20250731195414 --save-exact
npm i @clerk/remix@4.10.9-snapshot.v20250731195414 --save-exact
npm i @clerk/shared@3.17.0-snapshot.v20250731195414 --save-exact
npm i @clerk/tanstack-react-start@0.21.5-snapshot.v20250731195414 --save-exact
npm i @clerk/testing@1.10.9-snapshot.v20250731195414 --save-exact
npm i @clerk/themes@2.4.4-snapshot.v20250731195414 --save-exact
npm i @clerk/types@4.72.0-snapshot.v20250731195414 --save-exact
npm i @clerk/vue@1.9.1-snapshot.v20250731195414 --save-exact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
packages/clerk-js/src/core/state.ts (1)
20-26
: LGTM: Event handlers correctly update reactive signalsThe event handlers properly update the corresponding signals with event payloads, maintaining the reactive state correctly.
Note: As mentioned in previous reviews, this implementation could be made more generic and resource-agnostic for future extensibility when additional resources need similar reactive state management.
packages/types/src/state.ts (2)
3-13
: Add JSDoc documentation for public interfaceThis exported interface lacks JSDoc documentation explaining its purpose and stability status. Since this is part of the public types package, it needs proper documentation and internal members should be marked appropriately.
Add JSDoc documentation:
+/** + * Reactive state management interface for Clerk resources. + * @experimental This API is experimental and subject to change. + */ export interface State { + /** + * Reactive signal for sign-in state and errors. + * Can be called as a getter to retrieve current state or as a setter to update state. + */ signInSignal: { (): { errors: unknown; signIn: SignInBetaResource | null; }; (value: { errors: unknown; signIn: SignInBetaResource | null }): void; }; + /** + * @internal Internal effect function for reactive side effects. + */ __internal_effect: (callback: () => void) => () => void; + /** + * @internal Internal computed function for derived reactive values. + */ __internal_computed: <T>(getter: (previousValue?: T) => T) => () => T; }
11-11
: Allow cleanup functions in effect callbackThe current callback signature for
__internal_effect
only allowsvoid
return, but should allow returning cleanup functions to match thealien-signals
library behavior.- __internal_effect: (callback: () => void) => () => void; + __internal_effect: (callback: () => void | (() => void)) => () => void;
🧹 Nitpick comments (1)
packages/clerk-js/src/core/signals.ts (1)
1-3
: Fix import sorting to comply with ESLint rulesThe imports need to be sorted according to the project's ESLint configuration.
-import { signal, computed } from 'alien-signals'; - -import type { SignIn } from './resources/SignIn'; +import { computed, signal } from 'alien-signals'; + +import type { SignIn } from './resources/SignIn';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (9)
packages/clerk-js/package.json
(1 hunks)packages/clerk-js/src/core/clerk.ts
(2 hunks)packages/clerk-js/src/core/events.ts
(1 hunks)packages/clerk-js/src/core/resources/SignIn.ts
(5 hunks)packages/clerk-js/src/core/signals.ts
(1 hunks)packages/clerk-js/src/core/state.ts
(1 hunks)packages/react/src/hooks/useClerkSignal.ts
(1 hunks)packages/types/src/signIn.ts
(1 hunks)packages/types/src/state.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/clerk-js/src/core/clerk.ts
- packages/types/src/signIn.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/clerk-js/package.json
- packages/react/src/hooks/useClerkSignal.ts
- packages/clerk-js/src/core/events.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
**/*
⚙️ CodeRabbit Configuration File
**/*
: If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.Whenever reviewing a pull request, if there are any changes that could impact security, always tag
@clerk/security
in the PR.Security-impacting changes include, but are not limited to:
- Changes to authentication logic or mechanisms (e.g. login, session handling, token issuance)
- Any modification to access control, authorization checks, or role-based permissions
- Introduction or modification of hashing algorithms, signature verification, or cryptographic primitives
- Handling of sensitive data (e.g. passwords, tokens, secrets, PII)
- Integration with external identity providers (e.g. SSO, OAuth, OpenID Connect)
- Modifications to security headers, cookie flags, CORS policies, or CSRF protections
- Bypass mechanisms (e.g. feature flags, testing overrides) that could weaken protections
- Changes to rate limiting, abuse prevention, or input validation
If you're unsure whether a change is security-relevant, err on the side of caution and tag
@clerk/security
.Any time that you tag
@clerk/security
, please do so explicitly in a code comment, rather than within a collapsed section in a coderabbit comment, such as the "recent review details" section. If you do use the team name in any thinking or non-direct-code-comment content, it can be referred to as "clerk security team" to avoid accidentally printing the tag which sends a notification to the team.
Files:
packages/clerk-js/src/core/state.ts
packages/types/src/state.ts
packages/clerk-js/src/core/resources/SignIn.ts
packages/clerk-js/src/core/signals.ts
🧬 Code Graph Analysis (3)
packages/clerk-js/src/core/state.ts (3)
packages/types/src/state.ts (1)
State
(3-13)packages/clerk-js/src/core/signals.ts (3)
signInSignal
(5-5)signInErrorSignal
(6-6)signInComputedSignal
(8-17)packages/clerk-js/src/core/events.ts (2)
eventBus
(27-27)SignInUpdatePayload
(16-16)
packages/types/src/state.ts (2)
packages/clerk-js/src/core/state.ts (1)
State
(7-27)packages/types/src/signIn.ts (1)
SignInBetaResource
(128-131)
packages/clerk-js/src/core/signals.ts (1)
packages/clerk-js/src/core/resources/SignIn.ts (1)
SignIn
(73-481)
🪛 ESLint
packages/clerk-js/src/core/signals.ts
[error] 1-3: Run autofix to sort these imports!
(simple-import-sort/imports)
⏰ 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). (5)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Build Packages
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
packages/clerk-js/src/core/resources/SignIn.ts (4)
33-33
: LGTM: Necessary imports for new functionalityThe new imports for
SignInBetaResource
andeventBus
are correctly added to support the new reactive state management and beta sign-in functionality.Also applies to: 70-70
87-88
: LGTM: Internal properties correctly initializedThe internal properties
__internal_beta
and__internal_basePost
are appropriately named and initialized. The design allows the beta class to access the base posting functionality while maintaining encapsulation.Also applies to: 94-94
462-462
: LGTM: Event emission for reactive state updatesThe
signin:update
event emission infromJSON
correctly notifies subscribers when the SignIn resource is updated, enabling reactive state management throughout the application.
490-503
: Security review needed for new authentication flowThis introduces a new password-based authentication mechanism that directly handles user credentials. The implementation appears to follow secure patterns, but given that this affects authentication logic and credential handling, please have the security team review this change.
@clerk/security
packages/clerk-js/src/core/signals.ts (2)
5-6
: LGTM: Well-structured signal definitionsThe signals are properly typed with appropriate initial states. Using
unknown
for errors follows TypeScript best practices for error handling.
8-17
: LGTM: Computed signal correctly combines stateThe computed signal properly combines the sign-in resource and error states, with appropriate null handling. The exposure of
__internal_beta
aligns with the experimental nature of this feature.packages/clerk-js/src/core/state.ts (3)
1-5
: LGTM: Proper imports for State class functionalityAll necessary dependencies are correctly imported, including the interface, reactive primitives, event bus, and signal definitions.
7-13
: LGTM: State class properties correctly expose reactive functionalityThe property assignments properly expose the signals and reactive primitives, maintaining consistency with the interface definition.
15-18
: LGTM: Proper event subscription setupThe constructor correctly subscribes to the relevant events using arrow function handlers for proper
this
binding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/clerk-js/src/core/state.ts (2)
22-26
: Resource-specific error handling with room for generalization.The error handler correctly filters for
SignIn
resources and updates the appropriate signal. As noted in previous comments, this could be made more generic when additional resources are added to this pattern.
28-32
: Consistent resource update handling.The update handler follows the same pattern as the error handler, correctly filtering for
SignIn
resources and updating the signal. This maintains consistency in the event handling approach.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/clerk-js/src/core/events.ts
(1 hunks)packages/clerk-js/src/core/resources/SignIn.ts
(6 hunks)packages/clerk-js/src/core/state.ts
(1 hunks)packages/react/src/hooks/useClerkSignal.ts
(1 hunks)packages/types/src/signIn.ts
(1 hunks)packages/types/src/state.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/types/src/state.ts
- packages/react/src/hooks/useClerkSignal.ts
- packages/clerk-js/src/core/resources/SignIn.ts
- packages/types/src/signIn.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/clerk-js/src/core/state.ts
packages/clerk-js/src/core/events.ts
🧬 Code Graph Analysis (1)
packages/clerk-js/src/core/state.ts (1)
packages/types/src/state.ts (1)
State
(3-13)
🪛 ESLint
packages/clerk-js/src/core/state.ts
[error] 1-7: Run autofix to sort these imports!
(simple-import-sort/imports)
[error] 6-6: All imports in the declaration are only used as types. Use import type
.
(@typescript-eslint/consistent-type-imports)
packages/clerk-js/src/core/events.ts
[error] 4-4: All imports in the declaration are only used as types. Use import type
.
(@typescript-eslint/consistent-type-imports)
⏰ 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). (5)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: Build Packages
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
packages/clerk-js/src/core/events.ts (3)
11-12
: Excellent generic event design.The generic
resource:update
andresource:error
events follow the feedback from previous reviews to avoid resource-specific events. This approach will scale well as more resources adopt this pattern.
16-17
: Well-structured payload types.The payload types are properly designed with
unknown
for the error type, which is safer thanany
and allows for proper type narrowing in handlers.
24-25
: Proper integration into event system.The new events are correctly integrated into the
InternalEvents
type with proper payload type mapping.packages/clerk-js/src/core/state.ts (2)
9-16
: Well-structured State class with clear API boundaries.The class properly implements the
StateInterface
and uses appropriate naming conventions with__internal_
prefixes for internal APIs. The signal assignments are clean and follow the established pattern.
17-20
: Proper event subscription setup.The constructor correctly subscribes to the generic resource events using arrow function handlers to maintain proper
this
context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/types/src/state.ts (1)
15-22
: Allow cleanup functions in callback parameter.The callback signature should allow returning a cleanup function to align with standard effect patterns and the underlying
alien-signals
library.- __internal_effect: (callback: () => void) => () => void; + __internal_effect: (callback: () => void | (() => void)) => () => void;
🧹 Nitpick comments (1)
packages/types/src/state.ts (1)
1-1
: Use type-only import for better tree-shaking.Consider using a type-only import since
SignInFutureResource
is only used as a type annotation.-import type { SignInFutureResource } from './signIn'; +import type { SignInFutureResource } from './signIn';Actually, the import is already correctly using
import type
, so this is good as-is.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/types/src/state.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/types/src/state.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/types/src/state.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/types/src/state.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/types/src/state.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/types/src/state.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/types/src/state.ts
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/types/src/state.ts
🧬 Code Graph Analysis (1)
packages/types/src/state.ts (2)
packages/clerk-js/src/core/state.ts (1)
State
(9-33)packages/types/src/signIn.ts (1)
SignInFutureResource
(128-142)
⏰ 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). (5)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: Build Packages
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
packages/types/src/state.ts (2)
3-13
: Well-designed signal interface.The
signInSignal
property correctly implements the getter/setter pattern typical of signal libraries. The JSDoc clearly explains its purpose, and the return type structure witherrors
andsignIn
appropriately captures the sign-in state.
24-32
: Well-designed computed signal interface.The
__internal_computed
property correctly implements a generic computed signal pattern. The JSDoc is comprehensive with proper@experimental
tagging, and the signature allows for type-safe computed values with optional previous value access.
import { SignIn } from './resources/SignIn'; | ||
import { signInComputedSignal, signInErrorSignal, signInSignal } from './signals'; | ||
|
||
export class State implements StateInterface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSDoc would be good here 👀 what's it for? Maybe it belongs on the State
type instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put it on the __internal_state
type for Clerk
, which I'm okay with for the time being since that's where other JSDoc comments for properties are. I'll add more general doc comments to this file in a later PR.
@@ -470,3 +490,132 @@ export class SignIn extends BaseResource implements SignInResource { | |||
}; | |||
} | |||
} | |||
|
|||
class SignInFuture implements SignInFutureResource { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add JSDocs now or later to the methods here, but we should do it eventually! Saves us time later too 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments. Nothing blocking, let's iterate!
Description
This experimental PR introduces Signals to
clerk-js
, enabling reactivity for theSignIn
resource as part of our efforts to improve the experience of building custom flows with Clerk.This functionality is marked as
__internal_
, and is not currently intended for public use.Checklist
pnpm test
runs as expected.pnpm build
runs as expected.Type of change
Summary by CodeRabbit
New Features
Chores