@dougongjs/core 0.0.1

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 (50) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +18 -0
  3. package/dist/application-api.d.ts +51 -0
  4. package/dist/application-api.d.ts.map +1 -0
  5. package/dist/application-runtime.d.ts +36 -0
  6. package/dist/application-runtime.d.ts.map +1 -0
  7. package/dist/application.d.ts +6 -0
  8. package/dist/application.d.ts.map +1 -0
  9. package/dist/change-set.d.ts +51 -0
  10. package/dist/change-set.d.ts.map +1 -0
  11. package/dist/contract-registry.d.ts +19 -0
  12. package/dist/contract-registry.d.ts.map +1 -0
  13. package/dist/contracts.d.ts +30 -0
  14. package/dist/contracts.d.ts.map +1 -0
  15. package/dist/diagnostics.d.ts +35 -0
  16. package/dist/diagnostics.d.ts.map +1 -0
  17. package/dist/errors.d.ts +19 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/event-hub.d.ts +10 -0
  20. package/dist/event-hub.d.ts.map +1 -0
  21. package/dist/extension-store.d.ts +46 -0
  22. package/dist/extension-store.d.ts.map +1 -0
  23. package/dist/group-coordinator.d.ts +46 -0
  24. package/dist/group-coordinator.d.ts.map +1 -0
  25. package/dist/group-lifecycle.d.ts +19 -0
  26. package/dist/group-lifecycle.d.ts.map +1 -0
  27. package/dist/group.d.ts +31 -0
  28. package/dist/group.d.ts.map +1 -0
  29. package/dist/index.d.ts +12 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +2344 -0
  32. package/dist/lifetime-diagnostics.d.ts +36 -0
  33. package/dist/lifetime-diagnostics.d.ts.map +1 -0
  34. package/dist/lifetime.d.ts +77 -0
  35. package/dist/lifetime.d.ts.map +1 -0
  36. package/dist/plugin-graph.d.ts +17 -0
  37. package/dist/plugin-graph.d.ts.map +1 -0
  38. package/dist/plugin-installation.d.ts +44 -0
  39. package/dist/plugin-installation.d.ts.map +1 -0
  40. package/dist/plugin.d.ts +30 -0
  41. package/dist/plugin.d.ts.map +1 -0
  42. package/dist/readonly-map.d.ts +14 -0
  43. package/dist/readonly-map.d.ts.map +1 -0
  44. package/dist/resource.d.ts +13 -0
  45. package/dist/resource.d.ts.map +1 -0
  46. package/dist/serial-queue.d.ts +7 -0
  47. package/dist/serial-queue.d.ts.map +1 -0
  48. package/dist/snapshot-view.d.ts +15 -0
  49. package/dist/snapshot-view.d.ts.map +1 -0
  50. package/package.json +49 -0
