@dougongjs/core 0.0.3 → 0.2.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 (68) hide show
  1. package/README.md +18 -18
  2. package/dist/change-set.d.ts +27 -27
  3. package/dist/change-set.d.ts.map +1 -1
  4. package/dist/configuration.d.ts +4 -0
  5. package/dist/configuration.d.ts.map +1 -0
  6. package/dist/contract-registry.d.ts +1 -1
  7. package/dist/contract-registry.d.ts.map +1 -1
  8. package/dist/contracts.d.ts +7 -5
  9. package/dist/contracts.d.ts.map +1 -1
  10. package/dist/contribution-store.d.ts +48 -0
  11. package/dist/contribution-store.d.ts.map +1 -0
  12. package/dist/diagnostics.d.ts +13 -12
  13. package/dist/diagnostics.d.ts.map +1 -1
  14. package/dist/engine.d.ts +33 -0
  15. package/dist/engine.d.ts.map +1 -0
  16. package/dist/errors.d.ts +6 -9
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/event-hub.d.ts +6 -2
  19. package/dist/event-hub.d.ts.map +1 -1
  20. package/dist/group-coordinator.d.ts +27 -26
  21. package/dist/group-coordinator.d.ts.map +1 -1
  22. package/dist/group-lifecycle.d.ts +2 -2
  23. package/dist/group-lifecycle.d.ts.map +1 -1
  24. package/dist/group.d.ts +2 -2
  25. package/dist/group.d.ts.map +1 -1
  26. package/dist/host-api.d.ts +75 -0
  27. package/dist/host-api.d.ts.map +1 -0
  28. package/dist/host.d.ts +6 -0
  29. package/dist/host.d.ts.map +1 -0
  30. package/dist/index.d.ts +8 -7
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1500 -1190
  33. package/dist/installation-graph.d.ts +17 -0
  34. package/dist/installation-graph.d.ts.map +1 -0
  35. package/dist/installation-registry.d.ts +49 -0
  36. package/dist/installation-registry.d.ts.map +1 -0
  37. package/dist/installation.d.ts +46 -0
  38. package/dist/installation.d.ts.map +1 -0
  39. package/dist/lifecycle-status.d.ts +2 -0
  40. package/dist/lifecycle-status.d.ts.map +1 -0
  41. package/dist/lifetime-diagnostics.d.ts +2 -2
  42. package/dist/lifetime-diagnostics.d.ts.map +1 -1
  43. package/dist/lifetime.d.ts +29 -24
  44. package/dist/lifetime.d.ts.map +1 -1
  45. package/dist/plugin.d.ts +23 -7
  46. package/dist/plugin.d.ts.map +1 -1
  47. package/dist/readonly-map.d.ts.map +1 -1
  48. package/dist/record.d.ts +8 -0
  49. package/dist/record.d.ts.map +1 -0
  50. package/dist/resource.d.ts +15 -3
  51. package/dist/resource.d.ts.map +1 -1
  52. package/dist/runtime.d.ts +36 -0
  53. package/dist/runtime.d.ts.map +1 -0
  54. package/dist/snapshot-view.d.ts +2 -2
  55. package/dist/snapshot-view.d.ts.map +1 -1
  56. package/package.json +7 -1
  57. package/dist/application-api.d.ts +0 -51
  58. package/dist/application-api.d.ts.map +0 -1
  59. package/dist/application-runtime.d.ts +0 -36
  60. package/dist/application-runtime.d.ts.map +0 -1
  61. package/dist/application.d.ts +0 -6
  62. package/dist/application.d.ts.map +0 -1
  63. package/dist/extension-store.d.ts +0 -46
  64. package/dist/extension-store.d.ts.map +0 -1
  65. package/dist/plugin-graph.d.ts +0 -17
  66. package/dist/plugin-graph.d.ts.map +0 -1
  67. package/dist/plugin-installation.d.ts +0 -44
  68. package/dist/plugin-installation.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,91 +1,150 @@
