Classes
Import these from @grafloria/renderer.
Classes
DisposableStore
A bag of disposers with a single dispose(). Extensions accumulate their
registrations here so the host can tear the whole extension down atomically.
Disposal runs in REVERSE registration order (like a stack unwind) and is failure-tolerant: one throwing disposer must not strand the rest, or a single bad extension would leak every registry behind it.
tsclass DisposableStore implements Disposable
Methods
add(disposer: Disposer): Disposer— Track a disposer. If the store is ALREADY disposed, run it immediately.get size(): number— How many live registrations this store holds (tests assert on this).get isDisposed(): booleandispose(): void
ExtensionHost
tsclass ExtensionHost
Methods
constructor(options: ExtensionHostOptions)get engine(): DiagramEngine— The engine this host is bound to (hosts, not extensions, may ask).register<C extends CapabilityName>(extension: Extension<C>): Disposer— Register and ACTIVATE an extension.
Throws — deliberately, and before any side effect — when the manifest is malformed, the id is taken, the engine range excludes this host, or the extension asks for a capability this host cannot grant. A plugin that half- loads is worse than one that refuses to.
registerLazy<C extends CapabilityName>( manifest: ExtensionManifest<C>, load: LazyExtension<C> ): Disposer— Register WITHOUT loading. The factory is not called untilactivate(id), so a 500 KB plugin costs nothing until something needs it.
The manifest is supplied up front precisely so the host can answer "what shapes/routers exist?" and validate compatibility WITHOUT paying the import.
async activate(id: string): Promise<void>— Activate a lazily-registered extension (imports it on first call).dispose(id: string): void— Tear one extension down. Every registration it made is undone.disposeAll(): void— Tear everything down. The host is unusable afterwards.has(id: string): booleanget(id: string): RegisteredExtension | undefinedlist(): RegisteredExtension[]— Everything registered, loaded or not.
RegistryScope
One diagram's private overlay over the process-global registries.
An entry here SHADOWS the global one of the same name for reads taken inside
this scope; a name absent here falls through. That layering is what lets a
diagram override a built-in (or an app-wide registerShape() at import time)
for itself alone, without mutating what anybody else sees.
tsclass RegistryScope
Methods
table<V>(name: string): Map<string, V>— The named table, created on demand. Use for WRITES.peek<V>(name: string): Map<string, V> | undefined— The named table if it exists, WITHOUT creating it. Use for READS.isEmpty(): boolean— True when this diagram has contributed nothing — i.e. it is pure fall-through.clear(): void— Drop every contribution (instance teardown).
Was this page helpful?