my-two-perspectives-app
v1.1.5
Published
This example application showcases the **new "Two-Perspective DSL"** capability of the `mcf-communication` framework. It implements the same coordinator-worker pattern as `my-headless-app` but utilizes a more declarative approach for defining component in
Downloads
16
Readme
My Two-Perspectives App
Demonstrating the "Two-Perspective DSL" Approach
This example application showcases the new "Two-Perspective DSL" capability of the mcf-communication framework. It implements the same coordinator-worker pattern as my-headless-app but utilizes a more declarative approach for defining component interfaces and interactions.
Key Features Demonstrated
- Two-Perspective DSL:
- Child Self-Definition: Components like
WorkerComponentandCoordinatorComponentdefine their handled commands (onCommandName="handler") and emitted events (emits="...") directly within their own definition files (worker.component.html,coordinator.component.html) using definition tags (<worker-definition>,<coordinator-definition>). - Parent Usage: Parent components (
AppComponent,CoordinatorComponent) use simple tags (<coordinator>,<worker>) in their templates to include children and declaratively bind to the child's emitted events usingonEventName="parentHandler"attributes. - Matrix-Level DSL: A top-level
<matrix-definition>component serves as an "outer container" for the environment, holding environment-level attributes likerootTopicand referencing<app>usage.
- Child Self-Definition: Components like
- Multi-Event Emission:
- Support for defining multiple events in
emitsattribute (e.g.,emits="SystemCompleted:direct, AnotherEvent:bubble").
- Support for defining multiple events in
- Declarative Command & Event Wiring: The framework automatically wires both the self-defined command handlers and the parent-listens-to-child event handlers based entirely on the DSL attributes, minimizing boilerplate code in the
.component.tsfiles. - No
classNamein DSL: Component types are resolved viaNodeFactory.registerusing the DSL tag names (both definition and usage tags), keeping the DSL clean. - Recursive DSL Loading & Merging: The
bootstrap.tsuses theloadComponentTreeRecursivelylogic (shared withmy-headless-app) to find, load, and merge component definition files with their usage tags, creating a complete description tree forNodeFactory.
Table of Contents
- My Two-Perspectives App
Architecture & Implementation Notes
- Framework: Relies on the core
mcf-communicationpackage, utilizing the enhancedNodeFactoryandDslNodeDescriptionwhich support the two-perspective model. - Bootstrapping (
bootstrap.ts):- Implements
loadComponentTreeRecursivelyto load and merge definition files (*.component.html) with usage tags. - Registers both definition tags (e.g.,
worker-definition) and usage tags (e.g.,worker) withNodeFactory, mapping them to the same component class.
- Implements
- DSL Files (
*.component.html):- Definition Files: Use tags ending in
-definition(e.g.,<coordinator-definition>). ContainonCommandName="handler"attributes for self-commands andemits="EventA,EventB"to declare events. May also contain child tags defining the component's internal structure. - Usage in Parent Files: Use simple tags (e.g.,
<coordinator>) with anid. ContainonEventName="parentHandler"attributes for listening to child events.
- Definition Files: Use tags ending in
- Component Logic (
*.component.ts):- Handler methods match the
onCommandNameandonEventNameattributes in the DSL. - No manual
this.onCommand(...)calls are needed for commands defined viaonCommandNamein the definition DSL.
- Handler methods match the
Usage & Build Instructions
- Ensure you have Node.js and npm installed.
- Clone the repository.
- Install dependencies at the monorepo root:
npm install - Navigate to the
my-two-perspectives-apppackage directory:cd packages/my-two-perspectives-app - Install dependencies for this package (if not using workspace hoisting):
npm install
Building and Running
This package uses tsc (the TypeScript compiler) for building the TypeScript source code and copying assets.
To build the package, run the build script:
npm run buildThis will:
- Cleans the
distdirectory (prebuildscript). - Compiles TypeScript to JavaScript (
buildscript usingtsc). - Copies
*.component.htmlDSL files to thedist/components/...directory structure (postbuildscript). - Copies
matrix.htmlto thedistdirectory (postbuildscript).
To run the application after building:
# Run with debug logging enabled
npm run run
# OR run with only info logging (no debug)
npm run info
# Using the Matrix CLI (recommended approach) - run from the root of the monorepo
# Ensure matrix-cli is built and available in your PATH or use npx
# npx matrix up packages/my-two-perspectives-app/dist/matrix.html
# OR specify a DSL file
# npx matrix up packages/my-two-perspectives-app/dist/matrix.html
# OR use watch mode for auto-rebuild on file changes
# npx matrix watch packages/my-two-perspectives-app/dist/matrix.htmlTesting
This package uses Jest for running tests.
To run the tests, use the test script:
npm testNote: This package currently has no test files, so running npm test will exit with code 0 and report "No tests found". The --passWithNoTests flag is used in the script to allow this.
Important Notes
- This app demonstrates the recommended way to use the framework going forward, leveraging the two-perspective DSL for maximum clarity and reduced boilerplate.
- Compare this implementation with
my-headless-appto see the difference between the declarative (two-perspective) and imperative command handling approaches. - The Matrix CLI with
matrix.htmlis the recommended approach for running applications. It provides:- Auto-registration of components
- Environment-level DSL with the
<matrix-definition>component - Watch mode for auto-rebuild on file changes
- Manual vs. CLI Usage:
- CLI (Recommended): Uses auto-registration by scanning
dist/componentsand supportsmatrix upandmatrix watchcommands. - Manual: Still supported by calling
bootstrapApp(...)directly, which uses manualNodeFactory.register(...)calls ifprocess.env.MATRIX_AUTO_REGISTERis not set.
- CLI (Recommended): Uses auto-registration by scanning
- DSL Merging: The system intelligently merges child definitions, so you don't need to duplicate
<coordinator>or<worker>definitions inmatrix.htmlif they're already referenced inapp.component.html.
Logging
This application uses the logging system provided by the mcf-communication package:
Running with Different Log Levels
# Run with debug logging enabled (shows all logs)
npm run run
# OR
npm run debug
# Run with only info logging (no debug logs)
npm run infoLog Format in Code
All logs in the application follow a consistent format:
// Debug log with details
logDebug(`[ComponentName:${this.id}] Descriptive message`, {
detailKey1: value1,
detailKey2: value2
});
// Info log (always shown)
logInfo(`[ComponentName:${this.id}] Important status update`);For more details on the logging system, see the mcf-communication README.
Links to Docs
- Root Project README
- Root Docs Folder
- Design Log: Two-Perspective DSL Implementation
- Design Log: Matrix CLI Auto-Registration
- Design Log: Matrix CLI Watch Mode
mcf-communicationREADMEmy-headless-appREADME
License
MIT
Matrix CLI Compatibility Requirements
To ensure that this package can be correctly installed and executed by the Matrix CLI (matrix install, matrix up), specific build and configuration standards must be met.
Build Output
The package must be built so that the compiled JavaScript (.js) files and any necessary assets (like .html templates) are placed directly within the dist/ directory. The structure within dist/ must mirror the structure of the src/ directory.
For example:
src/components/app/app.component.tsshould compile todist/components/app/app.component.js.src/components/app/app.component.htmlshould be copied todist/components/app/app.component.html.
This structure is essential for the Matrix CLI's dynamic loading and component registration mechanisms.
TypeScript Configuration (tsconfig.json)
The tsconfig.json file plays a critical role in achieving the required build output structure. It is highly recommended to use the tsconfig.json from the mcf-communication package as a template or baseline, as it contains settings proven to work with the Matrix CLI.
Key settings that influence compatibility include:
outDir: Must be set to"./dist".rootDir: Should typically be set to"./src".module: Needs to be compatible with the CLI's loading mechanism (e.g.,"NodeNext"or"CommonJS"depending on the project setup).noEmit: Must befalseto ensure JavaScript files are generated.
Important: Avoid modifying the tsconfig.json file unless you fully understand how the changes will impact the final build output structure in the dist/ directory. Incorrect configuration can prevent the Matrix CLI from installing or running the package.
Component Requirements
- Base Class: All components intended to be managed by the Matrix framework must extend
BaseCommunicationComponentfrom themcf-communicationpackage. - Exports: Components must be exported from their corresponding compiled JavaScript (
.js) files within thedist/directory structure. This allows the Matrix CLI's auto-registration mechanism to discover and register them correctly during thematrix upprocess.