1
- function F(r, t) {
1
+ function rt(r, t) {
2
2
  if (typeof t != "string" || !t.trim())
3
3
  throw new TypeError(`${r} id must be a non-empty string`);
4
4
  if (t !== t.trim())
5
5
  throw new TypeError(`${r} id cannot start or end with whitespace`);
6
6
  }
7
- function k(r, t) {
8
- return F("Contract", t), Object.freeze({ id: t, kind: r });
7
+ function V(r, t) {
8
+ return rt("Contract", t), Object.freeze({ id: t, kind: r });
9
9
  }
10
- function w(r, t) {
10
+ function v(r, t) {
11
11
  if (!r || typeof r != "object") return !1;
12
12
  const e = r;
13
- return typeof e.id == "string" && e.id.length > 0 && e.id === e.id.trim() && (e.kind === "service" || e.kind === "extension" || e.kind === "event") && (t === void 0 || e.kind === t);
13
+ return typeof e.id == "string" && e.id.length > 0 && e.id === e.id.trim() && (e.kind === "service" || e.kind === "extensionPoint" || e.kind === "event") && (t === void 0 || e.kind === t);
14
14
  }
15
- function v(r, t) {
16
- if (!w(r, t))
17
- throw new TypeError(t ? `Expected a ${t} contract` : "Invalid contract");
15
+ function b(r, t) {
16
+ if (!v(r, t))
17
+ throw new TypeError(t ? `Expected ${nt(t)}` : "Invalid contract");
18
18
  }
19
- function qt(r) {
20
- return k("service", r);
19
+ function nt(r) {
20
+ return r === "extensionPoint" ? "an ExtensionPoint" : r === "event" ? "an Event" : "a Service";
21
21
  }
22
- function Dt(r) {
23
- return k("event", r);
22
+ function de(r) {
23
+ return V("service", r);
24
24
  }
25
- function Gt(r) {
26
- return k("extension", r);
25
+ function le(r) {
26
+ return V("event", r);
27
27
  }
28
- function Vt(r) {
29
- if (!w(r, "service"))
30
- throw new TypeError("optional() expects a service contract");
28
+ function ue(r) {
29
+ return V("extensionPoint", r);
30
+ }
31
+ function fe(r) {
32
+ if (!v(r, "service"))
33
+ throw new TypeError("optional() expects a Service");
31
34
  return Object.freeze({ kind: "optional", service: r });
32
35
  }
33
- class p extends Error {
36
+ function ot(r) {
37
+ if (!r || typeof r != "object") return !1;
38
+ const t = r;
39
+ return t.kind === "optional" && v(t.service, "service");
40
+ }
41
+ class u extends Error {
34
42
  constructor(t, e, i) {
35
43
  super(e, i), this.code = t;
36
44
  }
37
45
  code;
38
46
  name = "DougongError";
39
47
  }
48
+ class P extends u {
49
+ }
40
50
  function $(r, t, e) {
41
- return r instanceof Error ? r : new p(t, e, { cause: r });
51
+ return r instanceof P ? r.code === t ? r : new P(t, e, { cause: r.cause }) : r instanceof Error ? r : new P(t, e, { cause: r });
52
+ }
53
+ function J(r, t) {
54
+ if (!r || typeof r != "object" || typeof r.aborted != "boolean" || typeof r.addEventListener != "function" || typeof r.removeEventListener != "function" || typeof r.throwIfAborted != "function")
55
+ throw new TypeError("Cancellation classifier expects an AbortSignal");
56
+ return r.aborted ? Object.is(t, r.reason) ? !0 : t instanceof Error && t.name === "AbortError" : !1;
42
57
  }
43
- class H extends p {
58
+ class at extends u {
44
59
  name = "ConfigValidationError";
45
60
  issues;
46
61
  constructor(t) {
47
- const e = Object.freeze(
48
- t.map(
49
- (i) => Object.freeze({
50
- message: i.message,
51
- ...i.path === void 0 ? {} : {
52
- path: Object.freeze(
53
- i.path.map(
54
- (s) => typeof s == "object" && s !== null ? Object.freeze({ key: s.key }) : s
55
- )
56
- )
57
- }
58
- })
59
- )
60
- );
62
+ const e = ct(t);
61
63
  super(
62
64
  "CONFIG_INVALID",
63
- `Invalid plugin config:
65
+ `Invalid Plugin config:
64
66
  ${e.map((i) => ` - ${i.message}`).join(`
65
67
  `)}`
66
68
  ), this.issues = e;
67
69
  }
68
70
  }
69
- class K {
71
+ function ct(r) {
72
+ if (!Array.isArray(r))
73
+ throw new TypeError("Config validation issues must be an array");
74
+ return Object.freeze(
75
+ Array.from(r, (t, e) => {
76
+ if (!t || typeof t != "object")
77
+ throw new TypeError(`Config validation issue at index ${e} must be an object`);
78
+ const i = t;
79
+ if (typeof i.message != "string")
80
+ throw new TypeError(`Config validation issue at index ${e} message must be a string`);
81
+ return Object.freeze({
82
+ message: i.message,
83
+ ...i.path === void 0 ? {} : { path: ht(i.path, e) }
84
+ });
85
+ })
86
+ );
87
+ }
88
+ function ht(r, t) {
89
+ if (!Array.isArray(r))
90
+ throw new TypeError(`Config validation issue at index ${t} path must be an array`);
91
+ return Object.freeze(
92
+ Array.from(r, (e, i) => {
93
+ if (G(e)) return e;
94
+ if (!e || typeof e != "object")
95
+ throw new TypeError(
96
+ `Config validation issue at index ${t} path segment ${i} must be a property key`
97
+ );
98
+ const s = e.key;
99
+ if (!G(s))
100
+ throw new TypeError(
101
+ `Config validation issue at index ${t} path segment ${i} must contain a property key`
102
+ );
103
+ return Object.freeze({ key: s });
104
+ })
105
+ );
106
+ }
107
+ function G(r) {
108
+ return typeof r == "string" || typeof r == "number" || typeof r == "symbol";
109
+ }
110
+ async function X(r, t, e) {
111
+ if (!r) return t;
112
+ const i = await r["~standard"].validate(t);
113
+ if (!i || typeof i != "object")
114
+ throw new TypeError(
115
+ `Installation '${e}' config validator returned a non-object result`
116
+ );
117
+ const s = Object.hasOwn(i, "issues") ? i.issues : void 0;
118
+ if (s !== void 0)
119
+ throw Array.isArray(s) ? new at(s) : new TypeError(
120
+ `Installation '${e}' config validator returned non-array issues`
121
+ );
122
+ if (!Object.hasOwn(i, "value"))
123
+ throw new TypeError(
124
+ `Installation '${e}' config validator returned neither value nor issues`
125
+ );
126
+ return i.value;
127
+ }
128
+ class dt {
70
129
  #t = /* @__PURE__ */ new Map();
71
130
  get kinds() {
72
131
  return this.#t;
73
132
  }
74
133
  assertCompatible(t) {
75
- V(this.#t, t);
134
+ Z(this.#t, t);
76
135
  }
77
136
  remember(t) {
78
- S(this.#t, t);
137
+ T(this.#t, t);
79
138
  }
80
139
  draft(t) {
81
- return new W(this, t);
140
+ return new lt(this, t);
82
141
  }
83
142
  commit(t) {
84
143
  for (const [e, i] of t) this.assertCompatible({ id: e, kind: i });
85
144
  for (const [e, i] of t) this.#t.set(e, i);
86
145
  }
87
146
  }
88
- class W {
147
+ class lt {
89
148
  #t;
90
149
  constructor(t, e) {
91
150
  this.#t = { phase: "open", registry: t, pending: /* @__PURE__ */ new Map() };
@@ -98,8 +157,8 @@ class W {
98
157
  return;
99
158
  }
100
159
  if (e.phase === "discarded")
101
- throw new TypeError("Contract registry draft has been discarded");
102
- e.registry.assertCompatible(t), !e.registry.kinds.has(t.id) && S(e.pending, t);
160
+ throw new Error("Contract registry draft has been discarded");
161
+ e.registry.assertCompatible(t), !e.registry.kinds.has(t.id) && T(e.pending, t);
103
162
  }
104
163
  commit() {
105
164
  const t = this.#t;
@@ -109,81 +168,152 @@ class W {
109
168
  this.#t.phase === "open" && (this.#t = { phase: "discarded" });
110
169
  }
111
170
  }
112
- function S(r, t) {
113
- V(r, t), r.set(t.id, t.kind);
171
+ function T(r, t) {
172
+ Z(r, t), r.set(t.id, t.kind);
114
173
  }
115
- function V(r, t) {
174
+ function Z(r, t) {
116
175
  const e = r.get(t.id);
117
176
  if (e && e !== t.kind)
118
- throw new p(
177
+ throw new u(
119
178
  "CONTRACT_CONFLICT",
120
179
  `Contract '${t.id}' is used as both '${e}' and '${t.kind}'`
121
180
  );
122
181
  }
123
- class Y {
124
- #t;
125
- constructor(t) {
126
- this.#t = t, Object.freeze(this);
182
+ class M {
183
+ constructor(t, e, i, s, n, o) {
184
+ this.order = t, this.layers = e, this.providers = i, this.dependents = s, this.contractKinds = n, this.#t = o;
127
185
  }
128
- dispose() {
129
- const t = this.#t;
130
- this.#t = void 0, t?.dispose();
186
+ order;
187
+ layers;
188
+ providers;
189
+ dependents;
190
+ contractKinds;
191
+ #t;
192
+ static build(t, e) {
193
+ const i = [...t].sort((c, d) => c.index - d.index), s = new Map(e), n = ut(i, s), o = ft(i, n, s), { order: a, layers: h } = pt(
194
+ i,
195
+ o.dependents,
196
+ o.indegree
197
+ );
198
+ return new M(
199
+ Object.freeze(a),
200
+ Object.freeze(h.map((c) => Object.freeze(c))),
201
+ n,
202
+ o.dependents,
203
+ s,
204
+ o.resolvedProviders
205
+ );
131
206
  }
132
- [Symbol.dispose]() {
133
- this.dispose();
207
+ providerFor(t, e) {
208
+ return this.#t.get(t)?.get(e);
134
209
  }
135
- }
136
- class Q {
137
- #t;
138
- #e;
139
- handle;
140
- constructor(t, e, i, s) {
141
- this.#e = e, this.#t = { phase: "staged", hub: t, listener: i, release: s }, this.handle = new Y(this);
210
+ provider(t) {
211
+ return this.providers.get(t);
142
212
  }
143
- publish() {
144
- const t = this.#t;
145
- t.phase === "staged" && (t.hub.add(this.#e, t.listener), t.phase = "published");
213
+ affectedByTransitionTo(t, e) {
214
+ const i = /* @__PURE__ */ new Set();
215
+ return this.#e(e, i), t.#e(e, i), i;
146
216
  }
147
- dispose() {
148
- const t = this.#t;
149
- if (t.phase !== "removed") {
150
- this.#t = { phase: "removed" };
151
- try {
152
- t.phase === "published" && t.hub.delete(this.#e, t.listener);
153
- } finally {
154
- t.release(this);
217
+ #e(t, e) {
218
+ const i = [...t], s = /* @__PURE__ */ new Set();
219
+ for (let n = 0; n < i.length; n++) {
220
+ const o = i[n];
221
+ if (o && !s.has(o)) {
222
+ s.add(o), e.add(o);
223
+ for (const a of this.dependents.get(o) ?? []) i.push(a);
155
224
  }
156
225
  }
157
226
  }
158
- [Symbol.dispose]() {
159
- this.dispose();
160
- }
161
227
  }
162
- class J {
163
- #t = /* @__PURE__ */ new Map();
164
- stage(t, e, i) {
165
- if (typeof e != "function") throw new TypeError("Event listener must be a function");
166
- return new Q(this, t, e, i);
167
- }
168
- add(t, e) {
169
- const i = this.#t.get(t) ?? /* @__PURE__ */ new Set();
170
- this.#t.set(t, i), i.add(e);
228
+ function ut(r, t) {
229
+ const e = /* @__PURE__ */ new Map();
230
+ for (const i of r)
231
+ for (const s of Object.values(i.declaration.plugin.provides ?? {})) {
232
+ T(t, s);
233
+ const n = e.get(s.id);
234
+ if (n)
235
+ throw new u(
236
+ "SERVICE_CONFLICT",
237
+ `Service '${s.id}' is provided by both '${n.id}' and '${i.id}'`
238
+ );
239
+ e.set(s.id, i);
240
+ }
241
+ return e;
242
+ }
243
+ function ft(r, t, e) {
244
+ const i = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), n = new Map(r.map((o) => [o, 0]));
245
+ for (const o of r)
246
+ for (const a of Object.values(o.declaration.plugin.requires ?? {})) {
247
+ const h = a.kind === "optional" ? a.service : a;
248
+ if (T(e, h), h.kind === "extensionPoint") continue;
249
+ const c = t.get(h.id);
250
+ if (!c) {
251
+ if (a.kind === "optional") continue;
252
+ throw new u(
253
+ "SERVICE_MISSING",
254
+ `Installation '${o.id}' requires missing Service '${h.id}'`
255
+ );
256
+ }
257
+ if (c === o)
258
+ throw new u(
259
+ "SERVICE_CYCLE",
260
+ `Installation '${o.id}' cannot require Service '${h.id}' that it provides`
261
+ );
262
+ const d = i.get(o) ?? /* @__PURE__ */ new Map();
263
+ d.set(h.id, c), i.set(o, d);
264
+ const l = s.get(c) ?? /* @__PURE__ */ new Set();
265
+ l.has(o) || (l.add(o), s.set(c, l), n.set(o, (n.get(o) ?? 0) + 1));
266
+ }
267
+ return { resolvedProviders: i, dependents: s, indegree: n };
268
+ }
269
+ function pt(r, t, e) {
270
+ let i = r.filter((o) => e.get(o) === 0);
271
+ const s = [], n = [];
272
+ for (; i.length; ) {
273
+ i.sort((a, h) => a.index - h.index);
274
+ const o = i;
275
+ i = [], n.push(o), s.push(...o);
276
+ for (const a of o)
277
+ for (const h of t.get(a) ?? []) {
278
+ const c = (e.get(h) ?? 0) - 1;
279
+ e.set(h, c), c || i.push(h);
280
+ }
171
281
  }
172
- delete(t, e) {
173
- const i = this.#t.get(t);
174
- i && (i.delete(e), i.size || this.#t.delete(t));
282
+ if (s.length !== r.length) {
283
+ const o = gt(r, t);
284
+ throw new u(
285
+ "SERVICE_CYCLE",
286
+ `Installation dependency cycle: ${o.map((a) => a.id).join(" -> ")}`
287
+ );
175
288
  }
176
- async emit(t, e) {
177
- const i = [...this.#t.get(t) ?? []], n = (await Promise.allSettled(
178
- i.map((o) => Promise.resolve().then(() => o(e)))
179
- )).filter((o) => o.status === "rejected").map((o) => o.reason);
180
- if (n.length)
181
- throw new AggregateError(n, `Event '${t}' listeners failed`);
289
+ return { order: s, layers: n };
290
+ }
291
+ function gt(r, t) {
292
+ const e = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), s = [], n = (o) => {
293
+ i.add(o), s.push(o);
294
+ for (const a of t.get(o) ?? []) {
295
+ if (i.has(a)) {
296
+ const c = s.indexOf(a);
297
+ return [...s.slice(c), a];
298
+ }
299
+ if (e.has(a)) continue;
300
+ const h = n(a);
301
+ if (h) return h;
302
+ }
303
+ s.pop(), i.delete(o), e.add(o);
304
+ };
305
+ for (const o of r) {
306
+ if (e.has(o)) continue;
307
+ const a = n(o);
308
+ if (a) return a;
182
309
  }
310
+ throw new Error("Dependency graph is cyclic but no cycle path was found");
183
311
  }
184
- class C {
312
+ class S {
185
313
  #t;
186
- constructor(t) {
314
+ constructor(t = []) {
315
+ if (!t || typeof t != "object" && typeof t != "function" || typeof t[Symbol.iterator] != "function")
316
+ throw new TypeError("ReadonlyMapSnapshot values must be an iterable object");
187
317
  this.#t = new Map(t), Object.freeze(this);
188
318
  }
189
319
  get size() {
@@ -211,7 +341,110 @@ class C {
211
341
  return this.entries();
212
342
  }
213
343
  }
214
- class X {
344
+ function wt(r) {
345
+ if (typeof r != "function")
346
+ throw new Error("Unsupported JavaScript runtime: Promise.withResolvers is required");
347
+ }
348
+ function tt(r, t) {
349
+ return r ?? Symbol.for(t);
350
+ }
351
+ wt(Promise.withResolvers);
352
+ const g = tt(
353
+ Symbol.dispose,
354
+ "Symbol.dispose"
355
+ ), j = tt(
356
+ Symbol.asyncDispose,
357
+ "Symbol.asyncDispose"
358
+ ), m = /* @__PURE__ */ new WeakMap();
359
+ class q {
360
+ #t = /* @__PURE__ */ new Set();
361
+ #e;
362
+ #i;
363
+ #s = !1;
364
+ constructor(t, e) {
365
+ if (typeof t != "function") throw new TypeError("Snapshot reader must be a function");
366
+ if (typeof e != "function")
367
+ throw new TypeError("Snapshot error reporter must be a function");
368
+ this.#e = { phase: "active", read: t, report: e }, this.#i = t(), Object.freeze(this);
369
+ }
370
+ view = Object.freeze({
371
+ get: () => this.#n(),
372
+ subscribe: (t) => this.#o(t)
373
+ });
374
+ invalidate() {
375
+ const { report: t } = this.#a();
376
+ this.#s = !0;
377
+ const e = [];
378
+ for (const i of [...this.#t])
379
+ try {
380
+ bt(i);
381
+ } catch (s) {
382
+ try {
383
+ t(s);
384
+ } catch (n) {
385
+ e.push(s, n);
386
+ }
387
+ }
388
+ if (e.length)
389
+ throw new AggregateError(e, "Snapshot error reporting failed");
390
+ }
391
+ dispose() {
392
+ const t = this.#e;
393
+ if (t.phase !== "disposed") {
394
+ this.#e = { phase: "disposed" };
395
+ try {
396
+ this.#r(t.read);
397
+ } finally {
398
+ this.#s = !1;
399
+ const e = [...this.#t];
400
+ this.#t.clear();
401
+ for (const i of e) mt(i);
402
+ }
403
+ }
404
+ }
405
+ [g]() {
406
+ this.dispose();
407
+ }
408
+ #n() {
409
+ const t = this.#e;
410
+ return t.phase === "active" && this.#r(t.read), this.#i;
411
+ }
412
+ #o(t) {
413
+ if (typeof t != "function") throw new TypeError("Subscriber must be a function");
414
+ this.#a();
415
+ const e = new vt(t, (i) => {
416
+ this.#t.delete(i);
417
+ });
418
+ return this.#t.add(e), e;
419
+ }
420
+ #r(t) {
421
+ this.#s && (this.#i = t(), this.#s = !1);
422
+ }
423
+ #a() {
424
+ const t = this.#e;
425
+ if (t.phase === "disposed") throw new TypeError("Snapshot publisher is disposed");
426
+ return t;
427
+ }
428
+ }
429
+ class vt {
430
+ constructor(t, e) {
431
+ m.set(this, { listener: t, detach: e }), Object.freeze(this);
432
+ }
433
+ dispose() {
434
+ const t = m.get(this);
435
+ t && (m.delete(this), t.detach(this));
436
+ }
437
+ [g]() {
438
+ this.dispose();
439
+ }
440
+ }
441
+ function bt(r) {
442
+ m.get(r)?.listener();
443
+ }
444
+ function mt(r) {
445
+ m.delete(r);
446
+ }
447
+ class yt {
215
448
  #t;
216
449
  get;
217
450
  subscribe;
@@ -219,7 +452,7 @@ class X {
219
452
  this.#t = t, this.get = () => this.#e(), this.subscribe = (e) => this.#i(e), Object.freeze(this);
220
453
  }
221
454
  // The handle retains only revocable binding state. Disposing its lease clears
222
- // the Store edge even when downstream code retains the public view.
455
+ // the ContributionStore edge even when downstream code retains the public view.
223
456
  #e() {
224
457
  return this.#s().store.snapshot();
225
458
  }
@@ -229,11 +462,11 @@ class X {
229
462
  }
230
463
  #s() {
231
464
  const t = this.#t.binding;
232
- if (!t) throw new TypeError("Extension view has been disposed");
465
+ if (!t) throw new TypeError("Contribution view has been disposed");
233
466
  return t;
234
467
  }
235
468
  }
236
- class Z {
469
+ class Et {
237
470
  #t;
238
471
  constructor(t) {
239
472
  this.#t = t, Object.freeze(this);
@@ -244,20 +477,26 @@ class Z {
244
477
  dispose() {
245
478
  this.#t.dispose();
246
479
  }
247
- [Symbol.dispose]() {
480
+ [g]() {
248
481
  this.dispose();
249
482
  }
250
483
  }
251
- class tt {
484
+ class Ct {
252
485
  #t;
253
486
  #e;
254
487
  handle;
255
488
  constructor(t, e, i, s) {
256
- this.#e = e, this.#t = { phase: "staged", store: t, value: i, detachFromOwner: s }, this.handle = new Z(this);
489
+ this.#e = e, this.#t = { phase: "staged", store: t, value: i, detachFromOwner: s }, this.handle = new Et(this);
257
490
  }
258
491
  publish() {
259
492
  const t = this.#t;
260
- t.phase === "staged" && (t.store.insert(this.#e, this, t.value), t.phase = "published");
493
+ t.phase === "staged" && t.store.insert(this.#e, this, t.value);
494
+ }
495
+ commitPublication() {
496
+ const t = this.#t;
497
+ if (t.phase !== "staged")
498
+ throw new Error(`Contribution '${this.#e}' is not staged`);
499
+ t.phase = "published";
261
500
  }
262
501
  update(t) {
263
502
  const e = this.#t;
@@ -276,97 +515,124 @@ class tt {
276
515
  }
277
516
  }
278
517
  }
279
- [Symbol.dispose]() {
518
+ [g]() {
280
519
  this.dispose();
281
520
  }
282
521
  }
283
- class et {
522
+ class Ot {
284
523
  #t;
285
524
  #e;
286
- #i;
525
+ #i = /* @__PURE__ */ new Map();
287
526
  #s = /* @__PURE__ */ new Map();
288
- #r = /* @__PURE__ */ new Map();
289
- #n = /* @__PURE__ */ new Set();
290
- #a = new C();
291
- #o = 0;
527
+ #n;
528
+ #o = new S();
529
+ #r = 0;
530
+ #a = 0;
531
+ #d = !1;
532
+ #f = !1;
292
533
  constructor(t, e, i) {
293
- this.#t = t, this.#e = e, this.#i = i;
534
+ this.#t = t, this.#e = i, this.#n = new q(() => this.#o, e);
294
535
  }
295
536
  stage(t, e, i, s) {
296
- nt(e);
297
- const n = ot(t, e);
298
- if (this.#s.has(n))
299
- throw new TypeError(`Duplicate extension contribution '${n}'`);
300
- const o = new tt(this, n, i, s);
301
- return this.#s.set(n, o), o;
537
+ $t(e);
538
+ const n = Tt(t, e);
539
+ if (this.#i.has(n))
540
+ throw new TypeError(`Duplicate contribution '${n}'`);
541
+ const o = new Ct(this, n, i, s);
542
+ return this.#i.set(n, o), o;
302
543
  }
303
544
  view(t) {
304
- this.#o++;
545
+ this.#r++;
305
546
  const e = { binding: { store: this, own: t } };
306
547
  let i;
307
- const s = new it(e, () => {
548
+ const s = new St(e, () => {
308
549
  const n = i;
309
550
  i = void 0;
310
551
  try {
311
552
  n?.();
312
553
  } finally {
313
- this.#o--, this.#h();
554
+ this.#r--, this.#h();
314
555
  }
315
556
  });
316
557
  try {
317
558
  i = t(s, "view");
318
559
  } catch (n) {
319
- throw e.binding = void 0, this.#o--, this.#h(), n;
560
+ throw e.binding = void 0, this.#r--, this.#h(), n;
320
561
  }
321
- return new X(e);
562
+ return new yt(e);
563
+ }
564
+ /** A stable view explicitly owned by the Host for graph-external consumers. */
565
+ hostView() {
566
+ return this.#d = !0, this.#n.view;
322
567
  }
323
568
  snapshot() {
324
- return this.#a;
569
+ return this.#n.view.get();
325
570
  }
326
571
  subscribe(t, e) {
327
572
  if (typeof t != "function")
328
- throw new TypeError("Extension subscriber must be a function");
329
- let i;
330
- const s = new st(this, t, () => {
331
- const n = i;
332
- i = void 0, n?.();
573
+ throw new TypeError("Contribution subscriber must be a function");
574
+ const i = this.#n.view.subscribe(t);
575
+ this.#a++;
576
+ let s;
577
+ const n = new It(i, () => {
578
+ const o = s;
579
+ s = void 0;
580
+ try {
581
+ o?.();
582
+ } finally {
583
+ this.#a--, this.#h();
584
+ }
333
585
  });
334
- return i = e(s, "subscription"), this.#n.add(t), s;
586
+ try {
587
+ s = e(n, "subscription");
588
+ } catch (o) {
589
+ throw n.dispose(), o;
590
+ }
591
+ return n;
335
592
  }
336
593
  insert(t, e, i) {
337
- if (this.#s.get(t) !== e)
338
- throw new Error(`Extension contribution '${t}' is not the current claim`);
339
- if (this.#r.has(t))
340
- throw new Error(`Extension contribution '${t}' is already published`);
341
- this.#r.set(t, { contribution: e, value: i }), this.#t(this);
594
+ if (this.#l(t, e), this.#s.has(t))
595
+ throw new Error(`Contribution '${t}' is already published`);
596
+ e.commitPublication(), this.#s.set(t, { contribution: e, value: i }), this.#t(this);
342
597
  }
343
598
  update(t, e, i) {
344
- const s = this.#r.get(t);
345
- s?.contribution === e && (s.value = i, this.#t(this));
599
+ const s = this.#u(t, e);
600
+ s.value = i, this.#t(this);
346
601
  }
347
602
  removeContribution(t, e, i) {
348
- this.#s.get(t) === e && this.#s.delete(t), i === "published" && this.#r.get(t)?.contribution === e && (this.#r.delete(t), this.#t(this)), this.#h();
603
+ this.#l(t, e), i === "published" && this.#u(t, e);
604
+ try {
605
+ this.#i.delete(t), i === "published" && (this.#s.delete(t), this.#t(this));
606
+ } finally {
607
+ this.#h();
608
+ }
349
609
  }
350
610
  publishSnapshot() {
351
- const t = [...this.#r].map(([i, s]) => [i, s.value]);
352
- if (!(t.length === this.#a.size && t.every(([i, s]) => Object.is(this.#a.get(i), s)))) {
353
- this.#a = new C(t);
354
- for (const i of [...this.#n])
355
- try {
356
- i();
357
- } catch (s) {
358
- this.#e(s);
359
- }
360
- }
611
+ const t = [...this.#s].map(([i, s]) => [i, s.value]);
612
+ t.length === this.#o.size && t.every(([i, s]) => Object.is(this.#o.get(i), s)) || (this.#o = new S(t), this.#n.invalidate());
361
613
  }
362
- removeListener(t) {
363
- this.#n.delete(t), this.#h();
614
+ #l(t, e) {
615
+ if (this.#i.get(t) !== e)
616
+ throw new Error(`Contribution '${t}' is not the current claim`);
617
+ }
618
+ #u(t, e) {
619
+ const i = this.#s.get(t);
620
+ if (i?.contribution !== e)
621
+ throw new Error(`Contribution '${t}' is not the published entry`);
622
+ return i;
364
623
  }
365
624
  #h() {
366
- this.#s.size || this.#r.size || this.#n.size || this.#o || this.#i(this);
625
+ if (!(this.#f || this.#d || this.#i.size || this.#s.size || this.#a || this.#r)) {
626
+ this.#f = !0;
627
+ try {
628
+ this.#n.dispose();
629
+ } finally {
630
+ this.#e(this);
631
+ }
632
+ }
367
633
  }
368
634
  }
369
- class it {
635
+ class St {
370
636
  #t;
371
637
  constructor(t, e) {
372
638
  this.#t = { state: t, release: e }, Object.freeze(this);
@@ -375,31 +641,31 @@ class it {
375
641
  const t = this.#t;
376
642
  t && (this.#t = void 0, t.state.binding = void 0, t.release());
377
643
  }
378
- [Symbol.dispose]() {
644
+ [g]() {
379
645
  this.dispose();
380
646
  }
381
647
  }
382
- class st {
648
+ class It {
383
649
  #t;
384
- constructor(t, e, i) {
385
- this.#t = { store: t, listener: e, release: i }, Object.freeze(this);
650
+ constructor(t, e) {
651
+ this.#t = { subscription: t, release: e }, Object.freeze(this);
386
652
  }
387
653
  dispose() {
388
654
  const t = this.#t;
389
655
  if (t) {
390
656
  this.#t = void 0;
391
657
  try {
392
- t.store.removeListener(t.listener);
658
+ t.subscription.dispose();
393
659
  } finally {
394
660
  t.release();
395
661
  }
396
662
  }
397
663
  }
398
- [Symbol.dispose]() {
664
+ [g]() {
399
665
  this.dispose();
400
666
  }
401
667
  }
402
- class rt {
668
+ class At {
403
669
  #t = /* @__PURE__ */ new Map();
404
670
  #e = /* @__PURE__ */ new Set();
405
671
  #i;
@@ -410,8 +676,8 @@ class rt {
410
676
  get(t) {
411
677
  const e = this.#t.get(t.id);
412
678
  if (e) return e;
413
- const i = new et(
414
- (s) => this.#r(s),
679
+ const i = new Ot(
680
+ (s) => this.#n(s),
415
681
  this.#i,
416
682
  (s) => {
417
683
  this.#t.get(t.id) === s && (this.#e.delete(s), this.#t.delete(t.id));
@@ -419,126 +685,119 @@ class rt {
419
685
  );
420
686
  return this.#t.set(t.id, i), i;
421
687
  }
688
+ view(t) {
689
+ return this.get(t).hostView();
690
+ }
422
691
  beginBatch() {
423
692
  this.#s++;
424
693
  }
425
694
  endBatch() {
426
- if (!this.#s) throw new TypeError("Extension batch is not active");
695
+ if (!this.#s) throw new Error("Contribution batch is not active");
427
696
  if (this.#s--, this.#s) return;
428
697
  const t = [...this.#e];
429
698
  this.#e.clear();
430
- for (const e of t) e.publishSnapshot();
699
+ const e = [];
700
+ for (const i of t)
701
+ try {
702
+ i.publishSnapshot();
703
+ } catch (s) {
704
+ e.push(s);
705
+ }
706
+ if (e.length === 1) throw e[0];
707
+ if (e.length > 1)
708
+ throw new AggregateError(e, "Contribution batch publication failed");
431
709
  }
432
- #r(t) {
710
+ #n(t) {
433
711
  this.#e.add(t), !this.#s && (this.#e.delete(t), t.publishSnapshot());
434
712
  }
435
713
  }
436
- function nt(r) {
714
+ function $t(r) {
437
715
  if (typeof r != "string" || !r.trim())
438
716
  throw new TypeError("Contribution key must be a non-empty string");
439
717
  if (r !== r.trim())
440
718
  throw new TypeError("Contribution key cannot start or end with whitespace");
441
719
  }
442
- function ot(r, t) {
443
- return `${x(r)}/${x(t)}`;
720
+ function Tt(r, t) {
721
+ return `${B(r)}/${B(t)}`;
444
722
  }
445
- function x(r) {
723
+ function B(r) {
446
724
  return r.replaceAll("%", "%25").replaceAll("/", "%2F");
447
725
  }
448
- const m = /* @__PURE__ */ new WeakMap();
449
- class U {
450
- #t = /* @__PURE__ */ new Set();
726
+ class jt {
727
+ #t;
728
+ constructor(t) {
729
+ this.#t = t, Object.freeze(this);
730
+ }
731
+ dispose() {
732
+ const t = this.#t;
733
+ this.#t = void 0, t?.dispose();
734
+ }
735
+ [g]() {
736
+ this.dispose();
737
+ }
738
+ }
739
+ class kt {
740
+ #t;
451
741
  #e;
452
- #i;
453
- #s = !1;
454
- constructor(t, e) {
455
- if (typeof t != "function") throw new TypeError("Snapshot reader must be a function");
456
- if (typeof e != "function")
457
- throw new TypeError("Snapshot error reporter must be a function");
458
- this.#e = { phase: "active", read: t, report: e }, this.#i = t(), Object.freeze(this);
742
+ handle;
743
+ constructor(t, e, i, s) {
744
+ this.#e = e, this.#t = { phase: "staged", hub: t, slot: { listener: i }, release: s }, this.handle = new jt(this);
459
745
  }
460
- view = Object.freeze({
461
- get: () => this.#r(),
462
- subscribe: (t) => this.#n(t)
463
- });
464
- invalidate() {
465
- const { report: t } = this.#o();
466
- this.#s = !0;
467
- for (const e of [...this.#t])
468
- try {
469
- ht(e);
470
- } catch (i) {
471
- t(i);
472
- }
746
+ publish() {
747
+ const t = this.#t;
748
+ t.phase === "staged" && (t.hub.add(this.#e, t.slot), t.phase = "published");
473
749
  }
474
750
  dispose() {
475
- const t = this.#e;
476
- if (t.phase !== "disposed") {
477
- this.#e = { phase: "disposed" };
751
+ const t = this.#t;
752
+ if (t.phase !== "removed") {
753
+ this.#t = { phase: "removed" };
478
754
  try {
479
- this.#a(t.read);
755
+ t.phase === "published" && t.hub.delete(this.#e, t.slot);
480
756
  } finally {
481
- this.#s = !1;
482
- const e = [...this.#t];
483
- this.#t.clear();
484
- for (const i of e) ct(i);
757
+ t.release(this);
485
758
  }
486
759
  }
487
760
  }
488
- [Symbol.dispose]() {
761
+ [g]() {
489
762
  this.dispose();
490
763
  }
491
- #r() {
492
- const t = this.#e;
493
- return t.phase === "active" && this.#a(t.read), this.#i;
494
- }
495
- #n(t) {
496
- if (typeof t != "function") throw new TypeError("Subscriber must be a function");
497
- this.#o();
498
- const e = new at(t, (i) => {
499
- this.#t.delete(i);
500
- });
501
- return this.#t.add(e), e;
502
- }
503
- #a(t) {
504
- this.#s && (this.#i = t(), this.#s = !1);
505
- }
506
- #o() {
507
- const t = this.#e;
508
- if (t.phase === "disposed") throw new TypeError("Snapshot publisher is disposed");
509
- return t;
510
- }
511
764
  }
512
- class at {
513
- constructor(t, e) {
514
- m.set(this, { listener: t, detach: e }), Object.freeze(this);
765
+ class Pt {
766
+ #t = /* @__PURE__ */ new Map();
767
+ stage(t, e, i) {
768
+ if (typeof e != "function") throw new TypeError("Event listener must be a function");
769
+ return new kt(this, t, e, i);
515
770
  }
516
- dispose() {
517
- const t = m.get(this);
518
- t && (m.delete(this), t.detach(this));
771
+ add(t, e) {
772
+ const i = this.#t.get(t) ?? /* @__PURE__ */ new Set();
773
+ this.#t.set(t, i), i.add(e);
519
774
  }
520
- [Symbol.dispose]() {
521
- this.dispose();
775
+ delete(t, e) {
776
+ const i = this.#t.get(t);
777
+ i && (i.delete(e), i.size || this.#t.delete(t));
778
+ }
779
+ async emit(t, e) {
780
+ const i = [...this.#t.get(t) ?? []].map(
781
+ (o) => o.listener
782
+ ), n = (await Promise.allSettled(
783
+ i.map((o) => Promise.resolve().then(() => o(e)))
784
+ )).filter((o) => o.status === "rejected").map((o) => o.reason);
785
+ if (n.length)
786
+ throw new AggregateError(n, `Event '${t}' listeners failed`);
522
787
  }
523
788
  }
524
- function ht(r) {
525
- m.get(r)?.listener();
526
- }
527
- function ct(r) {
528
- m.delete(r);
529
- }
530
- class dt {
789
+ class Lt {
531
790
  #t;
532
791
  root;
533
792
  view;
534
793
  constructor(t, e) {
535
- this.root = R(t), this.#t = new U(() => B(this.root), e), this.view = this.#t.view;
794
+ this.root = F(t), this.#t = new q(() => et(this.root), e), this.view = this.#t.view;
536
795
  }
537
796
  createNode(t) {
538
- return R(t);
797
+ return F(t);
539
798
  }
540
799
  attach(t, e) {
541
- if (t.children.has(e)) throw new TypeError("Lifetime diagnostic node is attached");
800
+ if (t.children.has(e)) throw new Error("Lifetime diagnostic node is attached");
542
801
  t.children.add(e), this.#t.invalidate();
543
802
  }
544
803
  detach(t, e) {
@@ -546,7 +805,7 @@ class dt {
546
805
  }
547
806
  change(t, e, i) {
548
807
  const s = t.counts[e] + i;
549
- if (s < 0) throw new TypeError(`Lifetime '${e}' count cannot be negative`);
808
+ if (s < 0) throw new Error(`Lifetime '${e}' count cannot be negative`);
550
809
  t.counts[e] = s, this.#t.invalidate();
551
810
  }
552
811
  beginDisposing(t) {
@@ -556,7 +815,7 @@ class dt {
556
815
  this.root.phase !== "disposed" && (this.root.phase = "disposed", this.#t.invalidate(), this.#t.dispose());
557
816
  }
558
817
  }
559
- function R(r) {
818
+ function F(r) {
560
819
  return {
561
820
  label: r,
562
821
  phase: "active",
@@ -565,14 +824,14 @@ function R(r) {
565
824
  tasks: 0,
566
825
  listeners: 0,
567
826
  contributions: 0,
568
- extensionViews: 0,
827
+ contributionViews: 0,
569
828
  subscriptions: 0
570
829
  },
571
830
  children: /* @__PURE__ */ new Set()
572
831
  };
573
832
  }
574
- function B(r) {
575
- const t = Object.freeze([...r.children].map(B));
833
+ function et(r) {
834
+ const t = Object.freeze([...r.children].map(et));
576
835
  return Object.freeze({
577
836
  label: r.label,
578
837
  phase: r.phase,
@@ -580,15 +839,22 @@ function B(r) {
580
839
  children: t
581
840
  });
582
841
  }
583
- const A = Object.freeze(new DOMException("Resource disposed", "AbortError"));
584
- class g {
842
+ function zt(r) {
843
+ if (!r || typeof r != "object") return !1;
844
+ const t = r;
845
+ return [t.debug, t.info, t.warn, t.error].every(
846
+ (e) => typeof e == "function"
847
+ );
848
+ }
849
+ const R = Object.freeze(new DOMException("Resource disposed", "AbortError"));
850
+ class w {
585
851
  #t = /* @__PURE__ */ new Set();
586
852
  #e;
587
853
  constructor(t) {
588
854
  this.#e = t;
589
855
  }
590
856
  add(t) {
591
- if (this.#t.has(t)) throw new TypeError("Lifetime already owns this resource");
857
+ if (this.#t.has(t)) throw new Error("Lifetime already owns this resource");
592
858
  this.#t.add(t);
593
859
  const e = this.#e;
594
860
  e && e.diagnostics.change(e.node, e.kind, 1);
@@ -619,7 +885,7 @@ class g {
619
885
  return this.#t[Symbol.iterator]();
620
886
  }
621
887
  }
622
- class lt {
888
+ class Rt {
623
889
  #t;
624
890
  constructor(t, e) {
625
891
  this.#t = { phase: "active", cleanup: t, detachFromParent: e }, Object.freeze(this);
@@ -639,11 +905,11 @@ class lt {
639
905
  });
640
906
  return this.#t = { phase: "disposing", completion: e }, e;
641
907
  }
642
- [Symbol.asyncDispose]() {
908
+ [j]() {
643
909
  return this.dispose();
644
910
  }
645
911
  }
646
- class ut {
912
+ class Nt {
647
913
  #t;
648
914
  #e;
649
915
  #i;
@@ -656,7 +922,7 @@ class ut {
656
922
  () => this.#s(),
657
923
  (a) => {
658
924
  try {
659
- n.signal.aborted || i(a);
925
+ J(n.signal, a) || i(a);
660
926
  } finally {
661
927
  this.#s();
662
928
  }
@@ -674,718 +940,402 @@ class ut {
674
940
  () => {
675
941
  }
676
942
  );
677
- return this.#i = { phase: "disposing", completion: e }, t.controller.abort(A), this.#r(), e;
943
+ return this.#i = { phase: "disposing", completion: e }, t.controller.abort(R), this.#n(), e;
678
944
  }
679
- [Symbol.asyncDispose]() {
945
+ [j]() {
680
946
  return this.dispose();
681
947
  }
682
948
  #s() {
683
949
  if (this.#i.phase === "settled") return;
684
- this.#i = { phase: "settled" }, this.#r();
950
+ this.#i = { phase: "settled" }, this.#n();
685
951
  const t = this.#e;
686
952
  this.#e = void 0, t?.(this);
687
953
  }
688
- #r() {
954
+ #n() {
689
955
  const t = this.#t;
690
956
  this.#t = void 0, t?.();
691
957
  }
692
958
  }
693
- class L {
959
+ class D {
694
960
  #t;
695
961
  #e;
696
962
  #i;
697
963
  #s;
698
- #r;
699
964
  #n;
700
- #a;
701
965
  #o;
702
- #h;
703
- #c;
704
- #p;
705
- #g;
706
- handle;
966
+ #r;
967
+ #a;
968
+ #d;
969
+ #f;
707
970
  #l;
971
+ #u;
972
+ handle;
973
+ #h;
708
974
  constructor(t, e, i = {}) {
709
- this.#e = e, this.handle = new pt(this);
975
+ this.#e = e, this.handle = new xt(this);
710
976
  const s = new AbortController();
711
- this.#l = {
977
+ this.#h = {
712
978
  phase: "active",
713
979
  controller: s,
714
980
  declarations: i.declarations ?? "staged"
715
981
  };
716
982
  const n = i.parent;
717
- this.#g = n?.detach, this.#c = n ? "child" : "root";
718
- const o = n?.diagnostics ?? new dt(e, (l) => t.report(l)), a = n?.diagnosticNode ?? o.root;
719
- this.#t = { host: t, diagnostics: o, diagnosticNode: a };
983
+ this.#u = n?.detach, this.#f = n ? "child" : "root";
984
+ const o = n?.diagnostics ?? new Lt(e, (l) => t.report(l)), a = n?.diagnosticNode ?? o.root;
985
+ this.#t = { port: t, diagnostics: o, diagnosticNode: a };
720
986
  const h = (l) => ({
721
987
  diagnostics: o,
722
988
  node: a,
723
989
  kind: l
724
990
  });
725
- this.#i = new g(h("listeners")), this.#s = new g(h("contributions")), this.#r = new g(h("extensionViews")), this.#n = new g(h("subscriptions")), this.#a = new g(h("tasks")), this.#o = new g(), this.#h = new g(h("cleanups"));
991
+ this.#i = new w(h("listeners")), this.#s = new w(h("contributions")), this.#n = new w(h("contributionViews")), this.#o = new w(h("subscriptions")), this.#r = new w(h("tasks")), this.#a = new w(), this.#d = new w(h("cleanups"));
726
992
  const c = i.parentSignal;
727
993
  if (!c) return;
728
994
  const d = () => s.abort(c.reason);
729
- c.addEventListener("abort", d, { once: !0 }), this.#p = () => c.removeEventListener("abort", d), c.aborted && d();
995
+ c.addEventListener("abort", d, { once: !0 }), this.#l = () => c.removeEventListener("abort", d), c.aborted && d();
730
996
  }
731
997
  get signal() {
732
- const t = this.#l;
998
+ const t = this.#h;
733
999
  return t.phase === "disposed" ? t.signal : t.controller.signal;
734
1000
  }
735
1001
  get diagnostics() {
736
- return this.#d().diagnostics.view;
1002
+ return this.#c().diagnostics.view;
1003
+ }
1004
+ /** A facade whose only Runtime edge disappears when this Lifetime terminates. */
1005
+ contextLogger(t) {
1006
+ const e = (i) => (s, ...n) => this.#p().port.writeLog(i, s, t, n);
1007
+ return Object.freeze({
1008
+ debug: e("debug"),
1009
+ info: e("info"),
1010
+ warn: e("warn"),
1011
+ error: e("error")
1012
+ });
737
1013
  }
738
1014
  cleanup(t) {
739
- if (this.#d(), typeof t != "function") throw new TypeError("Cleanup must be a function");
740
- const e = new lt(t, this.#h.release);
741
- return this.#h.add(e), e;
1015
+ if (this.#c(), typeof t != "function") throw new TypeError("Cleanup must be a function");
1016
+ const e = new Rt(t, this.#d.release);
1017
+ return this.#d.add(e), e;
742
1018
  }
743
1019
  lifetime(t) {
744
- const { host: e, diagnostics: i, diagnosticNode: s } = this.#d();
745
- ft(t);
746
- const n = i.createNode(t), o = new L(e, this.#e, {
1020
+ const { port: e, diagnostics: i, diagnosticNode: s } = this.#c();
1021
+ Vt(t);
1022
+ const n = i.createNode(t), o = new D(e, this.#e, {
747
1023
  parentSignal: this.signal,
748
- declarations: this.#w(),
1024
+ declarations: this.#g(),
749
1025
  parent: {
750
1026
  diagnostics: i,
751
1027
  diagnosticNode: n,
752
1028
  detach: (a) => {
753
- this.#o.release(a) && i.detach(s, n);
1029
+ this.#a.release(a) && i.detach(s, n);
754
1030
  }
755
1031
  }
756
1032
  });
757
- return this.#o.add(o), i.attach(s, n), o.handle;
1033
+ return this.#a.add(o), i.attach(s, n), o.handle;
758
1034
  }
759
1035
  spawn(t) {
760
- const { host: e } = this.#d();
1036
+ const { port: e } = this.#c();
761
1037
  if (typeof t != "function") throw new TypeError("Background task must be a function");
762
- const i = new ut(
1038
+ const i = new Nt(
763
1039
  this.signal,
764
1040
  t,
765
1041
  (s) => e.report(s),
766
- this.#a.release
1042
+ this.#r.release
767
1043
  );
768
- return this.#a.add(i), i;
1044
+ return this.#r.add(i), i;
769
1045
  }
770
1046
  on(t, e) {
771
- const { host: i } = this.#d(), s = i.stageOn(this.#e, t, e, this.#i.release);
772
- return this.#i.add(s), this.#w() === "published" && s.publish(), s.handle;
1047
+ const { port: i } = this.#c(), s = i.stageOn(this.#e, t, e, this.#i.release);
1048
+ return this.#i.add(s), this.#g() === "published" && s.publish(), s.handle;
773
1049
  }
774
- emit(t, e) {
775
- return this.#d().host.emit(this.#e, t, e);
1050
+ async emit(t, ...e) {
1051
+ const { port: i } = this.#c();
1052
+ await i.emit(this.#e, t, e[0]);
776
1053
  }
777
1054
  contribute(t, e, i) {
778
- const { host: s } = this.#d(), n = s.stageContribution(
1055
+ const { port: s } = this.#c(), n = s.stageContribution(
779
1056
  this.#e,
780
1057
  t,
781
1058
  e,
782
1059
  i,
783
1060
  this.#s.release
784
1061
  );
785
- return this.#s.add(n), this.#w() === "published" && n.publish(), n.handle;
1062
+ return this.#s.add(n), this.#g() === "published" && n.publish(), n.handle;
786
1063
  }
787
1064
  /** Owns an internal live capability without exposing a second Context API. */
788
1065
  ownLease(t, e) {
789
- return this.#d(), (e === "view" ? this.#r : this.#n).own(t);
1066
+ return this.#c(), (e === "view" ? this.#n : this.#o).own(t);
790
1067
  }
791
1068
  /** Releases a temporary startup cancellation edge after its layer commits. */
792
1069
  detachStartupSignal() {
793
- const t = this.#p;
794
- this.#p = void 0, t?.();
1070
+ const t = this.#l;
1071
+ this.#l = void 0, t?.();
795
1072
  }
796
1073
  /** Atomically makes all declarations staged during setup visible. */
797
1074
  publish() {
798
- const t = this.#l;
799
- if (t.phase !== "active") throw b();
800
- if (this.#d(), t.declarations !== "published") {
1075
+ const t = this.#h;
1076
+ if (t.phase !== "active") throw y();
1077
+ if (this.#c(), t.declarations !== "published") {
801
1078
  for (const e of this.#i) e.publish();
802
1079
  for (const e of this.#s) e.publish();
803
- for (const e of this.#o) e.publish();
804
- this.#l = { ...t, declarations: "published" };
1080
+ for (const e of this.#a) e.publish();
1081
+ this.#h = { ...t, declarations: "published" };
805
1082
  }
806
1083
  }
807
1084
  dispose() {
808
- const t = this.#l;
1085
+ const t = this.#h;
809
1086
  if (t.phase === "disposing") return t.completion;
810
1087
  if (t.phase === "disposed") return Promise.resolve();
811
- const e = this.#b(), i = Promise.resolve().then(async () => {
1088
+ const e = this.#p(), i = Promise.resolve().then(async () => {
812
1089
  const s = [];
813
- if (await this.#i.dispose(s), await this.#s.dispose(s), await this.#n.dispose(s), await this.#r.dispose(s), t.controller.abort(A), this.detachStartupSignal(), await this.#a.dispose(s), await this.#o.dispose(s), await this.#h.dispose(s), s.length === 1) throw s[0];
1090
+ if (await this.#i.dispose(s), await this.#s.dispose(s), await this.#o.dispose(s), await this.#n.dispose(s), t.controller.abort(R), this.detachStartupSignal(), await this.#r.dispose(s), await this.#a.dispose(s), await this.#d.dispose(s), s.length === 1) throw s[0];
814
1091
  if (s.length > 1) throw new AggregateError(s, "Lifetime cleanup failed");
815
1092
  }).finally(() => {
816
- this.#l = { phase: "disposed", signal: AbortSignal.abort(A) };
817
- const s = this.#g;
818
- this.#g = void 0;
1093
+ this.#h = { phase: "disposed", signal: AbortSignal.abort(R) };
1094
+ const s = this.#u;
1095
+ this.#u = void 0;
819
1096
  try {
820
- s?.(this), this.#c === "root" && e.diagnostics.finishRoot();
1097
+ s?.(this), this.#f === "root" && e.diagnostics.finishRoot();
821
1098
  } finally {
822
1099
  this.#t = void 0;
823
1100
  }
824
- });
825
- return this.#l = { phase: "disposing", controller: t.controller, completion: i }, e.diagnostics.beginDisposing(e.diagnosticNode), i;
826
- }
827
- [Symbol.asyncDispose]() {
828
- return this.dispose();
829
- }
830
- #d() {
831
- const t = this.#t;
832
- if (this.#l.phase !== "active" || this.signal.aborted || !t)
833
- throw b();
834
- return t;
835
- }
836
- #b() {
837
- const t = this.#t;
838
- if (!t) throw b();
839
- return t;
840
- }
841
- #w() {
842
- const t = this.#l;
843
- if (t.phase !== "active") throw b();
844
- return t.declarations;
845
- }
846
- }
847
- class pt {
848
- #t;
849
- constructor(t) {
850
- this.#t = t, Object.freeze(this);
851
- }
852
- get signal() {
853
- return this.#t.signal;
854
- }
855
- cleanup(t) {
856
- return this.#t.cleanup(t);
857
- }
858
- lifetime(t) {
859
- return this.#t.lifetime(t);
860
- }
861
- spawn(t) {
862
- return this.#t.spawn(t);
863
- }
864
- on(t, e) {
865
- return this.#t.on(t, e);
866
- }
867
- emit(t, e) {
868
- return this.#t.emit(t, e);
869
- }
870
- contribute(t, e, i) {
871
- return this.#t.contribute(t, e, i);
872
- }
873
- dispose() {
874
- return this.#t.dispose();
875
- }
876
- [Symbol.asyncDispose]() {
877
- return this.dispose();
878
- }
879
- }
880
- function ft(r) {
881
- if (typeof r != "string" || !r.trim())
882
- throw new TypeError("Lifetime label must be a non-empty string");
883
- if (r !== r.trim())
884
- throw new TypeError("Lifetime label cannot start or end with whitespace");
885
- }
886
- function b() {
887
- return new TypeError("Lifetime is disposing or has been disposed");
888
- }
889
- class z {
890
- constructor(t, e, i, s, n, o) {
891
- this.order = t, this.layers = e, this.providers = i, this.dependents = s, this.contractKinds = n, this.#t = o;
892
- }
893
- order;
894
- layers;
895
- providers;
896
- dependents;
897
- contractKinds;
898
- #t;
899
- static build(t, e) {
900
- const i = [...t].sort((c, d) => c.index - d.index), s = new Map(e), n = gt(i, s), o = wt(i, n, s), { order: a, layers: h } = mt(
901
- i,
902
- o.dependents,
903
- o.indegree
904
- );
905
- return new z(
906
- Object.freeze(a),
907
- Object.freeze(h.map((c) => Object.freeze(c))),
908
- n,
909
- o.dependents,
910
- s,
911
- o.resolvedProviders
912
- );
913
- }
914
- providerFor(t, e) {
915
- return this.#t.get(t)?.get(e);
916
- }
917
- provider(t) {
918
- return this.providers.get(t);
919
- }
920
- affectedByTransitionTo(t, e) {
921
- const i = /* @__PURE__ */ new Set();
922
- return this.#e(e, i), t.#e(e, i), i;
923
- }
924
- #e(t, e) {
925
- const i = [...t], s = /* @__PURE__ */ new Set();
926
- for (let n = 0; n < i.length; n++) {
927
- const o = i[n];
928
- if (o && !s.has(o)) {
929
- s.add(o), e.add(o);
930
- for (const a of this.dependents.get(o) ?? []) i.push(a);
931
- }
932
- }
933
- }
934
- }
935
- function gt(r, t) {
936
- const e = /* @__PURE__ */ new Map();
937
- for (const i of r)
938
- for (const s of Object.values(i.spec.plugin.provides ?? {})) {
939
- S(t, s);
940
- const n = e.get(s.id);
941
- if (n)
942
- throw new p(
943
- "SERVICE_CONFLICT",
944
- `Service '${s.id}' is provided by both '${n.id}' and '${i.id}'`
945
- );
946
- e.set(s.id, i);
947
- }
948
- return e;
949
- }
950
- function wt(r, t, e) {
951
- const i = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), n = new Map(r.map((o) => [o, 0]));
952
- for (const o of r)
953
- for (const a of Object.values(o.spec.plugin.requires ?? {})) {
954
- const h = a.kind === "optional" ? a.service : a;
955
- if (S(e, h), h.kind === "extension") continue;
956
- const c = t.get(h.id);
957
- if (!c) {
958
- if (a.kind === "optional") continue;
959
- throw new p(
960
- "SERVICE_MISSING",
961
- `Plugin '${o.id}' requires missing service '${h.id}'`
962
- );
963
- }
964
- if (c === o)
965
- throw new p(
966
- "SERVICE_CYCLE",
967
- `Plugin '${o.id}' cannot require service '${h.id}' that it provides`
968
- );
969
- const d = i.get(o) ?? /* @__PURE__ */ new Map();
970
- d.set(h.id, c), i.set(o, d);
971
- const l = s.get(c) ?? /* @__PURE__ */ new Set();
972
- l.has(o) || (l.add(o), s.set(c, l), n.set(o, (n.get(o) ?? 0) + 1));
973
- }
974
- return { resolvedProviders: i, dependents: s, indegree: n };
975
- }
976
- function mt(r, t, e) {
977
- let i = r.filter((o) => e.get(o) === 0);
978
- const s = [], n = [];
979
- for (; i.length; ) {
980
- i.sort((a, h) => a.index - h.index);
981
- const o = i;
982
- i = [], n.push(o), s.push(...o);
983
- for (const a of o)
984
- for (const h of t.get(a) ?? []) {
985
- const c = (e.get(h) ?? 0) - 1;
986
- e.set(h, c), c || i.push(h);
987
- }
988
- }
989
- if (s.length !== r.length) {
990
- const o = vt(r, t);
991
- throw new p(
992
- "SERVICE_CYCLE",
993
- `Plugin dependency cycle: ${o.map((a) => a.id).join(" -> ")}`
994
- );
995
- }
996
- return { order: s, layers: n };
997
- }
998
- function vt(r, t) {
999
- const e = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), s = [], n = (o) => {
1000
- i.add(o), s.push(o);
1001
- for (const a of t.get(o) ?? []) {
1002
- if (i.has(a)) {
1003
- const c = s.indexOf(a);
1004
- return [...s.slice(c), a];
1005
- }
1006
- if (e.has(a)) continue;
1007
- const h = n(a);
1008
- if (h) return h;
1009
- }
1010
- s.pop(), i.delete(o), e.add(o);
1011
- };
1012
- for (const o of r) {
1013
- if (e.has(o)) continue;
1014
- const a = n(o);
1015
- if (a) return a;
1016
- }
1017
- throw new TypeError("Dependency graph is cyclic but no cycle path was found");
1018
- }
1019
- function N(r, t) {
1020
- return Object.freeze({ plugin: r, config: t });
1021
- }
1022
- class bt {
1023
- constructor(t, e, i, s) {
1024
- this.id = t, this.index = e, this.groupId = i.id, this.#i = { spec: s, group: i, notifyChanged: void 0 };
1025
- }
1026
- id;
1027
- index;
1028
- #t = { phase: "pending" };
1029
- #e;
1030
- #i;
1031
- groupId;
1032
- #s = /* @__PURE__ */ new Set();
1033
- attach(t) {
1034
- const e = this.#h();
1035
- if (e.notifyChanged) throw new TypeError(`Plugin '${this.id}' is already attached`);
1036
- e.notifyChanged = t;
1037
- }
1038
- get status() {
1039
- return this.#t.phase;
1040
- }
1041
- get runtime() {
1042
- const t = this.#t;
1043
- return t.phase === "active" || t.phase === "stopping" ? t.runtime : void 0;
1044
- }
1045
- get error() {
1046
- const t = this.#t;
1047
- if (t.phase === "failed")
1048
- return t.failure.retention === "live" ? t.failure.error : Et(t.failure.summary);
1049
- if (t.phase === "removed")
1050
- return new p("PLUGIN_REMOVED", `Plugin '${this.id}' has been removed`);
1051
- }
1052
- get group() {
1053
- return this.#h().group;
1054
- }
1055
- get spec() {
1056
- return this.#h().spec;
1057
- }
1058
- reconfigure(t) {
1059
- this.#h().spec = t;
1060
- }
1061
- ready() {
1062
- const t = this.#e;
1063
- return t ? t.barrier.then(() => this.#r()) : this.#r();
1064
- }
1065
- trackReadiness(t) {
1066
- const e = {}, i = t.then(
1067
- () => {
1068
- this.#e?.attempt === e && (this.#e = void 0);
1069
- },
1070
- (s) => {
1071
- if (this.#e?.attempt === e && (this.#e = void 0), this.#t.phase !== "active") throw s;
1072
- }
1073
- );
1074
- this.#e = { attempt: e, barrier: i }, i.catch(() => {
1075
- });
1076
- }
1077
- #r() {
1078
- const t = this.#t;
1079
- if ((t.phase === "active" || t.phase === "failed" || t.phase === "removed") && t.readiness === "settled") {
1080
- if (t.phase === "active") return Promise.resolve();
1081
- if (t.phase === "failed" || t.phase === "removed")
1082
- return Promise.reject(
1083
- this.error ?? new p("PLUGIN_UNAVAILABLE", `Plugin '${this.id}' is ${t.phase}`)
1084
- );
1085
- }
1086
- return new Promise((e, i) => {
1087
- this.#s.add({ resolve: e, reject: i });
1088
- });
1089
- }
1090
- activate(t) {
1091
- this.#a({ phase: "active", runtime: t, readiness: "unsettled" });
1092
- }
1093
- settleReady() {
1094
- const t = this.#t;
1095
- if (!(t.phase !== "active" && t.phase !== "failed" && t.phase !== "removed") && t.readiness !== "settled") {
1096
- if (this.#t = { ...t, readiness: "settled" }, t.phase === "active")
1097
- for (const e of this.#s) e.resolve();
1098
- else {
1099
- const e = this.error ?? new p("PLUGIN_UNAVAILABLE", `Plugin '${this.id}' is ${t.phase}`);
1100
- for (const i of this.#s) i.reject(e);
1101
- }
1102
- this.#s.clear();
1103
- }
1101
+ });
1102
+ return this.#h = { phase: "disposing", controller: t.controller, completion: i }, e.diagnostics.beginDisposing(e.diagnosticNode), i;
1104
1103
  }
1105
- beginStopping() {
1104
+ [j]() {
1105
+ return this.dispose();
1106
+ }
1107
+ #c() {
1106
1108
  const t = this.#t;
1107
- return t.phase !== "active" ? !1 : (this.#a({ phase: "stopping", runtime: t.runtime }), !0);
1109
+ if (this.#h.phase !== "active" || this.signal.aborted || !t)
1110
+ throw y();
1111
+ return t;
1108
1112
  }
1109
- deactivate() {
1110
- this.#a({ phase: "pending" });
1113
+ #p() {
1114
+ const t = this.#t;
1115
+ if (!t) throw y();
1116
+ return t;
1111
1117
  }
1112
- fail(t) {
1113
- this.#n(t);
1118
+ #g() {
1119
+ const t = this.#h;
1120
+ if (t.phase !== "active") throw y();
1121
+ return t.declarations;
1114
1122
  }
1115
- discard(t) {
1116
- const e = this.#o(t);
1117
- this.#a({
1118
- phase: "failed",
1119
- failure: { retention: "summary", summary: yt(e) },
1120
- readiness: "settled"
1121
- });
1122
- for (const i of this.#s) i.reject(e);
1123
- this.#s.clear(), this.#e = void 0, this.#i = void 0;
1123
+ }
1124
+ class xt {
1125
+ #t;
1126
+ constructor(t) {
1127
+ this.#t = t, Object.freeze(this);
1124
1128
  }
1125
- #n(t) {
1126
- const e = this.#o(t);
1127
- return this.#a({
1128
- phase: "failed",
1129
- failure: { retention: "live", error: e },
1130
- readiness: "unsettled"
1131
- }), e;
1129
+ get signal() {
1130
+ return this.#t.signal;
1132
1131
  }
1133
- remove() {
1134
- this.#a({ phase: "removed", readiness: "unsettled" }), this.#e = void 0, this.#i = void 0;
1132
+ cleanup(t) {
1133
+ return this.#t.cleanup(t);
1135
1134
  }
1136
- #a(t) {
1137
- this.#t = t, this.#i?.notifyChanged?.();
1135
+ lifetime(t) {
1136
+ return this.#t.lifetime(t);
1138
1137
  }
1139
- #o(t) {
1140
- return $(
1141
- t,
1142
- "PLUGIN_UNAVAILABLE",
1143
- `Plugin '${this.id}' failed with a non-Error value`
1144
- );
1138
+ spawn(t) {
1139
+ return this.#t.spawn(t);
1145
1140
  }
1146
- #h() {
1147
- const t = this.#i;
1148
- if (!t) throw new TypeError(`Plugin '${this.id}' is no longer installed`);
1149
- return t;
1141
+ on(t, e) {
1142
+ return this.#t.on(t, e);
1143
+ }
1144
+ emit(t, ...e) {
1145
+ return this.#t.emit(t, ...e);
1146
+ }
1147
+ contribute(t, e, i) {
1148
+ return this.#t.contribute(t, e, i);
1149
+ }
1150
+ dispose() {
1151
+ return this.#t.dispose();
1152
+ }
1153
+ [j]() {
1154
+ return this.dispose();
1150
1155
  }
1151
1156
  }
1152
- function yt(r) {
1153
- return r instanceof p ? { name: r.name, message: r.message, code: r.code } : { name: r.name, message: r.message };
1157
+ function Vt(r) {
1158
+ if (typeof r != "string" || !r.trim())
1159
+ throw new TypeError("Lifetime label must be a non-empty string");
1160
+ if (r !== r.trim())
1161
+ throw new TypeError("Lifetime label cannot start or end with whitespace");
1154
1162
  }
1155
- function Et(r) {
1156
- const t = r.code === void 0 ? new Error(r.message) : new p(r.code, r.message);
1157
- return t.name = r.name, t;
1163
+ function y() {
1164
+ return new u("LIFETIME_DISPOSED", "Lifetime is disposing or has been disposed");
1158
1165
  }
1159
- class O extends AggregateError {
1166
+ class N extends AggregateError {
1160
1167
  }
1161
- class Ct {
1168
+ class Mt {
1162
1169
  #t;
1163
1170
  #e;
1164
1171
  #i;
1165
1172
  #s;
1166
- #r = /* @__PURE__ */ new Map();
1167
- #n = new K();
1168
- #a = new J();
1169
- #o;
1170
- #h;
1171
- #c = [];
1173
+ #n = /* @__PURE__ */ new Map();
1174
+ #o = new Pt();
1175
+ #r;
1176
+ #a = [];
1172
1177
  constructor(t) {
1173
- this.#t = t.applicationName, this.#e = t.logger, this.#i = t.isInstalled, this.#s = t.report, this.#o = new rt(t.report);
1178
+ this.#t = t.hostName, this.#e = t.logger, this.#i = t.isInstalled, this.#s = t.report, this.#r = new At(t.report);
1174
1179
  }
1175
- get hasCommittedPlan() {
1176
- return this.#h !== void 0;
1177
- }
1178
- get(t, e) {
1179
- if (v(t, "service"), this.#n.assertCompatible(t), e === "unavailable")
1180
- throw M();
1181
- const i = this.#I().provider(t.id), s = i ? this.#r.get(i) : void 0;
1182
- if (!i || !s?.has(t.id))
1183
- throw new p("SERVICE_UNAVAILABLE", `Service '${t.id}' is not active`);
1184
- return s.get(t.id);
1180
+ readService(t, e) {
1181
+ const i = this.#n.get(t);
1182
+ return i?.has(e) ? { found: !0, value: i.get(e) } : { found: !1 };
1185
1183
  }
1186
- buildPlan(t) {
1187
- return z.build(t, this.#n.kinds);
1184
+ contributions(t) {
1185
+ return this.#r.view(t);
1188
1186
  }
1189
- async start(t) {
1190
- const e = this.#n.draft(t.contractKinds);
1191
- try {
1192
- await this.#j(() => this.#p(t, e)), this.#h = t;
1193
- } catch (i) {
1194
- throw e.discard(), this.#h = void 0, i;
1187
+ captureConfigs(t) {
1188
+ const e = /* @__PURE__ */ new Map();
1189
+ for (const i of t) {
1190
+ const s = i.instance;
1191
+ s && e.set(i, s.config);
1195
1192
  }
1193
+ return e;
1196
1194
  }
1197
- async stop() {
1198
- const t = await this.#j(
1199
- () => this.#f(new Set(this.#c))
1200
- );
1201
- return this.#h = void 0, t;
1202
- }
1203
- async transition(t, e, i) {
1204
- return this.#j(async () => {
1205
- const s = this.#I(), n = s.affectedByTransitionTo(t, e);
1206
- let o, a;
1207
- try {
1208
- o = await this.#v(
1209
- t.order.filter((d) => n.has(d))
1210
- ), a = this.#n.draft(t.contractKinds);
1211
- } catch (d) {
1212
- throw i(), d;
1213
- }
1214
- const h = /* @__PURE__ */ new Map();
1215
- for (const d of n) {
1216
- const l = d.runtime;
1217
- l && h.set(d, l.config);
1218
- }
1219
- const c = await this.#f(n);
1220
- if (c.length)
1221
- return a.discard(), this.#g(
1222
- i,
1223
- c,
1224
- "Plugin change could not cleanly stop the affected runtime"
1225
- );
1226
- try {
1227
- return await this.#d(t, n, o, a), a.commit(), this.#c = t.order.slice(), this.#h = t, Object.freeze({ kind: "committed", affected: n });
1228
- } catch (d) {
1229
- const l = await this.#f(n);
1230
- return a.discard(), d instanceof O || l.length ? this.#g(
1231
- i,
1232
- [d, ...l],
1233
- "Plugin change failed and its partial runtime could not be cleanly disposed"
1234
- ) : this.#l(i, s, n, h, [
1235
- d,
1236
- ...l
1237
- ]);
1238
- }
1239
- });
1240
- }
1241
- async #p(t, e) {
1242
- const i = new Set(t.order), s = await this.#v(t.order);
1243
- this.#r.clear(), this.#c = [];
1244
- try {
1245
- await this.#d(t, i, s, e), e.commit(), this.#c = t.order.slice();
1246
- } catch (n) {
1247
- const o = await this.#f(i);
1248
- throw o.length ? new AggregateError([n, ...o], "Application startup failed") : n;
1249
- }
1195
+ resetActivationState() {
1196
+ this.#n.clear(), this.#a = [];
1250
1197
  }
1251
- async #g(t, e, i) {
1252
- t();
1253
- const s = await this.#f(new Set(this.#c));
1254
- throw this.#h = void 0, new AggregateError([...e, ...s], i);
1198
+ commitActivationOrder(t) {
1199
+ this.#a = t.slice();
1255
1200
  }
1256
- async #l(t, e, i, s, n) {
1257
- t();
1258
- const o = this.#n.draft(e.contractKinds);
1259
- try {
1260
- await this.#d(e, i, s, o), o.commit(), this.#c = e.order.slice(), this.#h = e;
1261
- } catch (h) {
1262
- const c = await this.#f(new Set(this.#c));
1263
- throw o.discard(), this.#h = void 0, new AggregateError(
1264
- [...n, h, ...c],
1265
- "Plugin change failed and the previous application could not be restored"
1266
- );
1267
- }
1268
- const a = n.length === 1 ? n[0] : new AggregateError(n, "Plugin change failed");
1269
- return Object.freeze({ kind: "rolled-back", affected: i, error: a });
1201
+ deactivateAll() {
1202
+ return this.deactivate(new Set(this.#a));
1270
1203
  }
1271
- async #d(t, e, i, s) {
1272
- const n = this.#E(s);
1204
+ async activate(t, e, i, s) {
1205
+ const n = this.#c(s);
1273
1206
  for (const o of t.layers) {
1274
1207
  const a = o.filter(
1275
- (u) => e.has(u) && !u.runtime
1208
+ (f) => e.has(f) && !f.instance
1276
1209
  );
1277
1210
  if (!a.length) continue;
1278
1211
  const h = new AbortController(), c = await Promise.allSettled(
1279
- a.map(async (u) => {
1212
+ a.map(async (f) => {
1280
1213
  try {
1281
- const f = i.has(u) ? i.get(u) : await this.#y(
1282
- u.spec.plugin.config,
1283
- u.spec.config
1214
+ const p = i.has(f) ? i.get(f) : await X(
1215
+ f.declaration.plugin.config,
1216
+ f.declaration.config,
1217
+ f.id
1284
1218
  );
1285
- return await this.#b(
1219
+ return await this.#d(
1286
1220
  t,
1287
- u,
1288
1221
  f,
1222
+ p,
1289
1223
  h.signal,
1290
1224
  n
1291
1225
  );
1292
- } catch (f) {
1293
- throw h.abort(f), f;
1226
+ } catch (p) {
1227
+ throw h.abort(p), p;
1294
1228
  }
1295
1229
  })
1296
- ), d = c.filter((u) => u.status === "rejected").map((u) => u.reason), l = c.filter(
1297
- (u) => u.status === "fulfilled"
1298
- ).map((u) => u.value);
1230
+ ), d = qt(c, h.signal), l = c.filter(
1231
+ (f) => f.status === "fulfilled"
1232
+ ).map((f) => f.value);
1299
1233
  if (d.length) {
1300
- const u = await this.#O(l), f = d.length === 1 ? d[0] : new AggregateError(d, "Plugin startup layer failed");
1301
- throw u.length ? new O(
1302
- [f, ...u],
1303
- "Plugin startup layer failed and could not be cleanly disposed"
1304
- ) : f;
1234
+ const f = await this.#l(l), p = d.length === 1 ? d[0] : new AggregateError(d, "Installation startup layer failed");
1235
+ throw f.length ? new N(
1236
+ [p, ...f],
1237
+ "Installation startup layer failed and could not be cleanly disposed"
1238
+ ) : p;
1239
+ }
1240
+ this.#f(l);
1241
+ }
1242
+ }
1243
+ async deactivate(t) {
1244
+ const e = [], i = this.#a.filter((s) => t.has(s)).reverse();
1245
+ this.#a = this.#a.filter(
1246
+ (s) => !t.has(s)
1247
+ );
1248
+ for (const s of i) {
1249
+ const n = s.instance;
1250
+ if (n) {
1251
+ s.beginStopping(), this.#n.delete(s);
1252
+ try {
1253
+ await n.lifetime.dispose();
1254
+ } catch (o) {
1255
+ e.push(o);
1256
+ } finally {
1257
+ s.deactivate();
1258
+ }
1305
1259
  }
1306
- for (const u of l) this.#w(u);
1307
1260
  }
1261
+ return e;
1262
+ }
1263
+ async withContributionBatch(t) {
1264
+ this.#r.beginBatch();
1265
+ let e;
1266
+ try {
1267
+ e = { ok: !0, value: await t() };
1268
+ } catch (s) {
1269
+ e = { ok: !1, error: s };
1270
+ }
1271
+ let i;
1272
+ try {
1273
+ this.#r.endBatch(), i = { ok: !0 };
1274
+ } catch (s) {
1275
+ i = { ok: !1, error: s };
1276
+ }
1277
+ if (!e.ok && !i.ok)
1278
+ throw new AggregateError(
1279
+ [e.error, i.error],
1280
+ "Host operation and contribution publication failed"
1281
+ );
1282
+ if (!e.ok) throw e.error;
1283
+ if (!i.ok) throw i.error;
1284
+ return e.value;
1308
1285
  }
1309
- async #b(t, e, i, s, n) {
1286
+ async #d(t, e, i, s, n) {
1310
1287
  e.deactivate();
1311
- const o = e.spec.plugin, a = new L(n, e.id, { parentSignal: s });
1288
+ const o = e.declaration.plugin, a = new D(n, e.id, { parentSignal: s });
1312
1289
  try {
1313
- const h = this.#C(t, e, o, a), c = {
1314
- applicationName: this.#t,
1290
+ const h = this.#u(t, e, o, a), c = Object.freeze({
1291
+ hostName: this.#t,
1315
1292
  pluginName: o.name,
1316
1293
  installationId: e.id,
1317
1294
  groupId: e.groupId
1318
- }, d = this.#T(a, c, h), l = await o.setup(d, i), u = /* @__PURE__ */ new Map();
1319
- for (const [f, _] of Object.entries(o.provides ?? {})) {
1320
- if (typeof l != "object" || l === null || !Object.hasOwn(l, f))
1321
- throw new p(
1295
+ }), d = this.#h(a, c, h), l = await o.setup(d, i), f = /* @__PURE__ */ new Map();
1296
+ for (const [p, st] of Object.entries(o.provides ?? {})) {
1297
+ if (typeof l != "object" || l === null || !Object.hasOwn(l, p))
1298
+ throw new u(
1322
1299
  "SERVICE_NOT_RETURNED",
1323
- `Plugin '${e.id}' did not return provided service '${f}'`
1300
+ `Installation '${e.id}' did not return provided Service '${p}'`
1324
1301
  );
1325
- u.set(_.id, l[f]);
1302
+ f.set(st.id, l[p]);
1326
1303
  }
1327
1304
  return Object.freeze({
1328
1305
  installation: e,
1329
- runtime: Object.freeze({ plugin: o, config: i, lifetime: a }),
1330
- services: u
1306
+ instance: Object.freeze({ plugin: o, config: i, lifetime: a }),
1307
+ services: f
1331
1308
  });
1332
1309
  } catch (h) {
1333
- e.fail(h);
1310
+ const c = e.fail(h);
1334
1311
  try {
1335
1312
  await a.dispose();
1336
- } catch (c) {
1337
- throw new O(
1338
- [h, c],
1339
- `Plugin '${e.id}' failed to start and could not be cleanly disposed`
1313
+ } catch (d) {
1314
+ throw new N(
1315
+ [c, d],
1316
+ `Installation '${e.id}' failed to start and could not be cleanly disposed`
1340
1317
  );
1341
1318
  }
1342
- throw h;
1319
+ throw c;
1343
1320
  }
1344
1321
  }
1345
- #w(t) {
1346
- const { installation: e, runtime: i, services: s } = t;
1347
- this.#r.set(e, s), i.lifetime.publish(), i.lifetime.detachStartupSignal(), e.activate(i), this.#c.push(e);
1322
+ #f(t) {
1323
+ for (const { installation: e, instance: i, services: s } of t)
1324
+ this.#n.set(e, s), e.activate(i), this.#a.push(e);
1325
+ for (const { instance: e } of t)
1326
+ e.lifetime.publish(), e.lifetime.detachStartupSignal();
1348
1327
  }
1349
- async #O(t) {
1328
+ async #l(t) {
1350
1329
  const e = [];
1351
1330
  for (const i of [...t].reverse())
1352
1331
  try {
1353
- await i.runtime.lifetime.dispose();
1332
+ await i.instance.lifetime.dispose();
1354
1333
  } catch (s) {
1355
1334
  e.push(s);
1356
1335
  }
1357
1336
  return e;
1358
1337
  }
1359
- async #f(t) {
1360
- const e = [], i = this.#c.filter((s) => t.has(s)).reverse();
1361
- this.#c = this.#c.filter(
1362
- (s) => !t.has(s)
1363
- );
1364
- for (const s of i) {
1365
- const n = s.runtime;
1366
- if (n) {
1367
- s.beginStopping(), this.#r.delete(s);
1368
- try {
1369
- await n.lifetime.dispose();
1370
- } catch (o) {
1371
- e.push(o);
1372
- } finally {
1373
- s.deactivate();
1374
- }
1375
- }
1376
- }
1377
- return e;
1378
- }
1379
- async #v(t) {
1380
- const e = /* @__PURE__ */ new Map();
1381
- for (const i of t)
1382
- e.set(
1383
- i,
1384
- await this.#y(i.spec.plugin.config, i.spec.config)
1385
- );
1386
- return e;
1387
- }
1388
- #C(t, e, i, s) {
1338
+ #u(t, e, i, s) {
1389
1339
  const n = /* @__PURE__ */ Object.create(null);
1390
1340
  for (const [o, a] of Object.entries(i.requires ?? {}))
1391
1341
  if (a.kind === "optional") {
@@ -1394,33 +1344,33 @@ class Ct {
1394
1344
  n[o] = void 0;
1395
1345
  continue;
1396
1346
  }
1397
- const c = this.#r.get(h);
1347
+ const c = this.#n.get(h);
1398
1348
  if (!c?.has(a.service.id))
1399
- throw new p(
1349
+ throw new u(
1400
1350
  "SERVICE_UNAVAILABLE",
1401
- `Optional service '${a.service.id}' is not active for plugin '${e.id}'`
1351
+ `Optional Service '${a.service.id}' is not active for Installation '${e.id}'`
1402
1352
  );
1403
1353
  n[o] = c.get(a.service.id);
1404
1354
  } else if (a.kind === "service") {
1405
- const h = t.providerFor(e, a.id), c = h ? this.#r.get(h) : void 0;
1355
+ const h = t.providerFor(e, a.id), c = h ? this.#n.get(h) : void 0;
1406
1356
  if (!h || !c?.has(a.id))
1407
- throw new p(
1357
+ throw new u(
1408
1358
  "SERVICE_UNAVAILABLE",
1409
- `Service '${a.id}' is not active for plugin '${e.id}'`
1359
+ `Service '${a.id}' is not active for Installation '${e.id}'`
1410
1360
  );
1411
1361
  n[o] = c.get(a.id);
1412
1362
  } else
1413
- n[o] = this.#u(a, s);
1363
+ n[o] = this.#b(a, s);
1414
1364
  return n;
1415
1365
  }
1416
- #T(t, e, i) {
1366
+ #h(t, e, i) {
1417
1367
  return Object.freeze({
1418
1368
  ...i,
1419
1369
  get signal() {
1420
1370
  return t.signal;
1421
1371
  },
1422
- meta: Object.freeze(e),
1423
- log: this.#e,
1372
+ meta: e,
1373
+ log: t.contextLogger(e),
1424
1374
  cleanup: t.cleanup.bind(t),
1425
1375
  lifetime: t.lifetime.bind(t),
1426
1376
  spawn: t.spawn.bind(t),
@@ -1429,85 +1379,201 @@ class Ct {
1429
1379
  contribute: t.contribute.bind(t)
1430
1380
  });
1431
1381
  }
1432
- async #y(t, e) {
1433
- if (!t) return e;
1434
- const i = await t["~standard"].validate(e);
1435
- if (i.issues)
1436
- throw new H(
1437
- i.issues.map((s) => ({
1438
- message: s.message,
1439
- ...s.path ? { path: s.path } : {}
1440
- }))
1441
- );
1442
- return i.value;
1443
- }
1444
- #E(t) {
1382
+ #c(t) {
1445
1383
  return {
1446
- stageOn: (e, i, s, n) => this.#A(e, i, s, n, t),
1447
- emit: (e, i, s) => this.#P(e, i, s, t),
1448
- stageContribution: (e, i, s, n, o) => this.#S(e, i, s, n, o, t),
1384
+ stageOn: (e, i, s, n) => this.#p(e, i, s, n, t),
1385
+ emit: (e, i, s) => this.#g(e, i, s, t),
1386
+ stageContribution: (e, i, s, n, o) => this.#v(e, i, s, n, o, t),
1387
+ writeLog: (e, i, s, n) => this.#e[e](i, s, ...n),
1449
1388
  report: this.#s
1450
1389
  };
1451
1390
  }
1452
- #A(t, e, i, s, n) {
1453
- return this.#m(t), v(e, "event"), n.remember(e), this.#a.stage(e.id, i, s);
1391
+ #p(t, e, i, s, n) {
1392
+ return this.#w(t), b(e, "event"), n.remember(e), this.#o.stage(e.id, i, s);
1454
1393
  }
1455
- #P(t, e, i, s) {
1456
- return this.#m(t), v(e, "event"), s.remember(e), this.#a.emit(e.id, i);
1394
+ #g(t, e, i, s) {
1395
+ return this.#w(t), b(e, "event"), s.remember(e), this.#o.emit(e.id, i);
1457
1396
  }
1458
- #S(t, e, i, s, n, o) {
1459
- return this.#m(t), v(e, "extension"), o.remember(e), this.#o.get(e).stage(t, i, s, n);
1397
+ #v(t, e, i, s, n, o) {
1398
+ return this.#w(t), b(e, "extensionPoint"), o.remember(e), this.#r.get(e).stage(t, i, s, n);
1460
1399
  }
1461
- #u(t, e) {
1462
- return this.#o.get(t).view((i, s) => e.ownLease(i, s));
1400
+ #b(t, e) {
1401
+ return this.#r.get(t).view((i, s) => e.ownLease(i, s));
1402
+ }
1403
+ #w(t) {
1404
+ if (!this.#i(t))
1405
+ throw new Error(`Installation '${t}' is not installed`);
1406
+ }
1407
+ }
1408
+ function qt(r, t) {
1409
+ const e = [];
1410
+ let i = !1;
1411
+ for (const s of r)
1412
+ s.status !== "fulfilled" && (Object.is(s.reason, t.reason) ? (i || e.push(s.reason), i = !0) : J(t, s.reason) || e.push(s.reason));
1413
+ return e;
1414
+ }
1415
+ class Dt {
1416
+ #t = new dt();
1417
+ #e;
1418
+ #i;
1419
+ constructor(t) {
1420
+ this.#e = new Mt(t);
1463
1421
  }
1464
- #m(t) {
1465
- if (!this.#i(t)) throw new TypeError(`Plugin '${t}' is not installed`);
1422
+ get hasCommittedPlan() {
1423
+ return this.#i !== void 0;
1424
+ }
1425
+ get(t, e) {
1426
+ const i = ot(t), s = i ? t.service : t;
1427
+ if (b(s, "service"), this.#t.assertCompatible(s), e === "unavailable") throw U();
1428
+ const n = this.#a().provider(s.id);
1429
+ if (!n) {
1430
+ if (i) return;
1431
+ throw new u("SERVICE_UNAVAILABLE", `Service '${s.id}' is not active`);
1432
+ }
1433
+ const o = this.#e.readService(n, s.id);
1434
+ if (!o.found) {
1435
+ if (i) return;
1436
+ throw new u("SERVICE_UNAVAILABLE", `Service '${s.id}' is not active`);
1437
+ }
1438
+ return o.value;
1439
+ }
1440
+ contributions(t) {
1441
+ return b(t, "extensionPoint"), this.#t.remember(t), this.#e.contributions(t);
1442
+ }
1443
+ buildPlan(t) {
1444
+ return M.build(t, this.#t.kinds);
1466
1445
  }
1467
- async #j(t) {
1468
- this.#o.beginBatch();
1446
+ async start(t) {
1447
+ const e = this.#t.draft(t.contractKinds);
1469
1448
  try {
1470
- return await t();
1471
- } finally {
1472
- this.#o.endBatch();
1449
+ await this.#e.withContributionBatch(() => this.#s(t, e)), this.#i = t;
1450
+ } catch (i) {
1451
+ throw e.discard(), this.#i = void 0, i;
1452
+ }
1453
+ }
1454
+ async stop() {
1455
+ const t = await this.#e.withContributionBatch(() => this.#e.deactivateAll());
1456
+ return this.#i = void 0, t;
1457
+ }
1458
+ async transition(t, e, i) {
1459
+ return this.#e.withContributionBatch(async () => {
1460
+ const s = this.#a(), n = s.affectedByTransitionTo(t, e);
1461
+ let o, a;
1462
+ try {
1463
+ o = await this.#r(
1464
+ t.order.filter((d) => n.has(d))
1465
+ ), a = this.#t.draft(t.contractKinds);
1466
+ } catch (d) {
1467
+ throw i(), d;
1468
+ }
1469
+ const h = this.#e.captureConfigs(n), c = await this.#e.deactivate(n);
1470
+ if (c.length)
1471
+ return a.discard(), this.#n(
1472
+ i,
1473
+ c,
1474
+ "Installation change could not cleanly stop the affected Instances"
1475
+ );
1476
+ try {
1477
+ return await this.#e.activate(t, n, o, a), a.commit(), this.#e.commitActivationOrder(t.order), this.#i = t, Object.freeze({ kind: "committed", affected: n });
1478
+ } catch (d) {
1479
+ const l = await this.#e.deactivate(n);
1480
+ return a.discard(), d instanceof N || l.length ? this.#n(
1481
+ i,
1482
+ [d, ...l],
1483
+ "Installation change failed and its partial activation could not be cleanly disposed"
1484
+ ) : this.#o(i, s, n, h, [
1485
+ d,
1486
+ ...l
1487
+ ]);
1488
+ }
1489
+ });
1490
+ }
1491
+ async #s(t, e) {
1492
+ const i = new Set(t.order), s = await this.#r(t.order);
1493
+ this.#e.resetActivationState();
1494
+ try {
1495
+ await this.#e.activate(t, i, s, e), e.commit(), this.#e.commitActivationOrder(t.order);
1496
+ } catch (n) {
1497
+ const o = await this.#e.deactivate(i);
1498
+ throw o.length ? new AggregateError([n, ...o], "Host startup failed") : n;
1499
+ }
1500
+ }
1501
+ async #n(t, e, i) {
1502
+ t();
1503
+ const s = await this.#e.deactivateAll();
1504
+ throw this.#i = void 0, new AggregateError([...e, ...s], i);
1505
+ }
1506
+ async #o(t, e, i, s, n) {
1507
+ t();
1508
+ const o = this.#t.draft(e.contractKinds);
1509
+ try {
1510
+ await this.#e.activate(e, i, s, o), o.commit(), this.#e.commitActivationOrder(e.order), this.#i = e;
1511
+ } catch (h) {
1512
+ const c = await this.#e.deactivateAll();
1513
+ throw o.discard(), this.#i = void 0, new AggregateError(
1514
+ [...n, h, ...c],
1515
+ "Installation change failed and the previous Instances could not be restored"
1516
+ );
1473
1517
  }
1518
+ const a = n.length === 1 ? n[0] : new AggregateError(n, "Installation change failed");
1519
+ return Object.freeze({ kind: "rolled-back", affected: i, error: a });
1520
+ }
1521
+ async #r(t) {
1522
+ const e = /* @__PURE__ */ new Map();
1523
+ for (const i of t)
1524
+ try {
1525
+ e.set(
1526
+ i,
1527
+ await X(
1528
+ i.declaration.plugin.config,
1529
+ i.declaration.config,
1530
+ i.id
1531
+ )
1532
+ );
1533
+ } catch (s) {
1534
+ throw $(
1535
+ s,
1536
+ "INSTALLATION_UNAVAILABLE",
1537
+ `Installation '${i.id}' failed with a non-Error value`
1538
+ );
1539
+ }
1540
+ return e;
1474
1541
  }
1475
- #I() {
1476
- if (!this.#h)
1477
- throw M();
1478
- return this.#h;
1542
+ #a() {
1543
+ if (!this.#i) throw U();
1544
+ return this.#i;
1479
1545
  }
1480
1546
  }
1481
- function M() {
1482
- return new p("SERVICE_UNAVAILABLE", "Application services are not active");
1547
+ function U() {
1548
+ return new u("SERVICE_UNAVAILABLE", "Host services are not active");
1483
1549
  }
1484
- class Pt {
1550
+ class Gt {
1485
1551
  #t;
1486
1552
  #e;
1487
1553
  #i;
1488
1554
  #s = 0;
1489
1555
  view;
1490
1556
  constructor(t, e, i) {
1491
- this.#t = t, this.#i = this.#r("idle", [], e), this.#e = new U(() => this.#i, i), this.view = this.#e.view;
1557
+ this.#t = t, this.#i = this.#n("idle", [], e), this.#e = new q(() => this.#i, i), this.view = this.#e.view;
1492
1558
  }
1493
1559
  publish(t, e, i) {
1494
- this.#s++, this.#i = this.#r(t, e, i), this.#e.invalidate();
1560
+ this.#s++, this.#i = this.#n(t, e, i), this.#e.invalidate();
1495
1561
  }
1496
- #r(t, e, i) {
1562
+ #n(t, e, i) {
1497
1563
  const s = /* @__PURE__ */ new Map();
1498
1564
  for (const o of e) {
1499
1565
  const a = {
1500
1566
  id: o.id,
1501
- name: o.spec.plugin.name,
1567
+ pluginName: o.declaration.plugin.name,
1502
1568
  groupId: o.groupId,
1503
1569
  status: o.status,
1504
1570
  requires: Object.freeze(
1505
- Object.values(o.spec.plugin.requires ?? {}).map((c) => c.kind === "optional" ? c.service.id : c.id)
1571
+ Object.values(o.declaration.plugin.requires ?? {}).map((c) => c.kind === "optional" ? c.service.id : c.id)
1506
1572
  ),
1507
1573
  provides: Object.freeze(
1508
- Object.values(o.spec.plugin.provides ?? {}).map((c) => c.id)
1574
+ Object.values(o.declaration.plugin.provides ?? {}).map((c) => c.id)
1509
1575
  ),
1510
- ...o.runtime ? { lifetime: o.runtime.lifetime.diagnostics } : {}
1576
+ ...o.instance ? { lifetime: o.instance.lifetime.diagnostics } : {}
1511
1577
  }, h = o.error;
1512
1578
  s.set(
1513
1579
  o.id,
@@ -1526,12 +1592,28 @@ class Pt {
1526
1592
  name: this.#t,
1527
1593
  status: t,
1528
1594
  revision: this.#s,
1529
- plugins: new C(s),
1530
- groups: new C(n)
1595
+ installations: new S(s),
1596
+ groups: new S(n)
1531
1597
  });
1532
1598
  }
1533
1599
  }
1534
- const St = /* @__PURE__ */ new Set([
1600
+ function k(r, t, e = {}) {
1601
+ if (!r || typeof r != "object" || Array.isArray(r))
1602
+ throw E(e, `${t} must be a plain record`);
1603
+ const i = Object.getPrototypeOf(r);
1604
+ if (i !== Object.prototype && i !== null)
1605
+ throw E(e, `${t} must be a plain record`);
1606
+ for (const s of Reflect.ownKeys(r)) {
1607
+ if (typeof s != "string" || !Object.prototype.propertyIsEnumerable.call(r, s))
1608
+ throw E(e, `${t} keys must be enumerable strings`);
1609
+ if (e.fields && !e.fields.has(s))
1610
+ throw E(e, `${t}: unknown field '${s}'`);
1611
+ }
1612
+ }
1613
+ function E(r, t) {
1614
+ return r.createError?.(t) ?? new TypeError(t);
1615
+ }
1616
+ const Bt = /* @__PURE__ */ new Set([
1535
1617
  "signal",
1536
1618
  "meta",
1537
1619
  "log",
@@ -1541,138 +1623,187 @@ const St = /* @__PURE__ */ new Set([
1541
1623
  "on",
1542
1624
  "emit",
1543
1625
  "contribute"
1544
- ]);
1545
- function q(r) {
1546
- if (typeof r?.name != "string" || !r.name.trim())
1626
+ ]), Ft = /* @__PURE__ */ new Set(["name", "config", "requires", "provides", "setup"]);
1627
+ function pe(r) {
1628
+ return it(r);
1629
+ }
1630
+ function it(r) {
1631
+ Ut(r);
1632
+ const t = Object.hasOwn(r, "name") ? r.name : void 0, e = Object.hasOwn(r, "config") ? r.config : void 0, i = Object.hasOwn(r, "requires") ? r.requires : void 0, s = Object.hasOwn(r, "provides") ? r.provides : void 0, n = Object.hasOwn(r, "setup") ? r.setup : void 0;
1633
+ if (typeof t != "string" || !t.trim())
1547
1634
  throw new TypeError("Plugin name must be a non-empty string");
1548
- if (r.name !== r.name.trim())
1635
+ if (t !== t.trim())
1549
1636
  throw new TypeError("Plugin name cannot start or end with whitespace");
1550
- if (typeof r.setup != "function")
1551
- throw new TypeError(`Plugin '${r.name}' must define setup()`);
1552
- if (r.config !== void 0 && typeof r.config["~standard"]?.validate != "function")
1553
- throw new TypeError(`Plugin '${r.name}' config must implement Standard Schema`);
1554
- for (const [i, s] of Object.entries(r.requires ?? {})) {
1555
- if (!i.trim()) throw new TypeError("Plugin requirement alias cannot be empty");
1556
- if (i !== i.trim())
1637
+ if (typeof n != "function")
1638
+ throw new TypeError(`Plugin '${t}' must define setup()`);
1639
+ if (e !== void 0 && !_t(e))
1640
+ throw new TypeError(`Plugin '${t}' config must implement Standard Schema V1`);
1641
+ _(i, t, "requires"), _(s, t, "provides");
1642
+ const o = i ? Object.freeze({ ...i }) : void 0, a = s ? Object.freeze({ ...s }) : void 0, h = /* @__PURE__ */ new Map();
1643
+ for (const [c, d] of Object.entries(o ?? {})) {
1644
+ if (!c.trim()) throw new TypeError("Plugin requirement alias cannot be empty");
1645
+ if (c !== c.trim())
1557
1646
  throw new TypeError("Plugin requirement alias cannot start or end with whitespace");
1558
- if (St.has(i))
1559
- throw new TypeError(`Plugin requirement '${i}' conflicts with the context API`);
1560
- if (!s || typeof s != "object")
1561
- throw new TypeError(`Plugin requirement '${i}' is not a contract`);
1562
- if (s.kind === "optional") {
1563
- if (!w(s.service, "service"))
1564
- throw new TypeError(`Optional requirement '${i}' must wrap a service contract`);
1565
- } else if (!w(s, "service") && !w(s, "extension"))
1566
- throw new TypeError(`Plugin requirement '${i}' must be a service or extension contract`);
1567
- }
1568
- for (const [i, s] of Object.entries(r.provides ?? {})) {
1569
- if (!i.trim()) throw new TypeError("Plugin provision alias cannot be empty");
1570
- if (i !== i.trim())
1647
+ if (Bt.has(c))
1648
+ throw new TypeError(`Plugin requirement '${c}' conflicts with the context API`);
1649
+ if (!d || typeof d != "object")
1650
+ throw new TypeError(`Plugin requirement '${c}' is not a contract`);
1651
+ if (d.kind === "optional") {
1652
+ if (!v(d.service, "service"))
1653
+ throw new TypeError(`Optional requirement '${c}' must wrap a Service`);
1654
+ } else if (!v(d, "service") && !v(d, "extensionPoint"))
1655
+ throw new TypeError(`Plugin requirement '${c}' must be a Service or ExtensionPoint`);
1656
+ H(
1657
+ t,
1658
+ h,
1659
+ "requirement",
1660
+ c,
1661
+ d.kind === "optional" ? d.service : d
1662
+ );
1663
+ }
1664
+ for (const [c, d] of Object.entries(a ?? {})) {
1665
+ if (!c.trim()) throw new TypeError("Plugin provision alias cannot be empty");
1666
+ if (c !== c.trim())
1571
1667
  throw new TypeError("Plugin provision alias cannot start or end with whitespace");
1572
- if (!w(s, "service"))
1573
- throw new TypeError(`Plugin provision '${i}' must be a service contract`);
1668
+ if (!v(d, "service"))
1669
+ throw new TypeError(`Plugin provision '${c}' must be a Service`);
1670
+ H(t, h, "provision", c, d);
1574
1671
  }
1575
- const t = r.requires ? Object.freeze({ ...r.requires }) : void 0, e = r.provides ? Object.freeze({ ...r.provides }) : void 0;
1576
1672
  return Object.freeze({
1577
- ...r,
1578
- ...t ? { requires: t } : {},
1579
- ...e ? { provides: e } : {}
1673
+ name: t,
1674
+ ...e === void 0 ? {} : { config: e },
1675
+ ...o ? { requires: o } : {},
1676
+ ...a ? { provides: a } : {},
1677
+ setup: n
1580
1678
  });
1581
1679
  }
1582
- const j = /* @__PURE__ */ new WeakMap();
1583
- function Ot(r, t) {
1584
- j.get(r)?.(t);
1680
+ function Ut(r) {
1681
+ k(r, "Plugin declaration", { fields: Ft });
1682
+ }
1683
+ function _t(r) {
1684
+ if (!r || typeof r != "object" && typeof r != "function") return !1;
1685
+ const t = r["~standard"];
1686
+ if (!t || typeof t != "object") return !1;
1687
+ const e = t;
1688
+ return e.version === 1 && typeof e.vendor == "string" && typeof e.validate == "function";
1689
+ }
1690
+ function _(r, t, e) {
1691
+ r !== void 0 && k(r, `Plugin '${t}' ${e}`);
1692
+ }
1693
+ function H(r, t, e, i, s) {
1694
+ const n = t.get(s.id);
1695
+ if (!n) {
1696
+ t.set(s.id, { alias: i, kind: s.kind, role: e });
1697
+ return;
1698
+ }
1699
+ if (n.kind !== s.kind)
1700
+ throw new TypeError(
1701
+ `Plugin '${r}' uses Contract '${s.id}' as both ${L(n.kind)} and ${L(s.kind)}`
1702
+ );
1703
+ const o = L(s.kind);
1704
+ throw n.role !== e ? new TypeError(
1705
+ `Plugin '${r}' cannot both require and provide ${o} '${s.id}'`
1706
+ ) : new TypeError(
1707
+ `Plugin '${r}' ${e} aliases '${n.alias}' and '${i}' reference the same ${o} '${s.id}'`
1708
+ );
1709
+ }
1710
+ function L(r) {
1711
+ return r === "extensionPoint" ? "ExtensionPoint" : r === "event" ? "Event" : "Service";
1712
+ }
1713
+ function K(r) {
1714
+ return it(r);
1585
1715
  }
1586
- class Tt {
1716
+ const Ht = /* @__PURE__ */ new Set(["plugin", "config"]), x = /* @__PURE__ */ new WeakMap();
1717
+ function Kt(r, t) {
1718
+ x.get(r)?.(t);
1719
+ }
1720
+ class Wt {
1587
1721
  #t = /* @__PURE__ */ new Map();
1588
1722
  #e;
1589
1723
  constructor(t) {
1590
- this.#e = { phase: "open", host: t }, j.set(this, (e) => this.#i(e)), Object.freeze(this);
1724
+ this.#e = { phase: "open", port: t }, x.set(this, (e) => this.#i(e)), Object.freeze(this);
1591
1725
  }
1592
1726
  install(t, ...e) {
1593
- const i = this.#r(), s = q(t), n = i.create(s, e[0]);
1594
- return this.#s({ kind: "install", installation: n.installation }), n.handle;
1727
+ const i = this.#n(), s = K(t), n = i.create(s, e[0]);
1728
+ return this.#s({ kind: "install", installation: n.record }), n.publicInstallation;
1595
1729
  }
1596
1730
  update(t, e) {
1597
- const i = this.#r();
1598
- if (!e || typeof e != "object")
1599
- throw new TypeError("Plugin update must be an object");
1731
+ const i = this.#n();
1732
+ k(e, "Installation update", { fields: Ht });
1600
1733
  const s = Object.hasOwn(e, "plugin"), n = Object.hasOwn(e, "config");
1601
1734
  if (!s && !n)
1602
- throw new TypeError("Plugin update must include 'plugin' or 'config'");
1735
+ throw new TypeError("Installation update must include 'plugin' or 'config'");
1603
1736
  const o = i.resolve(t);
1604
1737
  let a;
1605
1738
  if (s) {
1606
1739
  const d = e.plugin;
1607
- if (!d) throw new TypeError("Plugin update 'plugin' must be a plugin definition");
1608
- a = q(d);
1740
+ if (!d) throw new TypeError("Installation update 'plugin' must be a Plugin");
1741
+ a = K(d);
1609
1742
  }
1610
1743
  let h;
1611
1744
  a && n ? h = { kind: "plugin-and-config", plugin: a, config: e.config } : a ? h = { kind: "plugin", plugin: a } : h = { kind: "config", config: e.config };
1612
1745
  const c = { kind: "update", installation: o, declaration: h };
1613
- return this.#s(c), this;
1746
+ this.#s(c);
1614
1747
  }
1615
1748
  remove(t) {
1616
- const e = this.#r();
1617
- return this.#s({ kind: "remove", installation: e.resolve(t) }), this;
1749
+ const e = this.#n();
1750
+ this.#s({ kind: "remove", installation: e.resolve(t) });
1618
1751
  }
1619
1752
  commit() {
1620
1753
  const t = this.#e;
1621
1754
  if (t.phase === "submitted") return t.promise;
1622
1755
  if (t.phase === "discarded")
1623
- throw new TypeError("Cannot commit a discarded ChangeSet");
1756
+ throw new Error("Cannot commit a discarded ChangeSet");
1624
1757
  if (t.phase === "committing")
1625
- throw new TypeError("Core ChangeSet commit is already being prepared");
1758
+ throw new Error("Core ChangeSet commit is already being prepared");
1626
1759
  this.#e = { phase: "committing" };
1627
- const e = Object.freeze([...this.#t.values()]), i = t.host;
1760
+ const e = Object.freeze([...this.#t.values()]), i = t.port;
1628
1761
  try {
1629
1762
  for (const n of e)
1630
1763
  n.kind === "install" && i.attach(n.installation);
1631
1764
  } catch (n) {
1632
1765
  for (const o of e)
1633
1766
  o.kind === "install" && i.discard(o.installation, n);
1634
- return this.#n(Promise.reject(n));
1767
+ return this.#o(Promise.reject(n));
1635
1768
  }
1636
- if (!e.length)
1637
- return this.#n(Promise.resolve());
1638
1769
  let s;
1639
1770
  try {
1640
1771
  s = i.execute(e);
1641
1772
  } catch (n) {
1642
1773
  s = Promise.reject(n);
1643
1774
  }
1644
- return this.#n(s);
1775
+ return this.#o(s);
1645
1776
  }
1646
1777
  #i(t) {
1647
1778
  const e = this.#e;
1648
1779
  if (e.phase !== "open") return;
1649
1780
  this.#e = { phase: "discarded" };
1650
1781
  const i = [...this.#t.values()];
1651
- this.#a();
1782
+ this.#r();
1652
1783
  for (const s of i)
1653
- s.kind === "install" && e.host.discard(s.installation, t);
1784
+ s.kind === "install" && e.port.discard(s.installation, t);
1654
1785
  }
1655
1786
  #s(t) {
1656
1787
  if (this.#t.has(t.installation))
1657
1788
  throw new TypeError(
1658
- `Plugin '${t.installation.id}' can only appear once in the same ChangeSet`
1789
+ `Installation '${t.installation.id}' can only appear once in the same ChangeSet`
1659
1790
  );
1660
1791
  this.#t.set(t.installation, Object.freeze(t));
1661
1792
  }
1662
- #r() {
1793
+ #n() {
1663
1794
  const t = this.#e;
1664
1795
  if (t.phase !== "open")
1665
1796
  throw new TypeError(`Cannot modify a ${t.phase} ChangeSet`);
1666
- return t.host;
1797
+ return t.port;
1667
1798
  }
1668
- #n(t) {
1669
- return this.#e = { phase: "submitted", promise: t }, this.#a(), t;
1799
+ #o(t) {
1800
+ return this.#e = { phase: "submitted", promise: t }, this.#r(), t;
1670
1801
  }
1671
- #a() {
1672
- this.#t.clear(), j.delete(this);
1802
+ #r() {
1803
+ this.#t.clear(), x.delete(this);
1673
1804
  }
1674
1805
  }
1675
- class At {
1806
+ class Yt {
1676
1807
  #t;
1677
1808
  constructor(t, e, i) {
1678
1809
  this.#t = { phase: "open", draft: t, discard: e, normalize: i };
@@ -1683,7 +1814,7 @@ class At {
1683
1814
  requireDraft() {
1684
1815
  const t = this.#t;
1685
1816
  if (t.phase === "failed") throw t.error;
1686
- if (t.phase === "sealed") throw T();
1817
+ if (t.phase === "sealed") throw z();
1687
1818
  return t.draft;
1688
1819
  }
1689
1820
  assertOpen() {
@@ -1692,7 +1823,7 @@ class At {
1692
1823
  fail(t) {
1693
1824
  const e = this.#t;
1694
1825
  if (e.phase === "failed") return e.error;
1695
- if (e.phase === "sealed") throw T();
1826
+ if (e.phase === "sealed") throw z();
1696
1827
  const i = e.normalize(t);
1697
1828
  return this.#t = {
1698
1829
  phase: "failed",
@@ -1704,7 +1835,7 @@ class At {
1704
1835
  seal() {
1705
1836
  const t = this.#t;
1706
1837
  if (t.phase === "failed") throw t.error;
1707
- if (t.phase === "sealed") throw T();
1838
+ if (t.phase === "sealed") throw z();
1708
1839
  return this.#t = { phase: "sealed" }, t.draft;
1709
1840
  }
1710
1841
  discard(t) {
@@ -1714,10 +1845,10 @@ class At {
1714
1845
  this.#t = { phase: "sealed" }, e.discard(e.draft, i);
1715
1846
  }
1716
1847
  }
1717
- function T() {
1718
- return new TypeError("Group configuration has been sealed");
1848
+ function z() {
1849
+ return new Error("Group configuration has been sealed");
1719
1850
  }
1720
- class P {
1851
+ class I {
1721
1852
  constructor(t, e, i) {
1722
1853
  this.id = t, this.name = e, this.#e = { phase: "attached", parent: i };
1723
1854
  }
@@ -1726,7 +1857,7 @@ class P {
1726
1857
  #t = /* @__PURE__ */ new Map();
1727
1858
  #e;
1728
1859
  static root(t) {
1729
- return new P("/", t, void 0);
1860
+ return new I("/", t, void 0);
1730
1861
  }
1731
1862
  get attached() {
1732
1863
  return this.#e.phase !== "detached";
@@ -1739,13 +1870,16 @@ class P {
1739
1870
  return t.phase === "detached" ? void 0 : t.parent;
1740
1871
  }
1741
1872
  create(t) {
1742
- if (this.assertAttached(), jt(t), this.#t.has(t))
1873
+ if (this.assertAttached(), Qt(t), this.#t.has(t))
1743
1874
  throw new TypeError(`Group '${this.#i(t)}' already exists`);
1744
- const e = new P(this.#i(t), t, this);
1875
+ const e = new I(this.#i(t), t, this);
1745
1876
  return this.#t.set(t, e), e;
1746
1877
  }
1747
- containsId(t) {
1748
- return this.id === "/" ? t.startsWith("/") : t === this.id || t.startsWith(`${this.id}/`);
1878
+ contains(t) {
1879
+ if (t === this) return !0;
1880
+ for (const e of this.#t.values())
1881
+ if (e.contains(t)) return !0;
1882
+ return !1;
1749
1883
  }
1750
1884
  assertAttached() {
1751
1885
  if (this.#e.phase === "detached")
@@ -1770,14 +1904,14 @@ class P {
1770
1904
  return this.id === "/" ? `/${t}` : `${this.id}/${t}`;
1771
1905
  }
1772
1906
  }
1773
- function jt(r) {
1907
+ function Qt(r) {
1774
1908
  if (typeof r != "string" || !r.trim())
1775
1909
  throw new TypeError("Group name must be a non-empty string");
1776
1910
  if (r !== r.trim())
1777
1911
  throw new TypeError("Group name cannot start or end with whitespace");
1778
1912
  if (r.includes("/")) throw new TypeError("Group name cannot contain '/'");
1779
1913
  }
1780
- class D {
1914
+ class W {
1781
1915
  constructor(t, e, i) {
1782
1916
  this.node = t, this.#t = { phase: e }, this.#e = i;
1783
1917
  }
@@ -1828,15 +1962,15 @@ class D {
1828
1962
  return e.phase === "pending" && e.attempt === t;
1829
1963
  }
1830
1964
  }
1831
- function I(r) {
1832
- return new p("GROUP_REMOVED", `Group '${r.id}' has been removed`);
1965
+ function A(r) {
1966
+ return new u("GROUP_REMOVED", `Group '${r.id}' has been removed`);
1833
1967
  }
1834
- const y = /* @__PURE__ */ new WeakMap();
1835
- class It {
1968
+ const C = /* @__PURE__ */ new WeakMap();
1969
+ class Jt {
1836
1970
  #t;
1837
1971
  #e;
1838
1972
  constructor(t, e, i) {
1839
- this.#t = e, this.#e = i ? { phase: "configuring", coordinator: t, configuration: i } : { phase: "attached", coordinator: t }, y.set(this, {
1973
+ this.#t = e, this.#e = i ? { phase: "configuring", coordinator: t, configuration: i } : { phase: "attached", coordinator: t }, C.set(this, {
1840
1974
  finishConfiguration: () => {
1841
1975
  const s = this.#e;
1842
1976
  s.phase === "configuring" && (this.#e = { phase: "attached", coordinator: s.coordinator });
@@ -1858,15 +1992,11 @@ class It {
1858
1992
  }
1859
1993
  ready() {
1860
1994
  const t = this.#e;
1861
- return t.phase === "revoked" ? Promise.reject(I(this.#t)) : t.coordinator.ready(this.#t);
1995
+ return t.phase === "revoked" ? Promise.reject(A(this.#t)) : t.coordinator.ready(this.#t);
1862
1996
  }
1863
1997
  install(t, ...e) {
1864
1998
  const i = this.#e;
1865
- return i.phase === "configuring" ? i.configuration.requireDraft().install(t, ...e) : this.#i().install(
1866
- this.#t,
1867
- t,
1868
- e[0]
1869
- );
1999
+ return i.phase === "configuring" ? i.configuration.requireDraft().install(t, ...e) : this.#i().install(this.#t, t, ...e);
1870
2000
  }
1871
2001
  change() {
1872
2002
  if (this.#e.phase === "configuring")
@@ -1890,19 +2020,19 @@ class It {
1890
2020
  }
1891
2021
  #i() {
1892
2022
  const t = this.#e;
1893
- if (t.phase === "revoked") throw I(this.#t);
2023
+ if (t.phase === "revoked") throw A(this.#t);
1894
2024
  return t.coordinator;
1895
2025
  }
1896
2026
  }
1897
- class kt {
2027
+ class Xt {
1898
2028
  root;
1899
2029
  #t;
1900
2030
  #e = /* @__PURE__ */ new WeakMap();
1901
2031
  #i = /* @__PURE__ */ new WeakMap();
1902
2032
  constructor(t, e) {
1903
- this.root = P.root(t), this.#t = e, this.#i.set(
2033
+ this.root = I.root(t), this.#t = e, this.#i.set(
1904
2034
  this.root,
1905
- new D(this.root, "established", () => e.notifyChanged())
2035
+ new W(this.root, "established", () => e.notifyChanged())
1906
2036
  );
1907
2037
  }
1908
2038
  nodes() {
@@ -1910,144 +2040,287 @@ class kt {
1910
2040
  }
1911
2041
  install(t, e, ...i) {
1912
2042
  const s = this.change(t), n = s.install(e, ...i);
1913
- return G(s.commit()), n;
2043
+ return Y(s.commit()), n;
1914
2044
  }
1915
2045
  change(t, e = "immediate") {
1916
- return t.assertAttached(), new Tt({
1917
- create: (i, s) => this.#t.createDraft(t, i, s),
2046
+ return this.#r(t), new Wt({
2047
+ create: (i, s) => (this.#r(t), this.#t.createDraft(t, i, s)),
1918
2048
  resolve: (i) => {
1919
- const s = this.#t.resolveHandle(i);
1920
- if (!t.containsId(s.groupId))
1921
- throw new TypeError(
1922
- `Plugin '${s.id}' is outside ChangeSet group '${t.id}'`
1923
- );
2049
+ this.#r(t);
2050
+ const s = this.#t.resolveInstallation(i);
2051
+ if (!s.attached) throw s.unavailableError();
2052
+ if (!t.contains(s.group))
2053
+ throw new TypeError(`Installation '${s.id}' is outside Group '${t.id}'`);
1924
2054
  return s;
1925
2055
  },
1926
2056
  execute: (i) => {
1927
- const s = this.#t.executeChanges(i);
2057
+ this.#r(t);
2058
+ const s = this.#t.executeChanges(t, i);
1928
2059
  for (const n of i) n.installation.trackReadiness(s);
1929
- return e === "immediate" && this.#n(t, s), s;
2060
+ return i.length && e === "immediate" && this.#o(t, s), s;
2061
+ },
2062
+ attach: (i) => {
2063
+ this.#r(t), this.#t.attachInstallation(i);
1930
2064
  },
1931
- attach: (i) => this.#t.attachInstallation(i),
1932
2065
  discard: (i, s) => this.#t.discardInstallation(i, s)
1933
2066
  });
1934
2067
  }
1935
2068
  create(t, e, i, s) {
1936
2069
  if (typeof i != "function") throw new TypeError("Group configure must be a function");
1937
2070
  const n = t.create(e);
1938
- this.#i.set(n, new D(n, "new", () => this.#t.notifyChanged()));
1939
- const o = s === void 0, a = s ?? new At(
2071
+ this.#i.set(n, new W(n, "new", () => this.#t.notifyChanged()));
2072
+ const o = s === void 0, a = s ?? new Yt(
1940
2073
  this.change(n, "deferred"),
1941
- Ot,
2074
+ Kt,
1942
2075
  (c) => $(
1943
2076
  c,
1944
2077
  "GROUP_UNAVAILABLE",
1945
2078
  `Group '${n.id}' configuration failed with a non-Error value`
1946
2079
  )
1947
- ), h = new It(this, n, a);
2080
+ ), h = new Jt(this, n, a);
1948
2081
  this.#e.set(n, h);
1949
2082
  try {
1950
2083
  const c = i(h);
1951
- Lt(c) && $t(c);
2084
+ te(c) && Zt(c);
1952
2085
  const d = a.failure;
1953
2086
  if (d) throw d;
1954
2087
  } catch (c) {
1955
2088
  const d = a.fail(c), l = n.walk();
1956
- throw n.detach(), this.#o(l), o && a.discard(d), this.#t.notifyChanged(), d;
2089
+ throw n.detach(), this.#a(l), o && a.discard(d), this.#t.notifyChanged(), d;
1957
2090
  }
1958
2091
  if (o) {
1959
2092
  const c = a.seal().commit();
1960
2093
  for (const d of n.walk()) {
1961
2094
  const l = this.#e.get(d);
1962
- l && y.get(l)?.finishConfiguration(), this.#n(d, c);
2095
+ l && C.get(l)?.finishConfiguration(), this.#o(d, c);
1963
2096
  }
1964
- G(c);
2097
+ Y(c);
1965
2098
  }
1966
2099
  return this.#t.notifyChanged(), h;
1967
2100
  }
1968
2101
  async ready(t) {
1969
- await this.#a(t).ready(async () => {
2102
+ await this.#r(t).ready(async () => {
1970
2103
  await Promise.all(this.#s(t).map((e) => e.ready()));
1971
2104
  });
1972
2105
  }
1973
2106
  status(t) {
1974
- return t.attached ? this.#a(t).status(this.#r(t)) : "removed";
2107
+ return t.attached ? this.#r(t).status(this.#n(t)) : "removed";
1975
2108
  }
1976
2109
  remove(t) {
1977
2110
  if (t === this.root) throw new TypeError("The root Group cannot be removed");
1978
2111
  return t.attached ? this.#t.runExclusive(async () => {
1979
2112
  if (!t.attached) {
1980
- this.#o([t]);
2113
+ this.#a([t]);
1981
2114
  return;
1982
2115
  }
1983
- const e = t.walk(), i = this.#s(t).map(
1984
- (s) => ({ kind: "remove", installation: s })
1985
- );
1986
- await this.#t.removeInstallations(i), t.detach(), this.#o(e), this.#t.notifyChanged();
1987
- }) : (this.#o([t]), Promise.resolve());
2116
+ const e = t.walk(), i = this.#s(t).map((s) => ({
2117
+ kind: "remove",
2118
+ installation: s
2119
+ }));
2120
+ await this.#t.removeInstallations(i), t.detach(), this.#a(e), this.#t.notifyChanged();
2121
+ }) : (this.#a([t]), Promise.resolve());
1988
2122
  }
1989
2123
  #s(t) {
1990
2124
  return [...this.#t.installations()].filter(
1991
- (e) => t.containsId(e.groupId)
2125
+ (e) => t.contains(e.group)
1992
2126
  );
1993
2127
  }
1994
- #r(t) {
2128
+ #n(t) {
1995
2129
  const e = this.#s(t);
1996
2130
  return e.some((i) => i.status === "failed") ? "failed" : e.some((i) => i.status === "stopping") ? "stopping" : e.length && e.every((i) => i.status === "active") ? "active" : e.length ? "pending" : "active";
1997
2131
  }
1998
- #n(t, e) {
1999
- this.#a(t).track(e);
2132
+ #o(t, e) {
2133
+ this.#r(t).track(e);
2000
2134
  }
2001
- #a(t) {
2135
+ #r(t) {
2002
2136
  const e = this.#i.get(t);
2003
- if (!e) throw I(t);
2137
+ if (!t.attached || !e) throw A(t);
2004
2138
  return e;
2005
2139
  }
2006
- #o(t) {
2140
+ #a(t) {
2007
2141
  for (const e of t) {
2008
2142
  this.#i.get(e)?.release(), this.#i.delete(e);
2009
2143
  const i = this.#e.get(e);
2010
- i && (y.get(i)?.revoke(), y.delete(i)), this.#e.delete(e);
2144
+ i && (C.get(i)?.revoke(), C.delete(i)), this.#e.delete(e);
2011
2145
  }
2012
2146
  }
2013
2147
  }
2014
- function G(r) {
2148
+ function Y(r) {
2015
2149
  Promise.resolve(r).catch(() => {
2016
2150
  });
2017
2151
  }
2018
- function $t(r) {
2152
+ function Zt(r) {
2019
2153
  throw Promise.resolve(r).catch(() => {
2020
2154
  }), new TypeError("Group configure must be synchronous");
2021
2155
  }
2022
- function Lt(r) {
2156
+ function te(r) {
2023
2157
  return r === null || typeof r != "object" && typeof r != "function" ? !1 : typeof r.then == "function";
2024
2158
  }
2025
- class zt {
2026
- #t = Promise.resolve();
2027
- get settled() {
2028
- return this.#t;
2159
+ function Q(r, t) {
2160
+ return Object.freeze({ plugin: r, config: t });
2161
+ }
2162
+ class ee {
2163
+ constructor(t, e, i, s) {
2164
+ this.id = t, this.index = e, this.groupId = i.id, this.#i = { declaration: s, group: i, notifyChanged: void 0 };
2029
2165
  }
2030
- run(t) {
2031
- if (typeof t != "function")
2032
- throw new TypeError("SerialQueue operation must be a function");
2033
- const e = this.#t.then(t);
2034
- return this.#t = e.then(
2166
+ id;
2167
+ index;
2168
+ #t = { phase: "pending" };
2169
+ #e;
2170
+ #i;
2171
+ groupId;
2172
+ #s = /* @__PURE__ */ new Set();
2173
+ attach(t) {
2174
+ const e = this.#d();
2175
+ if (e.notifyChanged) throw new Error(`Installation '${this.id}' is already attached`);
2176
+ e.notifyChanged = t;
2177
+ }
2178
+ get status() {
2179
+ return this.#t.phase;
2180
+ }
2181
+ /** Whether the owning ChangeSet has granted this Installation Host authority. */
2182
+ get attached() {
2183
+ return this.#i?.notifyChanged !== void 0;
2184
+ }
2185
+ get instance() {
2186
+ const t = this.#t;
2187
+ return t.phase === "active" || t.phase === "stopping" ? t.instance : void 0;
2188
+ }
2189
+ get error() {
2190
+ const t = this.#t;
2191
+ if (t.phase === "failed")
2192
+ return t.failure.retention === "live" ? t.failure.error : se(t.failure.summary);
2193
+ if (t.phase === "removed")
2194
+ return new u("INSTALLATION_REMOVED", `Installation '${this.id}' has been removed`);
2195
+ }
2196
+ get group() {
2197
+ return this.#d().group;
2198
+ }
2199
+ get declaration() {
2200
+ return this.#d().declaration;
2201
+ }
2202
+ replaceDeclaration(t) {
2203
+ this.#d().declaration = t;
2204
+ }
2205
+ ready() {
2206
+ const t = this.#e;
2207
+ return t ? t.barrier.then(() => this.#n()) : this.#n();
2208
+ }
2209
+ unavailableError() {
2210
+ return this.error ?? new u(
2211
+ "INSTALLATION_UNAVAILABLE",
2212
+ `Installation '${this.id}' has not been committed`
2213
+ );
2214
+ }
2215
+ trackReadiness(t) {
2216
+ const e = {}, i = t.then(
2035
2217
  () => {
2218
+ this.#e?.attempt === e && (this.#e = void 0);
2036
2219
  },
2037
- () => {
2220
+ (s) => {
2221
+ if (this.#e?.attempt === e && (this.#e = void 0), this.#t.phase !== "active") throw s;
2038
2222
  }
2039
- ), e;
2223
+ );
2224
+ this.#e = { attempt: e, barrier: i }, i.catch(() => {
2225
+ });
2226
+ }
2227
+ #n() {
2228
+ const t = this.#t;
2229
+ if ((t.phase === "active" || t.phase === "failed" || t.phase === "removed") && t.readiness === "settled") {
2230
+ if (t.phase === "active") return Promise.resolve();
2231
+ if (t.phase === "failed" || t.phase === "removed")
2232
+ return Promise.reject(
2233
+ this.error ?? new u(
2234
+ "INSTALLATION_UNAVAILABLE",
2235
+ `Installation '${this.id}' is ${t.phase}`
2236
+ )
2237
+ );
2238
+ }
2239
+ const e = Promise.withResolvers();
2240
+ return this.#s.add(e), e.promise;
2241
+ }
2242
+ activate(t) {
2243
+ this.#r({ phase: "active", instance: t, readiness: "unsettled" });
2244
+ }
2245
+ settleReady() {
2246
+ const t = this.#t;
2247
+ if (!(t.phase !== "active" && t.phase !== "failed" && t.phase !== "removed") && t.readiness !== "settled") {
2248
+ if (this.#t = { ...t, readiness: "settled" }, t.phase === "active")
2249
+ for (const e of this.#s) e.resolve();
2250
+ else {
2251
+ const e = this.error ?? new u("INSTALLATION_UNAVAILABLE", `Installation '${this.id}' is ${t.phase}`);
2252
+ for (const i of this.#s) i.reject(e);
2253
+ }
2254
+ this.#s.clear();
2255
+ }
2256
+ }
2257
+ beginStopping() {
2258
+ const t = this.#t;
2259
+ return t.phase !== "active" ? !1 : (this.#r({ phase: "stopping", instance: t.instance }), !0);
2260
+ }
2261
+ deactivate() {
2262
+ this.#r({ phase: "pending" });
2263
+ }
2264
+ fail(t) {
2265
+ return this.#o(t);
2266
+ }
2267
+ discard(t) {
2268
+ const e = this.#a(t);
2269
+ this.#r({
2270
+ phase: "failed",
2271
+ failure: { retention: "summary", summary: ie(e) },
2272
+ readiness: "settled"
2273
+ });
2274
+ for (const i of this.#s) i.reject(e);
2275
+ this.#s.clear(), this.#e = void 0, this.#i = void 0;
2276
+ }
2277
+ #o(t) {
2278
+ const e = this.#a(t);
2279
+ return this.#r({
2280
+ phase: "failed",
2281
+ failure: { retention: "live", error: e },
2282
+ readiness: "unsettled"
2283
+ }), e;
2284
+ }
2285
+ remove() {
2286
+ this.#r({ phase: "removed", readiness: "unsettled" }), this.#e = void 0, this.#i = void 0;
2287
+ }
2288
+ #r(t) {
2289
+ this.#t = t, this.#i?.notifyChanged?.();
2290
+ }
2291
+ #a(t) {
2292
+ return $(
2293
+ t,
2294
+ "INSTALLATION_UNAVAILABLE",
2295
+ `Installation '${this.id}' failed with a non-Error value`
2296
+ );
2297
+ }
2298
+ #d() {
2299
+ const t = this.#i;
2300
+ if (!t) throw new Error(`Installation '${this.id}' is no longer installed`);
2301
+ return t;
2040
2302
  }
2041
2303
  }
2042
- const xt = console, E = /* @__PURE__ */ new WeakMap();
2043
- class Rt {
2304
+ function ie(r) {
2305
+ return r instanceof u ? { category: "dougong", name: r.name, message: r.message, code: r.code } : {
2306
+ category: r instanceof TypeError ? "typeError" : "error",
2307
+ name: r.name,
2308
+ message: r.message
2309
+ };
2310
+ }
2311
+ function se(r) {
2312
+ const t = r.category === "dougong" ? new u(r.code, r.message) : r.category === "typeError" ? new TypeError(r.message) : new Error(r.message);
2313
+ return t.name = r.name, t;
2314
+ }
2315
+ const O = /* @__PURE__ */ new WeakMap();
2316
+ class re {
2044
2317
  #t;
2045
2318
  #e = { phase: "draft" };
2046
2319
  constructor(t) {
2047
- this.#t = t, E.set(this, {
2320
+ this.#t = t, O.set(this, {
2048
2321
  attach: (e, i) => {
2049
2322
  if (this.#e.phase !== "draft")
2050
- throw new TypeError(`Plugin '${this.#t.id}' control is already sealed`);
2323
+ throw new Error(`Installation '${this.#t.id}' control is already sealed`);
2051
2324
  this.#e = {
2052
2325
  phase: "attached",
2053
2326
  update: e,
@@ -2074,8 +2347,7 @@ class Rt {
2074
2347
  async update(t) {
2075
2348
  const e = this.#e;
2076
2349
  if (e.phase === "draft") throw this.#i();
2077
- if (e.phase === "revoked")
2078
- throw this.#t.error ?? new p("PLUGIN_REMOVED", `Plugin '${this.#t.id}' has been removed`);
2350
+ if (e.phase === "revoked") throw this.#t.unavailableError();
2079
2351
  await e.update(t);
2080
2352
  }
2081
2353
  async remove() {
@@ -2084,261 +2356,299 @@ class Rt {
2084
2356
  t.phase === "attached" && await t.remove();
2085
2357
  }
2086
2358
  #i() {
2087
- return new p(
2088
- "PLUGIN_UNAVAILABLE",
2089
- `Plugin '${this.#t.id}' installation has not been committed`
2359
+ return new u(
2360
+ "INSTALLATION_UNAVAILABLE",
2361
+ `Installation '${this.#t.id}' has not been committed`
2090
2362
  );
2091
2363
  }
2092
2364
  }
2093
- class Nt {
2094
- name;
2095
- diagnostics;
2365
+ class ne {
2096
2366
  #t = /* @__PURE__ */ new Map();
2097
2367
  #e = /* @__PURE__ */ new WeakMap();
2098
2368
  #i = /* @__PURE__ */ new WeakMap();
2099
2369
  #s;
2100
- #r;
2370
+ #n = 0;
2371
+ constructor(t) {
2372
+ this.#s = t;
2373
+ }
2374
+ values() {
2375
+ return this.#t.values();
2376
+ }
2377
+ has(t) {
2378
+ return this.#t.has(t);
2379
+ }
2380
+ contains(t) {
2381
+ return this.#t.get(t.id) === t;
2382
+ }
2383
+ create(t, e, i) {
2384
+ t.assertAttached();
2385
+ const s = ++this.#n, n = new ee(
2386
+ `${e.name}:${s}`,
2387
+ s,
2388
+ t,
2389
+ Q(e, i)
2390
+ ), o = new re(n);
2391
+ return this.#e.set(o, n), this.#i.set(n, o), { record: n, publicInstallation: o };
2392
+ }
2393
+ resolve(t) {
2394
+ const e = this.#e.get(t);
2395
+ if (!e) throw new TypeError("Installation belongs to a different Host");
2396
+ return e;
2397
+ }
2398
+ attach(t) {
2399
+ const e = this.#i.get(t);
2400
+ if (!e) throw new Error(`Installation '${t.id}' has no public facade`);
2401
+ const i = O.get(e);
2402
+ if (!i) throw new Error(`Installation '${t.id}' has no draft control`);
2403
+ t.attach(this.#s.notifyChanged), i.attach(
2404
+ (s) => this.#s.update(t, e, s),
2405
+ () => this.#s.remove(t, e)
2406
+ );
2407
+ }
2408
+ apply(t) {
2409
+ for (const e of t) {
2410
+ if (e.kind === "install") {
2411
+ if (e.installation.group.assertAttached(), this.#t.has(e.installation.id))
2412
+ throw new Error(`Installation '${e.installation.id}' is already installed`);
2413
+ continue;
2414
+ }
2415
+ if (!this.contains(e.installation))
2416
+ throw e.installation.unavailableError();
2417
+ if (e.kind === "update" && e.declaration.kind !== "config" && e.declaration.plugin.name !== e.installation.declaration.plugin.name)
2418
+ throw new u(
2419
+ "INSTALLATION_IDENTITY",
2420
+ `Installation '${e.installation.id}' cannot change name from '${e.installation.declaration.plugin.name}' to '${e.declaration.plugin.name}'`
2421
+ );
2422
+ }
2423
+ for (const e of t)
2424
+ if (e.kind === "install")
2425
+ this.#t.set(e.installation.id, e.installation);
2426
+ else if (e.kind === "update") {
2427
+ const i = e.installation.declaration, s = e.declaration.kind === "config" ? i.plugin : e.declaration.plugin, n = e.declaration.kind === "plugin" ? i.config : e.declaration.config;
2428
+ e.installation.replaceDeclaration(Q(s, n));
2429
+ } else this.contains(e.installation) && this.#t.delete(e.installation.id);
2430
+ }
2431
+ settleChanges(t, e) {
2432
+ for (const i of t)
2433
+ i.kind === "remove" ? (i.installation.remove(), i.installation.settleReady(), this.#o(i.installation)) : e || i.installation.deactivate();
2434
+ }
2435
+ settleReadiness(t) {
2436
+ for (const e of t) e.settleReady();
2437
+ }
2438
+ discard(t, e) {
2439
+ t.discard(e), this.#o(t);
2440
+ }
2441
+ capture() {
2442
+ return [...this.#t].map(([t, e]) => ({
2443
+ id: t,
2444
+ installation: e,
2445
+ declaration: e.declaration
2446
+ }));
2447
+ }
2448
+ restore(t) {
2449
+ this.#t.clear();
2450
+ for (const e of t)
2451
+ e.installation.replaceDeclaration(e.declaration), this.#t.set(e.id, e.installation);
2452
+ }
2453
+ #o(t) {
2454
+ const e = this.#i.get(t);
2455
+ e && (O.get(e)?.revoke(), O.delete(e)), this.#i.delete(t);
2456
+ }
2457
+ }
2458
+ class oe {
2459
+ #t = Promise.resolve();
2460
+ get settled() {
2461
+ return this.#t;
2462
+ }
2463
+ run(t) {
2464
+ if (typeof t != "function")
2465
+ throw new TypeError("SerialQueue operation must be a function");
2466
+ const e = this.#t.then(t);
2467
+ return this.#t = e.then(
2468
+ () => {
2469
+ },
2470
+ () => {
2471
+ }
2472
+ ), e;
2473
+ }
2474
+ }
2475
+ const ae = console, ce = /* @__PURE__ */ new Set(["name", "logger", "onError"]);
2476
+ class he {
2477
+ name;
2478
+ diagnostics;
2479
+ #t;
2480
+ #e;
2481
+ #i;
2482
+ #s;
2101
2483
  #n;
2102
- #a;
2103
2484
  #o;
2104
- #h = 0;
2105
- #c = "idle";
2106
- #p = new zt();
2485
+ #r = "idle";
2486
+ #a = new oe();
2107
2487
  constructor(t = {}) {
2108
- if (!t || typeof t != "object")
2109
- throw new TypeError("Application options must be an object");
2110
- const e = t.name ?? "app";
2111
- if (typeof e != "string" || !e.trim())
2112
- throw new TypeError("Application name must be a non-empty string");
2113
- if (e !== e.trim())
2114
- throw new TypeError("Application name cannot start or end with whitespace");
2115
- if (t.onError !== void 0 && typeof t.onError != "function")
2116
- throw new TypeError("Application onError must be a function");
2117
- if (t.logger !== void 0 && !Mt(t.logger))
2118
- throw new TypeError("Application logger must implement debug/info/warn/error");
2119
- this.name = e, this.#r = t.logger ?? xt, this.#a = t.onError ?? ((i) => this.#r.error(i)), this.#o = new Ct({
2120
- applicationName: e,
2121
- logger: this.#r,
2122
- isInstalled: (i) => this.#t.has(i),
2123
- report: (i) => this.#S(i)
2124
- }), this.#n = new kt(e, {
2125
- installations: () => this.#t.values(),
2126
- createDraft: (i, s, n) => this.#g(i, s, n),
2127
- resolveHandle: (i) => this.#l(i),
2128
- executeChanges: (i) => this.#d(i),
2129
- attachInstallation: (i) => this.#T(i),
2130
- discardInstallation: (i, s) => {
2131
- this.#C(i, s);
2488
+ k(t, "Host options", { fields: ce });
2489
+ const e = Object.hasOwn(t, "name") ? t.name : void 0, i = Object.hasOwn(t, "logger") ? t.logger : void 0, s = Object.hasOwn(t, "onError") ? t.onError : void 0, n = e ?? "host";
2490
+ if (typeof n != "string" || !n.trim())
2491
+ throw new TypeError("Host name must be a non-empty string");
2492
+ if (n !== n.trim())
2493
+ throw new TypeError("Host name cannot start or end with whitespace");
2494
+ if (s !== void 0 && typeof s != "function")
2495
+ throw new TypeError("Host onError must be a function");
2496
+ if (i !== void 0 && !zt(i))
2497
+ throw new TypeError("Host logger must implement debug/info/warn/error");
2498
+ this.name = n, this.#i = i ?? ae, this.#n = s ?? ((o) => this.#i.error(o)), this.#t = new ne({
2499
+ notifyChanged: () => this.#p(),
2500
+ update: (o, a, h) => {
2501
+ const c = this.#s.change(o.group);
2502
+ return c.update(a, h), c.commit();
2132
2503
  },
2133
- runExclusive: (i) => this.#p.run(i),
2134
- removeInstallations: (i) => this.#b(i),
2135
- notifyChanged: () => this.#m()
2136
- }), this.#s = new Pt(
2137
- e,
2138
- this.#n.nodes(),
2139
- (i) => this.#S(i)
2140
- ), this.diagnostics = this.#s.view, Object.freeze(this);
2504
+ remove: (o, a) => {
2505
+ const h = this.#s.change(o.group);
2506
+ return h.remove(a), h.commit();
2507
+ }
2508
+ }), this.#o = new Dt({
2509
+ hostName: n,
2510
+ logger: this.#i,
2511
+ isInstalled: (o) => this.#t.has(o),
2512
+ report: (o) => this.#h(o)
2513
+ }), this.#s = new Xt(n, {
2514
+ installations: () => this.#t.values(),
2515
+ createDraft: (o, a, h) => this.#t.create(o, a, h),
2516
+ resolveInstallation: (o) => this.#t.resolve(o),
2517
+ executeChanges: (o, a) => this.#d(o, a),
2518
+ attachInstallation: (o) => this.#t.attach(o),
2519
+ discardInstallation: (o, a) => this.#t.discard(o, a),
2520
+ runExclusive: (o) => this.#a.run(o),
2521
+ removeInstallations: (o) => this.#f(o),
2522
+ notifyChanged: () => this.#p()
2523
+ }), this.#e = new Gt(
2524
+ n,
2525
+ this.#s.nodes(),
2526
+ (o) => this.#h(o)
2527
+ ), this.diagnostics = this.#e.view, Object.freeze(this);
2141
2528
  }
2142
2529
  get status() {
2143
- return this.#c;
2530
+ return this.#r;
2144
2531
  }
2145
2532
  get(t) {
2146
- const e = this.#c === "active" ? "available" : "unavailable";
2533
+ const e = this.#r === "active" ? "available" : "unavailable";
2147
2534
  return this.#o.get(t, e);
2148
2535
  }
2536
+ contributions(t) {
2537
+ return this.#o.contributions(t);
2538
+ }
2149
2539
  install(t, ...e) {
2150
- return this.#n.install(this.#n.root, t, ...e);
2540
+ return this.#s.install(this.#s.root, t, ...e);
2151
2541
  }
2152
2542
  change() {
2153
- return this.#n.change(this.#n.root);
2543
+ return this.#s.change(this.#s.root);
2154
2544
  }
2155
2545
  group(t, e) {
2156
- return this.#n.create(this.#n.root, t, e);
2546
+ return this.#s.create(this.#s.root, t, e);
2157
2547
  }
2158
2548
  start() {
2159
- return this.#p.run(async () => {
2160
- if (this.#c !== "active") {
2161
- this.#u("starting");
2549
+ return this.#a.run(async () => {
2550
+ if (this.#r !== "active") {
2551
+ this.#c("starting");
2162
2552
  try {
2163
2553
  const t = this.#o.buildPlan(this.#t.values());
2164
- await this.#o.start(t), this.#u("active"), this.#E(t.order);
2554
+ await this.#o.start(t), this.#c("active"), this.#t.settleReadiness(t.order);
2165
2555
  } catch (t) {
2166
- this.#u("idle");
2556
+ this.#c("idle");
2167
2557
  for (const e of this.#t.values())
2168
2558
  e.status !== "active" && e.fail(t);
2169
- throw this.#E(this.#t.values()), t;
2559
+ throw this.#t.settleReadiness(this.#t.values()), t;
2170
2560
  }
2171
2561
  }
2172
2562
  });
2173
2563
  }
2174
2564
  stop() {
2175
- return this.#p.run(async () => {
2176
- if (this.#c === "idle") return;
2177
- this.#u("stopping");
2565
+ return this.#a.run(async () => {
2566
+ if (this.#r === "idle") return;
2567
+ this.#c("stopping");
2178
2568
  const t = await this.#o.stop();
2179
- if (this.#u("idle"), t.length === 1) throw t[0];
2180
- if (t.length > 1) throw new AggregateError(t, "Application shutdown failed");
2569
+ if (this.#c("idle"), t.length === 1) throw t[0];
2570
+ if (t.length > 1) throw new AggregateError(t, "Host shutdown failed");
2181
2571
  });
2182
2572
  }
2183
- #g(t, e, i) {
2184
- t.assertAttached();
2185
- const s = ++this.#h, n = `${e.name}:${s}`, o = new bt(
2186
- n,
2187
- s,
2188
- t,
2189
- N(e, i)
2190
- ), a = new Rt(o);
2191
- return this.#e.set(a, o), this.#i.set(o, a), { installation: o, handle: a };
2192
- }
2193
- #l(t) {
2194
- const e = this.#e.get(t);
2195
- if (!e) throw new TypeError("PluginHandle belongs to a different Application");
2196
- return e;
2197
- }
2198
- #d(t) {
2199
- const e = t.filter((i) => i.kind === "install").map((i) => i.installation);
2200
- return this.#p.run(async () => {
2573
+ #d(t, e) {
2574
+ const i = e.filter((s) => s.kind === "install").map((s) => s.installation);
2575
+ return this.#a.run(async () => {
2201
2576
  try {
2202
- this.#c === "active" ? await this.#w(t) : (this.#f(t), this.#v(t)), this.#m();
2203
- } catch (i) {
2204
- for (const s of e)
2205
- this.#t.get(s.id) !== s && this.#C(s, i);
2206
- throw i;
2577
+ if (!t.attached) throw A(t);
2578
+ if (!e.length) return;
2579
+ this.#r === "active" ? await this.#l(e) : (this.#t.apply(e), this.#t.settleChanges(e, !1)), this.#p();
2580
+ } catch (s) {
2581
+ for (const n of i)
2582
+ this.#t.contains(n) || this.#t.discard(n, s);
2583
+ throw s;
2207
2584
  }
2208
2585
  });
2209
2586
  }
2210
- async #b(t) {
2211
- t.length && this.#c === "active" ? await this.#w(t) : (this.#f(t), this.#v(t));
2587
+ async #f(t) {
2588
+ t.length && this.#r === "active" ? await this.#l(t) : (this.#t.apply(t), this.#t.settleChanges(t, !1));
2212
2589
  }
2213
- async #w(t) {
2214
- const e = await this.#O(t);
2215
- if (this.#E(e.affected), e.kind === "rolled-back") throw e.error;
2216
- this.#v(t);
2590
+ async #l(t) {
2591
+ const e = await this.#u(t);
2592
+ if (this.#t.settleReadiness(e.affected), e.kind === "rolled-back") throw e.error;
2593
+ this.#t.settleChanges(t, !0);
2217
2594
  }
2218
- async #O(t) {
2219
- const e = this.#A(), i = new Set(t.map((n) => n.installation));
2220
- this.#u("changing");
2595
+ async #u(t) {
2596
+ const e = this.#t.capture(), i = new Set(t.map((n) => n.installation));
2597
+ this.#c("changing");
2221
2598
  let s;
2222
2599
  try {
2223
- this.#f(t), s = this.#o.buildPlan(this.#t.values());
2600
+ this.#t.apply(t), s = this.#o.buildPlan(this.#t.values());
2224
2601
  } catch (n) {
2225
- throw this.#P(e), this.#u("active"), n;
2602
+ throw this.#t.restore(e), this.#c("active"), n;
2226
2603
  }
2227
2604
  try {
2228
2605
  const n = await this.#o.transition(
2229
2606
  s,
2230
2607
  i,
2231
- () => this.#P(e)
2608
+ () => this.#t.restore(e)
2232
2609
  );
2233
- return this.#u("active"), n;
2610
+ return this.#c("active"), n;
2234
2611
  } catch (n) {
2235
- throw this.#u(this.#o.hasCommittedPlan ? "active" : "idle"), n;
2236
- }
2237
- }
2238
- #f(t) {
2239
- for (const e of t) {
2240
- if (e.kind === "install") {
2241
- if (e.installation.group.assertAttached(), this.#t.has(e.installation.id))
2242
- throw new TypeError(`Plugin '${e.installation.id}' is already installed`);
2243
- continue;
2244
- }
2245
- const i = this.#t.get(e.installation.id) === e.installation;
2246
- if (!(e.kind === "remove" && !i && e.installation.status === "removed")) {
2247
- if (!i)
2248
- throw new p(
2249
- "PLUGIN_REMOVED",
2250
- `Plugin '${e.installation.id}' has been removed`
2251
- );
2252
- if (e.kind === "update" && e.declaration.kind !== "config" && e.declaration.plugin.name !== e.installation.spec.plugin.name)
2253
- throw new p(
2254
- "PLUGIN_IDENTITY",
2255
- `Plugin '${e.installation.id}' cannot change name from '${e.installation.spec.plugin.name}' to '${e.declaration.plugin.name}'`
2256
- );
2257
- }
2612
+ throw this.#c(this.#o.hasCommittedPlan ? "active" : "idle"), n;
2258
2613
  }
2259
- for (const e of t)
2260
- if (e.kind === "install")
2261
- this.#t.set(e.installation.id, e.installation);
2262
- else if (e.kind === "update") {
2263
- const i = e.installation.spec, s = e.declaration.kind === "config" ? i.plugin : e.declaration.plugin, n = e.declaration.kind === "plugin" ? i.config : e.declaration.config;
2264
- e.installation.reconfigure(N(s, n));
2265
- } else this.#t.get(e.installation.id) === e.installation && this.#t.delete(e.installation.id);
2266
- }
2267
- #v(t) {
2268
- for (const e of t)
2269
- e.kind === "remove" ? (e.installation.remove(), e.installation.settleReady(), this.#y(e.installation)) : this.#c !== "active" && e.installation.deactivate();
2270
- }
2271
- #C(t, e) {
2272
- t.discard(e), this.#y(t);
2273
- }
2274
- #T(t) {
2275
- const e = this.#i.get(t);
2276
- if (!e) throw new TypeError(`Plugin '${t.id}' has no control handle`);
2277
- const i = E.get(e);
2278
- if (!i) throw new TypeError(`Plugin '${t.id}' has no draft control`);
2279
- t.attach(() => this.#m()), i.attach(
2280
- (s) => this.#n.change(t.group).update(e, s).commit(),
2281
- () => this.#n.change(t.group).remove(e).commit()
2282
- );
2283
- }
2284
- #y(t) {
2285
- const e = this.#i.get(t);
2286
- e && (E.get(e)?.revoke(), E.delete(e)), this.#i.delete(t);
2287
- }
2288
- #E(t) {
2289
- for (const e of t) e.settleReady();
2290
- }
2291
- #A() {
2292
- return [...this.#t].map(([t, e]) => ({
2293
- id: t,
2294
- installation: e,
2295
- spec: e.spec
2296
- }));
2297
- }
2298
- #P(t) {
2299
- this.#t.clear();
2300
- for (const e of t)
2301
- e.installation.reconfigure(e.spec), this.#t.set(e.id, e.installation);
2302
2614
  }
2303
- #S(t) {
2615
+ #h(t) {
2304
2616
  try {
2305
- this.#a(t);
2617
+ this.#n(t);
2306
2618
  } catch (e) {
2307
2619
  try {
2308
- this.#r.error(
2309
- new AggregateError([t, e], "Application error reporter failed")
2620
+ this.#i.error(
2621
+ new AggregateError([t, e], "Host error reporter failed")
2310
2622
  );
2311
2623
  } catch {
2312
2624
  }
2313
2625
  }
2314
2626
  }
2315
- #u(t) {
2316
- this.#c = t, this.#m();
2627
+ #c(t) {
2628
+ this.#r = t, this.#p();
2317
2629
  }
2318
- #m() {
2319
- this.#s.publish(this.#c, this.#t.values(), this.#n.nodes());
2630
+ #p() {
2631
+ this.#e.publish(this.#r, this.#t.values(), this.#s.nodes());
2320
2632
  }
2321
2633
  }
2322
- function Mt(r) {
2323
- if (!r || typeof r != "object") return !1;
2324
- const t = r;
2325
- return [t.debug, t.info, t.warn, t.error].every(
2326
- (e) => typeof e == "function"
2327
- );
2328
- }
2329
- function Ut(r) {
2330
- return new Nt(r);
2634
+ function ge(r) {
2635
+ return new he(r);
2331
2636
  }
2332
2637
  export {
2333
- H as ConfigValidationError,
2334
- p as DougongError,
2335
- C as ReadonlyMapSnapshot,
2336
- zt as SerialQueue,
2337
- U as SnapshotPublisher,
2338
- Ut as createApp,
2339
- q as definePlugin,
2340
- Dt as event,
2341
- Gt as extension,
2342
- Vt as optional,
2343
- qt as service
2638
+ at as ConfigValidationError,
2639
+ u as DougongError,
2640
+ S as ReadonlyMapSnapshot,
2641
+ oe as SerialQueue,
2642
+ q as SnapshotPublisher,
2643
+ k as assertPlainRecord,
2644
+ j as asyncDisposeSymbol,
2645
+ ge as createHost,
2646
+ pe as definePlugin,
2647
+ g as disposeSymbol,
2648
+ le as event,
2649
+ ue as extensionPoint,
2650
+ J as isCancellationReason,
2651
+ zt as isLogger,
2652
+ fe as optional,
2653
+ de as service
2344
2654
  };