Item Registry

The Item Registry tracks all interactive canvas items with unique IDs and metadata.

Registering Items

Items are automatically registered when created via app.create():

const item = app.create({
  type: 'text',
  content: 'Hello',
  position: [400, 300]
});

// Item has a registry ID
console.log(item.data.registryId); // 'item_1'

Manual Registration

const customItem = new paper.Path.Circle({
  center: [200, 200],
  radius: 50
});

const id = app.itemRegistry.register(customItem, 'circle', {
  source: 'user',
  customProp: 'value'
});

Querying Items

Get All Items

const allItems = app.itemRegistry.getAll();

Get by Type

const textItems = app.itemRegistry.getByType('text');
const circles = app.itemRegistry.getByType('circle');

Get by Source

const userItems = app.itemRegistry.getBySource('user');
const generatorItems = app.itemRegistry.getBySource('generator');
const importedItems = app.itemRegistry.getBySource('import');

Get by ID

const item = app.itemRegistry.getItem('item_5');

Custom Query

const largeItems = app.itemRegistry.query(entry =>
  entry.item.bounds.width > 100
);

Item Properties

Update Properties

app.itemRegistry.updateProperties('item_1', {
  customProp: 'value',
  animationType: 'pulse'
});

Set Name

app.itemRegistry.setName('item_1', 'MainTitle');

// Find by name
const headers = app.itemRegistry.getByName('MainTitle');

Associations

Create relationships between items:

// Add association
app.itemRegistry.addAssociation('item_1', 'item_2', 'orbits');
app.itemRegistry.addAssociation('item_1', 'item_3', 'contains');

// Query associations
const orbiting = app.itemRegistry.getAssociations('item_1', 'orbits');
const allRelated = app.itemRegistry.getAssociations('item_1');

// Remove association
app.itemRegistry.removeAssociation('item_1', 'item_2', 'orbits');

Custom Types

Register custom item types:

app.itemRegistry.registerType('customWidget', {
  displayName: 'Custom Widget',
  description: 'A custom interactive widget',
  category: 'custom',
  properties: {
    size: { type: 'number', min: 10, max: 200 },
    color: { type: 'color' }
  }
});

Utility Methods

// Check existence
if (app.itemRegistry.has('item_5')) { ... }

// Get count
const count = app.itemRegistry.count();

// Remove item
app.itemRegistry.remove('item_5');

// Clear all
app.itemRegistry.clear();

Entry Structure

Each registry entry contains:

{
  id: 'item_1',
  item: paper.Item,       // The Paper.js item
  type: 'text',           // Item type
  source: 'user',         // 'user', 'generator', 'import'
  properties: {},         // Custom properties
  associations: [],       // Related items
  createdAt: 1701234567890
}

Statistics

Get registry statistics:

const stats = app.itemRegistry.getStats();
// {
//   total: 15,
//   byType: { text: 5, circle: 3, star: 2, ... },
//   bySource: { user: 10, generator: 4, import: 1 },
//   byCategory: { content: 5, shapes: 5, generator: 4, imports: 1 }
// }

Built-in Item Types

The registry includes these pre-registered types:

Type Category Key Properties
text content content, fontSize, fontFamily, fontColor
circle shapes radius, fillColor, strokeColor
rectangle shapes width, height, fillColor
star shapes points, radius1, radius2, fillColor
polygon shapes sides, radius, fillColor
ellipse shapes radiusX, radiusY, fillColor
path drawings strokeColor, strokeWidth, strokeCap
arrow connectors lineColor, lineWidth, headStyle, style
svg imports originalSrc
image imports width, height, originalSrc

MCP Integration

When building MCP tools, use the ItemRegistry for:

  1. Item Discovery: Find all items of a type for batch operations
  2. Existence Checks: Verify item exists before relations
  3. Property Access: Read item properties for decision making
// MCP tool example: Get all animated items
function getAnimatedItems() {
  return app.itemRegistry.query(entry =>
    entry.item.data?.animationType !== undefined
  ).map(entry => ({
    id: entry.id,
    type: entry.type,
    animationType: entry.item.data.animationType
  }));
}