.do

SDK.do Overview

The unified interface for the .do platform

SDK.do provides a unified interface that gives you access to all platform capabilities through a simple, semantic API. At its core is the $ proxy for building semantic triples and a suite of functions for AI, databases, events, and more.

Overview

SDK.do unifies all platform functionality through these core primitives:

graph TB SDK[SDK.do Core] SDK --> Dollar[$<br/>Semantic Paths] SDK --> DB[db<br/>Database] SDK --> AI[ai<br/>AI Operations] SDK --> Events[Events<br/>on/send/every] SDK --> User[user<br/>Auth & Permissions] SDK --> Decide[decide<br/>AI Decisions] Dollar --> Triples[$.Subject.predicate.Object] DB --> CRUD[CRUD Operations] DB --> Relations[Relationships] DB --> Queries[Query Builder] AI --> Generate[Text Generation] AI --> Chat[Chat Completion] AI --> Embed[Embeddings] AI --> Batch[Batch Processing] Events --> On[on - Subscribe] Events --> Send[send - Publish] Events --> Every[every - Schedule] SDK --> Predicates[Predicates] Predicates --> Temporal[Temporal<br/>after, before, during] Predicates --> Spatial[Spatial<br/>near, within, between] Predicates --> Relational[Relational<br/>of, for, about] SDK --> Integrations[Integrations] Integrations --> Stripe[stripe] Integrations --> GitHub[github] Integrations --> Email[email] Integrations --> API[api]

Core Functions

  • $ - Semantic path builder for $.Subject.predicate.Object patterns
  • db - Database CRUD operations and relationship queries
  • ai - AI text generation, chat, embeddings, and batch processing
  • user - Authentication, sessions, and permissions
  • decide - AI-powered decision making with confidence scoring

Event System

  • on - Event listeners with pattern matching
  • send - Event publishing with semantic paths
  • every - Scheduled tasks with cron-like syntax

Integrations

  • stripe - Payment processing and subscriptions
  • github - Repository automation and issues
  • email - Transactional email delivery
  • api - Generic HTTP client for external APIs

Predicates

  • Temporal - after, before, during, since, until, by, at, on
  • Spatial - near, within, above, below, between, around
  • Relational - of, for, about, concerning, like, as, than

Configuration

  • configure - SDK configuration and initialization

Installation

npm install sdk.do
# or
pnpm add sdk.do

Quick Start

import { $, db, ai, configure } from 'sdk.do'

// Configure SDK with your API key
configure({
  apiUrl: 'https://api.do',
  apiKey: process.env.DO_API_KEY,
})

// Use semantic paths
const path = $.Business.owns.Brand
console.log(String(path)) // Output: "$.Business.owns.Brand"

// Query database - capitalized collection names, promise chaining
db.Businesses.list({
  where: { status: 'active' },
  limit: 10,
}).then((businesses) => {
  // Process businesses
})

// Generate with AI - promise chaining
ai.generate({
  prompt: 'Write a product description',
  model: 'gpt-5',
}).then((result) => {
  // Use result
})

The $ Semantic Proxy

The $ is a JavaScript Proxy that enables semantic triple patterns:

import { $ } from 'sdk.do'

// Build semantic paths
$.Person.worksFor.Organization
$.Order.contains.Product
$.User.created.Account

// Automatic string conversion
String($.Business.owns.Brand) // "$.Business.owns.Brand"

// Use with event system - clean semantic syntax
send.Order.created(orderData)

on.User.updated((data) => {
  console.log('User updated:', data)
})

// Use with database relationships
db.Businesses.related('acme-inc', $.owns, 'brands').then((brands) => {
  // Process brands
})

Learn more: Semantic Patterns

Core Functions

Database Operations

Type-safe CRUD operations with relationship queries:

// List with filters - capitalized collection names
db.Users.list({
  where: { status: 'active' },
  limit: 100,
  sort: '-createdAt',
}).then((users) => {
  // Process users
})

// Get by ID
db.Users.get('user-123').then((user) => {
  // Use user
})

// Create
db.Users.create({
  name: 'Alice',
  email: '[email protected]',
}).then((newUser) => {
  // Use newUser
})

// Update - fire and forget
db.Users.update('user-123', {
  status: 'inactive',
})

// Delete - fire and forget
db.Users.delete('user-123')

// Query relationships
db.Users.related('user-123', $.placed, 'orders').then((orders) => {
  // Process orders
})

Learn more: Database Functions

AI Operations

Access AI capabilities for generation, chat, and embeddings:

// Text generation - promise chaining
ai.generate({
  prompt: 'Write a blog post about TypeScript',
  model: 'gpt-5',
  maxTokens: 1000,
}).then((result) => {
  // Use result
})

