-
Notifications
You must be signed in to change notification settings - Fork 326
/
Copy pathcreate-clerk-instance.ts
88 lines (74 loc) · 3.02 KB
/
create-clerk-instance.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { loadClerkJsScript, setClerkJsLoadingErrorPackageName } from '@clerk/shared/loadClerkJsScript';
import type { ClerkOptions } from '@clerk/types';
import { $clerkStore } from '../stores/external';
import { $clerk, $csrState } from '../stores/internal';
import type { AstroClerkCreateInstanceParams, AstroClerkUpdateOptions } from '../types';
import { invokeClerkAstroJSFunctions } from './invoke-clerk-astro-js-functions';
import { mountAllClerkAstroJSComponents } from './mount-clerk-astro-js-components';
import { runOnce } from './run-once';
let initOptions: ClerkOptions | undefined;
setClerkJsLoadingErrorPackageName(PACKAGE_NAME);
function createNavigationHandler(
windowNav: typeof window.history.pushState | typeof window.history.replaceState,
): Exclude<ClerkOptions['routerPush'], undefined> | Exclude<ClerkOptions['routerReplace'], undefined> {
return (to, opts) => {
if (opts?.__internal_metadata?.navigationType === 'internal') {
windowNav(history.state, '', to);
} else {
opts?.windowNavigate(to);
}
};
}
/**
* Prevents firing clerk.load() multiple times
*/
const createClerkInstance = runOnce(createClerkInstanceInternal);
async function createClerkInstanceInternal(options?: AstroClerkCreateInstanceParams) {
let clerkJSInstance = window.Clerk;
if (!clerkJSInstance) {
await loadClerkJsScript(options);
if (!window.Clerk) {
throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.');
}
clerkJSInstance = window.Clerk;
}
if (!$clerk.get()) {
$clerk.set(clerkJSInstance);
}
initOptions = {
routerPush: createNavigationHandler(window.history.pushState.bind(window.history)),
routerReplace: createNavigationHandler(window.history.replaceState.bind(window.history)),
...options,
};
return clerkJSInstance
.load(initOptions)
.then(() => {
$csrState.setKey('isLoaded', true);
// Notify subscribers that $clerkStore has been loaded.
// We're doing this because nanostores uses `===` for equality
// and just by setting the value to `window.Clerk` again won't trigger an update.
// We notify only once as this store is for advanced users.
$clerkStore.notify();
mountAllClerkAstroJSComponents();
invokeClerkAstroJSFunctions();
clerkJSInstance.addListener(payload => {
$csrState.setKey('client', payload.client);
$csrState.setKey('user', payload.user);
$csrState.setKey('session', payload.session);
$csrState.setKey('organization', payload.organization);
});
})
.catch(() => {});
}
function updateClerkOptions(options: AstroClerkUpdateOptions) {
const clerk = $clerk.get();
if (!clerk) {
throw new Error('Missing clerk instance');
}
// `__unstable__updateProps` is not exposed as public API from `@clerk/types`
void (clerk as any).__unstable__updateProps({
options: { ...initOptions, ...options },
appearance: { ...initOptions?.appearance, ...options.appearance },
});
}
export { createClerkInstance, updateClerkOptions };