npm package: @skroyc/langgraph-supabase-store
Description: Supabase Store for LangGraph
Author: SkrOYC
Latest version: 0.1.0

# @skroyc/langgraph-supabase-store

This package contains the Supabase implementation of the `BaseStore` for LangGraph. It provides a production-ready store with comprehensive error handling, retry logic, and security features.

## Installation

```bash
npm install @skroyc/langgraph-supabase-store
```

## Setup

Before using the `SupabaseStore`, you need to set up your Supabase project and run the migrations.

1.  **Create a Supabase project**

    If you don't have a Supabase project, create one at [supabase.com](https://supabase.com).

2.  **Run the migrations**

    The `migrations.sql` file contains the necessary SQL to create the `langgraph_store` and `langgraph_store_vectors` tables, as well as the `match_documents` and `upsert_store_item` functions. You can run this file in the Supabase SQL editor.

## Usage

```typescript
import { SupabaseStore } from "@skroyc/langgraph-supabase-store";
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.SUPABASE_URL;
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY;

if (!supabaseUrl || !supabaseAnonKey) {
  throw new Error("Supabase URL and anon key must be provided");
}

const client = createClient(supabaseUrl, supabaseAnonKey);

const store = new SupabaseStore({ client });

// Use the store
await store.put(["test"], "key1", { value: "hello" });
const item = await store.get(["test"], "key1");
console.log(item);
```

## Configuration Options

The `SupabaseStore` accepts several configuration options:

```typescript
const store = new SupabaseStore({
  client, // Required: Supabase client instance
  tableName: "langgraph_store", // Optional: Custom table name
  vectorTableName: "langgraph_store_vectors", // Optional: Custom vector table name
  userId: "user-id", // Optional: User ID for multi-tenancy
  retryConfig: {
    maxRetries: 3, // Optional: Maximum retry attempts (default: 3)
    baseDelay: 1000 // Optional: Base delay in ms (default: 1000)
  }
});
```

## Health Check

You can check the health of the store to verify connectivity:

```typescript
const isHealthy = await store.checkHealth();
console.log(`Store is healthy: ${isHealthy}`);
```

## Vector Search

To use vector search, you need to configure the `SupabaseStore` with an embeddings model.

```typescript
import { SupabaseStore } from "@skroyc/langgraph-supabase-store";
import { createClient } from "@supabase/supabase-js";
import { OpenAIEmbeddings } from "@langchain/openai";

const supabaseUrl = process.env.SUPABASE_URL;
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY;

if (!supabaseUrl || !supabaseAnonKey) {
  throw new Error("Supabase URL and anon key must be provided");
}

const client = createClient(supabaseUrl, supabaseAnonKey);

const store = new SupabaseStore({
  client,
  index: {
    dims: 1536,
    embed: new OpenAIEmbeddings({ modelName: "text-embedding-3-small" }),
  },
});

// Store documents
await store.put(["docs"], "doc1", { text: "Python tutorial" });
await store.put(["docs"], "doc2", { text: "TypeScript guide" });

// Search by similarity
const results = await store.search(["docs"], { query: "python programming" });
console.log(results);
```

## Error Handling

The SupabaseStore provides comprehensive error handling with custom error types:

- `SupabaseStoreError` - Base error class
- `DatabaseOperationError` - Database operation failures
- `NetworkError` - Network connectivity issues
- `AuthorizationError` - Authentication/authorization failures
- `ValidationError` - Input validation failures
- `ResourceNotFoundError` - Resource not found errors

Example error handling:

```typescript
try {
  await store.put(["test"], "key", { value: "data" });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Validation error:", error.message);
  } else if (error instanceof DatabaseOperationError) {
    console.error("Database error:", error.message);
  } else {
    console.error("Unexpected error:", error);
  }
}
```

## Security Features

The SupabaseStore includes built-in security features:

- Input validation and sanitization
- SQL injection prevention
- Retry logic with exponential backoff
- Proper error handling without exposing sensitive information

## TTL and Automated Cleanup

The SupabaseStore supports Time-To-Live (TTL) for automatic expiration of stored items:

```typescript
const store = new SupabaseStore({
  client,
  ttl: {
    defaultTtl: 60, // 60 minutes default TTL
    autoRefresh: true, // Automatically refresh TTL on access
  },
});
```

### Edge Function Cleanup

For production environments, you can deploy a Supabase edge function to handle automated cleanup of expired items. The edge function is located at `supabase/functions/ttl-cleanup/` and can be deployed with:

```bash
supabase functions deploy ttl-cleanup
```

To trigger the cleanup manually:

```typescript
await store.triggerEdgeFunctionCleanup();
```

You can also schedule the cleanup using Supabase's pg_cron or external schedulers.