resolvedModules property

List<JsWebModule> get resolvedModules

The dependency closure of modules (plus JsWebModule.fetch when fetch is set), ordered so that every module comes after everything it requires and after every installed module it lists as optional.

Implementation

List<JsWebModule> get resolvedModules {
  final requested = fetch == null
      ? modules
      : <JsWebModule>{...modules, JsWebModule.fetch};

  // Only hard requirements decide what gets installed.
  final closure = <String>{};
  void collect(JsWebModule module) {
    if (!closure.add(module.name)) return;
    module.requires.forEach(collect);
  }

  requested.forEach(collect);

  // Optional edges only affect order, and only between installed modules.
  final order = <JsWebModule>[];
  final seen = <String>{};
  void visit(JsWebModule module) {
    if (!seen.add(module.name)) return;
    for (final dependency in module.requires) {
      visit(dependency);
    }
    for (final dependency in module.optional) {
      if (closure.contains(dependency.name)) visit(dependency);
    }
    order.add(module);
  }

  for (final module in requested) {
    visit(module);
  }
  return order;
}