Insolitum Developers

Module Lifecycle

Initialization, authentication, runtime, and shutdown phases of an Insolitum Universe module.

Module Lifecycle

Every module goes through distinct phases from load to teardown.

Phase 1: Loading

The Shell renders an <iframe> pointing to your module's deploy_url:

<iframe
  src="https://my-module.vercel.app?org_id=550e8400-e29b-41d4-a716-446655440000"
  style="width: 100%; height: 100%; border: none;"
/>

Your Next.js app boots, loads layout.tsx, and mounts ShellAuthProvider.

Phase 2: Authentication

Module                          Shell
  β”‚                               β”‚
  β”‚  REQUEST_AUTH_SESSION ──────→ β”‚
  β”‚                               β”‚
  β”‚  ←────── AUTH_SESSION         β”‚
  β”‚  { access_token,              β”‚
  β”‚    refresh_token }            β”‚
  β”‚                               β”‚
  β”‚  supabase.auth.setSession()   β”‚
  β”‚                               β”‚
  β”‚  βœ“ Authenticated              β”‚

The ShellAuthProvider handles this automatically:

  1. On mount, reads org_id from URL query parameters
  2. Sends REQUEST_AUTH_SESSION to window.parent via postMessage
  3. Shell responds with AUTH_SESSION containing JWT tokens
  4. Provider calls supabase.auth.setSession() with the tokens
  5. Sets isAuthenticated = true, makes user and organizationId available

Timeout fallback: If no response arrives within 5 seconds, isLoading is set to false to prevent infinite loading states.

Phase 3: Runtime

Once authenticated, your module can:

  • Query data via useModuleApi() β€” all queries are automatically scoped to the current organization
  • Subscribe to events via useNats() β€” real-time telemetry, alerts, and custom events
  • Navigate the Shell via navigateShell() β€” trigger navigation in the parent frame
'use client';
 
import { useShellAuth } from '@/lib/shell-auth';
import { useModuleApi } from '@/hooks/useModuleApi';
import { useNats } from '@/hooks/useNats';
 
export default function Dashboard() {
  const { user, organizationId } = useShellAuth();
  const { query } = useModuleApi();
  const { connected, subscribe } = useNats();
 
  // All three hooks are ready to use
  // query() auto-filters by organization_id
  // subscribe() receives tenant-scoped events
}

Phase 4: Navigation

When the user switches to another module or navigates away:

  1. Shell removes the iframe from DOM
  2. Your module's React tree unmounts
  3. Cleanup functions in useEffect hooks run (Socket.io disconnect, etc.)
  4. Module process stays running on the server (for next load)

Modules should be stateless between sessions. Don't rely on in-memory state persisting across iframe loads. Use Supabase for persistent storage.

Provider Chain

The recommended provider hierarchy for your module's layout.tsx:

<html lang="pl" className="dark">
  <body>
    <ShellAuthProvider>        {/* Auth + organization context */}
      <QueryClientProvider>    {/* React Query (optional) */}
        <ThemeProvider>        {/* Dark/light theme (optional) */}
          {children}
        </ThemeProvider>
      </QueryClientProvider>
    </ShellAuthProvider>
  </body>
</html>

ShellAuthProvider must be the outermost provider since all other hooks depend on the auth context.

On this page