2ea0c4106b
* Spec composer API * Add composer api implementation * Tests * Copyright * update sigs * cleanup * a snap * cleanup * linting * Tidy up * Adjust
177 lines
4.9 KiB
TypeScript
177 lines
4.9 KiB
TypeScript
/*
|
|
Copyright 2025 New Vector Ltd.
|
|
Copyright 2026 Element Creations Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
import type { Root } from "react-dom/client";
|
|
import { type LegacyModuleApiExtension } from "./legacy-modules";
|
|
import { type LegacyCustomisationsApiExtension } from "./legacy-customisations";
|
|
import { type ConfigApi } from "./config";
|
|
import { type I18nApi } from "./i18n";
|
|
import { type CustomComponentsApi } from "./custom-components";
|
|
import { type NavigationApi } from "./navigation.ts";
|
|
import { type DialogApiExtension } from "./dialog.ts";
|
|
import { type AccountAuthApiExtension } from "./auth.ts";
|
|
import { type ProfileApiExtension } from "./profile.ts";
|
|
import { type ExtrasApi } from "./extras.ts";
|
|
import { type BuiltinsApi } from "./builtins.ts";
|
|
import { type StoresApi } from "./stores.ts";
|
|
import { type ClientApi } from "./client.ts";
|
|
import { type WidgetLifecycleApi } from "./widget-lifecycle.ts";
|
|
import { type WidgetApi } from "./widget.ts";
|
|
import { type CustomisationsApi } from "./customisations.ts";
|
|
import { type ComposerApi } from "./composer.ts";
|
|
|
|
/**
|
|
* Module interface for modules to implement.
|
|
* @public
|
|
*/
|
|
export interface Module {
|
|
load(): Promise<void>;
|
|
}
|
|
|
|
const moduleSignature: Record<keyof Module, Type> = {
|
|
load: "function",
|
|
};
|
|
|
|
/**
|
|
* Module interface for modules to export as the default export.
|
|
* @public
|
|
*/
|
|
export interface ModuleFactory {
|
|
readonly moduleApiVersion: string;
|
|
new (api: Api): Module;
|
|
readonly prototype: Module;
|
|
}
|
|
|
|
const moduleFactorySignature: Record<keyof ModuleFactory, Type> = {
|
|
moduleApiVersion: "string",
|
|
prototype: "object",
|
|
};
|
|
|
|
export interface ModuleExport {
|
|
default: ModuleFactory;
|
|
}
|
|
|
|
const moduleExportSignature: Record<keyof ModuleExport, Type> = {
|
|
default: "function",
|
|
};
|
|
|
|
type Type = "function" | "string" | "number" | "boolean" | "object";
|
|
|
|
function isInterface<T>(obj: unknown, type: "object" | "function", keys: Record<keyof T, Type>): obj is T {
|
|
if (obj === null || typeof obj !== type) return false;
|
|
for (const key in keys) {
|
|
if (typeof (obj as Record<keyof T, unknown>)[key] !== keys[key]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function isModule(module: unknown): module is ModuleExport {
|
|
return (
|
|
isInterface(module, "object", moduleExportSignature) &&
|
|
isInterface(module.default, "function", moduleFactorySignature) &&
|
|
isInterface(module.default.prototype, "object", moduleSignature)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The API for modules to interact with the application.
|
|
* @public
|
|
*/
|
|
export interface Api
|
|
extends
|
|
LegacyModuleApiExtension,
|
|
LegacyCustomisationsApiExtension,
|
|
DialogApiExtension,
|
|
AccountAuthApiExtension,
|
|
ProfileApiExtension {
|
|
/**
|
|
* The API to read config.json values.
|
|
* Keys should be scoped to the module in reverse domain name notation.
|
|
* @public
|
|
*/
|
|
readonly config: ConfigApi;
|
|
/**
|
|
* The internationalisation API.
|
|
* @public
|
|
*/
|
|
readonly i18n: I18nApi;
|
|
/**
|
|
* The root node the main application is rendered to.
|
|
* Intended for rendering sibling React trees.
|
|
* @public
|
|
*/
|
|
readonly rootNode: HTMLElement;
|
|
|
|
/**
|
|
* The custom message component API.
|
|
* @alpha
|
|
*/
|
|
readonly customComponents: CustomComponentsApi;
|
|
|
|
/**
|
|
* Allows modules to render components that are part of Element Web.
|
|
* @alpha
|
|
*/
|
|
readonly builtins: BuiltinsApi;
|
|
|
|
/**
|
|
* API to navigate the application.
|
|
* @public
|
|
*/
|
|
readonly navigation: NavigationApi;
|
|
|
|
/**
|
|
* Allows modules to insert extra UI into Element Web.
|
|
* @alpha
|
|
*/
|
|
readonly extras: ExtrasApi;
|
|
|
|
/**
|
|
* Allows modules to access a limited functionality of certain stores from Element Web.
|
|
*/
|
|
readonly stores: StoresApi;
|
|
|
|
/**
|
|
* Access some very specific functionality from the client.
|
|
*/
|
|
readonly client: ClientApi;
|
|
|
|
/**
|
|
* API for modules to auto-approve widget preloading, identity token requests, and capability requests.
|
|
* @alpha Subject to change.
|
|
*/
|
|
readonly widgetLifecycle: WidgetLifecycleApi;
|
|
|
|
/**
|
|
* API for modules to interact with widgets in Element Web, including getting what widgets
|
|
* are active in a given room.
|
|
* @alpha Subject to change.
|
|
*/
|
|
readonly widget: WidgetApi;
|
|
|
|
/**
|
|
* Allows modules to customise behaviour of app's components.
|
|
* @alpha Subject to change.
|
|
*/
|
|
readonly customisations: CustomisationsApi;
|
|
|
|
/**
|
|
* Allows modules to customise the message composer.
|
|
* @alpha Subject to change.
|
|
*/
|
|
readonly composer: ComposerApi;
|
|
|
|
/**
|
|
* Create a ReactDOM root for rendering React components.
|
|
* Exposed to allow modules to avoid needing to bundle their own ReactDOM.
|
|
* @param element - the element to render use as the root.
|
|
* @public
|
|
*/
|
|
createRoot(element: Element): Root;
|
|
}
|