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
6 changes: 3 additions & 3 deletions integration/presets/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const astroNode = applicationConfig()
.addScript('dev', 'pnpm dev')
.addScript('build', 'pnpm build')
.addScript('serve', 'pnpm preview')
.addDependency('@clerk/astro', linkPackage('astro'))
.addDependency('@clerk/shared', linkPackage('types'))
.addDependency('@clerk/localizations', linkPackage('localizations'));
.addDependency('@clerk/astro', linkPackage('astro', 'integration'))
.addDependency('@clerk/shared', linkPackage('types', 'integration'))
.addDependency('@clerk/localizations', linkPackage('localizations', 'integration'));

const astroStatic = astroNode.clone().setName('astro-hybrid').useTemplate(templates['astro-hybrid']);

Expand Down
2 changes: 1 addition & 1 deletion integration/templates/express-vite/src/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ document.addEventListener('DOMContentLoaded', async function () {
const clerk = new Clerk(publishableKey);

await clerk.load({
clerkUiCtor: Promise.resolve(ClerkUi),
clerkUiCtor: ClerkUi,
});

if (clerk.isSignedIn) {
Expand Down
16 changes: 9 additions & 7 deletions packages/astro/src/internal/create-clerk-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ async function createClerkInstanceInternal(options?: AstroClerkCreateInstancePar
if (!clerkJSInstance) {
// Load both clerk-js and clerk-ui in parallel
const clerkPromise = loadClerkJsScript(options);
clerkUiCtor = loadClerkUiScript(options).then(() => {
if (!window.__unstable_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
// After the check, TypeScript knows it's defined
return window.__unstable_ClerkUiCtor;
});
clerkUiCtor = options?.clerkUiCtor
? Promise.resolve(options.clerkUiCtor)
: loadClerkUiScript(options).then(() => {
if (!window.__unstable_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
// After the check, TypeScript knows it's defined
return window.__unstable_ClerkUiCtor;
});

await clerkPromise;

Expand Down
1 change: 0 additions & 1 deletion packages/astro/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ type AstroClerkIntegrationParams = Without<
| 'routerPush'
| 'polling'
| 'touchSession'
| 'clerkUiCtor'
> &
MultiDomainAndOrProxyPrimitives & {
clerkJSUrl?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ export class Clerk implements ClerkInterface {

// Initialize ClerkUi if it was provided
if (this.#options.clerkUiCtor) {
this.#clerkUi = this.#options.clerkUiCtor.then(
this.#clerkUi = Promise.resolve(this.#options.clerkUiCtor).then(
ClerkUI =>
new ClerkUI(
() => this,
Expand Down
56 changes: 31 additions & 25 deletions packages/react/src/isomorphicClerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,11 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}

constructor(options: IsomorphicClerkOptions) {
const { Clerk = null, publishableKey } = options || {};
this.#publishableKey = publishableKey;
this.#publishableKey = options?.publishableKey;
this.#proxyUrl = options?.proxyUrl;
this.#domain = options?.domain;
this.options = options;
this.Clerk = Clerk;
this.Clerk = options?.Clerk || null;
this.mode = inBrowser() ? 'browser' : 'server';
this.#stateProxy = new StateProxy(this);

Expand All @@ -266,7 +265,7 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
this.#eventBus.prioritizedOn(clerkEvents.Status, status => (this.#status = status));

if (this.#publishableKey) {
void this.loadClerkEntryChunks();
void this.getEntryChunks();
}
}

Expand Down Expand Up @@ -436,7 +435,7 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
});
}

async loadClerkEntryChunks(): Promise<void> {
async getEntryChunks(): Promise<void> {
if (this.mode !== 'browser' || this.loaded) {
return;
}
Expand All @@ -456,21 +455,15 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}

try {
const clerkPromise = this.loadClerkJsEntryChunk();
const clerkUiCtor = this.loadClerkUiEntryChunk();
await clerkPromise;
const clerkUiCtor = this.getClerkUiEntryChunk();
const clerk = await this.getClerkJsEntryChunk();

if (!global.Clerk) {
// TODO @nikos: somehow throw if clerk ui failed to load but it was not headless
throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.');
if (!clerk.loaded) {
this.beforeLoad(clerk);
await clerk.load({ ...this.options, clerkUiCtor });
}

if (!global.Clerk.loaded) {
this.beforeLoad(global.Clerk);
await global.Clerk.load({ ...this.options, clerkUiCtor });
}
if (global.Clerk.loaded) {
this.replayInterceptedInvocations(global.Clerk);
if (clerk.loaded) {
this.replayInterceptedInvocations(clerk);
}
} catch (err) {
const error = err as Error;
Expand All @@ -480,10 +473,11 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}
}

private async loadClerkJsEntryChunk() {
private async getClerkJsEntryChunk(): Promise<HeadlessBrowserClerk | BrowserClerk> {
// Hotload bundle
if (!this.Clerk && !__BUILD_DISABLE_RHC__) {
if (!this.options.Clerk && !__BUILD_DISABLE_RHC__) {
// the UMD script sets the global.Clerk instance
// we do not want to await here as we
await loadClerkJsScript({
...this.options,
publishableKey: this.#publishableKey,
Expand All @@ -494,25 +488,37 @@ export class IsomorphicClerk implements IsomorphicLoadedClerk {
}

// Otherwise, set global.Clerk to the bundled ctor or instance
if (this.Clerk) {
global.Clerk = isConstructor<BrowserClerkConstructor | HeadlessBrowserClerkConstructor>(this.Clerk)
? new this.Clerk(this.#publishableKey, { proxyUrl: this.proxyUrl, domain: this.domain })
: this.Clerk;
if (this.options.Clerk) {
global.Clerk = isConstructor<BrowserClerkConstructor | HeadlessBrowserClerkConstructor>(this.options.Clerk)
? new this.options.Clerk(this.#publishableKey, { proxyUrl: this.proxyUrl, domain: this.domain })
: this.options.Clerk;
}

if (!global.Clerk) {
// TODO @nikos: somehow throw if clerk ui failed to load but it was not headless
throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.');
}

return global.Clerk;
}

private async loadClerkUiEntryChunk() {
private async getClerkUiEntryChunk(): Promise<ClerkUiConstructor> {
if (this.options.clerkUiCtor) {
return this.options.clerkUiCtor;
}

await loadClerkUiScript({
...this.options,
publishableKey: this.#publishableKey,
proxyUrl: this.proxyUrl,
domain: this.domain,
nonce: this.options.nonce,
});

if (!global.__unstable_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}

return global.__unstable_ClerkUiCtor;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/types/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ export type ClerkOptions = ClerkOptionsNavigation &
/**
* Clerk UI entrypoint.
*/
clerkUiCtor?: Promise<ClerkUiConstructor>;
clerkUiCtor?: ClerkUiConstructor | Promise<ClerkUiConstructor>;
/**
* Optional object to style your components. Will only affect [Clerk Components](https://clerk.com/docs/reference/components/overview) and not [Account Portal](https://clerk.com/docs/guides/customizing-clerk/account-portal) pages.
*/
Expand Down
16 changes: 9 additions & 7 deletions packages/vue/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ export const clerkPlugin: Plugin<[PluginOptions]> = {
void (async () => {
try {
const clerkPromise = loadClerkJsScript(options);
const clerkUiCtorPromise = (async () => {
await loadClerkUiScript(options);
if (!window.__unstable_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__unstable_ClerkUiCtor;
})();
const clerkUiCtorPromise = pluginOptions.clerkUiCtor
? Promise.resolve(pluginOptions.clerkUiCtor)
: (async () => {
await loadClerkUiScript(options);
if (!window.__unstable_ClerkUiCtor) {
throw new Error('Failed to download latest Clerk UI. Contact support@clerk.com.');
}
return window.__unstable_ClerkUiCtor;
})();

await clerkPromise;

Expand Down
Loading