While the BaseEngine class is a singleton, normally, it is possible to have multiple instances of the class in an application if the class is used in multiple contexts that have different providers.
Private _Private _Private _Private _Private _Private _Private _createPrivate _loadedGet only the active user applications (IsActive = true)
Get ALL notifications in the cache (unfiltered by user). Useful for server-side admin scenarios.
Get ALL user applications in the cache (unfiltered by user). Useful for server-side admin scenarios.
Returns a COPY of the metadata configs array for the engine. This is a copy so you can't modify the original configs by modifying this array.
Get the current user's primary workspace (first one if multiple exist)
Observable that emits when any data property changes due to a refresh. Subscribe to this to react to engine data updates (e.g., sync Angular observables).
Events are emitted after data is refreshed in response to BaseEntity save/delete events. The event includes the full config and the new data array.
UserInfoEngine.Instance.DataChange$.subscribe(event => {
if (event.config.PropertyName === 'UserApplications') {
// Sync local state with engine's updated data
this.refreshLocalAppList();
}
});
Protected EntityOverridable property to set the debounce time for entity events. Default is 1500 milliseconds (1.5 seconds). This debounce time is used when immediate array mutations cannot be applied (e.g., when Filter, OrderBy, or AdditionalLoading overrides are present) and a full view refresh is required.
Note: When immediate mutations ARE possible (no Filter, OrderBy, or AdditionalLoading override), updates happen synchronously without any debounce delay.
Returns true if the data has been loaded, false otherwise.
Get the user ID this engine was loaded for
Returns the loading subject. You can call await Config() and after Config() comes back as true that means you're loaded. However you can also directly subscribe to this subject to get updates on the loading status.
Returns the metadata provider to use for the engine. If a provider is set via the Config method, that provider will be used, otherwise the default provider will be used.
Returns the RunView provider to use for the engine. This is the same underlying object as the
Get the count of unread notifications
Get unread notifications for the current user
Get all applications enabled for the current user, ordered by sequence then application name
Get all favorites for the current user, ordered by creation date (newest first)
Get all notifications for the current user, ordered by creation date (newest first)
Get all record logs for the current user (recent record access), ordered by LatestAt (most recent first)
Get all settings for the current user
Get all workspaces for the current user
Static InstanceReturns the global instance of the class. This is a singleton class, so there is only one instance of it in the application. Do not directly create new instances of it, always use this method to get the instance.
Private Static ProviderAdds a dynamic metadata configuration at runtime.
The metadata configuration to add
Optional contextUser: UserInfoThe context user information
Protected AdditionalSubclasses can override this method to perform additional loading tasks
Optional contextUser: UserInfoProtected CheckCheck the user's access status for an application.
The application ID to check
The user's access status for this application
Configures the engine by loading user-specific metadata from the database. All entities are filtered by the current user's ID and cached locally for performance.
Optional forceRefresh: booleanIf true, forces a refresh from the server even if data is cached
Optional contextUser: UserInfoThe user context (required for server-side, auto-detected on client)
Optional provider: IMetadataProviderOptional custom metadata provider
Extended configuration method with object-based options. This provides a more flexible API compared to Config() with positional parameters.
Internally calls Config() after setting up options that Load() can access.
Optional options: ConfigExOptionsConfiguration options object
Promise that resolves when configuration is complete
await MyEngine.Instance.ConfigEx({
forceRefresh: true,
contextUser: currentUser
});
Create default UserApplication records for apps marked with DefaultForNewUser=true. This is called automatically when a user has no UserApplication records.
This method is safe to call multiple times concurrently - it will return the same promise if already in progress, and will skip apps that already have UserApplication records.
Optional contextUser: UserInfoOptional user context for server-side use
Array of created UserApplicationEntity records
Protected DebounceThis method handles the debouncing process, by default using the EntityEventDebounceTime property to set the debounce time. Debouncing is done on a per-entity basis, meaning that if the debounce time passes for a specific entity name, the event will be processed. This is done to prevent multiple events from being processed in quick succession for a single entity which would cause a lot of wasted processing.
Override this method if you want to change how debouncing time such as having variable debounce times per-entity, etc.
Disable an application for the current user (set IsActive = false). This does not delete the UserApplication record, just deactivates it.
The application ID to disable
Optional contextUser: UserInfoOptional user context for server-side use
true if successful, false otherwise
Enable a disabled application for the current user (set IsActive = true).
The application ID to enable
Optional contextUser: UserInfoOptional user context for server-side use
true if successful, false otherwise
Find application info by path or name (case-insensitive).
The path or name to search for
Get application info by ID from metadata.
The application ID to find
Get favorites for a specific entity
The entity ID to filter by
The Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.
Get a notification by ID
The notification ID to find
Get notifications for a specific user
The user ID to filter by
Get recent record logs for a specific entity
The entity ID to filter by
Maximum number of items to return (default: 10)
Get a user application by application ID
The application ID to find
Get user applications for a specific user
The user ID to filter by
Protected HandleThis method handles the individual base entity event. For events that can use immediate array mutations (no Filter, OrderBy, or AdditionalLoading override), processing happens synchronously without debounce. For events that require full view refresh, debouncing is applied to batch rapid successive changes.
Override this method if you want to have a different handling for the filtering of events that are debounced or if you don't want to debounce at all you can do that in an override of this method.
Protected HandleSubclasses of BaseEngine can override this method to handle individual MJGlobal events. This is typically done to optimize the way refreshes are done when a BaseEntity is updated. If you are interested in only BaseEntity events, override the HandleIndividualBaseEntityEvent method instead as this method primarily serves to filter all the events we get from MJGlobal and only pass on BaseEntity events to HandleIndividualBaseEntityEvent.
Protected HandleHandles the result of a single view load.
All BaseEngine sub-classes get an implementation of IStartupSink so they can be set the auto start in their app container, if desired, simply by adding the
Optional contextUser: UserInfoOptional provider: IMetadataProvider-
decorator. The BaseEngine implementation of IStartupSink.HandleStartup is to simply call
Install an application for the current user by creating a UserApplication record. The new record is automatically added to the cached UserApplications array.
The application ID to install
Optional contextUser: UserInfoOptional user context for server-side use
The newly created UserApplicationEntity, or null if failed
Protected LoadThis method should be called by sub-classes to load up their specific metadata requirements. For more complex metadata loading or for post-processing of metadata loading done here, overide the AdditionalLoading method to add your logic.
Optional forceRefresh: booleanOptional contextUser: UserInfoProtected LoadLoads the specified metadata configurations.
The metadata configurations to load
The context user information
Protected LoadHandles the process of loading multiple entity configs in a single network call via RunViews()
Protected LoadLoads a single metadata configuration.
The metadata configuration to load
The context user information
Protected LoadHandles the process of loading a single config of type 'dataset'.
Protected LoadHandles the process of loading a single config of type 'entity'.
Protected NotifyNotify listeners that a data property has changed. Called automatically by HandleSingleViewResult after data refresh and by applyImmediateMutation for array operations. Subclasses can also call this manually when modifying data arrays directly.
The configuration for the property that changed
The current data array
Optional changeType: "update" | "delete" | "refresh" | "add"The type of change: 'refresh', 'add', 'update', or 'delete'
Optional affectedEntity: BaseEntity<unknown>For add/update/delete, the entity that was affected
Protected ProcessThis method does the actual work of processing the entity event. It is not directly called from the event handler because we want to first debounce the events which also introduces a delay which is usually desirable so that our processing is typically outside of the scope of any transaction processing that would have originated the event.
This is the best method to override if you want to change the actual processing of an entity event but do NOT want to modify the debouncing behavior.
Force refresh all user data
Optional contextUser: UserInfoOptional user context for server-side use
Protected SetInternal method to set the provider when an engine is loaded
Protected SetupThis method is responsible for registering for MJGlobal events and listening for BaseEntity events where those BaseEntity are related to the engine's configuration metadata. The idea is to auto-refresh the releated configs when the BaseEntity is updated.
Protected TryUninstall an application by deleting the UserApplication record.
The application ID to uninstall
Optional contextUser: UserInfoOptional user context for server-side use
true if successful, false otherwise
Protected UpgradeUtility method to upgrade an object to a BaseEnginePropertyConfig object.
Protected applyApplies an immediate array mutation based on the entity event type. This is faster than running a full view refresh for simple add/update/delete operations.
The configuration for the property being mutated
The entity event containing the affected entity and event type
Protected canDetermines if an immediate array mutation can be used instead of running a full view refresh. Immediate mutations are only safe when:
The configuration to check
true if immediate mutation is safe, false if a full view refresh is needed
Private doInternal implementation of CreateDefaultApplications. Separated to allow the public method to manage the promise state.
Optional contextUser: UserInfoProtected findFinds an entity in the array by matching all primary key columns. Supports composite primary keys by comparing all PrimaryKey fields from EntityInfo.
The array of entities to search
The entity to find (using its primary key values)
The index of the matching entity, or -1 if not found
Protected hasProtected isChecks if the exact entity object reference is already in the config's data array. Used to skip unnecessary refreshes for UPDATE events where the object was mutated in place.
The configuration to check
The entity to look for
true if the exact object reference is already in the array
Protected isChecks if an entity is in the config's data array by object reference OR by primary key match. Used for DELETE events where we need to know if the entity still exists in the array. The object reference may still exist (entity.Delete() just marks it deleted), but if it was manually spliced out by engine code, we check by primary key as fallback.
The configuration to check
The entity to look for
true if the entity is in the array (by reference or by primary key)
Static GetThis method will check for the existence of an instance of this engine class that is tied to a specific provider. If one exists, it will return it, otherwise it will create a new instance
Protected Static getReturns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.
UserInfoEngine is a singleton engine that provides centralized access to user-specific data including notifications, workspaces, applications, favorites, and record logs.
This engine consolidates multiple user-related RunView calls into a single batched load, improving performance and enabling local caching for faster subsequent access.
Usage:
Note: This engine filters all data by the current user's ID automatically. On the server side, you must call Config() with contextUser to specify which user's data to load.