npm package: @openverb/sdk
Description: OpenVerb client SDK
Latest version: 2.0.0-alpha.6

# @openverb/sdk

Client SDK for the OpenVerb Framework with React hooks.

## Installation
```bash
npm install @openverb/sdk
```

For React projects:
```bash
npm install @openverb/sdk react
```

## Quick Start (Vanilla JS)
```typescript
import { OpenVerbClient } from '@openverb/sdk'

const client = new OpenVerbClient({
  baseUrl: '/api/vrb/execute'  // Your API endpoint
})

// Execute a verb
const result = await client.execute(
  'todo.create',
  { title: 'Build amazing apps' }
)

console.log(result)
// {
//   ok: true,
//   result: { id: '123', title: 'Build amazing apps', completed: false }
// }
```

## React Hooks
```tsx
import { useVerb, useVerbMutation } from '@openverb/sdk/react'

function TodoList() {
  // Query hook (auto-fetches on mount)
  const { data, loading, error } = useVerb('todo.list', {})

  // Mutation hook (manual trigger)
  const { execute, loading: creating } = useVerbMutation('todo.create')

  const handleCreate = async () => {
    const result = await execute({ 
      title: 'New todo' 
    })
    
    if (result.ok) {
      console.log('Created:', result.result)
    }
  }

  if (loading) return <div>Loading...</div>
  if (error) return <div>Error: {error}</div>

  return (
    <div>
      <button onClick={handleCreate} disabled={creating}>
        Add Todo
      </button>
      <ul>
        {data?.items.map(todo => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>
    </div>
  )
}
```

## API Reference

### `OpenVerbClient`
```typescript
const client = new OpenVerbClient({
  baseUrl?: string  // Default: '/api/vrb/execute'
})

// Execute a verb
await client.execute(
  verbId: string,
  args: any,
  actor?: Actor,
  context?: Context
)

// Get available verbs
await client.introspect()
```

### `useVerb(verbId, args, options?)`

React hook for querying data.
```typescript
const { data, loading, error, refetch } = useVerb('todo.list', {
  filter: 'active'
})
```

**Options:**
- `enabled?: boolean` - Enable/disable auto-fetch (default: true)
- `refetchInterval?: number` - Auto-refetch interval in ms

### `useVerbMutation(verbId)`

React hook for mutations (create, update, delete).
```typescript
const { execute, loading, error } = useVerbMutation('todo.create')

await execute({ title: 'New todo' })
```

## With Next.js
```tsx
// app/api/vrb/execute/route.ts
import { runtime } from '@/lib/openverb/runtime'

export async function POST(request: Request) {
  const body = await request.json()
  const result = await runtime.execute(body)
  return Response.json(result)
}

// components/TodoList.tsx
'use client'
import { useVerb } from '@openverb/sdk/react'

export function TodoList() {
  const { data } = useVerb('todo.list', {})
  // ...
}
```

## Error Handling
```typescript
const result = await client.execute('todo.create', args)

if (!result.ok) {
  if (result.denied) {
    // Policy denied (e.g., user on free plan)
    console.log('Upgrade required:', result.upsell)
  } else {
    // Execution error
    console.error('Error:', result.error)
  }
}
```

## Related Packages

- [@openverb/runtime](https://www.npmjs.com/package/@openverb/runtime) - Server-side runtime
- [@openverb/policy](https://www.npmjs.com/package/@openverb/policy) - Policy engine
- [@openverb/cli](https://www.npmjs.com/package/@openverb/cli) - CLI tools

## License

MIT