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 >
Optional configuration object Enable event emission for registry operations. When enabled, the registry emits events for registration, unregistration, updates, clearing, and reindexing.
Enable Vue’s shallowReactive for the collection and tickets. Useful for triggering reactive updates when tickets are modified.
Registry instance with collection management methods Read-only view of tickets. Use registry methods to modify.
Number of tickets in the registry
register
(ticket?: Partial<Z>) => E
Register a new ticket. Auto-generates ID if not provided. Value defaults to index if not provided.
Remove a ticket by ID and reindex remaining tickets
onboard
(registrations: Partial<Z>[]) => E[]
Register multiple tickets in a single batched operation
Unregister multiple tickets with optimized reindexing
get
(id: ID) => E | undefined
Retrieve a ticket by ID
upsert
(id: ID, ticket?: Partial<Z>) => E
Update existing ticket or insert new one
browse
(value: E['value']) => ID[] | undefined
Find all ticket IDs with a specific value (reverse lookup)
lookup
(index: number) => ID | undefined
Get ticket ID by index position
seek
(direction?: 'first' | 'last', from?: number, predicate?: (ticket: E) => boolean) => E | undefined
Find first/last ticket, optionally from a starting index with a predicate filter
Get all ticket IDs (cached)
Get all [ID, ticket] pairs (cached)
Remove all tickets from the registry
Rebuild internal index mapping and update all ticket indexes
Execute operations in a batch, deferring cache invalidation and event emission until complete
on
<K extends string>(event: K, cb: EventHandler<E, K>) => void
Listen for registry events (requires events: true option)
off
<K extends string>(event: K, cb: EventHandler<E, K>) => void
Remove event listener
emit
<K extends string>(event: K, data: EventPayload<E, K>) => void
Emit custom event
Clear registry and remove all event listeners
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
// 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:
Emitted when a ticket is registered
Emitted when a ticket is unregistered
Emitted when a ticket is updated via upsert
Emitted when the registry is cleared
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
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