package/dist/index.js ADDED
@@ -0,0 +1,2344 @@
1
+ function F(r, t) {
2
+ if (typeof t != "string" || !t.trim())
3
+ throw new TypeError(`${r} id must be a non-empty string`);
4
+ if (t !== t.trim())
5
+ throw new TypeError(`${r} id cannot start or end with whitespace`);
6
+ }
7
+ function k(r, t) {
8
+ return F("Contract", t), Object.freeze({ id: t, kind: r });
9
+ }
10
+ function w(r, t) {
11
+ if (!r || typeof r != "object") return !1;
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);
14
+ }
15
+ function v(r, t) {
16
+ if (!w(r, t))
17
+ throw new TypeError(t ? `Expected a ${t} contract` : "Invalid contract");
18
+ }
19
+ function qt(r) {
20
+ return k("service", r);
21
+ }
22
+ function Dt(r) {
23
+ return k("event", r);
24
+ }
25
+ function Gt(r) {
26
+ return k("extension", r);
27
+ }
28
+ function Vt(r) {
29
+ if (!w(r, "service"))
30
+ throw new TypeError("optional() expects a service contract");
31
+ return Object.freeze({ kind: "optional", service: r });
32
+ }
33
+ class p extends Error {
34
+ constructor(t, e, i) {
35
+ super(e, i), this.code = t;
36
+ }
37
+ code;
38
+ name = "DougongError";
39
+ }
40
+ function $(r, t, e) {
41
+ return r instanceof Error ? r : new p(t, e, { cause: r });
42
+ }
43
+ class H extends p {
44
+ name = "ConfigValidationError";
45
+ issues;
46
+ 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
+ );
61
+ super(
62
+ "CONFIG_INVALID",
63
+ `Invalid plugin config:
64
+ ${e.map((i) => ` - ${i.message}`).join(`
65
+ `)}`
66
+ ), this.issues = e;
67
+ }
68
+ }
69
+ class K {
70
+ #t = /* @__PURE__ */ new Map();
71
+ get kinds() {
72
+ return this.#t;
73
+ }
74
+ assertCompatible(t) {
75
+ V(this.#t, t);
76
+ }
77
+ remember(t) {
78
+ S(this.#t, t);
79
+ }
80
+ draft(t) {
81
+ return new W(this, t);
82
+ }
83
+ commit(t) {
84
+ for (const [e, i] of t) this.assertCompatible({ id: e, kind: i });
85
+ for (const [e, i] of t) this.#t.set(e, i);
86
+ }
87
+ }
88
+ class W {
89
+ #t;
90
+ constructor(t, e) {
91
+ this.#t = { phase: "open", registry: t, pending: /* @__PURE__ */ new Map() };
92
+ for (const [i, s] of e) this.remember({ id: i, kind: s });
93
+ }
94
+ remember(t) {
95
+ const e = this.#t;
96
+ if (e.phase === "committed") {
97
+ e.registry.remember(t);
98
+ return;
99
+ }
100
+ 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);
103
+ }
104
+ commit() {
105
+ const t = this.#t;
106
+ t.phase === "open" && (t.registry.commit(t.pending), this.#t = { phase: "committed", registry: t.registry });
107
+ }
108
+ discard() {
109
+ this.#t.phase === "open" && (this.#t = { phase: "discarded" });
110
+ }
111
+ }
112
+ function S(r, t) {
113
+ V(r, t), r.set(t.id, t.kind);
114
+ }
115
+ function V(r, t) {
116
+ const e = r.get(t.id);
117
+ if (e && e !== t.kind)
118
+ throw new p(
119
+ "CONTRACT_CONFLICT",
120
+ `Contract '${t.id}' is used as both '${e}' and '${t.kind}'`
121
+ );
122
+ }
123
+ class Y {
124
+ #t;
125
+ constructor(t) {
126
+ this.#t = t, Object.freeze(this);
127
+ }
128
+ dispose() {
129
+ const t = this.#t;
130
+ this.#t = void 0, t?.dispose();
131
+ }
132
+ [Symbol.dispose]() {
133
+ this.dispose();
134
+ }
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);
142
+ }
143
+ publish() {
144
+ const t = this.#t;
145
+ t.phase === "staged" && (t.hub.add(this.#e, t.listener), t.phase = "published");
146
+ }
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);
155
+ }
156
+ }
157
+ }
158
+ [Symbol.dispose]() {
159
+ this.dispose();
160
+ }
161
+ }
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);
171
+ }
172
+ delete(t, e) {
173
+ const i = this.#t.get(t);
174
+ i && (i.delete(e), i.size || this.#t.delete(t));
175
+ }
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`);
182
+ }
183
+ }
184
+ class C {
185
+ #t;
186
+ constructor(t) {
187
+ this.#t = new Map(t), Object.freeze(this);
188
+ }
189
+ get size() {
190
+ return this.#t.size;
191
+ }
192
+ get(t) {
193
+ return this.#t.get(t);
194
+ }
195
+ has(t) {
196
+ return this.#t.has(t);
197
+ }
198
+ forEach(t, e) {
199
+ for (const [i, s] of this.#t) t.call(e, s, i, this);
200
+ }
201
+ entries() {
202
+ return this.#t.entries();
203
+ }
204
+ keys() {
205
+ return this.#t.keys();
206
+ }
207
+ values() {
208
+ return this.#t.values();
209
+ }
210
+ [Symbol.iterator]() {
211
+ return this.entries();
212
+ }
213
+ }
214
+ class X {
215
+ #t;
216
+ get;
217
+ subscribe;
218
+ constructor(t) {
219
+ this.#t = t, this.get = () => this.#e(), this.subscribe = (e) => this.#i(e), Object.freeze(this);
220
+ }
221
+ // The handle retains only revocable binding state. Disposing its lease clears
222
+ // the Store edge even when downstream code retains the public view.
223
+ #e() {
224
+ return this.#s().store.snapshot();
225
+ }
226
+ #i(t) {
227
+ const e = this.#s();
228
+ return e.store.subscribe(t, e.own);
229
+ }
230
+ #s() {
231
+ const t = this.#t.binding;
232
+ if (!t) throw new TypeError("Extension view has been disposed");
233
+ return t;
234
+ }
235
+ }
236
+ class Z {
237
+ #t;
238
+ constructor(t) {
239
+ this.#t = t, Object.freeze(this);
240
+ }
241
+ update(t) {
242
+ this.#t.update(t);
243
+ }
244
+ dispose() {
245
+ this.#t.dispose();
246
+ }
247
+ [Symbol.dispose]() {
248
+ this.dispose();
249
+ }
250
+ }
251
+ class tt {
252
+ #t;
253
+ #e;
254
+ handle;
255
+ constructor(t, e, i, s) {
256
+ this.#e = e, this.#t = { phase: "staged", store: t, value: i, detachFromOwner: s }, this.handle = new Z(this);
257
+ }
258
+ publish() {
259
+ const t = this.#t;
260
+ t.phase === "staged" && (t.store.insert(this.#e, this, t.value), t.phase = "published");
261
+ }
262
+ update(t) {
263
+ const e = this.#t;
264
+ if (e.phase === "disposed")
265
+ throw new TypeError(`Contribution '${this.#e}' has been disposed`);
266
+ Object.is(e.value, t) || (e.value = t, e.phase === "published" && e.store.update(this.#e, this, t));
267
+ }
268
+ dispose() {
269
+ const t = this.#t;
270
+ if (t.phase !== "disposed") {
271
+ this.#t = { phase: "disposed" };
272
+ try {
273
+ t.store.removeContribution(this.#e, this, t.phase);
274
+ } finally {
275
+ t.detachFromOwner(this);
276
+ }
277
+ }
278
+ }
279
+ [Symbol.dispose]() {
280
+ this.dispose();
281
+ }
282
+ }
283
+ class et {
284
+ #t;
285
+ #e;
286
+ #i;
287
+ #s = /* @__PURE__ */ new Map();
288
+ #r = /* @__PURE__ */ new Map();
289
+ #n = /* @__PURE__ */ new Set();
290
+ #a = new C();
291
+ #o = 0;
292
+ constructor(t, e, i) {
293
+ this.#t = t, this.#e = e, this.#i = i;
294
+ }
295
+ 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;
302
+ }
303
+ view(t) {
304
+ this.#o++;
305
+ const e = { binding: { store: this, own: t } };
306
+ let i;
307
+ const s = new it(e, () => {
308
+ const n = i;
309
+ i = void 0;
310
+ try {
311
+ n?.();
312
+ } finally {
313
+ this.#o--, this.#h();
314
+ }
315
+ });
316
+ try {
317
+ i = t(s, "view");
318
+ } catch (n) {
319
+ throw e.binding = void 0, this.#o--, this.#h(), n;
320
+ }
321
+ return new X(e);
322
+ }
323
+ snapshot() {
324
+ return this.#a;
325
+ }
326
+ subscribe(t, e) {
327
+ 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?.();
333
+ });
334
+ return i = e(s, "subscription"), this.#n.add(t), s;
335
+ }
336
+ 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);
342
+ }
343
+ update(t, e, i) {
344
+ const s = this.#r.get(t);
345
+ s?.contribution === e && (s.value = i, this.#t(this));
346
+ }
347
+ 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();
349
+ }
350
+ 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
+ }
361
+ }
362
+ removeListener(t) {
363
+ this.#n.delete(t), this.#h();
364
+ }
365
+ #h() {
366
+ this.#s.size || this.#r.size || this.#n.size || this.#o || this.#i(this);
367
+ }
368
+ }
369
+ class it {
370
+ #t;
371
+ constructor(t, e) {
372
+ this.#t = { state: t, release: e }, Object.freeze(this);
373
+ }
374
+ dispose() {
375
+ const t = this.#t;
376
+ t && (this.#t = void 0, t.state.binding = void 0, t.release());
377
+ }
378
+ [Symbol.dispose]() {
379
+ this.dispose();
380
+ }
381
+ }
382
+ class st {
383
+ #t;
384
+ constructor(t, e, i) {
385
+ this.#t = { store: t, listener: e, release: i }, Object.freeze(this);
386
+ }
387
+ dispose() {
388
+ const t = this.#t;
389
+ if (t) {
390
+ this.#t = void 0;
391
+ try {
392
+ t.store.removeListener(t.listener);
393
+ } finally {
394
+ t.release();
395
+ }
396
+ }
397
+ }
398
+ [Symbol.dispose]() {
399
+ this.dispose();
400
+ }
401
+ }
402
+ class rt {
403
+ #t = /* @__PURE__ */ new Map();
404
+ #e = /* @__PURE__ */ new Set();
405
+ #i;
406
+ #s = 0;
407
+ constructor(t) {
408
+ this.#i = t;
409
+ }
410
+ get(t) {
411
+ const e = this.#t.get(t.id);
412
+ if (e) return e;
413
+ const i = new et(
414
+ (s) => this.#r(s),
415
+ this.#i,
416
+ (s) => {
417
+ this.#t.get(t.id) === s && (this.#e.delete(s), this.#t.delete(t.id));
418
+ }
419
+ );
420
+ return this.#t.set(t.id, i), i;
421
+ }
422
+ beginBatch() {
423
+ this.#s++;
424
+ }
425
+ endBatch() {
426
+ if (!this.#s) throw new TypeError("Extension batch is not active");
427
+ if (this.#s--, this.#s) return;
428
+ const t = [...this.#e];
429
+ this.#e.clear();
430
+ for (const e of t) e.publishSnapshot();
431
+ }
432
+ #r(t) {
433
+ this.#e.add(t), !this.#s && (this.#e.delete(t), t.publishSnapshot());
434
+ }
435
+ }
436
+ function nt(r) {
437
+ if (typeof r != "string" || !r.trim())
438
+ throw new TypeError("Contribution key must be a non-empty string");
439
+ if (r !== r.trim())
440
+ throw new TypeError("Contribution key cannot start or end with whitespace");
441
+ }
442
+ function ot(r, t) {
443
+ return `${x(r)}/${x(t)}`;
444
+ }
445
+ function x(r) {
446
+ return r.replaceAll("%", "%25").replaceAll("/", "%2F");
447
+ }
448
+ const m = /* @__PURE__ */ new WeakMap();
449
+ class U {
450
+ #t = /* @__PURE__ */ new Set();
451
+ #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);
459
+ }
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
+ }
473
+ }
474
+ dispose() {
475
+ const t = this.#e;
476
+ if (t.phase !== "disposed") {
477
+ this.#e = { phase: "disposed" };
478
+ try {
479
+ this.#a(t.read);
480
+ } finally {
481
+ this.#s = !1;
482
+ const e = [...this.#t];
483
+ this.#t.clear();
484
+ for (const i of e) ct(i);
485
+ }
486
+ }
487
+ }
488
+ [Symbol.dispose]() {
489
+ this.dispose();
490
+ }
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
+ }
512
+ class at {
513
+ constructor(t, e) {
514
+ m.set(this, { listener: t, detach: e }), Object.freeze(this);
515
+ }
516
+ dispose() {
517
+ const t = m.get(this);
518
+ t && (m.delete(this), t.detach(this));
519
+ }
520
+ [Symbol.dispose]() {
521
+ this.dispose();
522
+ }
523
+ }
524
+ function ht(r) {
525
+ m.get(r)?.listener();
526
+ }
527
+ function ct(r) {
528
+ m.delete(r);
529
+ }
530
+ class dt {
531
+ #t;
532
+ root;
533
+ view;
534
+ constructor(t, e) {
535
+ this.root = R(t), this.#t = new U(() => B(this.root), e), this.view = this.#t.view;
536
+ }
537
+ createNode(t) {
538
+ return R(t);
539
+ }
540
+ attach(t, e) {
541
+ if (t.children.has(e)) throw new TypeError("Lifetime diagnostic node is attached");
542
+ t.children.add(e), this.#t.invalidate();
543
+ }
544
+ detach(t, e) {
545
+ t.children.delete(e) && this.#t.invalidate();
546
+ }
547
+ change(t, e, i) {
548
+ const s = t.counts[e] + i;
549
+ if (s < 0) throw new TypeError(`Lifetime '${e}' count cannot be negative`);
550
+ t.counts[e] = s, this.#t.invalidate();
551
+ }
552
+ beginDisposing(t) {
553
+ t.phase === "active" && (t.phase = "disposing", this.#t.invalidate());
554
+ }
555
+ finishRoot() {
556
+ this.root.phase !== "disposed" && (this.root.phase = "disposed", this.#t.invalidate(), this.#t.dispose());
557
+ }
558
+ }
559
+ function R(r) {
560
+ return {
561
+ label: r,
562
+ phase: "active",
563
+ counts: {
564
+ cleanups: 0,
565
+ tasks: 0,
566
+ listeners: 0,
567
+ contributions: 0,
568
+ extensionViews: 0,
569
+ subscriptions: 0
570
+ },
571
+ children: /* @__PURE__ */ new Set()
572
+ };
573
+ }
574
+ function B(r) {
575
+ const t = Object.freeze([...r.children].map(B));
576
+ return Object.freeze({
577
+ label: r.label,
578
+ phase: r.phase,
579
+ ...r.counts,
580
+ children: t
581
+ });
582
+ }
583
+ const A = Object.freeze(new DOMException("Resource disposed", "AbortError"));
584
+ class g {
585
+ #t = /* @__PURE__ */ new Set();
586
+ #e;
587
+ constructor(t) {
588
+ this.#e = t;
589
+ }
590
+ add(t) {
591
+ if (this.#t.has(t)) throw new TypeError("Lifetime already owns this resource");
592
+ this.#t.add(t);
593
+ const e = this.#e;
594
+ e && e.diagnostics.change(e.node, e.kind, 1);
595
+ }
596
+ own(t) {
597
+ return this.add(t), () => this.release(t);
598
+ }
599
+ release = (t) => {
600
+ if (!this.#t.delete(t)) return !1;
601
+ const e = this.#e;
602
+ return e && e.diagnostics.change(e.node, e.kind, -1), !0;
603
+ };
604
+ async dispose(t) {
605
+ try {
606
+ for (const e of [...this.#t].reverse())
607
+ try {
608
+ await e.dispose();
609
+ } catch (i) {
610
+ t.push(i);
611
+ } finally {
612
+ this.release(e);
613
+ }
614
+ } finally {
615
+ this.#e = void 0;
616
+ }
617
+ }
618
+ [Symbol.iterator]() {
619
+ return this.#t[Symbol.iterator]();
620
+ }
621
+ }
622
+ class lt {
623
+ #t;
624
+ constructor(t, e) {
625
+ this.#t = { phase: "active", cleanup: t, detachFromParent: e }, Object.freeze(this);
626
+ }
627
+ dispose() {
628
+ const t = this.#t;
629
+ if (t.phase === "disposing") return t.completion;
630
+ if (t.phase === "disposed") return Promise.resolve();
631
+ const e = Promise.resolve().then(async () => {
632
+ try {
633
+ await t.cleanup();
634
+ } finally {
635
+ t.detachFromParent(this);
636
+ }
637
+ }).finally(() => {
638
+ this.#t = { phase: "disposed" };
639
+ });
640
+ return this.#t = { phase: "disposing", completion: e }, e;
641
+ }
642
+ [Symbol.asyncDispose]() {
643
+ return this.dispose();
644
+ }
645
+ }
646
+ class ut {
647
+ #t;
648
+ #e;
649
+ #i;
650
+ result;
651
+ constructor(t, e, i, s) {
652
+ const n = new AbortController();
653
+ this.#i = { phase: "running", controller: n };
654
+ const o = () => n.abort(t.reason);
655
+ t.addEventListener("abort", o, { once: !0 }), this.#t = () => t.removeEventListener("abort", o), this.#e = s, t.aborted && o(), this.result = Promise.resolve().then(() => e(n.signal)), this.result.then(
656
+ () => this.#s(),
657
+ (a) => {
658
+ try {
659
+ n.signal.aborted || i(a);
660
+ } finally {
661
+ this.#s();
662
+ }
663
+ }
664
+ ).catch((a) => i(a)), Object.freeze(this);
665
+ }
666
+ dispose() {
667
+ const t = this.#i;
668
+ if (t.phase === "disposing") return t.completion;
669
+ if (t.phase === "settled")
670
+ return Promise.resolve();
671
+ const e = this.result.then(
672
+ () => {
673
+ },
674
+ () => {
675
+ }
676
+ );
677
+ return this.#i = { phase: "disposing", completion: e }, t.controller.abort(A), this.#r(), e;
678
+ }
679
+ [Symbol.asyncDispose]() {
680
+ return this.dispose();
681
+ }
682
+ #s() {
683
+ if (this.#i.phase === "settled") return;
684
+ this.#i = { phase: "settled" }, this.#r();
685
+ const t = this.#e;
686
+ this.#e = void 0, t?.(this);
687
+ }
688
+ #r() {
689
+ const t = this.#t;
690
+ this.#t = void 0, t?.();
691
+ }
692
+ }
693
+ class L {
694
+ #t;
695
+ #e;
696
+ #i;
697
+ #s;
698
+ #r;
699
+ #n;
700
+ #a;
701
+ #o;
702
+ #h;
703
+ #c;
704
+ #p;
705
+ #g;
706
+ handle;
707
+ #l;
708
+ constructor(t, e, i = {}) {
709
+ this.#e = e, this.handle = new pt(this);
710
+ const s = new AbortController();
711
+ this.#l = {
712
+ phase: "active",
713
+ controller: s,
714
+ declarations: i.declarations ?? "staged"
715
+ };
716
+ 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 };
720
+ const h = (l) => ({
721
+ diagnostics: o,
722
+ node: a,
723
+ kind: l
724
+ });
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"));
726
+ const c = i.parentSignal;
727
+ if (!c) return;
728
+ const d = () => s.abort(c.reason);
729
+ c.addEventListener("abort", d, { once: !0 }), this.#p = () => c.removeEventListener("abort", d), c.aborted && d();
730
+ }
731
+ get signal() {
732
+ const t = this.#l;
733
+ return t.phase === "disposed" ? t.signal : t.controller.signal;
734
+ }
735
+ get diagnostics() {
736
+ return this.#d().diagnostics.view;
737
+ }
738
+ 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;
742
+ }
743
+ 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, {
747
+ parentSignal: this.signal,
748
+ declarations: this.#w(),
749
+ parent: {
750
+ diagnostics: i,
751
+ diagnosticNode: n,
752
+ detach: (a) => {
753
+ this.#o.release(a) && i.detach(s, n);
754
+ }
755
+ }
756
+ });
757
+ return this.#o.add(o), i.attach(s, n), o.handle;
758
+ }
759
+ spawn(t) {
760
+ const { host: e } = this.#d();
761
+ if (typeof t != "function") throw new TypeError("Background task must be a function");
762
+ const i = new ut(
763
+ this.signal,
764
+ t,
765
+ (s) => e.report(s),
766
+ this.#a.release
767
+ );
768
+ return this.#a.add(i), i;
769
+ }
770
+ 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;
773
+ }
774
+ emit(t, e) {
775
+ return this.#d().host.emit(this.#e, t, e);
776
+ }
777
+ contribute(t, e, i) {
778
+ const { host: s } = this.#d(), n = s.stageContribution(
779
+ this.#e,
780
+ t,
781
+ e,
782
+ i,
783
+ this.#s.release
784
+ );
785
+ return this.#s.add(n), this.#w() === "published" && n.publish(), n.handle;
786
+ }
787
+ /** Owns an internal live capability without exposing a second Context API. */
788
+ ownLease(t, e) {
789
+ return this.#d(), (e === "view" ? this.#r : this.#n).own(t);
790
+ }
791
+ /** Releases a temporary startup cancellation edge after its layer commits. */
792
+ detachStartupSignal() {
793
+ const t = this.#p;
794
+ this.#p = void 0, t?.();
795
+ }
796
+ /** Atomically makes all declarations staged during setup visible. */
797
+ publish() {
798
+ const t = this.#l;
799
+ if (t.phase !== "active") throw b();
800
+ if (this.#d(), t.declarations !== "published") {
801
+ for (const e of this.#i) e.publish();
802
+ for (const e of this.#s) e.publish();
803
+ for (const e of this.#o) e.publish();
804
+ this.#l = { ...t, declarations: "published" };
805
+ }
806
+ }
807
+ dispose() {
808
+ const t = this.#l;
809
+ if (t.phase === "disposing") return t.completion;
810
+ if (t.phase === "disposed") return Promise.resolve();
811
+ const e = this.#b(), i = Promise.resolve().then(async () => {
812
+ 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];
814
+ if (s.length > 1) throw new AggregateError(s, "Lifetime cleanup failed");
815
+ }).finally(() => {
816
+ this.#l = { phase: "disposed", signal: AbortSignal.abort(A) };
817
+ const s = this.#g;
818
+ this.#g = void 0;
819
+ try {
820
+ s?.(this), this.#c === "root" && e.diagnostics.finishRoot();
821
+ } finally {
822
+ this.#t = void 0;
823
+ }
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
+ }
1104
+ }
1105
+ beginStopping() {
1106
+ const t = this.#t;
1107
+ return t.phase !== "active" ? !1 : (this.#a({ phase: "stopping", runtime: t.runtime }), !0);
1108
+ }
1109
+ deactivate() {
1110
+ this.#a({ phase: "pending" });
1111
+ }
1112
+ fail(t) {
1113
+ this.#n(t);
1114
+ }
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;
1124
+ }
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;
1132
+ }
1133
+ remove() {
1134
+ this.#a({ phase: "removed", readiness: "unsettled" }), this.#e = void 0, this.#i = void 0;
1135
+ }
1136
+ #a(t) {
1137
+ this.#t = t, this.#i?.notifyChanged?.();
1138
+ }
1139
+ #o(t) {
1140
+ return $(
1141
+ t,
1142
+ "PLUGIN_UNAVAILABLE",
1143
+ `Plugin '${this.id}' failed with a non-Error value`
1144
+ );
1145
+ }
1146
+ #h() {
1147
+ const t = this.#i;
1148
+ if (!t) throw new TypeError(`Plugin '${this.id}' is no longer installed`);
1149
+ return t;
1150
+ }
1151
+ }
1152
+ function yt(r) {
1153
+ return r instanceof p ? { name: r.name, message: r.message, code: r.code } : { name: r.name, message: r.message };
1154
+ }
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;
1158
+ }
1159
+ class O extends AggregateError {
1160
+ }
1161
+ class Ct {
1162
+ #t;
1163
+ #e;
1164
+ #i;
1165
+ #s;
1166
+ #r = /* @__PURE__ */ new Map();
1167
+ #n = new K();
1168
+ #a = new J();
1169
+ #o;
1170
+ #h;
1171
+ #c = [];
1172
+ 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);
1174
+ }
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);
1185
+ }
1186
+ buildPlan(t) {
1187
+ return z.build(t, this.#n.kinds);
1188
+ }
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;
1195
+ }
1196
+ }
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
+ }
1250
+ }
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);
1255
+ }
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 });
1270
+ }
1271
+ async #d(t, e, i, s) {
1272
+ const n = this.#E(s);
1273
+ for (const o of t.layers) {
1274
+ const a = o.filter(
1275
+ (u) => e.has(u) && !u.runtime
1276
+ );
1277
+ if (!a.length) continue;
1278
+ const h = new AbortController(), c = await Promise.allSettled(
1279
+ a.map(async (u) => {
1280
+ try {
1281
+ const f = i.has(u) ? i.get(u) : await this.#y(
1282
+ u.spec.plugin.config,
1283
+ u.spec.config
1284
+ );
1285
+ return await this.#b(
1286
+ t,
1287
+ u,
1288
+ f,
1289
+ h.signal,
1290
+ n
1291
+ );
1292
+ } catch (f) {
1293
+ throw h.abort(f), f;
1294
+ }
1295
+ })
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);
1299
+ 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;
1305
+ }
1306
+ for (const u of l) this.#w(u);
1307
+ }
1308
+ }
1309
+ async #b(t, e, i, s, n) {
1310
+ e.deactivate();
1311
+ const o = e.spec.plugin, a = new L(n, e.id, { parentSignal: s });
1312
+ try {
1313
+ const h = this.#C(t, e, o, a), c = {
1314
+ applicationName: this.#t,
1315
+ pluginName: o.name,
1316
+ installationId: e.id,
1317
+ 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(
1322
+ "SERVICE_NOT_RETURNED",
1323
+ `Plugin '${e.id}' did not return provided service '${f}'`
1324
+ );
1325
+ u.set(_.id, l[f]);
1326
+ }
1327
+ return Object.freeze({
1328
+ installation: e,
1329
+ runtime: Object.freeze({ plugin: o, config: i, lifetime: a }),
1330
+ services: u
1331
+ });
1332
+ } catch (h) {
1333
+ e.fail(h);
1334
+ try {
1335
+ 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`
1340
+ );
1341
+ }
1342
+ throw h;
1343
+ }
1344
+ }
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);
1348
+ }
1349
+ async #O(t) {
1350
+ const e = [];
1351
+ for (const i of [...t].reverse())
1352
+ try {
1353
+ await i.runtime.lifetime.dispose();
1354
+ } catch (s) {
1355
+ e.push(s);
1356
+ }
1357
+ return e;
1358
+ }
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) {
1389
+ const n = /* @__PURE__ */ Object.create(null);
1390
+ for (const [o, a] of Object.entries(i.requires ?? {}))
1391
+ if (a.kind === "optional") {
1392
+ const h = t.providerFor(e, a.service.id);
1393
+ if (!h) {
1394
+ n[o] = void 0;
1395
+ continue;
1396
+ }
1397
+ const c = this.#r.get(h);
1398
+ if (!c?.has(a.service.id))
1399
+ throw new p(
1400
+ "SERVICE_UNAVAILABLE",
1401
+ `Optional service '${a.service.id}' is not active for plugin '${e.id}'`
1402
+ );
1403
+ n[o] = c.get(a.service.id);
1404
+ } else if (a.kind === "service") {
1405
+ const h = t.providerFor(e, a.id), c = h ? this.#r.get(h) : void 0;
1406
+ if (!h || !c?.has(a.id))
1407
+ throw new p(
1408
+ "SERVICE_UNAVAILABLE",
1409
+ `Service '${a.id}' is not active for plugin '${e.id}'`
1410
+ );
1411
+ n[o] = c.get(a.id);
1412
+ } else
1413
+ n[o] = this.#u(a, s);
1414
+ return n;
1415
+ }
1416
+ #T(t, e, i) {
1417
+ return Object.freeze({
1418
+ ...i,
1419
+ get signal() {
1420
+ return t.signal;
1421
+ },
1422
+ meta: Object.freeze(e),
1423
+ log: this.#e,
1424
+ cleanup: t.cleanup.bind(t),
1425
+ lifetime: t.lifetime.bind(t),
1426
+ spawn: t.spawn.bind(t),
1427
+ on: t.on.bind(t),
1428
+ emit: t.emit.bind(t),
1429
+ contribute: t.contribute.bind(t)
1430
+ });
1431
+ }
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) {
1445
+ 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),
1449
+ report: this.#s
1450
+ };
1451
+ }
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);
1454
+ }
1455
+ #P(t, e, i, s) {
1456
+ return this.#m(t), v(e, "event"), s.remember(e), this.#a.emit(e.id, i);
1457
+ }
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);
1460
+ }
1461
+ #u(t, e) {
1462
+ return this.#o.get(t).view((i, s) => e.ownLease(i, s));
1463
+ }
1464
+ #m(t) {
1465
+ if (!this.#i(t)) throw new TypeError(`Plugin '${t}' is not installed`);
1466
+ }
1467
+ async #j(t) {
1468
+ this.#o.beginBatch();
1469
+ try {
1470
+ return await t();
1471
+ } finally {
1472
+ this.#o.endBatch();
1473
+ }
1474
+ }
1475
+ #I() {
1476
+ if (!this.#h)
1477
+ throw M();
1478
+ return this.#h;
1479
+ }
1480
+ }
1481
+ function M() {
1482
+ return new p("SERVICE_UNAVAILABLE", "Application services are not active");
1483
+ }
1484
+ class Pt {
1485
+ #t;
1486
+ #e;
1487
+ #i;
1488
+ #s = 0;
1489
+ view;
1490
+ 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;
1492
+ }
1493
+ publish(t, e, i) {
1494
+ this.#s++, this.#i = this.#r(t, e, i), this.#e.invalidate();
1495
+ }
1496
+ #r(t, e, i) {
1497
+ const s = /* @__PURE__ */ new Map();
1498
+ for (const o of e) {
1499
+ const a = {
1500
+ id: o.id,
1501
+ name: o.spec.plugin.name,
1502
+ groupId: o.groupId,
1503
+ status: o.status,
1504
+ requires: Object.freeze(
1505
+ Object.values(o.spec.plugin.requires ?? {}).map((c) => c.kind === "optional" ? c.service.id : c.id)
1506
+ ),
1507
+ provides: Object.freeze(
1508
+ Object.values(o.spec.plugin.provides ?? {}).map((c) => c.id)
1509
+ ),
1510
+ ...o.runtime ? { lifetime: o.runtime.lifetime.diagnostics } : {}
1511
+ }, h = o.error;
1512
+ s.set(
1513
+ o.id,
1514
+ Object.freeze(h === void 0 ? a : { ...a, error: h })
1515
+ );
1516
+ }
1517
+ const n = /* @__PURE__ */ new Map();
1518
+ for (const o of i) {
1519
+ const a = { id: o.id, name: o.name };
1520
+ n.set(
1521
+ o.id,
1522
+ Object.freeze(o.parent ? { ...a, parentId: o.parent.id } : a)
1523
+ );
1524
+ }
1525
+ return Object.freeze({
1526
+ name: this.#t,
1527
+ status: t,
1528
+ revision: this.#s,
1529
+ plugins: new C(s),
1530
+ groups: new C(n)
1531
+ });
1532
+ }
1533
+ }
1534
+ const St = /* @__PURE__ */ new Set([
1535
+ "signal",
1536
+ "meta",
1537
+ "log",
1538
+ "cleanup",
1539
+ "lifetime",
1540
+ "spawn",
1541
+ "on",
1542
+ "emit",
1543
+ "contribute"
1544
+ ]);
1545
+ function q(r) {
1546
+ if (typeof r?.name != "string" || !r.name.trim())
1547
+ throw new TypeError("Plugin name must be a non-empty string");
1548
+ if (r.name !== r.name.trim())
1549
+ 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())
1557
+ 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())
1571
+ 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`);
1574
+ }
1575
+ const t = r.requires ? Object.freeze({ ...r.requires }) : void 0, e = r.provides ? Object.freeze({ ...r.provides }) : void 0;
1576
+ return Object.freeze({
1577
+ ...r,
1578
+ ...t ? { requires: t } : {},
1579
+ ...e ? { provides: e } : {}
1580
+ });
1581
+ }
1582
+ const j = /* @__PURE__ */ new WeakMap();
1583
+ function Ot(r, t) {
1584
+ j.get(r)?.(t);
1585
+ }
1586
+ class Tt {
1587
+ #t = /* @__PURE__ */ new Map();
1588
+ #e;
1589
+ constructor(t) {
1590
+ this.#e = { phase: "open", host: t }, j.set(this, (e) => this.#i(e)), Object.freeze(this);
1591
+ }
1592
+ 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;
1595
+ }
1596
+ update(t, e) {
1597
+ const i = this.#r();
1598
+ if (!e || typeof e != "object")
1599
+ throw new TypeError("Plugin update must be an object");
1600
+ const s = Object.hasOwn(e, "plugin"), n = Object.hasOwn(e, "config");
1601
+ if (!s && !n)
1602
+ throw new TypeError("Plugin update must include 'plugin' or 'config'");
1603
+ const o = i.resolve(t);
1604
+ let a;
1605
+ if (s) {
1606
+ const d = e.plugin;
1607
+ if (!d) throw new TypeError("Plugin update 'plugin' must be a plugin definition");
1608
+ a = q(d);
1609
+ }
1610
+ let h;
1611
+ 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
+ const c = { kind: "update", installation: o, declaration: h };
1613
+ return this.#s(c), this;
1614
+ }
1615
+ remove(t) {
1616
+ const e = this.#r();
1617
+ return this.#s({ kind: "remove", installation: e.resolve(t) }), this;
1618
+ }
1619
+ commit() {
1620
+ const t = this.#e;
1621
+ if (t.phase === "submitted") return t.promise;
1622
+ if (t.phase === "discarded")
1623
+ throw new TypeError("Cannot commit a discarded ChangeSet");
1624
+ if (t.phase === "committing")
1625
+ throw new TypeError("Core ChangeSet commit is already being prepared");
1626
+ this.#e = { phase: "committing" };
1627
+ const e = Object.freeze([...this.#t.values()]), i = t.host;
1628
+ try {
1629
+ for (const n of e)
1630
+ n.kind === "install" && i.attach(n.installation);
1631
+ } catch (n) {
1632
+ for (const o of e)
1633
+ o.kind === "install" && i.discard(o.installation, n);
1634
+ return this.#n(Promise.reject(n));
1635
+ }
1636
+ if (!e.length)
1637
+ return this.#n(Promise.resolve());
1638
+ let s;
1639
+ try {
1640
+ s = i.execute(e);
1641
+ } catch (n) {
1642
+ s = Promise.reject(n);
1643
+ }
1644
+ return this.#n(s);
1645
+ }
1646
+ #i(t) {
1647
+ const e = this.#e;
1648
+ if (e.phase !== "open") return;
1649
+ this.#e = { phase: "discarded" };
1650
+ const i = [...this.#t.values()];
1651
+ this.#a();
1652
+ for (const s of i)
1653
+ s.kind === "install" && e.host.discard(s.installation, t);
1654
+ }
1655
+ #s(t) {
1656
+ if (this.#t.has(t.installation))
1657
+ throw new TypeError(
1658
+ `Plugin '${t.installation.id}' can only appear once in the same ChangeSet`
1659
+ );
1660
+ this.#t.set(t.installation, Object.freeze(t));
1661
+ }
1662
+ #r() {
1663
+ const t = this.#e;
1664
+ if (t.phase !== "open")
1665
+ throw new TypeError(`Cannot modify a ${t.phase} ChangeSet`);
1666
+ return t.host;
1667
+ }
1668
+ #n(t) {
1669
+ return this.#e = { phase: "submitted", promise: t }, this.#a(), t;
1670
+ }
1671
+ #a() {
1672
+ this.#t.clear(), j.delete(this);
1673
+ }
1674
+ }
1675
+ class At {
1676
+ #t;
1677
+ constructor(t, e, i) {
1678
+ this.#t = { phase: "open", draft: t, discard: e, normalize: i };
1679
+ }
1680
+ get failure() {
1681
+ return this.#t.phase === "failed" ? this.#t.error : void 0;
1682
+ }
1683
+ requireDraft() {
1684
+ const t = this.#t;
1685
+ if (t.phase === "failed") throw t.error;
1686
+ if (t.phase === "sealed") throw T();
1687
+ return t.draft;
1688
+ }
1689
+ assertOpen() {
1690
+ this.requireDraft();
1691
+ }
1692
+ fail(t) {
1693
+ const e = this.#t;
1694
+ if (e.phase === "failed") return e.error;
1695
+ if (e.phase === "sealed") throw T();
1696
+ const i = e.normalize(t);
1697
+ return this.#t = {
1698
+ phase: "failed",
1699
+ draft: e.draft,
1700
+ discard: e.discard,
1701
+ error: i
1702
+ }, i;
1703
+ }
1704
+ seal() {
1705
+ const t = this.#t;
1706
+ if (t.phase === "failed") throw t.error;
1707
+ if (t.phase === "sealed") throw T();
1708
+ return this.#t = { phase: "sealed" }, t.draft;
1709
+ }
1710
+ discard(t) {
1711
+ const e = this.#t;
1712
+ if (e.phase === "sealed") return;
1713
+ const i = e.phase === "failed" ? e.error : e.normalize(t);
1714
+ this.#t = { phase: "sealed" }, e.discard(e.draft, i);
1715
+ }
1716
+ }
1717
+ function T() {
1718
+ return new TypeError("Group configuration has been sealed");
1719
+ }
1720
+ class P {
1721
+ constructor(t, e, i) {
1722
+ this.id = t, this.name = e, this.#e = { phase: "attached", parent: i };
1723
+ }
1724
+ id;
1725
+ name;
1726
+ #t = /* @__PURE__ */ new Map();
1727
+ #e;
1728
+ static root(t) {
1729
+ return new P("/", t, void 0);
1730
+ }
1731
+ get attached() {
1732
+ return this.#e.phase !== "detached";
1733
+ }
1734
+ get children() {
1735
+ return [...this.#t.values()];
1736
+ }
1737
+ get parent() {
1738
+ const t = this.#e;
1739
+ return t.phase === "detached" ? void 0 : t.parent;
1740
+ }
1741
+ create(t) {
1742
+ if (this.assertAttached(), jt(t), this.#t.has(t))
1743
+ throw new TypeError(`Group '${this.#i(t)}' already exists`);
1744
+ const e = new P(this.#i(t), t, this);
1745
+ return this.#t.set(t, e), e;
1746
+ }
1747
+ containsId(t) {
1748
+ return this.id === "/" ? t.startsWith("/") : t === this.id || t.startsWith(`${this.id}/`);
1749
+ }
1750
+ assertAttached() {
1751
+ if (this.#e.phase === "detached")
1752
+ throw new TypeError(`Group '${this.id}' has been removed`);
1753
+ }
1754
+ detach() {
1755
+ const t = this.#e;
1756
+ if (t.phase !== "detached") {
1757
+ for (const e of this.#t.values()) e.detach();
1758
+ this.#t.clear(), this.#e = { phase: "detached" }, t.parent && t.parent.#t.delete(this.name);
1759
+ }
1760
+ }
1761
+ walk() {
1762
+ const t = [this];
1763
+ for (let e = 0; e < t.length; e++) {
1764
+ const i = t[e];
1765
+ i && t.push(...i.children);
1766
+ }
1767
+ return t;
1768
+ }
1769
+ #i(t) {
1770
+ return this.id === "/" ? `/${t}` : `${this.id}/${t}`;
1771
+ }
1772
+ }
1773
+ function jt(r) {
1774
+ if (typeof r != "string" || !r.trim())
1775
+ throw new TypeError("Group name must be a non-empty string");
1776
+ if (r !== r.trim())
1777
+ throw new TypeError("Group name cannot start or end with whitespace");
1778
+ if (r.includes("/")) throw new TypeError("Group name cannot contain '/'");
1779
+ }
1780
+ class D {
1781
+ constructor(t, e, i) {
1782
+ this.node = t, this.#t = { phase: e }, this.#e = i;
1783
+ }
1784
+ node;
1785
+ #t;
1786
+ #e;
1787
+ status(t) {
1788
+ if (!this.node.attached) return "removed";
1789
+ const e = this.#t;
1790
+ return e.phase === "pending" ? t === "stopping" ? "stopping" : "pending" : e.phase === "failed" ? "failed" : e.phase === "established" ? t : "pending";
1791
+ }
1792
+ async ready(t) {
1793
+ this.node.assertAttached();
1794
+ const e = this.#t;
1795
+ e.phase === "pending" && await e.barrier, this.node.assertAttached();
1796
+ const i = this.#t;
1797
+ if (i.phase === "failed") throw i.error;
1798
+ await t();
1799
+ }
1800
+ track(t) {
1801
+ this.node.assertAttached();
1802
+ const e = this.#t, i = e.phase === "established" || e.phase === "pending" && e.baseline === "established", s = {}, n = t.then(
1803
+ () => {
1804
+ this.#i(s) && (this.#t = { phase: "established" }, this.#e?.());
1805
+ },
1806
+ (o) => {
1807
+ const a = $(
1808
+ o,
1809
+ "GROUP_UNAVAILABLE",
1810
+ `Group '${this.node.id}' operation failed with a non-Error value`
1811
+ );
1812
+ if (this.#i(s) && (this.#t = i ? { phase: "established" } : { phase: "failed", error: a }, this.#e?.()), !i) throw a;
1813
+ }
1814
+ );
1815
+ this.#t = {
1816
+ phase: "pending",
1817
+ attempt: s,
1818
+ barrier: n,
1819
+ baseline: i ? "established" : "new"
1820
+ }, this.#e?.(), n.catch(() => {
1821
+ });
1822
+ }
1823
+ release() {
1824
+ this.#t = { phase: "released" }, this.#e = void 0;
1825
+ }
1826
+ #i(t) {
1827
+ const e = this.#t;
1828
+ return e.phase === "pending" && e.attempt === t;
1829
+ }
1830
+ }
1831
+ function I(r) {
1832
+ return new p("GROUP_REMOVED", `Group '${r.id}' has been removed`);
1833
+ }
1834
+ const y = /* @__PURE__ */ new WeakMap();
1835
+ class It {
1836
+ #t;
1837
+ #e;
1838
+ constructor(t, e, i) {
1839
+ this.#t = e, this.#e = i ? { phase: "configuring", coordinator: t, configuration: i } : { phase: "attached", coordinator: t }, y.set(this, {
1840
+ finishConfiguration: () => {
1841
+ const s = this.#e;
1842
+ s.phase === "configuring" && (this.#e = { phase: "attached", coordinator: s.coordinator });
1843
+ },
1844
+ revoke: () => {
1845
+ this.#e = { phase: "revoked" };
1846
+ }
1847
+ }), Object.freeze(this);
1848
+ }
1849
+ get id() {
1850
+ return this.#t.id;
1851
+ }
1852
+ get name() {
1853
+ return this.#t.name;
1854
+ }
1855
+ get status() {
1856
+ const t = this.#e;
1857
+ return t.phase === "revoked" ? "removed" : t.coordinator.status(this.#t);
1858
+ }
1859
+ ready() {
1860
+ const t = this.#e;
1861
+ return t.phase === "revoked" ? Promise.reject(I(this.#t)) : t.coordinator.ready(this.#t);
1862
+ }
1863
+ install(t, ...e) {
1864
+ 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
+ );
1870
+ }
1871
+ change() {
1872
+ if (this.#e.phase === "configuring")
1873
+ throw new TypeError("Cannot create a ChangeSet while a Group is being configured");
1874
+ return this.#i().change(this.#t);
1875
+ }
1876
+ group(t, e) {
1877
+ const i = this.#e;
1878
+ return i.phase === "configuring" && i.configuration.assertOpen(), this.#i().create(
1879
+ this.#t,
1880
+ t,
1881
+ e,
1882
+ i.phase === "configuring" ? i.configuration : void 0
1883
+ );
1884
+ }
1885
+ remove() {
1886
+ const t = this.#e;
1887
+ if (t.phase === "configuring")
1888
+ throw new TypeError("Cannot remove a Group while it is being configured");
1889
+ return t.phase === "attached" ? t.coordinator.remove(this.#t) : Promise.resolve();
1890
+ }
1891
+ #i() {
1892
+ const t = this.#e;
1893
+ if (t.phase === "revoked") throw I(this.#t);
1894
+ return t.coordinator;
1895
+ }
1896
+ }
1897
+ class kt {
1898
+ root;
1899
+ #t;
1900
+ #e = /* @__PURE__ */ new WeakMap();
1901
+ #i = /* @__PURE__ */ new WeakMap();
1902
+ constructor(t, e) {
1903
+ this.root = P.root(t), this.#t = e, this.#i.set(
1904
+ this.root,
1905
+ new D(this.root, "established", () => e.notifyChanged())
1906
+ );
1907
+ }
1908
+ nodes() {
1909
+ return this.root.walk();
1910
+ }
1911
+ install(t, e, ...i) {
1912
+ const s = this.change(t), n = s.install(e, ...i);
1913
+ return G(s.commit()), n;
1914
+ }
1915
+ change(t, e = "immediate") {
1916
+ return t.assertAttached(), new Tt({
1917
+ create: (i, s) => this.#t.createDraft(t, i, s),
1918
+ 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
+ );
1924
+ return s;
1925
+ },
1926
+ execute: (i) => {
1927
+ const s = this.#t.executeChanges(i);
1928
+ for (const n of i) n.installation.trackReadiness(s);
1929
+ return e === "immediate" && this.#n(t, s), s;
1930
+ },
1931
+ attach: (i) => this.#t.attachInstallation(i),
1932
+ discard: (i, s) => this.#t.discardInstallation(i, s)
1933
+ });
1934
+ }
1935
+ create(t, e, i, s) {
1936
+ if (typeof i != "function") throw new TypeError("Group configure must be a function");
1937
+ 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(
1940
+ this.change(n, "deferred"),
1941
+ Ot,
1942
+ (c) => $(
1943
+ c,
1944
+ "GROUP_UNAVAILABLE",
1945
+ `Group '${n.id}' configuration failed with a non-Error value`
1946
+ )
1947
+ ), h = new It(this, n, a);
1948
+ this.#e.set(n, h);
1949
+ try {
1950
+ const c = i(h);
1951
+ Lt(c) && $t(c);
1952
+ const d = a.failure;
1953
+ if (d) throw d;
1954
+ } catch (c) {
1955
+ const d = a.fail(c), l = n.walk();
1956
+ throw n.detach(), this.#o(l), o && a.discard(d), this.#t.notifyChanged(), d;
1957
+ }
1958
+ if (o) {
1959
+ const c = a.seal().commit();
1960
+ for (const d of n.walk()) {
1961
+ const l = this.#e.get(d);
1962
+ l && y.get(l)?.finishConfiguration(), this.#n(d, c);
1963
+ }
1964
+ G(c);
1965
+ }
1966
+ return this.#t.notifyChanged(), h;
1967
+ }
1968
+ async ready(t) {
1969
+ await this.#a(t).ready(async () => {
1970
+ await Promise.all(this.#s(t).map((e) => e.ready()));
1971
+ });
1972
+ }
1973
+ status(t) {
1974
+ return t.attached ? this.#a(t).status(this.#r(t)) : "removed";
1975
+ }
1976
+ remove(t) {
1977
+ if (t === this.root) throw new TypeError("The root Group cannot be removed");
1978
+ return t.attached ? this.#t.runExclusive(async () => {
1979
+ if (!t.attached) {
1980
+ this.#o([t]);
1981
+ return;
1982
+ }
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());
1988
+ }
1989
+ #s(t) {
1990
+ return [...this.#t.installations()].filter(
1991
+ (e) => t.containsId(e.groupId)
1992
+ );
1993
+ }
1994
+ #r(t) {
1995
+ const e = this.#s(t);
1996
+ 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
+ }
1998
+ #n(t, e) {
1999
+ this.#a(t).track(e);
2000
+ }
2001
+ #a(t) {
2002
+ const e = this.#i.get(t);
2003
+ if (!e) throw I(t);
2004
+ return e;
2005
+ }
2006
+ #o(t) {
2007
+ for (const e of t) {
2008
+ this.#i.get(e)?.release(), this.#i.delete(e);
2009
+ const i = this.#e.get(e);
2010
+ i && (y.get(i)?.revoke(), y.delete(i)), this.#e.delete(e);
2011
+ }
2012
+ }
2013
+ }
2014
+ function G(r) {
2015
+ Promise.resolve(r).catch(() => {
2016
+ });
2017
+ }
2018
+ function $t(r) {
2019
+ throw Promise.resolve(r).catch(() => {
2020
+ }), new TypeError("Group configure must be synchronous");
2021
+ }
2022
+ function Lt(r) {
2023
+ return r === null || typeof r != "object" && typeof r != "function" ? !1 : typeof r.then == "function";
2024
+ }
2025
+ class zt {
2026
+ #t = Promise.resolve();
2027
+ get settled() {
2028
+ return this.#t;
2029
+ }
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(
2035
+ () => {
2036
+ },
2037
+ () => {
2038
+ }
2039
+ ), e;
2040
+ }
2041
+ }
2042
+ const xt = console, E = /* @__PURE__ */ new WeakMap();
2043
+ class Rt {
2044
+ #t;
2045
+ #e = { phase: "draft" };
2046
+ constructor(t) {
2047
+ this.#t = t, E.set(this, {
2048
+ attach: (e, i) => {
2049
+ if (this.#e.phase !== "draft")
2050
+ throw new TypeError(`Plugin '${this.#t.id}' control is already sealed`);
2051
+ this.#e = {
2052
+ phase: "attached",
2053
+ update: e,
2054
+ remove: i
2055
+ };
2056
+ },
2057
+ revoke: () => {
2058
+ this.#e = { phase: "revoked" };
2059
+ }
2060
+ }), Object.freeze(this);
2061
+ }
2062
+ get id() {
2063
+ return this.#t.id;
2064
+ }
2065
+ get groupId() {
2066
+ return this.#t.groupId;
2067
+ }
2068
+ get status() {
2069
+ return this.#t.status;
2070
+ }
2071
+ ready() {
2072
+ return this.#t.ready();
2073
+ }
2074
+ async update(t) {
2075
+ const e = this.#e;
2076
+ 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`);
2079
+ await e.update(t);
2080
+ }
2081
+ async remove() {
2082
+ const t = this.#e;
2083
+ if (t.phase === "draft") throw this.#i();
2084
+ t.phase === "attached" && await t.remove();
2085
+ }
2086
+ #i() {
2087
+ return new p(
2088
+ "PLUGIN_UNAVAILABLE",
2089
+ `Plugin '${this.#t.id}' installation has not been committed`
2090
+ );
2091
+ }
2092
+ }
2093
+ class Nt {
2094
+ name;
2095
+ diagnostics;
2096
+ #t = /* @__PURE__ */ new Map();
2097
+ #e = /* @__PURE__ */ new WeakMap();
2098
+ #i = /* @__PURE__ */ new WeakMap();
2099
+ #s;
2100
+ #r;
2101
+ #n;
2102
+ #a;
2103
+ #o;
2104
+ #h = 0;
2105
+ #c = "idle";
2106
+ #p = new zt();
2107
+ 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);
2132
+ },
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);
2141
+ }
2142
+ get status() {
2143
+ return this.#c;
2144
+ }
2145
+ get(t) {
2146
+ const e = this.#c === "active" ? "available" : "unavailable";
2147
+ return this.#o.get(t, e);
2148
+ }
2149
+ install(t, ...e) {
2150
+ return this.#n.install(this.#n.root, t, ...e);
2151
+ }
2152
+ change() {
2153
+ return this.#n.change(this.#n.root);
2154
+ }
2155
+ group(t, e) {
2156
+ return this.#n.create(this.#n.root, t, e);
2157
+ }
2158
+ start() {
2159
+ return this.#p.run(async () => {
2160
+ if (this.#c !== "active") {
2161
+ this.#u("starting");
2162
+ try {
2163
+ const t = this.#o.buildPlan(this.#t.values());
2164
+ await this.#o.start(t), this.#u("active"), this.#E(t.order);
2165
+ } catch (t) {
2166
+ this.#u("idle");
2167
+ for (const e of this.#t.values())
2168
+ e.status !== "active" && e.fail(t);
2169
+ throw this.#E(this.#t.values()), t;
2170
+ }
2171
+ }
2172
+ });
2173
+ }
2174
+ stop() {
2175
+ return this.#p.run(async () => {
2176
+ if (this.#c === "idle") return;
2177
+ this.#u("stopping");
2178
+ 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");
2181
+ });
2182
+ }
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 () => {
2201
+ 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;
2207
+ }
2208
+ });
2209
+ }
2210
+ async #b(t) {
2211
+ t.length && this.#c === "active" ? await this.#w(t) : (this.#f(t), this.#v(t));
2212
+ }
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);
2217
+ }
2218
+ async #O(t) {
2219
+ const e = this.#A(), i = new Set(t.map((n) => n.installation));
2220
+ this.#u("changing");
2221
+ let s;
2222
+ try {
2223
+ this.#f(t), s = this.#o.buildPlan(this.#t.values());
2224
+ } catch (n) {
2225
+ throw this.#P(e), this.#u("active"), n;
2226
+ }
2227
+ try {
2228
+ const n = await this.#o.transition(
2229
+ s,
2230
+ i,
2231
+ () => this.#P(e)
2232
+ );
2233
+ return this.#u("active"), n;
2234
+ } 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
+ }
2258
+ }
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
+ }
2303
+ #S(t) {
2304
+ try {
2305
+ this.#a(t);
2306
+ } catch (e) {
2307
+ try {
2308
+ this.#r.error(
2309
+ new AggregateError([t, e], "Application error reporter failed")
2310
+ );
2311
+ } catch {
2312
+ }
2313
+ }
2314
+ }
2315
+ #u(t) {
2316
+ this.#c = t, this.#m();
2317
+ }
2318
+ #m() {
2319
+ this.#s.publish(this.#c, this.#t.values(), this.#n.nodes());
2320
+ }
2321
+ }
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);
2331
+ }
2332
+ 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
2344
+ };