import * as flexui from '@openflexui/core'
import { AssociatedBackend } from './backend'
import { CodeSpace } from './space'
import { NATIVE_JS_LOGIC_BUILTINS, registerBuiltinComponentsOnSpace } from './components'
* A FlexUI application environment
*
* Each environment manages multiple backend contexts.
* However, a backend context should be exclusively managed by a single environment
* (to avoid `StyleScopeId` confliction).
* It is able to create multiple `CodeSpace` within the environment.
*/
export class FrontendEnv {
private codeSpaceMap: { [id: string]: CodeSpace }
private globalCodeSpace: CodeSpace
* Create an empty FlexUI application environment
*/
constructor() {
this.codeSpaceMap = Object.create(null) as { [id: string]: CodeSpace }
this.globalCodeSpace = new CodeSpace(this, false, {})
registerBuiltinComponentsOnSpace(this.globalCodeSpace, NATIVE_JS_LOGIC_BUILTINS)
}
* Get a global code space in which global components can be defined
*
* External flexui based components can be defined in this code space.
* All global components should be defined before any other `CodeSpace` created!
*/
getGlobalCodeSpace(): CodeSpace {
return this.globalCodeSpace
}
* Associate a backend context
*
* If `backendContext` is not given, the DOM-based backend is used
* (causes failure if running outside browsers).
* The backend context SHOULD NOT be associated by other environments!
*/
associateBackend(backendContent?: flexui.GeneralBackendContext): AssociatedBackend {
const ctx = backendContent ?? new flexui.CurrentWindowBackendContext()
return new AssociatedBackend(this, ctx)
}
* Create a component space that can manage templates, stylesheets, JS and static JSON config files
*
* The space can be specified as a *main* space.
* This makes some features available:
* * the `app.hjss` will be used as a style sheet for all root components in the space;
* * the `StyleIsolation.Shared` is accepted for components in the space.
* Non-main spaces usually act as plugins.
* `publicComponents` is a map for specifying a map of aliases and component paths.
*/
createCodeSpace(
id: string,
isMainSpace: boolean,
publicComponents = Object.create(null) as { [alias: string]: string },
): CodeSpace {
const cs = new CodeSpace(this, isMainSpace, publicComponents, this.globalCodeSpace)
this.codeSpaceMap[id] = cs
registerBuiltinComponentsOnSpace(cs, NATIVE_JS_LOGIC_BUILTINS)
return cs
}
* Get a component space by the `id` specified when created
*/
getCodeSpace(id: string): CodeSpace | undefined {
return this.codeSpaceMap[id]
}
}