@antelopejs/core 1.13.4 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/core/build/build-artifact.d.ts +2 -1
  2. package/dist/core/build/build-artifact.js.map +1 -1
  3. package/dist/core/cli/command.d.ts +2 -1
  4. package/dist/core/cli/command.js +36 -22
  5. package/dist/core/cli/command.js.map +1 -1
  6. package/dist/core/cli/output/interface-conflicts.d.ts +3 -0
  7. package/dist/core/cli/output/interface-conflicts.js +61 -0
  8. package/dist/core/cli/output/interface-conflicts.js.map +1 -0
  9. package/dist/core/cli/output/translations.js +5 -0
  10. package/dist/core/cli/output/translations.js.map +1 -1
  11. package/dist/core/config/config-parser.d.ts +1 -0
  12. package/dist/core/config/config-parser.js +11 -0
  13. package/dist/core/config/config-parser.js.map +1 -1
  14. package/dist/core/config/config-paths.d.ts +1 -0
  15. package/dist/core/config/config-paths.js +3 -2
  16. package/dist/core/config/config-paths.js.map +1 -1
  17. package/dist/core/embedded/prepare-embedded.js +5 -4
  18. package/dist/core/embedded/prepare-embedded.js.map +1 -1
  19. package/dist/core/embedded/types.d.ts +1 -0
  20. package/dist/core/interface-registry.d.ts +2 -2
  21. package/dist/core/interface-registry.js +19 -12
  22. package/dist/core/interface-registry.js.map +1 -1
  23. package/dist/core/module-isolation.d.ts +18 -0
  24. package/dist/core/module-isolation.js +107 -0
  25. package/dist/core/module-isolation.js.map +1 -0
  26. package/dist/core/module-manager.d.ts +21 -3
  27. package/dist/core/module-manager.js +217 -39
  28. package/dist/core/module-manager.js.map +1 -1
  29. package/dist/core/module-manifest.d.ts +1 -0
  30. package/dist/core/module-manifest.js +34 -0
  31. package/dist/core/module-manifest.js.map +1 -1
  32. package/dist/core/module-registry.d.ts +1 -0
  33. package/dist/core/module-registry.js +3 -0
  34. package/dist/core/module-registry.js.map +1 -1
  35. package/dist/core/module.d.ts +1 -3
  36. package/dist/core/module.js +0 -18
  37. package/dist/core/module.js.map +1 -1
  38. package/dist/core/resolution/binding-diagnostics.d.ts +30 -0
  39. package/dist/core/resolution/binding-diagnostics.js +65 -0
  40. package/dist/core/resolution/binding-diagnostics.js.map +1 -0
  41. package/dist/core/resolution/binding-graph-order.d.ts +3 -0
  42. package/dist/core/resolution/binding-graph-order.js +49 -0
  43. package/dist/core/resolution/binding-graph-order.js.map +1 -0
  44. package/dist/core/resolution/binding-graph-types.d.ts +46 -0
  45. package/dist/core/resolution/binding-graph-types.js +3 -0
  46. package/dist/core/resolution/binding-graph-types.js.map +1 -0
  47. package/dist/core/resolution/binding-graph-warnings.d.ts +11 -0
  48. package/dist/core/resolution/binding-graph-warnings.js +73 -0
  49. package/dist/core/resolution/binding-graph-warnings.js.map +1 -0
  50. package/dist/core/resolution/binding-graph.d.ts +2 -0
  51. package/dist/core/resolution/binding-graph.js +375 -0
  52. package/dist/core/resolution/binding-graph.js.map +1 -0
  53. package/dist/core/resolution/binding-providers.d.ts +11 -0
  54. package/dist/core/resolution/binding-providers.js +47 -0
  55. package/dist/core/resolution/binding-providers.js.map +1 -0
  56. package/dist/core/resolution/instance-copies.d.ts +5 -0
  57. package/dist/core/resolution/instance-copies.js +109 -0
  58. package/dist/core/resolution/instance-copies.js.map +1 -0
  59. package/dist/core/resolution/interface-dependencies.d.ts +1 -0
  60. package/dist/core/resolution/interface-dependencies.js +27 -0
  61. package/dist/core/resolution/interface-dependencies.js.map +1 -0
  62. package/dist/core/resolution/interface-instances.d.ts +28 -0
  63. package/dist/core/resolution/interface-instances.js +188 -0
  64. package/dist/core/resolution/interface-instances.js.map +1 -0
  65. package/dist/core/resolution/interface-resolution-error.d.ts +24 -0
  66. package/dist/core/resolution/interface-resolution-error.js +30 -0
  67. package/dist/core/resolution/interface-resolution-error.js.map +1 -0
  68. package/dist/core/resolution/resolver-detour.js +14 -22
  69. package/dist/core/resolution/resolver-detour.js.map +1 -1
  70. package/dist/core/resolution/resolver.d.ts +30 -72
  71. package/dist/core/resolution/resolver.js +201 -659
  72. package/dist/core/resolution/resolver.js.map +1 -1
  73. package/dist/core/runtime/build-runtime.d.ts +1 -1
  74. package/dist/core/runtime/build-runtime.js +9 -1
  75. package/dist/core/runtime/build-runtime.js.map +1 -1
  76. package/dist/core/runtime/dev-server-registry.js +1 -1
  77. package/dist/core/runtime/dev-server-registry.js.map +1 -1
  78. package/dist/core/runtime/launch-sequence.js +68 -24
  79. package/dist/core/runtime/launch-sequence.js.map +1 -1
  80. package/dist/core/runtime/launch-steps.d.ts +5 -0
  81. package/dist/core/runtime/launch-steps.js +26 -0
  82. package/dist/core/runtime/launch-steps.js.map +1 -0
  83. package/dist/core/runtime/module-loading.d.ts +1 -0
  84. package/dist/core/runtime/module-loading.js +18 -5
  85. package/dist/core/runtime/module-loading.js.map +1 -1
  86. package/dist/core/runtime/project-launch.js +33 -12
  87. package/dist/core/runtime/project-launch.js.map +1 -1
  88. package/dist/core/runtime/runtime-bootstrap.js +0 -3
  89. package/dist/core/runtime/runtime-bootstrap.js.map +1 -1
  90. package/dist/core/runtime/runtime-policy.js.map +1 -1
  91. package/dist/core/runtime/runtime-types.d.ts +3 -2
  92. package/dist/core/shutdown/shutdown-manager.d.ts +2 -0
  93. package/dist/core/shutdown/shutdown-manager.js +11 -2
  94. package/dist/core/shutdown/shutdown-manager.js.map +1 -1
  95. package/dist/core/version-checker.d.ts +2 -2
  96. package/dist/core/version-checker.js +49 -31
  97. package/dist/core/version-checker.js.map +1 -1
  98. package/dist/core/watch/file-watcher.d.ts +7 -0
  99. package/dist/core/watch/file-watcher.js +70 -14
  100. package/dist/core/watch/file-watcher.js.map +1 -1
  101. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-isolation.js","sourceRoot":"","sources":["../../src/core/module-isolation.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,12 @@ import { ModuleRegistry } from "./module-registry";