// Structured output with schema
ai.generate({
  prompt: 'Extract product info from: ...',
  schema: {
    name: { type: 'string' },
    price: { type: 'number' },
    category: { type: 'string' },
  },
}).then((product) => {
  // Use product
})

// Chat completion
ai.chat({
  messages: [
    { role: 'system', content: 'You are a helpful assistant' },
    { role: 'user', content: 'Hello!' },
  ],
  model: 'gpt-5',
}).then((chat) => {
  // Use chat
})

// Embeddings
ai.embed(['First document', 'Second document']).then((embeddings) => {
  // Use embeddings
})

// Batch processing
ai.batch([
  { type: 'generate', payload: { prompt: 'Write a story' } },
  { type: 'embed', payload: { text: 'Sample text' } },
]).then((results) => {
  // Use results
})

Learn more: AI Functions

Event System

Pub/sub event system with semantic event paths:

// Subscribe to events - clean semantic syntax
on.Order.created((order) => {
  console.log('New order:', order.id)
  send.Email({
    to: order.customerEmail,
    subject: 'Order Confirmation',
  })
})

// Pattern matching with wildcards
on.Order['*']((data) => {
  // Matches Order.created, Order.updated, Order.deleted
  console.log('Any order event:', data)
})

// Send events - fire and forget
send.User.updated({
  userId: 'user-123',
  changes: { name: 'Alice Smith' },
})

// Send with options
send.Order.created(orderData, {
  priority: 'high',
  delay: 5000, // 5 second delay
})

Learn more: Event Functions

Scheduled Tasks

Cron-like scheduling for recurring tasks:

// Every hour
every('0 * * * *', async () => {
  await syncData()
})

// Daily at 9 AM
every('0 9 * * *', async () => {
  await sendDailyReports()
})

// Every 5 minutes
every('*/5 * * * *', async () => {
  await checkStatus()
})

// With options
every(
  '0 0 * * *',
  async () => {
    await cleanupOldRecords()
  },
  {
    timezone: 'America/New_York',
    runImmediately: false,
  }
)

Learn more: Event Functions

User & Authentication

Access current user, session, and permissions:

// Get current user
const currentUser = await user.current()
if (!currentUser) {
  throw new Error('Not authenticated')
}

// Get session
const session = await user.session()
console.log('Session expires:', session.expiresAt)

// Check permissions
const permissions = await user.permissions()
if (!permissions.includes('admin')) {
  throw new Error('Insufficient permissions')
}

Learn more: User Functions

API Client

Make external API calls with automatic authentication:

import { api } from 'sdk.do'

// GET request
const users = await api.get('/users')

// POST request
const newUser = await api.post('/users', {
  name: 'Alice',
  email: '[email protected]',
})

// With custom headers
const data = await api.get('/private', {
  headers: { 'X-Custom': 'value' },
})

// Integration methods
await api.stripe.customers.create({
  email: '[email protected]',
})

Learn more: API Functions

Decision Making

AI-powered decisions with confidence scoring:

// Make intelligent decisions
const decision = await decide({
  question: 'Should we approve this expense?',
  options: ['approve', 'reject', 'request more info'],
  context: {
    amount: 500,
    category: 'software',
    budget: 10000,
  },
})

console.log(decision.choice) // 'approve'
console.log(decision.confidence) // 0.95
console.log(decision.reasoning) // 'Amount is within budget...'

// Content moderation
const moderation = await decide({
  question: 'Is this comment appropriate?',
  options: ['approve', 'flag', 'remove'],
  context: { text: comment.text },
  criteria: ['No hate speech', 'Relevant to discussion', 'Follows community guidelines'],
  minConfidence: 0.8,
})

Learn more: Decision Functions

Predicates

Semantic predicates for natural relationship expressions:

import { after, before, near, within, of, for } from 'sdk.do'

// Temporal predicates
const recentEvents = await db.list('events', {
  where: { startDate: after(lastWeek()) }
})

const upcomingTasks = await db.list('tasks', {
  where: { dueDate: before(nextWeek()) }
})

// Spatial predicates
const nearbyStores = await db.list('stores', {
  where: near(userLocation, 5) // Within 5 miles
})

const localEvents = await db.list('events', {
  where: within(cityBoundary)
})

// Relational predicates
const teamMembers = of(team)
const userTasks = for(user)
const techArticles = about('TypeScript')

Learn more: Predicates

Integrations

Pre-built integrations with popular services:

import { stripe, github, email } from 'sdk.do'

// Stripe - Payment processing
const customer = await stripe.customers.create({
  email: '[email protected]',
  name: 'Alice Smith',
})

const subscription = await stripe.subscriptions.create({
  customer: customer.id,
  items: [{ price: 'price_monthly_premium' }],
})

