Plugin API Reference

Complete reference for all hooks, context APIs, command interfaces, and signal systems available to OpenGPEX plugin developers.


Core Hooks

useEditorServices()

The primary hook for accessing editor capabilities within a plugin component.

const { actions, state, services } = useEditorServices();
Property Type Description
actions EditorActions All state mutation methods (atomic, fast, adv, executeCommand)
state EditorState Current immutable state snapshot
services EditorServices Geometry, spatial, engine facades

useEditorState(selector)

Subscribe to a specific state slice with automatic memoization:

// Only re-renders when this specific value changes
const opacity = useEditorState(s =>
  s.frames.byId[frameId]?.layers.byId[layerId]?.opacity
);

const activeFrameId = useEditorState(s => s.activeFrameId);
const interaction = useEditorState(s => s.interaction);

usePluginConfig(defaults)

Access and update plugin-scoped persistent configuration:

const config = usePluginConfig<MyConfig>({ mode: 'normal', size: 10 });

// Read
console.log(config.mode);

// Write (via scoped context)
const { scoped } = useEditorServices();
scoped.updateConfig({ mode: 'advanced' });

useSignal(signalId)

Read a plugin signal value (reactive — triggers re-render on change):

const isActive = useSignal('signal.active_tab');

usePluginResource(path)

Load a static asset bundled with the plugin:

const iconUrl = usePluginResource('assets/icon.png');
// Returns: "/api/plugins/serve?plugin=my-plugin&path=assets/icon.png"

Command Context (scoped)

When a command executes, it receives a context object:

execute: (ctx, payload) => {
  const {
    actions,           // Full EditorActions
    scoped: {
      selfConfig,      // () => current plugin config
      updateConfig,    // (patch) => update plugin config
      getSignal,       // (id) => read signal value
      setSignal,       // (id, value) => write signal value
      pluginUid,       // Current plugin's full UID
    },
  } = ctx;
}

Signal API

Signals are reactive state atoms scoped to a plugin. Other plugins can subscribe to them.

Defining Signals

// In plugin definition
signals: [
  { id: 'signal.active_tab', defaultValue: 'basic' },
  { id: 'signal.preview_mode', defaultValue: false },
],

Reading/Writing

// In commands
const tab = ctx.scoped.getSignal('signal.active_tab');
ctx.scoped.setSignal('signal.active_tab', 'advanced');

// In components
const tab = useSignal('signal.active_tab');

Cross-Plugin Signal Access

// Must use full UID for cross-plugin reads
const value = useSignal('opengpex.drawers.crop.signal.is_active');

EditorActions Quick Reference

Category Methods
Atomic addFrame, updateFrame, removeFrame, addLayers, updateLayer, batchUpdateLayers, removeLayers, updateCamera, setInteraction, updateUI
Fast Track fast.override, fast.commit, fast.latestLayer, fast.latestFrame, fast.latestCamera, fast.isInteracting, fast.setTransient, fast.getTransient
Advanced adv.rotateLayer, adv.flipLayer, adv.physicalCrop, adv.mergeDown, adv.fitToFrame, adv.registerAsset, adv.duplicateLayer, adv.groupLayers
Command Bus executeCommand(uid, payload?)
History history.undo(), history.redo(), history.checkpoint(label?)

Services

Service Purpose Key Methods
GeometryService Coordinate transforms screenToWorld, worldToLocal, getProjectionMatrix
SpatialService Hit-testing, bounds hitTest, getBounds, getVisibleRect
PixelService Engine facade renderToBlob, getPixelColor

Next Steps


Last updated: 2026-06-14