packages/@alicloud/ros-cdk-core/lib/dependency.ts (31 lines of code) (raw):
import { IConstruct } from "./construct-compat";
/**
* Trait marker for classes that can be depended upon
*
* The presence of this interface indicates that an object has
* an `IDependableTrait` implementation.
*
* This interface can be used to take an (ordering) dependency on a set of
* constructs. An ordering dependency implies that the resources represented by
* those constructs are deployed before the resources depending ON them are
* deployed.
*/
export interface IDependable {
// Empty, this interface is a trait marker
}
/**
* A set of constructs to be used as a dependable
*
* This class can be used when a set of constructs which are disjoint in the
* construct tree needs to be combined to be used as a single dependable.
*
* @experimental
*/
export class ConcreteDependable implements IDependable {
private readonly _dependencyRoots = new Array<IConstruct>();
constructor() {
const self = this;
DependableTrait.implement(this, {
get dependencyRoots() {
return self._dependencyRoots;
},
});
}
/**
* Add a construct to the dependency roots
*/
public add(construct: IConstruct) {
this._dependencyRoots.push(construct);
}
}
const DEPENDABLE_SYMBOL = Symbol.for("ros-cdk-core.DependableTrait");
/**
* Trait for IDependable
*
* Traits are interfaces that are privately implemented by objects. Instead of
* showing up in the public interface of a class, they need to be queried
* explicitly. This is used to implement certain framework features that are
* not intended to be used by Construct consumers, and so should be hidden
* from accidental use.
*
* @example
*
* // Usage
* const roots = DependableTrait.get(construct).dependencyRoots;
*
* // Definition
* DependableTrait.implement(construct, {
* get dependencyRoots() { return []; }
* });
*
* @experimental
*/
export abstract class DependableTrait {
/**
* Register `instance` to have the given DependableTrait
*
* Should be called in the class constructor.
*/
public static implement(instance: IDependable, trait: DependableTrait) {
// I would also like to reference classes (to cut down on the list of objects
// we need to manage), but we can't do that either since jsii doesn't have the
// concept of a class reference.
(instance as any)[DEPENDABLE_SYMBOL] = trait;
}
/**
* Return the matching DependableTrait for the given class instance.
*/
public static get(instance: IDependable): DependableTrait {
const ret = (instance as any)[DEPENDABLE_SYMBOL];
if (!ret) {
throw new Error(`${instance} does not implement DependableTrait`);
}
return ret;
}
/**
* The set of constructs that form the root of this dependable
*
* All resources under all returned constructs are included in the ordering
* dependency.
*/
public abstract readonly dependencyRoots: IConstruct[];
}