@@ -16,9 +16,14 @@ import { getMockLogic } from "./mocks";
1616import { componentRoutes , mintlifyLoader } from "./routes" ;
1717import { setupPopperFix } from "./helpers/util" ;
1818
19- // Cache for loaded module
19+ // ==================== State & Cache ====================
2020let cachedModule : any = null ;
21+ const mountedRoots = new Map < HTMLElement , Root > ( ) ;
22+ let isScanning = false ;
23+ let routeChangeHandler : ( ( ) => void ) | null = null ;
24+ let popperObserver : MutationObserver | null = null ;
2125
26+ // ==================== Helper Functions ====================
2227async function getModule ( ) {
2328 if ( ! cachedModule ) {
2429 cachedModule = await mintlifyLoader ( ) ;
@@ -40,15 +45,9 @@ function WaitForCoreClient({
4045 return < > { children } </ > ;
4146}
4247
43- const wrapperCache : Record < string , React . ComponentType < any > > = { } ;
44-
4548async function getWrapper (
4649 componentName : string
4750) : Promise < React . ComponentType < any > | null > {
48- if ( wrapperCache [ componentName ] ) {
49- return wrapperCache [ componentName ] ;
50- }
51-
5251 const route = componentRoutes [ componentName ] ;
5352 if ( ! route ) return null ;
5453
@@ -68,7 +67,7 @@ async function getWrapper(
6867 < Auth0ComponentProvider
6968 authDetails = { {
7069 skipApiClients : true ,
71- domain : "example.auth0.com" , // Add domain here
70+ domain : "example.auth0.com" ,
7271 } }
7372 themeSettings = { { theme : "default" , mode : "light" } }
7473 >
@@ -82,12 +81,10 @@ async function getWrapper(
8281 ) ;
8382 }
8483
85- wrapperCache [ componentName ] = Wrapper ;
8684 return Wrapper ;
8785}
8886
89- const mountedRoots = new Map < HTMLElement , Root > ( ) ;
90-
87+ // ==================== Mount/Unmount Functions ====================
9188function unmountAll ( ) {
9289 mountedRoots . forEach ( ( root ) => {
9390 root . unmount ( ) ;
@@ -117,8 +114,10 @@ async function mountComponent(
117114 mountedRoots . set ( container , root ) ;
118115}
119116
120- function scanAndMount ( ) {
121- console . log ( "scanAndMount called" ) ;
117+ async function scanAndMount ( ) {
118+ if ( isScanning ) return ;
119+ isScanning = true ;
120+
122121 // Unmount components that are no longer in DOM
123122 mountedRoots . forEach ( ( root , container ) => {
124123 if ( ! document . body . contains ( container ) ) {
@@ -128,49 +127,28 @@ function scanAndMount() {
128127 } ) ;
129128
130129 // Mount new components
131- document
132- . querySelectorAll < HTMLElement > ( "[data-uc-component]" )
133- . forEach ( ( el ) => {
134- const name = el . dataset . ucComponent ;
135- if ( ! name ) return ;
136-
137- let props = { } ;
138- try {
139- props = el . dataset . ucProps ? JSON . parse ( el . dataset . ucProps ) : { } ;
140- } catch ( e ) {
141- console . error ( "Failed to parse props:" , e ) ;
142- }
143-
144- mountComponent ( name , el , props ) ;
145- } ) ;
146- }
147-
148- let routeChangeHandler : ( ( ) => void ) | null = null ;
149- let popperObserver : MutationObserver | null = null ;
150-
151- function main ( ) {
152- overrideHistoryMethods ( ) ;
130+ const elements = document . querySelectorAll < HTMLElement > ( "[data-uc-component]" ) ;
153131
154- // Setup popper fix after DOM is ready
155- if ( document . readyState === 'loading' ) {
156- document . addEventListener ( 'DOMContentLoaded' , ( ) => {
157- popperObserver = setupPopperFix ( ) ;
158- } ) ;
159- } else {
160- popperObserver = setupPopperFix ( ) ;
132+ for ( const el of elements ) {
133+ if ( mountedRoots . has ( el ) ) continue ;
134+
135+ const name = el . dataset . ucComponent ;
136+ if ( ! name ) continue ;
137+
138+ let props = { } ;
139+ try {
140+ props = el . dataset . ucProps ? JSON . parse ( el . dataset . ucProps ) : { } ;
141+ } catch ( e ) {
142+ console . error ( "Failed to parse props:" , e ) ;
143+ }
144+
145+ await mountComponent ( name , el , props ) ;
161146 }
162147
163- // Scan on route change
164- routeChangeHandler = ( ) => {
165- setTimeout ( scanAndMount , 100 ) ;
166- } ;
167- addRouteChangeListener ( routeChangeHandler ) ;
168-
169- // Initial scan
170- scanAndMount ( ) ;
148+ isScanning = false ;
171149}
172150
173- // Cleanup function (useful for HMR or SPA unmount)
151+ // ==================== Lifecycle Functions ====================
174152function cleanup ( ) {
175153 if ( routeChangeHandler ) {
176154 removeRouteChangeListener ( routeChangeHandler ) ;
@@ -183,6 +161,32 @@ function cleanup() {
183161 unmountAll ( ) ;
184162}
185163
164+ function main ( ) {
165+ overrideHistoryMethods ( ) ;
166+
167+ // Setup popper fix
168+ popperObserver = setupPopperFix ( ) ;
169+
170+ // Scan on route change
171+ routeChangeHandler = ( ) => {
172+ setTimeout ( scanAndMount , 200 ) ;
173+ } ;
174+ addRouteChangeListener ( routeChangeHandler ) ;
175+
176+ // Initial scan
177+ if ( document . readyState === 'complete' ) {
178+ setTimeout ( scanAndMount , 200 ) ;
179+ } else {
180+ window . addEventListener ( 'load' , ( ) => setTimeout ( scanAndMount , 200 ) ) ;
181+ }
182+ }
183+
184+ // ==================== Initialize ====================
185+ // Setup cleanup handlers
186+ window . addEventListener ( 'beforeunload' , cleanup ) ;
187+ window . addEventListener ( 'unload' , cleanup ) ;
188+
189+ // Start the application
186190main ( ) ;
187191
188192// Export for external usage
0 commit comments