Skip to content

Plugins

Plugins extend the viewer with self-contained features. They are registered with the PluginManager, receive a PluginContext on load, and clean up on unload.

Authoring a plugin

ts
import type { IPlugin, PluginContext, PluginMetadata, PluginStatus } from "@optellix/xviewr-sdk";

class MyPlugin implements IPlugin {
  readonly metadata: PluginMetadata = {
    name: "my-plugin",
    version: "1.0.0",
    author: "Me",
    description: "Example",
    serviceDependencies: ["camera", "selection"],
  };

  private ctx!: PluginContext;

  async load(context: PluginContext): Promise<void> {
    this.ctx = context;
  }

  async init(context: PluginContext): Promise<void> {
    // Wire up listeners, scene objects, services.
    context.eventBus.on("selection:object-selected", ({ object }) => {
      // ...
    });
  }

  async destroy(): Promise<void> {
    // Remove listeners, dispose GPU resources, detach DOM.
  }
}

await viewer.loadPlugin(new MyPlugin());

load runs first, then init. destroy runs on unload or viewer dispose. activate/deactivate/unload are optional hooks used by plugins that toggle interaction modes.

IPlugin

MemberTypeRequiredDescription
metadataPluginMetadatayesIdentity and dependency declaration.
load(context)Promise<void>yesFirst call. Receive the context.
init(context)Promise<void>yesInitialize state, listeners, scene contributions.
destroy()Promise<void>yesTear down everything created in load/init.
getStatus()PluginStatusnoReport current lifecycle status.
activate()Promise<void>noEnter active interaction mode.
deactivate()Promise<void>noExit active mode. Free transient resources.
unload()Promise<void>noOptional pre-destroy hook.
getCommands()CommandDefinition[]noDeclare commands the plugin contributes to the command runner. Registered on activate, removed on deactivate.

PluginMetadata

FieldTypeDescription
namestringUnique plugin identifier.
versionstringSemver string.
authorstringAuthor name.
descriptionstringShort description.
serviceDependenciesstring[]Services required for the plugin to load.
pluginDependenciesstring[]Plugins required to be loaded first.
optionalServiceDependenciesstring[]Services used if present.
optionalPluginDependenciesstring[]Plugins used if present.
homepagestringOptional URL.

PluginContext

Passed to load and init.

FieldTypeDescription
viewerIViewerThe viewer.
eventBusIEventBusShared event bus.
serviceRegistryIServiceRegistryLookup services.
configManagerIConfigManagerRead and watch config.
apiRecord<string, unknown>Optional per-plugin API namespace.

PluginStatus

ts
enum PluginStatus {
  Unregistered = "unregistered",
  Registered = "registered",
  Loading = "loading",
  Loaded = "loaded",
  Initialized = "initialized",
  Activating = "activating",
  Active = "active",
  Deactivating = "deactivating",
  Deactivated = "deactivated",
  Unloading = "unloading",
  Unloaded = "unloaded",
  Destroyed = "destroyed",
  Error = "error",
}

IPluginManager

Accessible as viewer.pluginManager.

MethodReturnsDescription
register(plugin)voidRegister a plugin instance.
unregister(name)booleanRemove a registered plugin.
load(name, options?)Promise<void>Load and initialize. skipIfUnlicensed swallows license failures.
unload(name)Promise<void>Destroy and remove.
getPlugin(name)IPlugin | nullLookup by name.
getStatus(name)PluginStatusCurrent status.
listPlugins()PluginMetadata[]Metadata for every registered plugin.
unloadAll()Promise<void>Unload everything.
loadPluginsFromConfig(configs)Promise<void>Load plugins from XViewerConfig.plugins.

Plugin lifecycle events on the event bus: plugin:registered, plugin:loading, plugin:loaded, plugin:activated, plugin:deactivated, plugin:unloaded, plugin:error.

Resource discipline

Every THREE.Geometry, Material, and Texture created by a plugin must be .dispose()d on destroy. Three.js does not garbage-collect GPU resources. Remove every event listener registered in init. Detach any DOM elements added to viewer.container.

XViewr SDK and xConvert CLI documentation.