Skip to content

Example Plugins

Jeremiah edited this page Oct 22, 2026 · 1 revision

Example Plugins

This page uses the bundled Mass / m/z Analyzer to explain the working example and distinguishes it from future style-pack descriptions.

The working example

examples/plugins/mass-fragment-demo is a complete, deliberately non-NMR plugin. Its manifest calls it Mass / m/z Analyzer, with ID org.chemdraft.mass.fragment. It demonstrates selection access, analysis storage, host-computed isotope envelopes, and declarative reports without a spectroscopy database.

The desktop bundles this example. It is separate from the official downloadable-plugin catalog. Its current source manifest has version 0.0.0 and apiVersion: "^0.1.0"; that example-package version is not the ChemDraft application version.

Select a molecule, then use Analyze → Analyze Mass / m/z. The command is plugin.massFragment.analyzeSelectedStructure, its panel is panel.massFragment.review, and its analyzer contribution is analyzer.massFragment.forwardAnalysis. On macOS the menu is app-wide; on Windows use the document window's menu.

What it calculates

The plugin's own OpenChemLib calculation supplies molecular formula in Hill notation, monoisotopic mass, average mass, and common ESI ion m/z values. ESI means electrospray ionization; m/z is mass divided by charge number. A neutral structure can be reported with common adducts such as [M+H]⁺ and [M+Na]⁺. An already charged structure instead reports its native ion and net charge, without inventing a neutral precursor.

The isotope envelope comes from the host through chemistry.isotopeEnvelope, gated by chemistry.compute. It carries engine information, truncation policy, and abundance conventions. A missing or declining engine yields an explanation, not an improvised fallback. Preserve those conventions when quoting a result; the shared IsoSpec-based host calculation discloses its carbon-13 abundance convention.

This example illustrates plugin plumbing and explicit method ownership. Do not assume that its OpenChemLib mass values and every number in the core property suite use an identical method. See Analysis and Properties for the core analysis contracts.

Follow the code

File inside the example What to learn
src/manifest.ts Identity, permissions, and command/menu/panel/analyzer contributions
src/register.ts createMassRegistration returns a command-handler map
src/application/analyzeSelectedStructureMass.ts Selection → calculation → analysis record → report
src/massAnalysis.ts Pure mass/adduct calculations and the OpenChemLib boundary
src/composeMassReport.ts Calculation output → PluginPanelReport
src/workerEntry.ts Installable module-worker entry using runPluginWorker
src/index.ts Public exports, excluding the side-effecting worker entry

Its declared permissions are selection.read, analysis.write, chemistry.compute, ui.menu, and ui.panel. It needs neither document.write nor broad document access to analyze the selected snapshot. It writes session analysis records, not page objects.

The mass computation is synchronous once loaded and has no nested worker of its own. The desktop still wraps the plugin in its own worker when Workers are available; test environments without Workers can use the in-process path. This distinction matters because the example README's older “no worker” wording describes the calculation rather than today's desktop execution path.

Build a distributable example

From a prepared developer checkout, the existing packaging commands are:

pnpm plugin:package -- examples/plugins/mass-fragment-demo
pnpm plugin:extract -- examples/plugins/mass-fragment-demo

The first emits an installable ZIP and .zip.sha256 under dist/plugin-packages. The second emits a source archive and checksum under dist/plugins for host developers. Both require committed, clean plugin source, a licence file, and the public SDK import boundary. These Node-based tools are intended for both macOS and Windows; no system ZIP utility is required.

For the example's current version, the installable archive is mass-fragment-demo-0.0.0.zip. The desktop already owns the bundled ID, so do not treat another package with that identity as an unrelated extension. Read the package manager's replacement or duplicate-ID result carefully. For a new plugin, choose its own identity and contribution IDs, as explained in Writing a Plugin.

The style-pack directories

examples/plugins/advanced-style-pack and examples/plugins/journal-style-pack contain README-only descriptions of future original style examples. They have no working plugin manifest or runtime. They are not installable packages, shipped journal presets, or enabled style collections.

Do not infer plugin status from a directory name. Inspect the manifest, command implementation, worker entry, licence, and package output. A description of an intended extension is different from an extension you can install.

Licensing and reuse

The working example is MIT-licensed. ChemDraft's core is Apache-2.0, and the two SDK packages are MIT. Preserve the example's licence and dependency notices when reusing its code. Any new bundled dataset needs its own licence declaration and attribution; a code licence alone does not cover it.

Next

Clone this wiki locally