Aspect Dependencies

Aspects can depend on other Aspect and obtain access the declared Aspect API. To use Aspects as dependencies, compose the Aspect reference to the static dependencies property and annotate the type on the provider first argument.

import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform';

export class PeopleBrowser {
  // declare the requested aspect dependencies. 
  static dependencies = [SymphonyPlatformAspect];

  // accept an array of all requested dependencies in your runtime.
  static async provider([symphonyPlatform]: [SymphonyPlatformBrowser]) {
    console.log(symphonyPlatform); // echos the wayne platform runtime API
    return new PeopleBrowser();
  }
}
CopiedCopy

An Aspect can only depend on the same runtime on the requested Aspect. If there is implementation for the Aspect in the same runtime, the dependency would be undefined.

Register to Aspects

Registering to Aspect slots is best upon construction of the platform. Use the provider execution to plugin to slots of your dependencies:

import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform';

export class PeopleBrowser {
  static dependencies = [SymphonyPlatformAspect];

  static async provider([symphonyPlatform]: [SymphonyPlatformBrowser]) {
    symphonyPlatform.registerRoute([
      {
        path: 'user-profile',
        component: () => {
          return <div>hello there!</div>;
        }
      }
    ]);

    return new PeopleBrowser();
  }
}
CopiedCopy

Registering into slots in different phases of the platform runtime is possible but consider the slot value might before the register occurs.

Use Aspect APIs

Pass the Aspect to your constructor to use it your Aspect APIs:

import { PeopleAspect, type PeopleNode } from '@pied/people.people';

export class OrganizationNode {
  constructor(
    private people: PeopleNode
  ) {}

  async listOrgMembers(orgName: string) {
    const org = await this.getOrg(orgName);
    const members = org.listMembers();
    const people = await this.people.listUsers(members); // use the people aspect to compose new APIs.
    return people;
  }

  static dependencies = [PeopleAspect]; // declare the required dependencies.

  static async provider([people]: [PeopleNode]) {
    return new OrganizationNode(people); // pass the aspect to the constructor to use it from your APIs.
  }
}
CopiedCopy

Avoid passing Aspect runtimes as props to inner dependencies and rather keep Aspects using components and not vice versa.

Optional dependencies

If Aspects are not composed in the Harmony platform they might be missing even if declaring them. Annotate you are allowing for an optional dependency using |undefined an keep your aspect implementation aware to the case.

import { SymphonyPlatformAspect, type SymphonyPlatformBrowser } from '@bitdev/symphony.symphony-platform';

export class PeopleBrowser {
  // declare the requested aspect dependencies. 
  static dependencies = [SymphonyPlatformAspect];

  // accept an array of all requested dependencies in your runtime.
  static async provider([waynePlatform]: [SymphonyPlatformBrowser|undefined]) {
    console.log(waynePlatform); // echos the wayne platform runtime API
    return new PeopleBrowser();
  }
}
CopiedCopy

Cyclic dependencies

Cyclic dependencies are not allowed to use between Aspects. We recommend to avoid cyclic dependencies of all components, learn more on avoiding cyclic dependencies.