npm package: @geenius/adapters
Description: > The architectural lynchpin of the Geenius ecosystem — standardized adapter **contracts** that make backend services interchangeable with a one-file swap.
Author: Antigravity HQ
Latest version: 0.3.1

# `@geenius/adapters`

> The architectural lynchpin of the Geenius ecosystem — standardized adapter **contracts** that make backend services interchangeable with a one-file swap.

---

## Overview

`@geenius/adapters` defines **standard interfaces** for six infrastructure domains and provides **localStorage mock implementations** for zero-config prototyping. Any frontend component talks exclusively to an adapter interface — never to a database or service directly.

This is what makes "swap Convex for Supabase" a single-file change instead of a months-long rewrite.

### Architecture: Thin Contracts + Domain Packages

`@geenius/adapters` is the **contract layer** — it only defines *what* each service must do (the interfaces) and provides localStorage mocks for fast prototyping. Real provider implementations live in the dedicated domain packages:

| Domain | Interface | Mock (here) | Real Providers (domain package) |
|--------|-----------|-------------|-------------------------------|
| **DB** | `DbAdapter` | `localStorage` | `@geenius/db` → Convex, Supabase, Neon, MongoDB, CloudflareKV, Memory |
| **Auth** | `AuthAdapter` | `localStorage` | `@geenius/auth` → Better Auth, Convex Auth, Clerk, Supabase Auth |
| **Payments** | `PaymentsAdapter` | `localStorage`, noop | `@geenius/payments` → Stripe, LemonSqueezy, Polar |
| **AI** | `AiAdapter` | `localStorage` | `@geenius/ai` → OpenAI, Anthropic, Gemini, Ollama, CF AI Gateway, Vercel AI SDK |
| **File Storage** | `FileStorageAdapter` | `localStorage` | `@geenius/file-storage` → R2, S3, Uploadthing, Supabase Storage, Convex Storage, Minio |
| **Admin** | `AdminAdapter` | `localStorage` | *(localStorage only for now)* |

---

## Installation

```bash
pnpm add @geenius/adapters
```

## Sub-package Exports

```typescript
import { configureAdapters, createLocalStorageDbAdapter }  from '@geenius/adapters'          // shared (default)
import { AdapterProvider, useDb, useAuth, useAi }          from '@geenius/adapters/react'     // React hooks
import { AdapterProvider, createDb, createAuth }            from '@geenius/adapters/solidjs'   // SolidJS primitives
import { adapterTables }                                    from '@geenius/adapters/convex'    // Convex schema
import { AdaptersPage, AdapterCard }                        from '@geenius/adapters/react-css' // Styled React components
import { AdaptersPage, AdapterCard }                        from '@geenius/adapters/solidjs-css' // Styled SolidJS components
```

---

## Quick Start

### 1. Configure adapters at app startup

```typescript
import { configureAdapters } from '@geenius/adapters'

// Call once before rendering
configureAdapters({
  db:       { provider: 'convex' },
  auth:     { provider: 'better-auth' },
  ai:       { provider: 'openai', apiKey: process.env.OPENAI_API_KEY },
  storage:  { provider: 'r2' },
  payments: { provider: 'stripe' },
})
```

### 2. Wrap your app with AdapterProvider (React)

```tsx
import { AdapterProvider } from '@geenius/adapters/react'
import { createLocalStorageDbAdapter, createLocalStorageAuthAdapter } from '@geenius/adapters'

// Pronto tier — zero external deps
export function App() {
  return (
    <AdapterProvider
      adapters={{
        db:   createLocalStorageDbAdapter(),
        auth: createLocalStorageAuthAdapter(),
      }}
      healthCheck
    >
      <Router />
    </AdapterProvider>
  )
}
```

For production (Lancio/Studio), use real providers from the domain packages:

```tsx
import { AdapterProvider } from '@geenius/adapters/react'
import { createConvexDbAdapter } from '@geenius/adapters'    // DB still in adapters
import { createAuthProvider } from '@geenius/auth'            // Real auth provider
import { createPaymentProvider } from '@geenius/payments'     // Real payment provider

export function App() {
  return (
    <AdapterProvider
      adapters={{
        db:       createConvexDbAdapter({ client: convex, functions: myFns }),
        auth:     createAuthProvider({ provider: 'better-auth', baseUrl: '/api/auth' }),
        payments: createPaymentProvider({ provider: 'stripe', apiKey: '...' }),
      }}
      healthCheck
    >
      <Router />
    </AdapterProvider>
  )
}
```

### 3. Use adapters in components

