Architecture

Store Adapters

Connect DevConsole to your authentication and state management systems using built-in adapters or create custom ones.

Adapters allow DevConsole to automatically detect authentication tokens, user data, and application state from your existing systems. The toolkit includes built-in adapters for popular libraries, or you can create custom adapters.

Built-in Adapters

DevConsole includes adapters for the most popular authentication and state management libraries:

Supabase

Automatically detects Supabase auth tokens and user sessions. Perfect for Next.js apps using Supabase.

tsx
import { createSupabaseAdapter, registerStore } from "devconsole-package";
import { createClient } from "@/lib/supabase/client";

const supabase = createClient();
const adapter = createSupabaseAdapter(supabase);
if (adapter) {
  registerStore(adapter);
}

NextAuth.js / Auth.js

Connect to NextAuth.js sessions for automatic token detection.

tsx
import { createNextAuthAdapter, registerStore } from "devconsole-package";
import { useSession } from "next-auth/react";

const { data: session } = useSession();
useEffect(() => {
  if (session) {
    const adapter = createNextAuthAdapter(session);
    registerStore(adapter);
  }
}, [session]);

Clerk

Integrate with Clerk authentication for automatic token management.

tsx
import { createClerkAdapter, registerStore } from "devconsole-package";
import { useAuth } from "@clerk/nextjs";

const { getToken, userId } = useAuth();
useEffect(() => {
  const adapter = createClerkAdapter({ getToken, userId });
  registerStore(adapter);
}, [getToken, userId]);

Firebase Auth

Connect to Firebase Authentication for token and user detection.

tsx
import { createFirebaseAdapter, registerStore } from "devconsole-package";
import { getAuth } from "firebase/auth";

const auth = getAuth();
const adapter = createFirebaseAdapter(auth);
if (adapter) {
  registerStore(adapter);
}

Generic JWT

For custom JWT implementations. Provide a token getter function.

tsx
import { createJWTAdapter, registerStore } from "devconsole-package";

const adapter = createJWTAdapter(
  () => localStorage.getItem('token'),
  () => localStorage.getItem('userId')
);
registerStore(adapter);

LocalStorage

Read from browser localStorage with optional prefix for namespacing.

tsx
import { createLocalStorageAdapter, registerStore } from "devconsole-package";

// With prefix
const adapter = createLocalStorageAdapter('myApp');
registerStore(adapter);

// Without prefix (reads all localStorage)
const adapter2 = createLocalStorageAdapter();
registerStore(adapter2);

React Context

Connect to any React Context for state inspection.

tsx
import { createContextAdapter, registerStore } from "devconsole-package";
import { useContext } from "react";
import { AuthContext } from "./AuthContext";

const authContext = useContext(AuthContext);
useEffect(() => {
  if (authContext) {
    const adapter = createContextAdapter('auth', authContext, {
      token: 'auth.token',
      userId: 'user.id'
    });
    registerStore(adapter);
  }
}, [authContext]);

Zustand

Connect to Zustand stores with optional ID mapping for feature flags.

tsx
import { registerStore, createZustandAdapter } from "devconsole-package";
import { useUserStore } from "./stores/userStore";

// Map toolkit feature flag IDs to your real store field names
const mapping = {
  'ff_ai_memory': 'hasMemoryEnabled',
  'ff_dark_mode': 'ui.darkMode',
  'billing_active': 'subscription.isActive'
};

registerStore(
  createZustandAdapter('MainStore', useUserStore, mapping)
);

When you click a toggle in God Mode, the toolkit will automatically call setState on your real store using the mapped key.

Redux

Connect to Redux stores for state inspection.

tsx
import { createReduxAdapter, registerStore } from "devconsole-package";
import { store } from "./store";

registerStore(createReduxAdapter('ReduxStore', store));

TanStack Query (React Query)

Inspect and manipulate React Query cache.

tsx
import { createReactQueryAdapter, registerStore } from "devconsole-package";
import { QueryClient } from "@tanstack/react-query";

const queryClient = new QueryClient();
registerStore(createReactQueryAdapter('ReactQuery', queryClient));

Custom Adapters

If you need to connect to a system not covered by built-in adapters, you can create a custom adapter by implementing the StoreAdapter interface.

tsx
import { StoreAdapter, registerStore } from "devconsole-package";

const myCustomAdapter: StoreAdapter = {
  getName: () => 'myCustomStore',
  getState: () => {
    // Return current state
    return {
      token: getToken(),
      userId: getUserId()
    };
  },
  subscribe: (callback) => {
    // Subscribe to state changes
    const unsubscribe = myStore.subscribe(() => {
      callback(myStore.getState());
    });
    return unsubscribe;
  },
  setState: (path, value) => {
    // Optional: Allow toolkit to modify state
    myStore.set(path, value);
  },
  metadata: {
    idMap: {},
    description: 'My custom adapter'
  }
};

registerStore(myCustomAdapter);

Auto-Detection

Once registered, adapters automatically provide tokens and user data to the Auth tab and API requests. The toolkit prioritizes adapters in this order:

  1. Supabase adapter (if registered)
  2. Other registered adapters (in registration order)
  3. Manual token entry (fallback)

Tokens from adapters are automatically used in all API requests as Authorization: Bearer <token> headers.