Skip to main content

Overview

The createRegistry composable provides a foundational system for managing collections of items (tickets) with unique ID-based access, index-based ordering, value-based reverse lookup, and automatic reindexing. It serves as the base for many other composables including createSelection, createSingle, createGroup, and createStep.

Signature

function createRegistry<
  Z extends RegistryTicketInput = RegistryTicketInput,
  E extends RegistryTicket & Z = RegistryTicket & Z
>(options?: RegistryOptions): RegistryContext<Z, E>
options
RegistryOptions
Optional configuration object
RegistryContext
object
Registry instance with collection management methods

Usage

Basic Registration

import { createRegistry } from '@vuetify/v0'

const registry = createRegistry()

// Register with auto-generated ID
const ticket1 = registry.register()
// { id: 'auto-id-123', index: 0, value: 0, valueIsIndex: true }

// Register with custom ID and value
const ticket2 = registry.register({ id: 'user-1', value: { name: 'John' } })
// { id: 'user-1', index: 1, value: { name: 'John' }, valueIsIndex: false }

Batch Operations

const tickets = registry.onboard([
  { id: 'item-1', value: 'Apple' },
  { id: 'item-2', value: 'Banana' },
  { id: 'item-3', value: 'Cherry' },
])

console.log(registry.size) // 5

Value Lookups

// Browse by value (reverse lookup)
const ids = registry.browse('Apple') // ['item-1']

// Lookup by index
const id = registry.lookup(0) // Returns first ticket's ID

// Get by ID
const ticket = registry.get('item-1')

Seeking

// Find first ticket
const first = registry.seek('first')

// Find last ticket
const last = registry.seek('last')

// Find with predicate
const found = registry.seek('first', undefined, 
  ticket => ticket.value.startsWith('B')
) // Finds 'Banana'

Event Emission

const registry = createRegistry({ events: true })

registry.on('register:ticket', (ticket) => {
  console.log('Ticket registered:', ticket)
})

registry.on('unregister:ticket', (ticket) => {
  console.log('Ticket unregistered:', ticket)
})

registry.register({ id: 'test' })
// Console: Ticket registered: { id: 'test', ... }

Reactive Collections

import { watchEffect } from 'vue'

const registry = createRegistry({ reactive: true })

watchEffect(() => {
  console.log('Size changed:', registry.collection.size)
})

registry.register({ id: 'item-1' }) // Triggers watcher

Batch for Performance

// Defer cache invalidation and events until batch completes
const result = registry.batch(() => {
  registry.register({ id: 'a' })
  registry.register({ id: 'b' })
  registry.register({ id: 'c' })
  return registry.size
})

console.log(result) // 3

Events

When events: true is set:
register:ticket
(ticket: E) => void
Emitted when a ticket is registered
unregister:ticket
(ticket: E) => void
Emitted when a ticket is unregistered
update:ticket
(ticket: E) => void
Emitted when a ticket is updated via upsert
clear:registry
() => void
Emitted when the registry is cleared
reindex:registry
() => void
Emitted when the registry is reindexed

Context Pattern

import { createRegistryContext } from '@vuetify/v0'

// Create context trinity
export const [useItems, provideItems, items] = createRegistryContext()

// In parent component
provideItems()

// In child component
const items = useItems()
items.register({ id: 'item-1', value: 'Value 1' })

Type Safety

interface CustomTicket extends RegistryTicketInput {
  label: string
  priority: number
}

const registry = createRegistry<CustomTicket>()

const ticket = registry.register({
  label: 'Task 1',
  priority: 5
})

// ticket.label is typed as string
// ticket.priority is typed as number

Performance

  • keys/values/entries: Cached on first call, O(1) subsequent calls until invalidation
  • get/has: O(1) Map lookups
  • browse: O(1) value-to-IDs lookup
  • lookup: O(1) index-to-ID lookup
  • reindex: O(n) full reindexing, or O(k) partial from dirty index

See Also

Build docs developers (and LLMs) love