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 { WaynePlatformAspect, type WaynePlatformBrowser } from '@wayne/wayne.wayne-platform';

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

  // accept an array of all requested dependencies in your runtime.
  static async provider([waynePlatform]: [WaynePlatformBrowser]) {
    console.log(waynePlatform); // 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.

Plugin to Aspects

Plugging to Aspect slots is best upon consturction of the platform. Use the provider exection to plugin to slots of your dependencies:

import { WaynePlatformAspect, type WaynePlatformBrowser } from '@wayne/wayne.wayne-platform';

export class PeopleBrowser {
  static dependencies = [];

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

    return new PeopleBrowser();
  }
}
CopiedCopy

Plugging 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 '@wayne/people.people';

export class OrganiztaionNode {
  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 dependnecies.

  static async provider([people]: [PeopleNode]) {
    return new OrganiztaionNode(people); // pass the aspect to the contructor 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 declearing them. Annotate you are allowing for an optional dependency using |undefined an keep your aspect implementation aware to the case.

import { WaynePlatformAspect, type WaynePlatformBrowser } from '@wayne/wayne.wayne-platform';

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

  // accept an array of all requested dependencies in your runtime.
  static async provider([waynePlatform]: [WaynePlatformBrowser|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 dependenceis of all components, learn more on avoiding cyclic dependencies.