@moonbase.sh/gorilla-engine
v0.3.1
Published
Moonbase.sh licensing for Gorilla Engine plugins, with a finished activation overlay
Downloads
2,885
Readme
@moonbase.sh/gorilla-engine
Moonbase licensing for a Gorilla Engine plugin, on top of
@moonbase.sh/licensing. It is a React component for
Gorilla Engine React: the activation screens in a panel over the plugin's interface, the counterpart of
moonbase-cpp's JUCE module. It runs in the plugin's own JavaScript and draws with Gorilla Engine's native
controls.
Install
npm install @moonbase.sh/gorilla-engineIt is tested with Gorilla Engine React 1.6 and React 19 (which Gorilla Engine React 1.6 needs), built with TypeScript 5 or 6 on Node 18 or later.
Set up
In the project's .ugep, keep MIDI and audio off until the plugin's JavaScript has checked the license, with these
two among its pluginConfig settings:
{
"pluginConfig": {
"audioEnabledOnStartup": false,
"midiEnabledOnStartup": false
}
}Then create the module once, at the top level of the plugin's script, and render its overlay last:
import { createMoonbase, MoonbaseActivation } from '@moonbase.sh/gorilla-engine'
const moonbase = createMoonbase({
endpoint: 'https://your-store.moonbase.sh',
productId: 'your-product',
publicKey: MOONBASE_PUBLIC_KEY,
appVersion: '1.2.0',
ui: {
manufacturerName: 'Helio Audio',
logo: 'images/logo.png',
fonts: { regular: 'fonts/Inter-Regular.otf', medium: 'fonts/Inter-Medium.otf', semibold: 'fonts/Inter-SemiBold.otf' },
},
})
moonbase.start()
function App() {
return (
<geLabel width={920} height={590}>
<PluginUI />
<MoonbaseActivation moonbase={moonbase} width={920} height={590} />
</geLabel>
)
}npx @moonbase.sh/gorilla-engine doctor checks the project before you build it: the startup settings, that
appVersion matches the project's version, and that the fonts and logo are among its assets. It reads files and
nothing else, and shows each fix as a diff for you to apply.
Render MoonbaseActivation last, so it lies over the rest. While the plugin has no license it comes up by itself,
covers the interface, takes every click, and cannot be closed; once licensed it gets a close button, and
moonbase.present() brings it back (on a screen: license, update, offline or addons). It takes the same ui
options as @moonbase.sh/electron, except that logo is an image among the plugin's assets and fonts are the
plugin's .otf assets, since Gorilla Engine draws with the system's font otherwise. Set appVersion to the
plugin's version, as Gorilla Engine has no version of its own to read.
The overlay moves as the other Moonbase UIs do: it fades in and out, its panel resizes to each screen, and an
activation ends on a check that draws itself. reduceMotion: true turns that off. Only the look waits: the license,
and the plugin's MIDI and audio with it, change at once.
Lifecycle
The module lives as long as the plugin instance whose script created it. Closing the plugin's window leaves it
watching the license, with MIDI and audio as they were. Gorilla Engine tells a script nothing when its plugin is
unloaded, so there is nothing to dispose: create it at the top level, not in a component, where React would make it
again on every mount. await moonbase.ready() resolves with the license state once the stored license is checked.
moonbase.dispose() is for tests, and for a development reload that runs the script again: it stops watching and
stops telling the overlay anything, and a disposed instance can't start again, so create a new one.
MIDI and audio
The module turns the plugin's MIDI and audio off when it starts, on once the stored license checks out (a license or
a trial), and off again whenever it is lost, through GorillaEngine.getPluginMM and getPluginAE. The project's
startup settings above cover the moment before the script runs, which JavaScript can't. If Gorilla Engine doesn't
offer those calls, the module says so through onError rather than claim the plugin is locked. Pass
lockAudioAndMidi: false to handle it yourself. To gate parts of the interface, read the state with
useMoonbaseState(moonbase), or check moonbase.isLicensed() and moonbase.hasSubProduct(id).
Instances and storage
Every instance of the plugin, in any number of hosts, shares the license, kept by default in the manufacturer's
folder: ~/Library/Application Support/<manufacturer>/<plugin>/license.mb on macOS and
%APPDATA%\<manufacturer>\<plugin>\license.mb on Windows. Activating in one unlocks the others within a few seconds,
and deactivating locks them. Moonbase's mark for the overlay's footer is written beside it, as moonbase-mark.png and
[email protected], and the overlay's icons into moonbase-icons, since Gorilla Engine draws images from files only.
The folder is named after the plugin as it was built, so renaming the plugin would lose its customers' licenses.
storage: { manufacturer, plugin } names the folder for good instead, and previousLicenseFiles takes the license
from where an earlier version kept it:
const moonbase = createMoonbase({
// ...
storage: { manufacturer: 'Helio Audio', plugin: 'Solstice' },
previousLicenseFiles: [path.join(os.homedir(), 'Library/Application Support/Helio Audio/Solstice 1/license.mb')],
})A previous license is copied over only when the plugin has none of its own, and checked like any stored license, so
it has to be for the same product and this device. Without Gorilla Engine, as in a test, there are no names to go by,
and the module asks for storage or licenseFile rather than pick a folder another plugin could share.
The host
The browser opens through GorillaEngine.openURLinBrowser, the machine and license files for offline activation go
through Gorilla Engine's file dialogs, and the clipboard and file manager are the system's. Replace any of these with
host, for tests or a host of your own: openUrl, copyText, chooseFile, reveal, downloadsFolder,
setAudioAndMidi and onFocusChange. Every link the module opens goes through the same openUrl.
Errors and support
Whatever the overlay or the host can't do, such as open the browser or copy a link, goes to onError with what was
being done and why, and to a warning in the log by default. The customer sees the reason where it matters to them.
moonbase.diagnostics() gives a report to paste into a support request: the module and SDK versions, where the
license is kept, what the host can do and whether MIDI and audio are on. It has no license, links, names, emails or
device identity in it.
ActivationError, MoonbaseError, the state types and the logger type come from this package too, so the plugin
needs nothing else installed to handle them.
Every method of ActivationController is
on moonbase too.
License: MIT
