Last active
May 9, 2025 18:13
-
-
Save DennisKraaijeveld/18cdc4d44015b1d957c49322ca7abc5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function AppWithProviders() { | |
const data = useLoaderData<typeof loader>() | |
const [zeroEngine, setZeroEngine] = useState<Zero<Schema> | null>(null) // Initialize with null | |
const didPreloadRef = useRef(false) // For one-time preload | |
const userId = data.user?.id ?? 'anon-user' | |
const currentJwtFromLoader = useMemo( | |
() => data.userJWT ?? undefined, | |
[data.userJWT], | |
) | |
// Store the latest JWT in a ref so the auth callback can always access the freshest one | |
const latestJwtRef = useRef(currentJwtFromLoader) | |
useEffect(() => { | |
latestJwtRef.current = currentJwtFromLoader | |
}, [currentJwtFromLoader]) | |
useEffect(() => { | |
const getLatestJwt = async ( | |
error?: 'invalid-token', | |
) => { | |
if (error) { | |
// TODO: Clear JWT here and revalidate | |
} | |
return latestJwtRef.current | |
} | |
const z = new Zero({ | |
logLevel: 'info', | |
server: ENV.ZERO_SERVER, | |
userID: userId, | |
auth: getLatestJwt, // This callback now uses the ref | |
schema, | |
kvStore: 'idb', | |
}) | |
setZeroEngine(z) | |
didPreloadRef.current = false // Reset preload flag if engine re-initializes | |
return () => { | |
console.log('Effect Cleanup: Destroying Zero Engine for user:', userId) | |
void z.close() | |
} | |
}, [userId]) // Re-run if userId or the initial JWT changes | |
useEffect(() => { | |
if (zeroEngine && !didPreloadRef.current) { | |
didPreloadRef.current = true // Mark as preloaded | |
zeroEngine.query.Contact.preload({ ttl: 'forever' }) | |
zeroEngine.query.Website.preload({ ttl: 'forever' }) | |
} | |
}, [zeroEngine]) | |
if (!zeroEngine) { | |
// Render a loading state or null while the engine is initializing. | |
return ( | |
<div className="app-loading-skeleton">Initializing App...</div> | |
) | |
} | |
return ( | |
<ZeroProvider zero={zeroEngine}> | |
<App /> | |
</ZeroProvider> | |
) | |
} | |
// And then in a route we will use the useQuery hook and wrap the component which is using this in ClientOnly | |
import { ClientOnly } from 'remix-utils/client-only' | |
<ClientOnly>{() => <ContactWidget />}</ClientOnly> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment