Primitives.org.ai

Verbs

Action definitions with automatic conjugation

Verbs define actions with full grammatical conjugation support. Every verb includes imperative, present, gerund, and past participle forms that are automatically derived.

What is a Verb?

A Verb defines an action type with all its grammatical forms:

interface Verb {
  name: string        // 'create', 'publish'
  action: string      // 'create' (imperative/base)
  act: string         // 'creates' (3rd person singular)
  activity: string    // 'creating' (present participle/gerund)
  event: string       // 'created' (past participle)
  reverseBy?: string  // 'createdBy' (actor reference)
  reverseAt?: string  // 'createdAt' (timestamp reference)
  reverseIn?: string  // 'createdIn' (location reference)
  inverse?: string    // 'delete' (opposite action)
  description?: string
  createdAt: Date
}

Linguistic Derivation

Verbs are automatically conjugated from the base form:

import { deriveVerb } from 'digital-objects'

deriveVerb('create')
// {
//   action: 'create',
//   act: 'creates',
//   activity: 'creating',
//   event: 'created',
//   reverseBy: 'createdBy',
//   reverseAt: 'createdAt',
//   reverseIn: 'createdIn'
// }

deriveVerb('publish')
// {
//   action: 'publish',
//   act: 'publishes',
//   activity: 'publishing',
//   event: 'published',
//   reverseBy: 'publishedBy',
//   reverseAt: 'publishedAt',
//   reverseIn: 'publishedIn'
// }

Conjugation Rules

The conjugation engine handles regular and irregular verbs:

FormRuleExample
3rd Person+s, +es, +iescreates, publishes, carries
Gerund+ing, drop ecreating, publishing, running
Past+ed, +d, +iedcreated, published, carried
// Regular verbs
deriveVerb('create')   // creates, creating, created
deriveVerb('update')   // updates, updating, updated
deriveVerb('delete')   // deletes, deleting, deleted

// -es endings
deriveVerb('publish')  // publishes, publishing, published
deriveVerb('watch')    // watches, watching, watched

// -ies endings
deriveVerb('carry')    // carries, carrying, carried
deriveVerb('apply')    // applies, applying, applied

// Doubled consonants
deriveVerb('stop')     // stops, stopping, stopped
deriveVerb('submit')   // submits, submitting, submitted

// Irregular verbs (handled specially)
deriveVerb('write')    // writes, writing, written
deriveVerb('read')     // reads, reading, read
deriveVerb('run')      // runs, running, run
deriveVerb('do')       // does, doing, done

Defining Verbs

Basic Definition

import { MemoryProvider } from 'digital-objects'

const provider = new MemoryProvider()

// Minimal definition - forms are auto-derived
const verb = await provider.defineVerb({ name: 'publish' })
// { name: 'publish', action: 'publish', act: 'publishes', ... }

Custom Forms

Override auto-derived forms for irregular verbs:

// Custom past participle
await provider.defineVerb({
  name: 'write',
  event: 'written',  // Override auto-derived 'writed'
})

// Custom inverse
await provider.defineVerb({
  name: 'publish',
  inverse: 'unpublish',
})

// Custom description
await provider.defineVerb({
  name: 'approve',
  description: 'Grant approval for an item',
})

With Inverse

Define bidirectional actions:

await provider.defineVerb({
  name: 'follow',
  inverse: 'unfollow',
})

await provider.defineVerb({
  name: 'archive',
  inverse: 'unarchive',
})

await provider.defineVerb({
  name: 'publish',
  inverse: 'unpublish',
})

Querying Verbs

Get a Verb

const verb = await provider.getVerb('publish')
if (verb) {
  console.log(verb.action)    // 'publish'
  console.log(verb.act)       // 'publishes'
  console.log(verb.activity)  // 'publishing'
  console.log(verb.event)     // 'published'
}

List All Verbs

const verbs = await provider.listVerbs()
for (const verb of verbs) {
  console.log(`${verb.action}: ${verb.description ?? 'No description'}`)
}

Use Cases

UI Labels

const verb = await provider.getVerb('publish')

// Button labels
const buttonLabel = verb.action           // 'publish'
const confirmLabel = `${verb.action}?`    // 'publish?'

// Status indicators
const inProgress = verb.activity          // 'publishing'
const completed = verb.event              // 'published'

// Notifications
const notification = `Post ${verb.event}!` // 'Post published!'

Form Field Generation

const verb = await provider.getVerb('create')

// Generate timestamp fields
const fields = {
  [verb.reverseAt]: 'datetime',   // createdAt
  [verb.reverseBy]: 'string',     // createdBy
}