```tsx
import { useAuth, useDb, useAi } from '@geenius/adapters/react'

export function Dashboard() {
  const auth = useAuth()
  const db   = useDb()

  const users = await db.list('users')
  const session = await auth.getSession()
}
```

---

## Prototyping with localStorage (Pronto tier)

Every domain ships a `localStorage` implementation for zero-config prototyping:

```typescript
import {
  createLocalStorageAuthAdapter,
  createLocalStorageDbAdapter,
  createLocalStorageAiAdapter,
  createLocalStorageFileAdapter,
  createLocalStoragePaymentsAdapter,
  createLocalStorageAdminAdapter,
  createNoopPaymentsAdapter,
} from '@geenius/adapters'
```

These adapters persist data in the browser's localStorage with no external dependencies. Upgrade to real adapters by swapping one factory call.

---

## Where are the real providers?

| Domain | Package | Example |
|--------|---------|---------|
| **AI** | `@geenius/ai` | `AIClient`, memory, skills, tool calling, content templates |
| **Auth** | `@geenius/auth` | `AuthProviderAdapter` with MFA, passkeys, API keys, RBAC, session management |
| **Payments** | `@geenius/payments` | `PaymentProviderAdapter` with webhooks, invoices, customer portal, plan sync |
| **File Storage** | `@geenius/file-storage` | R2, S3, Uploadthing, Supabase Storage, Convex Storage, Minio |

These domain packages implement the contracts defined here and extend them with rich, production-grade features.

---

## Tier Gating

```typescript
import { isFeatureAvailable, isPackageAvailable, getUpgradeFeatures } from '@geenius/adapters'

isFeatureAvailable('admin', 'pronto')    // → false
isFeatureAvailable('admin', 'lancio')   // → true
isFeatureAvailable('ai-magic', 'studio') // → true

getUpgradeFeatures('pronto', 'lancio')
// → ['admin', 'payments', 'blog', 'file-storage', 'ai-workflow', 'ai-embeddings']
```

---

## Provider Registry

```typescript
import { PROVIDER_REGISTRY, getProvidersForDomain, getProviderMeta } from '@geenius/adapters'

getProvidersForDomain('ai')
// → [{ id: 'localStorage', tier: 'pronto' }, { id: 'openai', tier: 'lancio' }, ...]

getProviderMeta('payments', 'stripe')
// → { id: 'stripe', name: 'Stripe', domain: 'payments', tier: 'lancio', ... }
```

---

## Adapter Interface Contracts

All interfaces are **async (Promise-based)**, generic, and framework-agnostic. Swapping a provider only requires replacing the adapter factory call — no changes to consumers.

```typescript
// DbAdapter — generic, collection-based
interface DbAdapter {
  create<T>(collection: string, data: Omit<T, 'id'>): Promise<T & { id: string }>
  get<T>(collection: string, id: string): Promise<T | null>
  update<T>(collection: string, id: string, data: Partial<T>): Promise<T | null>
  delete(collection: string, id: string): Promise<boolean>
  list<T>(collection: string, options?: ListOptions): Promise<T[]>
  query<T>(collection: string, filter: QueryFilter): Promise<T[]>
  count(collection: string, filter?: QueryFilter): Promise<number>
}

// AuthAdapter — minimal contract (see @geenius/auth for MFA, passkeys, etc.)
interface AuthAdapter {
  signIn(email: string, password: string): Promise<AuthSession>
  signUp(email: string, password: string, name?: string): Promise<AuthSession>
  signInWithOAuth(provider: OAuthProvider, options?: { redirectUrl?: string }): Promise<{ url: string }>
  signOut(): Promise<void>
  getSession(): Promise<AuthSession | null>
  getUser(): Promise<AuthUser | null>
  updateUser(updates: Partial<Pick<AuthUser, 'name' | 'image'>>): Promise<AuthUser | null>
}

// AiAdapter — minimal contract (see @geenius/ai for memory, skills, tools)
interface AiAdapter {
  chat(messages: ChatMessage[], options?: AiOptions): Promise<ChatResponse>
  complete(prompt: string, options?: AiOptions): Promise<string>
  embed(text: string | string[]): Promise<number[][]>
  stream(messages: ChatMessage[], options?: AiOptions): AsyncIterable<string>
}
```

---

## Tier Availability

| Tier | Description |
|------|-------------|
| **Pronto** | Prototype-ready. localStorage only. Zero external deps. |
| **Lancio** | Production-ready. Real backends via domain packages. |
| **Studio** | Full ecosystem. All Lancio providers + AI Magic, Analytics, Teams, and more. |

---

## License

MIT — © Antigravity HQ