Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fine-ducks-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/elements': patch
---

Upgrading xstate and @xstate/react to add react@19 as a transitive peerDependency
4 changes: 2 additions & 2 deletions packages/elements/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@
"@radix-ui/primitive": "^1.1.0",
"@radix-ui/react-form": "^0.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@xstate/react": "^4.1.1",
"@xstate/react": "^5.0.3",
"client-only": "^0.0.1",
"tslib": "catalog:repo",
"xstate": "^5.15.0"
"xstate": "^5.19.2"
},
"devDependencies": {
"@statelyai/inspect": "^0.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ export type SignInRouterSnapshot = MachineSnapshot<
SignInRouterStateValue,
SignInRouterTags,
SignInRouterOuptut,
any // TMeta - Introduced in XState 5.12.x
any, // TMeta - Introduced in XState 5.12.x
any // TConfig - Required in newer XState versions
>;

// ---------------------------------- Machine Type ---------------------------------- //
Expand All @@ -158,7 +159,8 @@ export type TSignInRouterParentMachine = StateMachine<
any, // input
SignInRouterOuptut, // output
any, // emitted
any // meta
any, // meta
any // config
>;

// ---------------------------------- Machine Actor Ref ---------------------------------- //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ const SignInVerificationMachine = setup({
if (process.env.NODE_ENV === 'development') {
if (
clerk.client.signIn.supportedFirstFactors &&
!clerk.client.signIn.supportedFirstFactors.every(factor => context.registeredStrategies.has(factor.strategy))
!clerk.client.signIn.supportedFirstFactors.every((factor: SignInFirstFactor) =>
context.registeredStrategies.has(factor.strategy),
)
) {
console.warn(
`Clerk: Your instance is configured to support these strategies: ${clerk.client.signIn.supportedFirstFactors
.map(factor => factor.strategy)
.map((factor: SignInFirstFactor) => factor.strategy)
.join(', ')}, but the rendered strategies are: ${Array.from(context.registeredStrategies).join(
', ',
)}. Make sure to render a <Strategy> component for each supported strategy. More information: https://clerk.com/docs/elements/reference/sign-in#strategy`,
Expand All @@ -122,19 +124,24 @@ const SignInVerificationMachine = setup({

if (
clerk.client.signIn.supportedSecondFactors &&
!clerk.client.signIn.supportedSecondFactors.every(factor => context.registeredStrategies.has(factor.strategy))
!clerk.client.signIn.supportedSecondFactors.every((factor: SignInSecondFactor) =>
context.registeredStrategies.has(factor.strategy),
)
) {
console.warn(
`Clerk: Your instance is configured to support these 2FA strategies: ${clerk.client.signIn.supportedSecondFactors
.map(f => f.strategy)
.map((f: SignInSecondFactor) => f.strategy)
.join(', ')}, but the rendered strategies are: ${Array.from(context.registeredStrategies).join(
', ',
)}. Make sure to render a <Strategy> component for each supported strategy. More information: https://clerk.com/docs/elements/reference/sign-in#strategy`,
);
}

const strategiesUsedButNotActivated = Array.from(context.registeredStrategies).filter(
strategy => !clerk.client.signIn.supportedFirstFactors?.some(supported => supported.strategy === strategy),
strategy =>
!clerk.client.signIn.supportedFirstFactors?.some(
(supported: SignInFirstFactor) => supported.strategy === strategy,
),
);

if (strategiesUsedButNotActivated.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ export const SignUpContinueMachine = setup({

for (const key of required.concat(optional) as (keyof SignUpResource)[]) {
if (key in signUp) {
// @ts-expect-error - TS doesn't understand that key is a valid key of SignUpResource
progressiveFieldValues.set(key, signUp[key]);
progressiveFieldValues.set(key, signUp[key] as string | number | readonly string[] | undefined);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ export type TSignUpRouterParentMachine = StateMachine<
any, // input
SignUpRouterOuptut, // output
any, // emitted
any // meta - Introduced in XState 5.12.x
any, // meta - Introduced in XState 5.12.x
any // config - Required in newer XState versions
>;

// ---------------------------------- Machine Actor Ref ---------------------------------- //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const SignUpVerificationMachine = setup({
void run(async () =>
clerk.client.signUp
.reload()
.then(resource => {
.then((resource: SignUpResource) => {
const signInStatus = resource.status;
const verificationStatus = resource.verifications.emailAddress.status;

Expand Down Expand Up @@ -124,9 +124,9 @@ export const SignUpVerificationMachine = setup({

stop();
})
.catch(error => {
.catch((error: Error) => {
stop();
new ClerkElementsRuntimeError(error);
new ClerkElementsRuntimeError(error.message);
}),
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AnyActorRef, AnyEventObject, InspectionEvent, Observer } from 'xstate';
import type { ActorRefLike, AnyEventObject, InspectionEvent, Observer } from 'xstate';

let consoleInspector: Observer<InspectionEvent> | undefined;

Expand All @@ -24,17 +24,19 @@ export function createConsoleInspector({
return undefined;
}

const parseRefId = (ref: AnyActorRef | undefined, includeSystemId?: false): string | undefined => {
const parseRefId = (ref: ActorRefLike | undefined, includeSystemId?: false): string | undefined => {
if (!ref) {
return undefined;
}

// @ts-expect-error - Exists on the ref.src
const id = ref.src.id;
const id = ref.src?.id;

// @ts-expect-error - id exists on ActorRefLike
let output = id || ref.id;

if (includeSystemId) {
// @ts-expect-error - id exists on ActorRefLike
output += `(${ref.id})`;
}

Expand Down Expand Up @@ -152,6 +154,7 @@ export function createConsoleInspector({
},
() => {
logEvent('Type', inspectionEvent.event.type);
// @ts-expect-error - _parent exists on ActorRefLike
logEvent('Parent', parseRefId(inspectionEvent.actorRef._parent));
logEvent('Actor', inspectionEvent.actorRef);
logEvent('Event', inspectionEvent.event);
Expand Down
4 changes: 3 additions & 1 deletion packages/elements/src/react/hooks/use-active-states.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { useSelector } from '@xstate/react';
import type { ActorRef, AnyActorRef, AnyMachineSnapshot, MachineSnapshot } from 'xstate';

type StatefulActor<TActor extends AnyActorRef> =
TActor extends ActorRef<MachineSnapshot<any, any, any, infer TStateValue, any, any, any>, any> ? TStateValue : never;
TActor extends ActorRef<MachineSnapshot<any, any, any, infer TStateValue, any, any, any, any>, any>
? TStateValue
: never;

/**
* Generic hook to check if a state is active.
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/react/hooks/use-active-tags.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useSelector } from '@xstate/react';
import type { ActorRef, AnyActorRef, AnyMachineSnapshot, MachineSnapshot } from 'xstate';

type TaggedActor<TActor extends AnyActorRef> =
TActor extends ActorRef<MachineSnapshot<any, any, any, any, infer TTags, any, any>, any> ? TTags : never;
TActor extends ActorRef<MachineSnapshot<any, any, any, any, infer TTags, any, any, any>, any> ? TTags : never;

export const ActiveTagsMode = {
any: 'any',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { createContextFromActorRef } from '~/react/utils/create-context-from-act

export type SnapshotState = SnapshotFrom<TSignInRouterMachine>;

export const SignInRouterCtx = createContextFromActorRef<TSignInRouterMachine>('SignInRouterCtx');
export const SignInRouterCtx: ReturnType<typeof createContextFromActorRef<TSignInRouterMachine>> =
createContextFromActorRef<TSignInRouterMachine>('SignInRouterCtx');

function useSignInStep<M extends AnyStateMachine, T = ActorRefFrom<M>>(name: string) {
return SignInRouterCtx.useSelector(state => state.children[name] as AnyActorRef) as T;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { createContextFromActorRef } from '~/react/utils/create-context-from-act

export type SnapshotState = SnapshotFrom<TSignUpRouterMachine>;

export const SignUpRouterCtx = createContextFromActorRef<TSignUpRouterMachine>('SignUpRouterCtx');
export const SignUpRouterCtx: ReturnType<typeof createContextFromActorRef<TSignUpRouterMachine>> =
createContextFromActorRef<TSignUpRouterMachine>('SignUpRouterCtx');

function useSignUpStep<M extends AnyStateMachine, T = ActorRefFrom<M>>(name: string) {
return SignUpRouterCtx.useSelector(state => state.children[name] as AnyActorRef) as T;
Expand Down
32 changes: 16 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.