@j2inn/app
Version:
J2 Innovations core application framework
87 lines (86 loc) • 2.63 kB
JavaScript
/*
* Copyright (c) 2021, J2 Innovations. All Rights Reserved
*/
import { HNamespace } from 'haystack-core';
import { RemoteAppView } from './RemoteAppView';
import { getPodName, loadDefault } from './util';
/**
* A guaranteed system wide unique symbol.
*/
const SYMBOL = Symbol.for('RemoteApp');
/**
* An application that loads remotely as a micro frontend application.
*
* All behavior and plugin points are defined using haystack defs.
*/
export class RemoteApp {
constructor(app, namespace) {
this.views = {};
/**
* Used by the `isRemoteApp` type guard check.
*/
this._symbol = SYMBOL;
this.app = app;
this.loadMessages();
this.loadAppViews(namespace);
}
loadMessages() {
this.messages = this.app
.get('finUiMessages')
?.map((message) => message.value);
}
loadAppViews(namespace) {
const finUis = namespace.associations(this.app.defName, 'finUis');
for (const ui of finUis) {
this.views[HNamespace.getFeatureName(ui.defName)] =
new RemoteAppView(this.app, ui, namespace);
}
}
get id() {
return HNamespace.getFeatureName(this.app.defName);
}
get remoteStoreUri() {
return this.app.get('finUiAppStore')?.value ?? '';
}
/**
* Asynchronously ensure the store is loaded if one is available.
*/
async loadStore() {
if (!this.store && this.remoteStoreUri) {
try {
const module = await loadDefault(getPodName(this.app), this.remoteStoreUri)();
// Make sure we don't accidently overwrite a store that was loaded
// in the meantime.
if (!this.store) {
this.store = new module.default();
}
}
catch (err) {
console.error('Error loading remote app store', err);
}
}
}
/**
* Returns a list of apps.
*
* @param namespace The namespace to query for apps.
* @returns An array of apps.
*/
static makeApps(namespace) {
return namespace
.allSubTypesOf('finApp')
.filter((dict) => dict.has('finUiApp') && !dict.has('finUiAppInternal'))
.map((finApp) => {
return new RemoteApp(finApp, namespace);
});
}
}
/**
* Type guard check for checking whether an app is a remote app or not.
*
* @param app The app.
* @returns True if the app is a remote app.
*/
export function isRemoteApp(app) {
return app?._symbol === SYMBOL;
}