Activity Feeds

const actions = await provider.listActions({ verb: 'publish' })
const verb = await provider.getVerb('publish')

for (const action of actions) {
  const actor = await provider.get(action.subject)
  const target = await provider.get(action.object)

  // "Alice published 'Hello World'"
  console.log(`${actor.data.name} ${verb.event} '${target.data.title}'`)
}

Audit Logs

const verb = await provider.getVerb('update')

// Generate audit entry
const audit = {
  action: verb.action,           // 'update'
  actor: userId,
  target: postId,
  timestamp: new Date(),
  field: verb.reverseAt,         // 'updatedAt'
  actorField: verb.reverseBy,    // 'updatedBy'
}

Command/Event Naming

const verbs = await provider.listVerbs()

for (const verb of verbs) {
  // Commands (imperative)
  const command = `${verb.action}Post`     // 'createPost', 'publishPost'

  // Events (past tense)
  const event = `Post${capitalize(verb.event)}`  // 'PostCreated', 'PostPublished'

  // Handlers
  const handler = `handle${capitalize(verb.activity)}`  // 'handleCreating', 'handlePublishing'
}

function capitalize(s: string): string {
  return s.charAt(0).toUpperCase() + s.slice(1)
}

VerbDefinition Type

The input type for defining verbs:

interface VerbDefinition {
  name: string              // Required: base form
  action?: string           // Optional: override imperative
  act?: string              // Optional: override 3rd person
  activity?: string         // Optional: override gerund
  event?: string            // Optional: override past participle
  reverseBy?: string        // Optional: override actor reference
  reverseAt?: string        // Auto-generated from event
  reverseIn?: string        // Optional: override location reference
  inverse?: string          // Optional: opposite action
  description?: string      // Optional: human-readable description
}

Reverse Forms

The reverse forms are used for timestamps and actor tracking:

const verb = await provider.getVerb('create')

// Use in entity schema
const postSchema = {
  title: 'string',
  [verb.reverseAt]: 'datetime',  // createdAt: datetime
  [verb.reverseBy]: 'string',    // createdBy: string
}

// Use in update tracking
const updateVerb = await provider.getVerb('update')
const updatedFields = {
  [updateVerb.reverseAt]: new Date(),  // updatedAt
  [updateVerb.reverseBy]: userId,       // updatedBy
}

Common Verbs

Digital Objects works well with these common action patterns:

CRUD Operations

await provider.defineVerb({ name: 'create', inverse: 'delete' })
await provider.defineVerb({ name: 'update' })
await provider.defineVerb({ name: 'delete', inverse: 'create' })
await provider.defineVerb({ name: 'read' })

State Changes

await provider.defineVerb({ name: 'publish', inverse: 'unpublish' })
await provider.defineVerb({ name: 'archive', inverse: 'unarchive' })
await provider.defineVerb({ name: 'activate', inverse: 'deactivate' })
await provider.defineVerb({ name: 'approve', inverse: 'reject' })

Relationships

await provider.defineVerb({ name: 'follow', inverse: 'unfollow' })
await provider.defineVerb({ name: 'like', inverse: 'unlike' })
await provider.defineVerb({ name: 'subscribe', inverse: 'unsubscribe' })
await provider.defineVerb({ name: 'assign', inverse: 'unassign' })

Workflow

await provider.defineVerb({ name: 'submit' })
await provider.defineVerb({ name: 'review' })
await provider.defineVerb({ name: 'approve', inverse: 'reject' })
await provider.defineVerb({ name: 'complete' })

Best Practices

Naming Conventions

// Good: lowercase, imperative form
await provider.defineVerb({ name: 'create' })
await provider.defineVerb({ name: 'publish' })

// Avoid: past tense
await provider.defineVerb({ name: 'created' })  // Use 'create'

// Avoid: gerund
await provider.defineVerb({ name: 'creating' }) // Use 'create'

// Avoid: nouns
await provider.defineVerb({ name: 'creation' }) // Use 'create'

Define Inverses

// Always define inverse for reversible actions
await provider.defineVerb({
  name: 'publish',
  inverse: 'unpublish',
})

// Helps with undo functionality
const verb = await provider.getVerb('publish')
const undoAction = verb.inverse  // 'unpublish'

Use Descriptions

// Add descriptions for clarity
await provider.defineVerb({
  name: 'promote',
  description: 'Elevate a user to a higher role',
  inverse: 'demote',
})

Next Steps

  • Things - Create entity instances
  • Actions - Perform actions on things
  • Graph - Traverse relationships created by actions
Was this page helpful?

On this page