// GitHub - Repository automation
const issue = await github.issues.create({
  owner: 'company',
  repo: 'project',
  title: 'Bug: Login not working',
  labels: ['bug', 'high-priority'],
})

// Email - Transactional emails
await email.sendTemplate({
  to: '[email protected]',
  templateId: 'welcome-email',
  templateData: {
    name: 'Alice',
    activationLink: 'https://app.com/activate/abc',
  },
})

Learn more: Integrations

Configuration

Configure the SDK with your API credentials and settings:

import { configure } from 'sdk.do'

configure({
  // Required
  apiUrl: 'https://api.do',
  apiKey: process.env.DO_API_KEY,

  // Optional worker URLs
  aiWorkerUrl: 'https://ai.do',
  authWorkerUrl: 'https://auth.do',

  // Optional settings
  debug: true,
  timeout: 30000, // 30 seconds
  retries: 3,
  retryDelay: 1000,
})

Learn more: Configuration

Error Handling

SDK.do uses consistent error handling patterns across all functions:

import { db, ai, user } from 'sdk.do'
import { SDKError } from 'sdk.do'

// Pattern 1: Null returns (no throw)
const currentUser = await user.current()
if (!currentUser) {
  throw new Error('Not authenticated')
}

// Pattern 2: Try-catch for operations
try {
  await db.create('users', userData)
} catch (error) {
  if (error instanceof SDKError) {
    console.error('SDK Error:', error.code, error.message)
  }
  throw error
}

// Pattern 3: Error events
on($.Order.created, async (order) => {
  try {
    await processOrder(order)
  } catch (error) {
    await send($.Order.failed, {
      orderId: order.id,
      error: error.message,
    })
  }
})

TypeScript Support

Full TypeScript support with type inference:

import { $, db, ai, user } from 'sdk.do'
import type { User, GenerateResult } from 'sdk.do'

// Typed database queries
const users: User[] = await db.list('users')

// Typed AI responses
const result: GenerateResult = await ai.generate({
  prompt: 'Write a story',
})

// Typed event handlers
on<OrderCreatedEvent>($.Order.created, async (event) => {
  // event is fully typed
  console.log(event.orderId)
})

Composing Operations

Combine different primitives to build powerful workflows:

// AI + Database + Events
on($.Support.ticket.created, async (ticket) => {
  // Analyze with AI
  const analysis = await ai.generate({
    prompt: `Analyze this support ticket: ${ticket.description}`,
    schema: {
      priority: { type: 'string', enum: ['low', 'medium', 'high', 'urgent'] },
      category: { type: 'string' },
      sentiment: { type: 'string' },
    },
  })

  // Update database
  await db.update('tickets', ticket.id, {
    analysis: analysis.data,
  })

  // Send notification if urgent
  if (analysis.data.priority === 'urgent') {
    await send($.Support.urgent, {
      ticketId: ticket.id,
      priority: 'urgent',
    })
  }
})

// Scheduled data sync
every('0 * * * *', async () => {
  // Get current user
  const currentUser = await user.current()
  if (!currentUser) return

  // Fetch external data
  const externalData = await api.get('https://external-api.com/data')

  // Store in database
  await db.create('synced-data', {
    userId: currentUser.id,
    data: externalData,
    syncedAt: new Date(),
  })

  // Send completion event
  await send($.Data.synced, {
    userId: currentUser.id,
    recordCount: externalData.length,
  })
})

Architecture

SDK.do uses an RPC-first architecture where all operations communicate with specialized Cloudflare Workers:

  • API Worker (api.do) - Database operations, collection management
  • AI Worker (ai.do) - AI generation, chat, embeddings
  • Auth Worker (auth.do) - User authentication, sessions, permissions
  • Pipeline Worker (pipeline.do) - Event pub/sub, scheduling
  • Integration Workers (stripe.do, github.do, email.do) - External integrations

This architecture provides:

  • Scalability - Workers scale automatically
  • Separation of concerns - Each worker handles specific functionality
  • Small bundle size - No direct database dependencies
  • Type safety - Full TypeScript support throughout

Advanced Patterns

Decision-Driven Workflows

Combine AI decisions with events and database operations:

import { $, on, decide, db, send, email } from 'sdk.do'

on($.Support.ticket.created, async (ticket) => {
  // AI-powered routing decision
  const routing = await decide({
    question: 'Which team should handle this ticket?',
    options: ['technical', 'billing', 'sales'],
    context: {
      title: ticket.title,
      description: ticket.description,
      customerTier: ticket.customerTier,
    },
  })

  // AI-powered priority decision
  const priority = await decide({
    question: 'What priority level?',
    options: ['low', 'medium', 'high', 'urgent'],
    context: {
      description: ticket.description,
      customerTier: ticket.customerTier,
    },
  })

  // Update ticket in database
  await db.update('tickets', ticket.id, {
    assignedTeam: routing.choice,
    priority: priority.choice,
    routingReason: routing.reasoning,
    priorityReason: priority.reasoning,
  })

  // Send notifications
  await send($.Ticket.assigned, {
    ticketId: ticket.id,
    team: routing.choice,
    priority: priority.choice,
  })

  // Email customer
  await email.send({
    to: ticket.customerEmail,
    subject: `Ticket #${ticket.id} Received`,
    html: `Your ticket has been assigned to our ${routing.choice} team.`,
  })
})