5
5
  import type { UnresolvedInterface } from "./resolution/interface-resolution";
6
6
  import { type ModuleManifest } from "./module-manifest";
7
7
  import { type InterfaceConnectionRef, InterfaceRegistry } from "./interface-registry";
8
+ import type { BindingGraph } from "./resolution/binding-graph-types";
8
9
  export interface ModuleConfig {
9
10
  config?: unknown;
10
11
  importOverrides?: Map<string, InterfaceConnectionRef[]>;
11
12
  disabledExports?: Set<string>;
13
+ exportPriority?: Map<string, number>;
12
14
  }
13
15
  export interface ManagedModule {
14
16
  module: Module;
@@ -35,6 +37,8 @@ export declare class ModuleManager {
35
37
  private readonly interfacePackagePlans;
36
38
  private readonly configVars;
37
39
  private pendingCleanup;
40
+ private bindingGraph?;
41
+ private readonly isolation;
38
42
  private startupOrder;
39
43
  constructor(deps?: ModuleManagerDeps);
40
44
  addStaticModule(entry: {
@@ -45,6 +49,7 @@ export declare class ModuleManager {
45
49
  manifest: ModuleManifest;
46
50
  config?: ModuleConfig;
47
51
  }>): ManagedModule[];
52
+ private restoreModules;
48
53
  listModules(): string[];
49
54
  getModule(id: string): Module | undefined;
50
55
  getModuleEntry(id: string): ManagedModule | undefined;
@@ -55,12 +60,17 @@ export declare class ModuleManager {
55
60
  private evictModuleFiles;
56
61
  private collectAvoidedFolders;
57
62
  private belongsToInterfacePackageTree;
63
+ setInstanceRoot(root: string): void;
64
+ placeModule(moduleId: string, manifest: ModuleManifest): ModuleManifest;
65
+ checkReplacement(moduleId: string, replacement: Module): void;
66
+ discardPlacedModule(manifest: ModuleManifest): void;
58
67
  replaceLoadedModule(id: string, module: Module): ManagedModule | undefined;
59
68
  refreshAssociations(): void;
60
69
  hasResolvedInterface(moduleId: string, interfaceName: string): boolean;
61
70
  registerStubbedInterfaces(stubbed: UnresolvedInterface[]): void;
62
71
  private registerStubbedInterfacePackage;
63
72
  private applyInterfaceStubs;
73
+ private neutralizeInstances;
64
74
  private collectImplementedInterfaces;
65
75
  constructAll(): Promise<void>;
66
76
  constructModules(modules: ManagedModule[]): Promise<void>;
@@ -85,20 +95,28 @@ export declare class ModuleManager {
85
95
  private clearManagedState;
86
96
  private releaseRuntimeState;
87
97
  private trackModuleStart;
98
+ getBindingGraph(): BindingGraph | undefined;
88
99
  private rebuildAssociations;
100
+ private buildBindings;
101
+ private runningBindings;
102
+ private logBindingWarnings;
103
+ private bindablePackages;
104
+ private collectBindingInterfaces;
105
+ private collectBindingModules;
89
106
  private collectInterfaceSources;
90
107
  private resolveInterfacePackagePaths;
91
108
  private resolveImplementedPackage;
92
109
  private collectInterfacePackageConsumers;
93
110
  private registerInterfacePackage;
94
111
  private validateInterfacePackages;
95
- private findVersionErrors;
96
- private findPreloadedCopyErrors;
112
+ private findRangeConflicts;
113
+ private findPreloadedCopies;
97
114
  private buildModuleAssociations;
98
115
  private addDefaultAssociations;
99
116
  private applyImportOverrides;
100
117
  private addInterfaceSource;
101
118
  private validateImportOverrides;
102
- private configureModuleContexts;
119
+ private validateOverrideSource;
120
+ private validateSelfHostedConnection;
103
121
  }
104
122
  export {};
@@ -38,6 +38,7 @@ const path = __importStar(require("node:path"));
38
38
  const semver_1 = require("semver");
39
39
  const logging_1 = require("@antelopejs/interface-core/logging");
40
40
  const module_1 = require("./module");
41
+ const module_isolation_1 = require("./module-isolation");
41
42
  const types_1 = require("../types");
42
43
  const module_tracker_1 = require("./module-tracker");
43
44
  const resolver_1 = require("./resolution/resolver");
@@ -51,7 +52,12 @@ const config_var_graph_1 = require("./config/config-var-graph");
51
52
  const interface_registry_1 = require("./interface-registry");
52
53
  const stub_interface_runtime_1 = require("./resolution/stub-interface-runtime");
53
54
  const package_resolution_1 = require("./resolution/package-resolution");
55
+ const binding_graph_1 = require("./resolution/binding-graph");
56
+ const binding_diagnostics_1 = require("./resolution/binding-diagnostics");
57
+ const interface_dependencies_1 = require("./resolution/interface-dependencies");
58
+ const interface_resolution_error_1 = require("./resolution/interface-resolution-error");
54
59
  const Logger = new logging_1.Logging.Channel("loader");
60
+ const INTERFACE_CORE_PACKAGE = "@antelopejs/interface-core";
55
61
  function compareModuleIds(left, right) {
56
62
  return left.localeCompare(right);
57
63
  }
@@ -70,6 +76,8 @@ class ModuleManager {
70
76
  interfacePackagePlans = new Map();
71
77
  configVars = new config_var_store_1.ConfigVarStore();
72
78
  pendingCleanup = [];
79
+ bindingGraph;
80
+ isolation = new module_isolation_1.ModuleIsolation();
73
81
  startupOrder = [];
74
82
  constructor(deps = {}) {
75
83
  this.registry = deps.registry ?? new module_registry_1.ModuleRegistry();
@@ -84,27 +92,54 @@ class ModuleManager {
84
92
  config: entry.config?.config,
85
93
  importOverrides: entry.config?.importOverrides ?? new Map(),
86
94
  disabledExports: entry.config?.disabledExports ?? new Set(),
95
+ exportPriority: entry.config?.exportPriority ?? new Map(),
87
96
  };
88
97
  this.registry.register(module);
89
98
  this.staticModules.push({ module, config });
90
99
  }
91
100
  addModules(entries) {
92
101
  const created = [];
102
+ const replaced = new Map();
93
103
  for (const entry of entries) {
94
- const module = new module_1.Module(entry.manifest);
104
+ replaced.set(entry.manifest.name, this.loaded.get(entry.manifest.name));
105
+ const manifest = this.placeModule(entry.manifest.name, entry.manifest);
106
+ const module = new module_1.Module(manifest);
107
+ this.isolation.adopt(module.id, manifest);
95
108
  const config = {
96
109
  config: entry.config?.config,
97
110
  importOverrides: entry.config?.importOverrides ?? new Map(),
98
111
  disabledExports: entry.config?.disabledExports ?? new Set(),
112
+ exportPriority: entry.config?.exportPriority ?? new Map(),
99
113
  };
100
114
  this.registry.register(module);
101
115
  const managed = { module, config };
102
116
  this.loaded.set(module.id, managed);
103
117
  created.push(managed);
104
118
  }
105
- this.rebuildAssociations();
119
+ try {
120
+ this.rebuildAssociations();
121
+ }
122
+ catch (error) {
123
+ this.restoreModules(replaced);
124
+ throw error;
125
+ }
106
126
  return created;
107
127
  }
128
+ restoreModules(replaced) {
129
+ for (const [id, previous] of replaced) {
130
+ this.isolation.forget(id);
131
+ if (previous) {
132
+ this.loaded.set(id, previous);
133
+ this.registry.register(previous.module);
134
+ this.isolation.adopt(id, previous.module.manifest);
135
+ }
136
+ else {
137
+ this.loaded.delete(id);
138
+ this.registry.unregister(id);
139
+ }
140
+ }
141
+ this.rebuildAssociations();
142
+ }
108
143
  listModules() {
109
144
  return this.registry.list();
110
145
  }
@@ -172,11 +207,39 @@ class ModuleManager {
172
207
  }
173
208
  return isInModule(path.resolve(root));
174
209
  }
210
+ setInstanceRoot(root) {
211
+ this.isolation.setRoot(root);
212
+ }
213
+ placeModule(moduleId, manifest) {
214
+ return this.isolation.place(moduleId, manifest);
215
+ }
216
+ checkReplacement(moduleId, replacement) {
217
+ const entry = this.loaded.get(moduleId);
218
+ if (!entry) {
219
+ return;
220
+ }
221
+ const modules = this.collectBindingModules();
222
+ modules.set(moduleId, toBindingModule(replacement, entry.config, this.bindablePackages(), this.resolvedConnections));
223
+ const running = this.runningBindings();
224
+ running.delete(moduleId);
225
+ const graph = (0, binding_graph_1.buildBindingGraph)({
226
+ interfaces: this.collectBindingInterfaces(),
227
+ modules,
228
+ running,
229
+ });
230
+ if (graph.errors.length > 0) {
231
+ throw new binding_diagnostics_1.InterfaceBindingError(graph.errors);
232
+ }
233
+ }
234
+ discardPlacedModule(manifest) {
235
+ this.isolation.discard(manifest);
236
+ }
175
237
  replaceLoadedModule(id, module) {
176
238
  const entry = this.loaded.get(id);
177
239
  if (!entry) {
178
240
  return;
179
241
  }
242
+ this.isolation.adopt(id, module.manifest);
180
243
  entry.module = module;
181
244
  this.registry.register(module);
182
245
  return entry;
@@ -193,6 +256,7 @@ class ModuleManager {
193
256
  const entries = stubbed.filter((entry) => entry.interfacePackage === packageName);
194
257
  this.registerStubbedInterfacePackage(packageName, entries);
195
258
  }
259
+ this.buildBindings();
196
260
  }
197
261
  registerStubbedInterfacePackage(packageName, entries) {
198
262
  const consumers = this.collectInterfacePackageConsumers(packageName);
@@ -222,14 +286,22 @@ class ModuleManager {
222
286
  if (!this.resolver.interfacePackages.has(interfaceName)) {
223
287
  this.registerInterfacePackage(interfaceName, resolvedPackage, true);
224
288
  }
289
+ this.neutralizeInstances(interfaceName);
290
+ }
291
+ }
292
+ neutralizeInstances(interfaceName) {
293
+ for (const instance of this.resolver.instances.keysOf(interfaceName)) {
294
+ let root;
225
295
  try {
226
- require(interfaceName);
296
+ root = this.resolver.loadInstance(instance);
227
297
  }
228
298
  catch (err) {
229
- Logger.Error(`Failed to load interface '${interfaceName}':`, err);
299
+ Logger.Error(`Failed to load interface '${instance}':`, err);
230
300
  continue;
231
301
  }
232
- (0, stub_interface_runtime_1.neutralizeInterfacePackage)(resolvedPackage.root, interfaceName);
302
+ if (root) {
303
+ (0, stub_interface_runtime_1.neutralizeInterfacePackage)(root, interfaceName);
304
+ }
233
305
  }
234
306
  }
235
307
  collectImplementedInterfaces() {
@@ -249,7 +321,7 @@ class ModuleManager {
249
321
  let plan;
250
322
  let provided;
251
323
  try {
252
- this.configureModuleContexts();
324
+ this.logBindingWarnings();
253
325
  this.validateInterfacePackages();
254
326
  this.applyInterfaceStubs();
255
327
  plan = this.planConfigVars(modules);
@@ -278,7 +350,7 @@ class ModuleManager {
278
350
  async constructModules(modules) {
279
351
  const leaseAcquired = this.resolverDetour.attach();
280
352
  try {
281
- this.configureModuleContexts();
353
+ this.logBindingWarnings();
282
354
  this.validateInterfacePackages();
283
355
  this.applyInterfaceStubs();
284
356
  await Promise.all(modules
@@ -334,6 +406,8 @@ class ModuleManager {
334
406
  for (const id of this.loaded.keys()) {
335
407
  this.evictModuleFiles(id, false);
336
408
  }
409
+ this.isolation.releaseAll();
410
+ this.resolver.releaseInstances();
337
411
  const errors = [...results.errors, ...this.clearManagedState()];
338
412
  if (errors.length > 0) {
339
413
  throw new AggregateError(errors, "Failed to destroy modules");
@@ -436,20 +510,24 @@ class ModuleManager {
436
510
  !config.disabledExports?.has(interfaceName));
437
511
  }
438
512
  rejectCallsInto(moduleId, interfaceName) {
439
- const packageRoot = this.resolver.interfacePackages.get(interfaceName);
440
513
  const entry = this.getModuleEntry(moduleId);
441
- if (!packageRoot || !entry) {
514
+ if (!entry) {
442
515
  return;
443
516
  }
517
+ let instanceRoot;
444
518
  try {
445
- require(interfaceName);
519
+ instanceRoot = this.resolver.loadInstance(`${interfaceName}@${moduleId}`);
446
520
  }
447
521
  catch (error) {
448
522
  Logger.Trace(`Could not load interface '${interfaceName}' to fail calls into '${moduleId}':`, error);
449
523
  return;
450
524
  }
525
+ if (!instanceRoot) {
526
+ return;
527
+ }
528
+ const root = instanceRoot;
451
529
  Logger.Debug(`Interface '${interfaceName}' lost its provider '${moduleId}'; calls into it now reject.`);
452
- entry.module.runInContext(() => (0, stub_interface_runtime_1.neutralizeInterfacePackage)(packageRoot, interfaceName, `has no provider: module '${moduleId}' did not construct`));
530
+ entry.module.runInContext(() => (0, stub_interface_runtime_1.neutralizeInterfacePackage)(root, interfaceName, `has no provider: module '${moduleId}' did not construct`));
453
531
  }
454
532
  findFailedProvider(plan, moduleId, failed) {
455
533
  return [...(plan.dependencies.get(moduleId) ?? [])].find((provider) => failed.has(provider));
@@ -530,10 +608,69 @@ class ModuleManager {
530
608
  this.startupOrder = this.startupOrder.filter((id) => id !== moduleId);
531
609
  this.startupOrder.push(moduleId);
532
610
  }
611
+ getBindingGraph() {
612
+ return this.bindingGraph;
613
+ }
533
614
  rebuildAssociations() {
534
615
  (0, package_resolution_1.clearPathResolutionCache)();
535
616
  const interfaceSources = this.collectInterfaceSources();
536
617
  this.buildModuleAssociations(interfaceSources);
618
+ this.buildBindings();
619
+ }
620
+ buildBindings() {
621
+ const graph = (0, binding_graph_1.buildBindingGraph)({
622
+ interfaces: this.collectBindingInterfaces(),
623
+ modules: this.collectBindingModules(),
624
+ running: this.runningBindings(),
625
+ });
626
+ if (graph.errors.length > 0) {
627
+ throw new binding_diagnostics_1.InterfaceBindingError(graph.errors);
628
+ }
629
+ this.bindingGraph = graph;
630
+ this.resolver.setBindings(graph);
631
+ }
632
+ runningBindings() {
633
+ const running = new Map();
634
+ for (const { module } of this.getAllManagedModules()) {
635
+ const scope = this.bindingGraph?.modules.get(module.id)?.scope;
636
+ if (module.state === types_1.ModuleState.Loaded || !scope) {
637
+ continue;
638
+ }
639
+ const bindings = new Map();
640
+ scope.forEach((binding, interfaceName) => {
641
+ if (binding.provider) {
642
+ bindings.set(interfaceName, binding.provider);
643
+ }
644
+ });
645
+ running.set(module.id, bindings);
646
+ }
647
+ return running;
648
+ }
649
+ logBindingWarnings() {
650
+ this.bindingGraph?.warnings.forEach((warning) => Logger.Warn(warning));
651
+ }
652
+ bindablePackages() {
653
+ return new Set([...this.resolver.interfacePackages.keys()].filter((packageName) => packageName !== INTERFACE_CORE_PACKAGE));
654
+ }
655
+ collectBindingInterfaces() {
656
+ const packages = this.bindablePackages();
657
+ const interfaces = new Map();
658
+ for (const name of packages) {
659
+ const root = this.resolver.interfacePackages.get(name);
660
+ interfaces.set(name, {
661
+ name,
662
+ dependencies: (0, interface_dependencies_1.readInterfaceDependencies)(name, root, packages),
663
+ });
664
+ }
665
+ return interfaces;
666
+ }
667
+ collectBindingModules() {
668
+ const packages = this.bindablePackages();
669
+ const modules = new Map();
670
+ for (const { module, config } of this.getAllManagedModules()) {
671
+ modules.set(module.id, toBindingModule(module, config, packages, this.resolvedConnections));
672
+ }
673
+ return modules;
537
674
  }
538
675
  collectInterfaceSources() {
539
676
  this.resolver.moduleByFolder.clear();
@@ -652,41 +789,49 @@ class ModuleManager {
652
789
  this.resolver.lifecycleInterfacePackages.delete(packageName);
653
790
  }
654
791
  validateInterfacePackages() {
655
- const errors = [...this.interfacePackagePlans].flatMap(([name, plan]) => [
656
- ...this.findVersionErrors(name, plan),
657
- ...this.findPreloadedCopyErrors(name, plan),
658
- ]);
659
- if (errors.length === 0) {
792
+ const plans = [...this.interfacePackagePlans];
793
+ const rangeConflicts = plans.flatMap(([name, plan]) => this.findRangeConflicts(name, plan));
794
+ const preloadedCopies = plans.flatMap(([name, plan]) => this.findPreloadedCopies(name, plan));
795
+ if (rangeConflicts.length === 0 && preloadedCopies.length === 0) {
660
796
  return;
661
797
  }
662
- throw new Error(`Incompatible interface package resolution:\n${errors.join("\n")}`);
798
+ throw new interface_resolution_error_1.InterfaceResolutionError({ rangeConflicts, preloadedCopies });
663
799
  }
664
- findVersionErrors(packageName, plan) {
800
+ findRangeConflicts(packageName, plan) {
665
801
  return plan.consumers.flatMap((consumer) => {
666
802
  const range = (0, semver_1.validRange)(consumer.range);
667
803
  if (!range || (0, semver_1.satisfies)(plan.canonicalPackage.version, range)) {
668
804
  return [];
669
805
  }
670
- const installed = consumer.resolvedPackage
671
- ? `${consumer.resolvedPackage.version} at ${consumer.resolvedPackage.root}`
672
- : "not installed from the consumer";
673
806
  return [
674
- ` - ${consumer.moduleId} requires ${packageName}@${consumer.range}, but the canonical package is ${plan.canonicalPackage.version} at ${plan.canonicalPackage.root} (consumer copy: ${installed})`,
807
+ {
808
+ moduleId: consumer.moduleId,
809
+ packageName,
810
+ range: consumer.range,
811
+ canonical: plan.canonicalPackage,
812
+ consumerCopy: consumer.resolvedPackage,
813
+ },
675
814
  ];
676
815
  });
677
816
  }
678
- findPreloadedCopyErrors(packageName, plan) {
817
+ findPreloadedCopies(packageName, plan) {
679
818
  const canonicalRoot = plan.canonicalPackage.realRoot;
680
- const copies = plan.consumers
681
- .map((consumer) => consumer.resolvedPackage)
682
- .filter((resolvedPackage) => Boolean(resolvedPackage && resolvedPackage.realRoot !== canonicalRoot));
683
819
  const loadedFiles = Object.keys(require.cache);
684
- return copies.flatMap((copy) => {
820
+ return plan.consumers.flatMap(({ moduleId, resolvedPackage: copy }) => {
821
+ if (!copy || copy.realRoot === canonicalRoot) {
822
+ return [];
823
+ }
685
824
  const isInCopy = (0, package_resolution_1.createPathWithinMatcher)(copy.root);
686
825
  const loadedFile = loadedFiles.find((filePath) => isInCopy(filePath));
687
826
  return loadedFile
688
827
  ? [
689
- ` - ${packageName}@${copy.version} was loaded from ${copy.root} before the canonical copy at ${plan.canonicalPackage.root}; preloaded interface copies cannot be redirected (${loadedFile})`,
828
+ {
829
+ moduleId,
830
+ packageName,
831
+ copy,
832
+ canonical: plan.canonicalPackage,
833
+ loadedFile,
834
+ },
690
835
  ]
691
836
  : [];
692
837
  });
@@ -725,7 +870,12 @@ class ModuleManager {
725
870
  for (const [iface, overrides] of importOverrides.entries()) {
726
871
  this.validateImportOverrides(moduleId, iface, overrides);
727
872
  connections.set(iface, overrides);
728
- selected.set(iface, overrides[0].module);
873
+ if (overrides[0].module === undefined) {
874
+ selected.delete(iface);
875
+ }
876
+ else {
877
+ selected.set(iface, overrides[0].module);
878
+ }
729
879
  }
730
880
  }
731
881
  addInterfaceSource(sources, interfaceName, module) {
@@ -739,12 +889,7 @@ class ModuleManager {
739
889
  }
740
890
  const connectionIds = new Set();
741
891
  for (const override of overrides) {
742
- const target = this.getModuleEntry(override.module);
743
- const implementsInterface = target?.module.manifest.implements.includes(interfaceName) &&
744
- !target.config.disabledExports?.has(interfaceName);
745
- if (!implementsInterface) {
746
- throw new Error(`Module '${consumerId}' routes '${interfaceName}' to '${override.module}', but that loaded module does not provide the interface.`);
747
- }
892
+ this.validateOverrideSource(consumerId, interfaceName, override.module);
748
893
  if (override.id && connectionIds.has(override.id)) {
749
894
  throw new Error(`Module '${consumerId}' has duplicate connection ID '${override.id}' for '${interfaceName}'.`);
750
895
  }
@@ -753,14 +898,47 @@ class ModuleManager {
753
898
  }
754
899
  }
755
900
  }
756
- configureModuleContexts() {
757
- for (const { module, config } of this.getAllManagedModules()) {
758
- const isProvider = (module.manifest.implements ?? []).some((interfaceName) => !config.disabledExports?.has(interfaceName));
759
- module.setProviderRoutes(this.resolver.buildProviderRoutes(module.id), isProvider);
901
+ validateOverrideSource(consumerId, interfaceName, source) {
902
+ if (source === undefined) {
903
+ this.validateSelfHostedConnection(consumerId, interfaceName);
904
+ return;
905
+ }
906
+ const target = this.getModuleEntry(source);
907
+ const implementsInterface = target?.module.manifest.implements.includes(interfaceName) &&
908
+ !target.config.disabledExports?.has(interfaceName);
909
+ if (!implementsInterface) {
910
+ throw new Error(`Module '${consumerId}' routes '${interfaceName}' to '${source}', but that loaded module does not provide the interface.`);
911
+ }
912
+ }
913
+ validateSelfHostedConnection(consumerId, interfaceName) {
914
+ if (this.hasLiveImplementer(interfaceName, new Set())) {
915
+ throw new Error(`Module '${consumerId}' declares a '${interfaceName}' connection without a source, but loaded modules provide that interface; name the provider.`);
760
916
  }
761
917
  }
762
918
  }
763
919
  exports.ModuleManager = ModuleManager;
920
+ function toBindingConnections(connections) {
921
+ return new Map([...(connections ?? [])].map(([interfaceName, refs]) => [
922
+ interfaceName,
923
+ refs.map(({ module: source, id }) => ({ source, id })),
924
+ ]));
925
+ }
926
+ function toBindingModule(module, config, packages, listed) {
927
+ const manifest = module.manifest.manifest;
928
+ const declared = {
929
+ ...manifest.optionalDependencies,
930
+ ...manifest.dependencies,
931
+ };
932
+ const connections = toBindingConnections(config.importOverrides);
933
+ return {
934
+ id: module.id,
935
+ implements: (module.manifest.implements ?? []).filter((name) => packages.has(name) && !config.disabledExports?.has(name)),
936
+ uses: Object.keys(declared).filter((name) => packages.has(name)),
937
+ connections,
938
+ listedConnections: toBindingConnections(listed.get(module.id)),
939
+ exportPriority: config.exportPriority ?? new Map(),
940
+ };
941
+ }
764
942
  function collectRejectedErrors(results) {
765
943
  return results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
766
944
  }