add a new base extension initializer to initialize new types of entry point modules
This commit is contained in:
@@ -1,35 +1,18 @@
|
||||
import type { ManifestBase, ManifestBundle } from '../types/index.js';
|
||||
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
|
||||
import { loadManifestPlainJs } from '../functions/load-manifest-plain-js.function.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbExtensionInitializerBase } from './extension-initializer-base.js';
|
||||
import type { UmbElement } from '@umbraco-cms/backoffice/element-api';
|
||||
|
||||
export class UmbBundleExtensionInitializer extends UmbControllerBase {
|
||||
#extensionRegistry;
|
||||
#bundleMap = new Map();
|
||||
|
||||
constructor(host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry<ManifestBundle>) {
|
||||
super(host);
|
||||
this.#extensionRegistry = extensionRegistry;
|
||||
this.observe(extensionRegistry.byType('bundle'), (bundles) => {
|
||||
// Unregister removed bundles:
|
||||
this.#bundleMap.forEach((existingBundle) => {
|
||||
if (!bundles.find((b) => b.alias === existingBundle.alias)) {
|
||||
this.unregisterBundle(existingBundle);
|
||||
this.#bundleMap.delete(existingBundle.alias);
|
||||
}
|
||||
});
|
||||
|
||||
// Register new bundles:
|
||||
bundles.forEach((bundle) => {
|
||||
if (this.#bundleMap.has(bundle.alias)) return;
|
||||
this.#bundleMap.set(bundle.alias, bundle);
|
||||
this.instantiateBundle(bundle);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Extension initializer for the `bundle` extension type
|
||||
*/
|
||||
export class UmbBundleExtensionInitializer extends UmbExtensionInitializerBase<'bundle', ManifestBundle> {
|
||||
constructor(host: UmbElement, extensionRegistry: UmbExtensionRegistry<ManifestBundle>) {
|
||||
super(host, extensionRegistry, 'bundle');
|
||||
}
|
||||
|
||||
async instantiateBundle(manifest: ManifestBundle) {
|
||||
async instantiateExtension(manifest: ManifestBundle): Promise<void> {
|
||||
if (manifest.js) {
|
||||
const js = await loadManifestPlainJs(manifest.js);
|
||||
|
||||
@@ -38,16 +21,16 @@ export class UmbBundleExtensionInitializer extends UmbControllerBase {
|
||||
const value = js[key];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
this.#extensionRegistry.registerMany(value);
|
||||
this.extensionRegistry.registerMany(value);
|
||||
} else if (typeof value === 'object') {
|
||||
this.#extensionRegistry.register(value);
|
||||
this.extensionRegistry.register(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async unregisterBundle(manifest: ManifestBundle) {
|
||||
async unloadExtension(manifest: ManifestBundle): Promise<void> {
|
||||
if (manifest.js) {
|
||||
const js = await loadManifestPlainJs(manifest.js);
|
||||
|
||||
@@ -56,9 +39,9 @@ export class UmbBundleExtensionInitializer extends UmbControllerBase {
|
||||
const value = js[key];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
this.#extensionRegistry.unregisterMany(value.map((v) => v.alias));
|
||||
this.extensionRegistry.unregisterMany(value.map((v) => v.alias));
|
||||
} else if (typeof value === 'object') {
|
||||
this.#extensionRegistry.unregister((value as ManifestBase).alias);
|
||||
this.extensionRegistry.unregister((value as ManifestBase).alias);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,43 +1,31 @@
|
||||
import type { ManifestEntryPoint } from '../types/index.js';
|
||||
import { hasInitExport, loadManifestPlainJs } from '../functions/index.js';
|
||||
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
|
||||
import type { UmbEntryPointModule } from '../models/entry-point.interface.js';
|
||||
import { hasBeforeInitExport, hasInitExport, loadManifestPlainJs } from '../functions/index.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import { UmbExtensionInitializerBase } from './extension-initializer-base.js';
|
||||
import type { UmbElement } from '@umbraco-cms/backoffice/element-api';
|
||||
|
||||
export class UmbEntryPointExtensionInitializer extends UmbControllerBase {
|
||||
#host;
|
||||
#extensionRegistry;
|
||||
#entryPointMap = new Map();
|
||||
|
||||
constructor(
|
||||
host: UmbElement,
|
||||
extensionRegistry: UmbExtensionRegistry<ManifestEntryPoint>,
|
||||
initFn: keyof UmbEntryPointModule,
|
||||
) {
|
||||
super(host);
|
||||
this.#host = host;
|
||||
this.#extensionRegistry = extensionRegistry;
|
||||
this.observe(extensionRegistry.byType('entryPoint'), (entryPoints) => {
|
||||
entryPoints.forEach((entryPoint) => {
|
||||
if (this.#entryPointMap.has(entryPoint.alias)) return;
|
||||
this.#entryPointMap.set(entryPoint.alias, entryPoint);
|
||||
// TODO: Should we unInit a entry point if is removed?
|
||||
this.instantiateEntryPoint(entryPoint, initFn);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Extension initializer for the `entryPoint` extension type
|
||||
*/
|
||||
export class UmbEntryPointExtensionInitializer extends UmbExtensionInitializerBase<'entryPoint', ManifestEntryPoint> {
|
||||
constructor(host: UmbElement, extensionRegistry: UmbExtensionRegistry<ManifestEntryPoint>) {
|
||||
super(host, extensionRegistry, 'entryPoint');
|
||||
}
|
||||
|
||||
async instantiateEntryPoint(manifest: ManifestEntryPoint, initFn: keyof UmbEntryPointModule = 'onInit') {
|
||||
async instantiateExtension(manifest: ManifestEntryPoint) {
|
||||
if (manifest.js) {
|
||||
const js = await loadManifestPlainJs(manifest.js);
|
||||
|
||||
// If the extension has known exports, be sure to run those
|
||||
if (initFn === 'beforeInit' && hasBeforeInitExport(js)) {
|
||||
js.beforeInit(this.#host, this.#extensionRegistry);
|
||||
} else if (initFn === 'onInit' && hasInitExport(js)) {
|
||||
js.onInit(this.#host, this.#extensionRegistry);
|
||||
if (hasInitExport(js)) {
|
||||
js.onInit(this.host, this.extensionRegistry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
unloadExtension(_manifest: ManifestEntryPoint): void {
|
||||
// No-op
|
||||
// Entry points are not unloaded, but if they were, this is where you would do it.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { ManifestBase } from '../types/index.js';
|
||||
import type { UmbExtensionRegistry } from '../registry/extension.registry.js';
|
||||
import type { SpecificManifestTypeOrManifestBase } from '../types/map.types.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { UmbElement } from '@umbraco-cms/backoffice/element-api';
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
/**
|
||||
* Base class for extension initializers, which are responsible for loading and unloading extensions.
|
||||
*/
|
||||
export abstract class UmbExtensionInitializerBase<
|
||||
Key extends string,
|
||||
T extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, Key>,
|
||||
> extends UmbControllerBase {
|
||||
protected host;
|
||||
protected extensionRegistry;
|
||||
#extensionMap = new Map();
|
||||
|
||||
constructor(host: UmbElement, extensionRegistry: UmbExtensionRegistry<T>, manifestType: Key) {
|
||||
super(host);
|
||||
this.host = host;
|
||||
this.extensionRegistry = extensionRegistry;
|
||||
this.observe(extensionRegistry.byType<Key, T>(manifestType), (extensions) => {
|
||||
this.#extensionMap.forEach((existingExt) => {
|
||||
if (!extensions.find((b) => b.alias === existingExt.alias)) {
|
||||
this.unloadExtension(existingExt);
|
||||
this.#extensionMap.delete(existingExt.alias);
|
||||
}
|
||||
});
|
||||
|
||||
extensions.forEach((extension) => {
|
||||
if (this.#extensionMap.has(extension.alias)) return;
|
||||
this.#extensionMap.set(extension.alias, extension);
|
||||
this.instantiateExtension(extension);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any logic required to instantiate the extension.
|
||||
*/
|
||||
abstract instantiateExtension(manifest: T): Promise<void> | void;
|
||||
|
||||
/**
|
||||
* Perform any logic required to unload the extension.
|
||||
*/
|
||||
abstract unloadExtension(manifest: T): Promise<void> | void;
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './bundle-extension-initializer.js';
|
||||
export * from './entry-point-extension-initializer.js';
|
||||
export * from './extension-initializer-base.js';
|
||||
|
||||
Reference in New Issue
Block a user