Temporal + Spatial Queries

Combine temporal and spatial predicates for powerful queries:

import { after, before, near } from 'sdk.do'

// Events this week near user
const relevantEvents = await db.list('events', {
  where: {
    startDate: after(startOfWeek()),
    endDate: before(endOfWeek()),
    location: near(userLocation, 25),
  },
  sort: 'startDate',
})

// Recently opened stores nearby
const newStores = await db.list('stores', {
  where: {
    openedAt: after(lastMonth()),
    location: near(userLocation, 10),
  },
})

Payment Processing Pipeline

Complete payment workflow with Stripe integration:

import { $, on, stripe, email, db, send, decide } from 'sdk.do'

on($.Order.placed, async (order) => {
  const user = await db.get('users', order.userId)

  // Risk assessment decision
  const risk = await decide({
    question: 'What is the fraud risk?',
    options: ['low', 'medium', 'high'],
    context: {
      amount: order.total,
      userHistory: user.orderCount,
      location: order.shippingAddress,
    },
  })

  if (risk.choice === 'high') {
    await send($.Order.flagged, { orderId: order.id, reason: risk.reasoning })
    return
  }

  // Create Stripe payment
  const intent = await stripe.paymentIntents.create({
    amount: Math.round(order.total * 100),
    currency: 'usd',
    customer: user.stripeCustomerId,
    metadata: { orderId: order.id },
  })

  await db.update('orders', order.id, {
    paymentIntentId: intent.id,
    riskLevel: risk.choice,
  })

  await email.send({
    to: user.email,
    subject: 'Complete Your Order',
    html: `<a href="https://app.com/pay/${intent.id}">Pay Now</a>`,
  })
})

// Handle successful payment
on($.Stripe.webhook, async (event) => {
  if (event.type === 'payment_intent.succeeded') {
    const orderId = event.data.object.metadata.orderId
    await send($.Order.paid, { orderId })
  }
})

Automated Content Management

AI-powered content moderation and publishing:

import { $, on, decide, ai, db, github, send } from 'sdk.do'

on($.Content.submitted, async (content) => {
  // Moderate content
  const moderation = await decide({
    question: 'Is this content appropriate?',
    options: ['approve', 'reject', 'review'],
    context: { text: content.body },
    criteria: ['No hate speech', 'Factually accurate', 'Properly formatted'],
    minConfidence: 0.85,
  })

  if (moderation.choice === 'reject') {
    await send($.Content.rejected, {
      contentId: content.id,
      reason: moderation.reasoning,
    })
    return
  }

  // Generate SEO metadata with AI
  const seo = await ai.generate({
    prompt: `Generate SEO metadata for: ${content.title}`,
    schema: {
      metaTitle: { type: 'string' },
      metaDescription: { type: 'string' },
      keywords: { type: 'array', items: { type: 'string' } },
    },
  })

  // Update in database
  await db.update('content', content.id, {
    status: moderation.choice,
    seo: seo.data,
    moderationReason: moderation.reasoning,
  })

  if (moderation.choice === 'approve') {
    // Create GitHub PR for deployment
    await github.pulls.create({
      owner: 'company',
      repo: 'website',
      title: `Publish: ${content.title}`,
      head: `content/${content.id}`,
      base: 'main',
    })

    await send($.Content.approved, { contentId: content.id })
  }
})

Smart Scheduling System

Intelligent task scheduling with temporal predicates:

import { $, every, db, decide, send, after, before } from 'sdk.do'

every('0 * * * *', async () => {
  // Find tasks due in next 2 hours
  const upcoming = await db.list('tasks', {
    where: {
      dueDate: {
        $and: [after(new Date()), before(new Date(Date.now() + 2 * 60 * 60 * 1000))],
      },
      status: 'pending',
    },
  })

  for (const task of upcoming) {
    // Decide if task can be auto-completed
    const decision = await decide({
      question: 'Can this task be auto-completed?',
      options: ['yes', 'no', 'needs-review'],
      context: {
        type: task.type,
        complexity: task.complexity,
        dependencies: task.dependencies,
      },
    })

    if (decision.choice === 'yes') {
      await send($.Task.autoComplete, { taskId: task.id })
    } else {
      await send($.Task.reminderDue, { taskId: task.id })
    }
  }
})