Skip to main content

Hub Utilities

Hub provides several utility classes in Utils/ for environment management, worker threads, PDF generation, notifications, and more.

EnvironmentHelper​

Utils/EnvironmentHelper.ts — Singleton connector that manages application configuration, runtime state, and PDF printing.

Key Responsibilities​

AreaMethodsPurpose
App SettingsgetAppSettings(), SyncAppSettings(), seedAppSettings()Read/write the AppSettings singleton (fixed _id, see Database Models). Syncs version, build timestamp, and feature flags. Solution projects override the protected seedAppSettings($settings) hook to fill their own defaults from the configuration when the document is created for the first time, instead of overriding getAppSettings()
ConfigurationSyncConfigsData(), ResetConfigsCache()Synchronizes JSONP configuration files with ConfigEntry DB storage; drops the runtime cache of the parsed configurations
PDF PrintingInitPDFPrint(), PrintPDF()Initialize Puppeteer browser, render URLs/HTML to PDF
Event LoopgetEventLoopState()Returns event loop health metrics
Release NotesgetReleaseNotes(), getWhatsNew()Load release notes and "what's new" content from JSONP files
FAQgetFAQ()Load FAQ content from JSONP configuration
FeedbackFeedback()Submit user feedback via MailEngine
RuntimegetEnvironmentInfo()Server environment details (Node version, OS, memory, uptime)

RuntimeHandler Symbol​

EnvironmentHelper is registered as the *.RuntimeHandler symbol in the connectors register, making it accessible via the standard RuntimeHandler connector symbol from any project.

Configuration Cache​

Every configuration registered in getConfigsSource() (release notes, FAQ, cookie bar, legal documents) is read from ConfigEntry and parsed once, then kept in a cache shared by the whole runtime. That matters because the same helper is reached through two different objects: HTTP resolvers, cron tasks and mails use the singleton from Loader.getInstance().getEnvironmentHelper(), while every LCP call runs on the connector instance the register keeps per auth token, one per session.

FactConsequence
A configuration deployed while the application runs is not picked up on its ownPress Reset configs cache in the dashboard Registry tab, or restart the application. The method returns the number of dropped configurations, which the button reports in a toast
The cache is shared by all readersOne reset covers the SPA of every logged-in session, the standalone pages and the PDF exports at once
Cached DAO objects are handed out by referenceTreat them as read-only — mutating one corrupts the configuration for the whole runtime
The cache lives per V8 isolateA worker thread keeps its own copy, so a job that reads configurations must stay on the main thread
Configuration reads are deliberately identity-freeA requester-scoped read must not use this cache — the content is cached per configuration type only

Threads​

Utils/Threads.ts — Worker thread management using Node.js worker_threads.

Static Methods​

MethodPurpose
IsMainThread()Check if running in the main thread
OnMessage($callback)Register message handler in worker thread
Send($data)Send message from worker to parent
getData()Get workerData passed during thread creation
Sleep($time)Async sleep utility (default 1000ms)

Instance Methods​

const thread = new Threads();
thread.Create({
binClone : true, // clone bin/ directory for worker
initData : { isCron: true }, // workerData passed to thread
scriptPath: "" // custom entry script (default: same as main)
});
thread.OnMessage(($data) => { /* handle response */ });
thread.Send("message to worker");

Hub Usage​

The Loader creates a cron worker thread during onDbPrepared() (if authManagerWorker.enabled). This thread runs:

  • Activation check — Periodic user account expiration check (activationCheck.interval)
  • Cleanup service — Expired reset token cleanup (cleanUpService.interval)

PuppeteerHandler​

Utils/PuppeteerHandler.ts — Headless Chrome/Chromium controller for PDF generation and screenshots.

Key Methods​

MethodPurpose
Export($input, $options?)Render URL or HTML to PDF/screenshot
setConfig($value)Override Puppeteer configuration at runtime

Export Options​

await handler.Export({
url : "https://example.com/report", // URL to render (or use html)
html : "<html>...</html>", // Direct HTML content
format : "pdf", // "pdf" or "screenshot"
cookies: [], // Inject cookies for auth
verbose: true // Log progress
});

Configuration​

puppeteer: {
enabled : true,
urlThreads : 2, // concurrent browser pages
maxWaitTime : 30000, // max render wait (ms)
proxy : { enabled: false, location: "" },
chromeBuildId: "", // specific Chrome version
cacheDir : "" // Chrome binary cache directory
}

Requires puppeteer-core and oidis/oidis-chromium-base packages.

PushNotifications​

Utils/PushNotifications.ts — In-memory broadcast of live events to every open GUI connection (no external service).

Created in the Loader constructor (server-side only) and reached through Loader.getInstance().PushNotifications().

  • Push({type, data}) calls every registered listener; there is no targeting (by user, group or organization) and nothing is stored — a client that is not connected at that moment never receives the event. Only the last HEADER_CHANGE / HEADER_RESTORE event is replayed to a newly attached listener.
  • The GUI attaches through EnvironmentConnector.AttachToPushNotifications() (a persistent connection opened by BasePageLayoutController) and handles events in the overridable protected async pushNotificationHandler($event); the base implementation only logs unknown types, so an override calls super for types it does not handle.
  • Every connection receives every event, including anonymous pages — never put private data (not even organization ids) into data. Send a bare signal (a kind) and let each page load its own details through an authorized connector call.
// Backend
(<any>Loader.getInstance()).PushNotifications?.()?.Push({type: "my.app.attention", data: {kind: "pairing"}});

// Page controller
protected async pushNotificationHandler($event : IPushNotificationEvent) : Promise<void> {
if ($event?.type !== "my.app.attention") {
await super.pushNotificationHandler($event);
return;
}
// check the rights of the signed-in user, then load the details through an authorized connector call
}

AuthManager (Coordinator)​

Utils/AuthManager.ts — The central authentication coordinator. Composed from 11+ partial classes via @Partial. See Authentication for full documentation.

Other Utilities​

ClassFilePurpose
ConfigurationsManagerUtils/ConfigurationsManager.tsJSONP configuration loading and dynamic updates
SendMailUtils/SendMail.tsSMTP transport wrapper (nodemailer) used by MailEngine
ConvertUtils/Convert.tsHub-specific type conversions
AdminInitHelperUtils/AuthManager.tsFirst-time admin initialization flow

See also: Authentication | Hub Backend Overview | Hub Configuration