JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 22
  • Score
    100M100P100Q79629F
  • License MIT

Package Exports

  • @geenius/adapters
  • @geenius/adapters/convex
  • @geenius/adapters/convex/api
  • @geenius/adapters/react
  • @geenius/adapters/react-css
  • @geenius/adapters/shared
  • @geenius/adapters/solidjs
  • @geenius/adapters/solidjs-css

Readme

@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

pnpm add @geenius/adapters

Sub-package Exports

import { configureAdapters, createLocalStorageDbAdapter }  from '@geenius/adapters'          // shared (default)
import { AdapterProvider, useDb, useAuthAdapter, useAi }   from '@geenius/adapters/react'     // React hooks
import { AdapterProvider, createDb, createAuth }            from '@geenius/adapters/solidjs'   // SolidJS primitives
import { schema, createConvexAdapter }                      from '@geenius/adapters/convex'    // Convex schema + client helper
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

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)

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), keep the same AdapterProvider API and pass real adapter instances from your own backend integration package. @geenius/adapters provides the contract layer, the shared config helpers, and the resolver registry. It does not bundle production backend adapters itself.

3. Use adapters in components

import { useAuthAdapter, useDb, useAi } from '@geenius/adapters/react'

export function Dashboard() {
  const auth = useAuthAdapter()
  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:

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

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

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', ... }

Error Handling

All adapter methods throw structured GeeniusError instances to map underlying service exceptions to unified error classes (e.g. NotFoundError, UnauthorizedError).

View the Complete Error Handling Guide for how exceptions map to unified errors.


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.

// 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 — © Mehdi Nabhani