@dougongjs/core 0.4.0 → 0.5.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 (59) hide show
  1. package/dist/change-set.d.ts +6 -0
  2. package/dist/change-set.d.ts.map +1 -1
  3. package/dist/configuration.d.ts +12 -1
  4. package/dist/configuration.d.ts.map +1 -1
  5. package/dist/contract-registry.d.ts +2 -2
  6. package/dist/contract-registry.d.ts.map +1 -1
  7. package/dist/contracts.d.ts +27 -0
  8. package/dist/contracts.d.ts.map +1 -1
  9. package/dist/contribution-store.d.ts +20 -1
  10. package/dist/contribution-store.d.ts.map +1 -1
  11. package/dist/diagnostics.d.ts +21 -3
  12. package/dist/diagnostics.d.ts.map +1 -1
  13. package/dist/engine.d.ts +28 -1
  14. package/dist/engine.d.ts.map +1 -1
  15. package/dist/errors.d.ts +44 -7
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/event-hub.d.ts +12 -1
  18. package/dist/event-hub.d.ts.map +1 -1
  19. package/dist/group-configuration.d.ts +20 -0
  20. package/dist/group-configuration.d.ts.map +1 -0
  21. package/dist/group-coordinator.d.ts +20 -2
  22. package/dist/group-coordinator.d.ts.map +1 -1
  23. package/dist/group-lifecycle.d.ts +13 -0
  24. package/dist/group-lifecycle.d.ts.map +1 -1
  25. package/dist/group.d.ts +5 -11
  26. package/dist/group.d.ts.map +1 -1
  27. package/dist/host-api.d.ts +33 -0
  28. package/dist/host-api.d.ts.map +1 -1
  29. package/dist/host.d.ts.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +905 -590
  33. package/dist/installation-graph.d.ts +8 -1
  34. package/dist/installation-graph.d.ts.map +1 -1
  35. package/dist/installation-registry.d.ts +6 -0
  36. package/dist/installation-registry.d.ts.map +1 -1
  37. package/dist/installation.d.ts +21 -3
  38. package/dist/installation.d.ts.map +1 -1
  39. package/dist/instance-coordinator.d.ts +32 -3
  40. package/dist/instance-coordinator.d.ts.map +1 -1
  41. package/dist/lifecycle-status.d.ts.map +1 -1
  42. package/dist/lifetime-diagnostics.d.ts +7 -1
  43. package/dist/lifetime-diagnostics.d.ts.map +1 -1
  44. package/dist/lifetime.d.ts +37 -1
  45. package/dist/lifetime.d.ts.map +1 -1
  46. package/dist/plugin.d.ts +28 -2
  47. package/dist/plugin.d.ts.map +1 -1
  48. package/dist/readonly-map.d.ts +8 -1
  49. package/dist/readonly-map.d.ts.map +1 -1
  50. package/dist/record.d.ts +16 -1
  51. package/dist/record.d.ts.map +1 -1
  52. package/dist/resource.d.ts +6 -0
  53. package/dist/resource.d.ts.map +1 -1
  54. package/dist/serial-queue.d.ts +7 -1
  55. package/dist/serial-queue.d.ts.map +1 -1
  56. package/dist/snapshot-view.d.ts +2 -0
  57. package/dist/snapshot-view.d.ts.map +1 -1
  58. package/dist/sync-result.d.ts.map +1 -1
  59. package/package.json +1 -1
@@ -48,6 +48,12 @@ export declare class ChangeSetDraft implements ChangeSet {
48
48
  install<Declaration extends AnyPlugin>(plugin: Declaration, ...config: PluginConfigArguments<Declaration>): Installation<Declaration>;
49
49
  update<Declaration extends AnyPlugin>(installation: Installation<Declaration>, update: InstallationUpdate<Declaration>): void;
50
50
  remove<Declaration extends AnyPlugin>(installation: Installation<Declaration>): void;
51
+ /**
52
+ * Commit is idempotent by returning the same promise, so two callers awaiting
53
+ * one draft get one transaction rather than two. `committing` exists to catch
54
+ * the reentrant case — an `attach` hook that calls `commit()` again — which
55
+ * would otherwise submit the operation list twice.
56
+ */
51
57
  commit(): Promise<void>;
52
58
  }
53
59
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"change-set.d.ts","sourceRoot":"","sources":["../src/change-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElF,KAAK,iBAAiB,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACrD;IACE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAIN,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,GACvE;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;CACzC,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE3E,UAAU,UAAU;IAClB,QAAQ,CAAC,MAAM,EAAE,CACf,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,OAAO,KACZ;QACH,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;QACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;KAC1C,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,QAAQ,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9E;AAED,KAAK,wBAAwB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;AAmBrD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,QAE1E;AAED,+FAA+F;AAC/F,wBAAgB,0BAA0B,CAAC,WAAW,SAAS,SAAS,EACtE,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,wBAAwB,6BAKjC;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,SAAS;;gBAIlC,IAAI,EAAE,UAAU;IAS5B,OAAO,CAAC,WAAW,SAAS,SAAS,EACnC,MAAM,EAAE,WAAW,EACnB,GAAG,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC5C,YAAY,CAAC,WAAW,CAAC;IAkB5B,MAAM,CAAC,WAAW,SAAS,SAAS,EAClC,YAAY,EAAE,YAAY,CAAC,WAAW,CAAC,EACvC,MAAM,EAAE,kBAAkB,CAAC,WAAW,CAAC;IA6BzC,MAAM,CAAC,WAAW,SAAS,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,WAAW,CAAC;IAK7E,MAAM;CAqEP"}
1
+ {"version":3,"file":"change-set.d.ts","sourceRoot":"","sources":["../src/change-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElF,KAAK,iBAAiB,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACrD;IACE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAIN,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,GACvE;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;CACzC,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAE3E,UAAU,UAAU;IAClB,QAAQ,CAAC,MAAM,EAAE,CACf,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,OAAO,KACZ;QACH,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;QACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;KAC1C,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,QAAQ,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9E;AAED,KAAK,wBAAwB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;AAwBrD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,QAE1E;AAED,+FAA+F;AAC/F,wBAAgB,0BAA0B,CAAC,WAAW,SAAS,SAAS,EACtE,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,wBAAwB,6BAKjC;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,SAAS;;gBAIlC,IAAI,EAAE,UAAU;IAS5B,OAAO,CAAC,WAAW,SAAS,SAAS,EACnC,MAAM,EAAE,WAAW,EACnB,GAAG,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC5C,YAAY,CAAC,WAAW,CAAC;IAkB5B,MAAM,CAAC,WAAW,SAAS,SAAS,EAClC,YAAY,EAAE,YAAY,CAAC,WAAW,CAAC,EACvC,MAAM,EAAE,kBAAkB,CAAC,WAAW,CAAC;IA6BzC,MAAM,CAAC,WAAW,SAAS,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,WAAW,CAAC;IAK7E;;;;;OAKG;IACH,MAAM;CA4EP"}
@@ -1,4 +1,15 @@
1
1
  import { StandardSchemaV1 } from '@standard-schema/spec';
2
- /** Resolves one Plugin config at the Standard Schema trust boundary. */
2
+ /**
3
+ * Resolves one Plugin config at the Standard Schema trust boundary.
4
+ *
5
+ * The validator is third-party code, so its return value is checked as
6
+ * untrusted input rather than trusted to match the spec. A validator that
7
+ * returns a string, or an object with neither `value` nor `issues`, is a bug in
8
+ * that library — it becomes a `TypeError` naming the Installation rather than an
9
+ * `undefined` config that fails somewhere inside `setup()`.
10
+ *
11
+ * A schema is optional. With none declared, the input passes through untouched:
12
+ * Core does not invent a validation step the Plugin author did not ask for.
13
+ */
3
14
  export declare function resolvePluginConfig(schema: StandardSchemaV1<unknown, unknown> | undefined, input: unknown, installationId: string): Promise<unknown>;
4
15
  //# sourceMappingURL=configuration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,wEAAwE;AACxE,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,EACtD,KAAK,EAAE,OAAO,EACd,cAAc,EAAE,MAAM,oBA6BvB"}
1
+ {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,EACtD,KAAK,EAAE,OAAO,EACd,cAAc,EAAE,MAAM,oBA6BvB"}
@@ -5,10 +5,10 @@ export declare class ContractRegistry {
5
5
  get kinds(): ReadonlyMap<string, ContractKind>;
6
6
  assertCompatible(contract: ContractIdentity): void;
7
7
  remember(contract: ContractIdentity): void;
8
- draft(candidateKinds: ReadonlyMap<string, ContractKind>): ContractRegistryDraft;
8
+ writer(candidateKinds: ReadonlyMap<string, ContractKind>): ContractRegistryWriter;
9
9
  commit(kinds: ReadonlyMap<string, ContractKind>): void;
10
10
  }
11
- export declare class ContractRegistryDraft {
11
+ export declare class ContractRegistryWriter {
12
12
  #private;
13
13
  constructor(registry: ContractRegistry, candidateKinds: ReadonlyMap<string, ContractKind>);
14
14
  remember(contract: ContractIdentity): void;
@@ -1 +1 @@
1
- {"version":3,"file":"contract-registry.d.ts","sourceRoot":"","sources":["../src/contract-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGlE,0EAA0E;AAC1E,qBAAa,gBAAgB;;IAG3B,IAAI,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAE7C;IAED,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB;IAI3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IAInC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;IAIvD,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;CAIhD;AAYD,qBAAa,qBAAqB;;gBAGpB,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;IAKzF,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IAenC,MAAM;IAON,OAAO;CAGR;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,QAAQ,EAAE,gBAAgB,QAGhG"}
1
+ {"version":3,"file":"contract-registry.d.ts","sourceRoot":"","sources":["../src/contract-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAYlE,0EAA0E;AAC1E,qBAAa,gBAAgB;;IAG3B,IAAI,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAE7C;IAED,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB;IAI3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IAInC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;IAIxD,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;CAIhD;AAYD,qBAAa,sBAAsB;;gBAGrB,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC;IAKzF,QAAQ,CAAC,QAAQ,EAAE,gBAAgB;IAmBnC,MAAM;IAON,OAAO;CAGR;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,QAAQ,EAAE,gBAAgB,QAGhG"}
@@ -1,15 +1,27 @@
1
1
  declare const contractBrand: unique symbol;
2
2
  declare const contractValueSlot: unique symbol;
3
3
  declare const optionalBrand: unique symbol;
4
+ /**
5
+ * Holds `T` in a covariant and a contravariant position at once, which makes
6
+ * every Contract invariant in `T`. Without the contravariant half, `Service<Cat>`
7
+ * would be assignable to `Service<Animal>` and `host.get()` could hand back a
8
+ * value narrower than the token the caller passed in.
9
+ */
4
10
  interface ContractValueSlot<T> {
5
11
  readonly value: T;
6
12
  readonly accept: (value: T) => void;
7
13
  }
8
14
  export type ContractKind = "service" | "extensionPoint" | "event";
15
+ /** The erased half of a token: all a registry needs to key it, with no value type. */
9
16
  export interface ContractIdentity {
10
17
  readonly id: string;
11
18
  readonly kind: ContractKind;
12
19
  }
20
+ /**
21
+ * Nominal marker. A structurally identical `{ id, kind }` literal is not a
22
+ * Contract, so a token has to come from `service()`, `event()` or
23
+ * `extensionPoint()` rather than from an object written at the call site.
24
+ */
13
25
  interface ContractBrand {
14
26
  readonly [contractBrand]: true;
15
27
  }
@@ -29,6 +41,11 @@ export interface ExtensionPoint<T> extends Contract<T, "extensionPoint"> {
29
41
  }
30
42
  export interface Event<T> extends Contract<T, "event"> {
31
43
  }
44
+ /**
45
+ * `optional()` wraps rather than flags, so the required and optional forms of
46
+ * one Service stay distinct values. A Plugin cannot weaken a hard dependency by
47
+ * mutating a shared token.
48
+ */
32
49
  interface OptionalServiceIdentity {
33
50
  readonly [optionalBrand]: true;
34
51
  readonly kind: "optional";
@@ -38,8 +55,18 @@ export interface OptionalService<T> extends OptionalServiceIdentity {
38
55
  readonly service: Service<T>;
39
56
  readonly [contractValueSlot]: ContractValueSlot<T>;
40
57
  }
58
+ /**
59
+ * Everything a Plugin may name in `requires`. Events are absent on purpose: an
60
+ * Event is a transient fact reached through the Lifetime, never something whose
61
+ * presence the dependency graph can order.
62
+ */
41
63
  export type Requirement = ServiceIdentity | ExtensionPointIdentity | OptionalServiceIdentity;
42
64
  export type ContractValue<T> = T extends Contract<infer Value, ContractKind> ? Value : never;
65
+ /**
66
+ * The brand is compile-time only, so a runtime check can be structural at best.
67
+ * This validates identity shape, not factory provenance. Declaration
68
+ * normalization takes an owned identity snapshot of accepted values.
69
+ */
43
70
  export declare function isContract(value: unknown, expected?: ContractKind): value is ContractIdentity;
44
71
  export declare function assertContract(value: unknown, expected?: ContractKind): asserts value is ContractIdentity;
45
72
  export declare function service<T>(id: string): Service<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAOA,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAC3C,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AAC/C,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAE3C;;;;;GAKG;AACH,UAAU,iBAAiB,CAAC,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAElE,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC7B;AAED;;;;GAIG;AACH,UAAU,aAAa;IACrB,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;CAChC;AAED,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,YAAY,CAAE,SAAQ,gBAAgB,EAAE,aAAa;IACnF,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CACpD;AAED,UAAU,eAAgB,SAAQ,gBAAgB,EAAE,aAAa;IAC/D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED,UAAU,sBAAuB,SAAQ,gBAAgB,EAAE,aAAa;IACtE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CACjC;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC;CAAG;AAC7D,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,gBAAgB,CAAC;CAAG;AAC3E,MAAM,WAAW,KAAK,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;CAAG;AAEzD;;;;GAIG;AACH,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,CAAE,SAAQ,uBAAuB;IACjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;CACpD;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,sBAAsB,GAAG,uBAAuB,CAAC;AAE7F,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,KAAK,EAAE,YAAY,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;AAgB7F;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,KAAK,IAAI,gBAAgB,CAY7F;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,KAAK,IAAI,gBAAgB,CAGnC;AAQD,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAEjD;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAE7C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAE/D;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAKjE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GACrC,KAAK,IAAI,eAAe,CAAC,CAAC,CAAC,CAI7B"}
@@ -1,9 +1,15 @@
1
1
  import { Requirement } from './contracts';
2
2
  import { disposeSymbol, Disposable, Publication, StagedResource } from './resource';
3
3
  import { SnapshotView } from './snapshot-view';
4
+ /** A contributed entry the contributor may update or withdraw — nobody else can. */
4
5
  export interface Contribution<T> extends Disposable {
5
6
  readonly update: (value: T) => void;
6
7
  }
8
+ /**
9
+ * The read side: a keyed map, not a list. Keys are `installationId/key`, so two
10
+ * Installations contributing under the same local key stay distinct, and a
11
+ * consumer can tell which Installation an entry came from.
12
+ */
7
13
  export type ContributionView<T> = SnapshotView<ReadonlyMap<string, T>>;
8
14
  export type ContributionLeaseKind = "view" | "subscription";
9
15
  type ExtensionPointIdentity = Extract<Requirement, {
@@ -24,13 +30,26 @@ export declare class ContributionStore<T> {
24
30
  constructor(invalidate: (store: ContributionStore<unknown>) => void, report: (error: unknown) => void, releaseIfUnused: (store: ContributionStore<unknown>) => void);
25
31
  stage(installationId: string, key: string, value: T, release: (publication: Publication) => void): ContributionRecord<T>;
26
32
  view(own: (resource: Disposable, kind: ContributionLeaseKind) => () => void): ContributionView<T>;
27
- /** A stable view explicitly owned by the Host for graph-external consumers. */
33
+ /**
34
+ * A stable view explicitly owned by the Host for graph-external consumers.
35
+ *
36
+ * Application code has no Lifetime to lease a view from, so this one is
37
+ * retained by the Host instead — which also pins the store open for as long as
38
+ * the Host lives. That is the trade: `host.contributions()` gives a handle that
39
+ * never goes stale, at the cost of a store that is no longer self-releasing.
40
+ */
28
41
  hostView(): ContributionView<T>;
29
42
  snapshot(): ReadonlyMap<string, T>;
30
43
  subscribe(listener: () => void, own: (resource: Disposable, kind: ContributionLeaseKind) => () => void): ContributionSubscription;
31
44
  insert(id: string, contribution: ContributionRecord<T>, value: T): void;
32
45
  update(id: string, contribution: ContributionRecord<T>, value: T): void;
33
46
  removeContribution(id: string, contribution: ContributionRecord<T>, visibility: "staged" | "published"): void;
47
+ /**
48
+ * Rebuilds the published snapshot, and does nothing when the result would be
49
+ * equal by identity per key. A change that adds and removes the same entry —
50
+ * an Instance restarting with an identical contribution — therefore notifies
51
+ * nobody, instead of waking every observer to hand them what they already had.
52
+ */
34
53
  publishSnapshot(): void;
35
54
  }
36
55
  declare class ContributionSubscription implements Disposable {
@@ -1 +1 @@
1
- {"version":3,"file":"contribution-store.d.ts","sourceRoot":"","sources":["../src/contribution-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contribution-store.d.ts","sourceRoot":"","sources":["../src/contribution-store.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,11 @@ import { InstallationRecord } from './installation';
3
3
  import { LifetimeSnapshot } from './lifetime';
4
4
  import { LifecycleStatus } from './lifecycle-status';
5
5
  import { SnapshotView } from './snapshot-view';
6
+ /**
7
+ * `changing` is the reason the read window is closed during a transaction.
8
+ * `host.get()` only answers while the status is `active`, so a Service lookup
9
+ * mid-change cannot observe a half-applied plan — it fails instead.
10
+ */
6
11
  export type HostStatus = "idle" | "starting" | "active" | "changing" | "stopping";
7
12
  export interface InstallationSnapshot {
8
13
  readonly id: string;
@@ -26,11 +31,24 @@ export interface HostSnapshot {
26
31
  readonly installations: ReadonlyMap<string, InstallationSnapshot>;
27
32
  readonly groups: ReadonlyMap<string, GroupSnapshot>;
28
33
  }
29
- /** Immutable operational read model; never a service locator or control plane. */
34
+ interface HostDiagnosticSource {
35
+ readonly status: HostStatus;
36
+ readonly installations: Iterable<InstallationRecord>;
37
+ readonly groups: Iterable<GroupNode>;
38
+ }
39
+ /**
40
+ * Immutable operational read model; never a service locator or control plane.
41
+ *
42
+ * Everything here is data or another read-only view. There is deliberately no
43
+ * way back: nothing in a snapshot can install, remove, or reach a live Instance.
44
+ * `revision` increments on every publish so a consumer can tell "nothing
45
+ * changed" from "changed back to an equal value".
46
+ */
30
47
  export declare class HostDiagnostics {
31
48
  #private;
32
49
  readonly view: SnapshotView<HostSnapshot>;
33
- constructor(name: string, groups: Iterable<GroupNode>, report: (error: unknown) => void);
34
- publish(status: HostStatus, installations: Iterable<InstallationRecord>, groups: Iterable<GroupNode>): void;
50
+ constructor(name: string, read: () => HostDiagnosticSource, report: (error: unknown) => void);
51
+ publish(): void;
35
52
  }
53
+ export {};
36
54
  //# sourceMappingURL=diagnostics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACrD;AAED,kFAAkF;AAClF,qBAAa,eAAe;;IAM1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;gBAE9B,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI;IAOvF,OAAO,CACL,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAC3C,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC;CAqD9B"}
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAElF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACrD;AAED,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACrD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,qBAAa,eAAe;;IAK1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;gBAE9B,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI;IAS5F,OAAO;CAmDR"}
package/dist/engine.d.ts CHANGED
@@ -2,6 +2,12 @@ import { ExtensionPoint, OptionalService, Service } from './contracts';
2
2
  import { InstallationGraph } from './installation-graph';
3
3
  import { InstallationRecord } from './installation';
4
4
  import { InstanceCoordinatorPort } from './instance-coordinator';
5
+ /**
6
+ * A rolled-back transition is a returned value, not a thrown error: the Host
7
+ * still has to settle readiness for everything the attempt touched before the
8
+ * caller's rejection is raised. Only fail-closed — where no consistent state
9
+ * could be restored — throws out of `transition()`.
10
+ */
5
11
  export type TransitionOutcome = {
6
12
  readonly kind: "committed";
7
13
  readonly affected: ReadonlySet<InstallationRecord>;
@@ -11,7 +17,14 @@ export type TransitionOutcome = {
11
17
  readonly error: unknown;
12
18
  };
13
19
  type ServiceAvailability = "available" | "unavailable";
14
- /** Owns the committed plan and its commit, rollback and fail-closed transitions. */
20
+ /**
21
+ * Owns the committed plan and its commit, rollback and fail-closed transitions.
22
+ *
23
+ * `#plan` is the single definition of "committed". It is assigned only after an
24
+ * activation succeeds and cleared whenever no consistent graph exists, so
25
+ * `hasCommittedPlan` is the honest answer to whether this Host can serve reads —
26
+ * there is no second flag that could disagree with it.
27
+ */
15
28
  export declare class Engine {
16
29
  #private;
17
30
  constructor(port: InstanceCoordinatorPort);
@@ -21,6 +34,20 @@ export declare class Engine {
21
34
  buildPlan(installations: Iterable<InstallationRecord>): InstallationGraph;
22
35
  start(plan: InstallationGraph): Promise<void>;
23
36
  stop(): Promise<unknown[]>;
37
+ /**
38
+ * The whole transaction, in the order the steps have to happen.
39
+ *
40
+ * Configs resolve and Contract identities draft *before* anything stops,
41
+ * because those are the failures that can still be taken back for free — a
42
+ * schema rejection at this point costs nothing. Once the affected Instances
43
+ * are down, every remaining failure has a price, and the only question left is
44
+ * whether the previous state can be restored.
45
+ *
46
+ * The whole body runs inside one contribution batch, so contributions
47
+ * withdrawn by stopping Instances and added by starting ones become visible in
48
+ * a single step. Without it, an ExtensionPoint observer would see the set
49
+ * briefly empty in the middle of a successful change.
50
+ */
24
51
  transition(nextPlan: InstallationGraph, changed: ReadonlySet<InstallationRecord>, restoreDeclarations: () => void): Promise<TransitionOutcome>;
25
52
  }
26
53
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAA;CAAE,GAClF;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEN,KAAK,mBAAmB,GAAG,WAAW,GAAG,aAAa,CAAC;AAEvD,oFAAoF;AACpF,qBAAa,MAAM;;gBAKL,IAAI,EAAE,uBAAuB;IAIzC,IAAI,gBAAgB,YAEnB;IAED,GAAG,CAAC,CAAC,EACH,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,EAC5C,YAAY,EAAE,mBAAmB,GAChC,CAAC,GAAG,SAAS;IAoBhB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAMzC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IAI/C,KAAK,CAAC,IAAI,EAAE,iBAAiB;IAY7B,IAAI;IAQJ,UAAU,CACd,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,WAAW,CAAC,kBAAkB,CAAC,EACxC,mBAAmB,EAAE,MAAM,IAAI,GAC9B,OAAO,CAAC,iBAAiB,CAAC;CAsI9B"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,wBAAwB,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAA;CAAE,GAClF;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEN,KAAK,mBAAmB,GAAG,WAAW,GAAG,aAAa,CAAC;AAEvD;;;;;;;GAOG;AACH,qBAAa,MAAM;;gBAKL,IAAI,EAAE,uBAAuB;IAIzC,IAAI,gBAAgB,YAEnB;IAED,GAAG,CAAC,CAAC,EACH,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,EAC5C,YAAY,EAAE,mBAAmB,GAChC,CAAC,GAAG,SAAS;IAoBhB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAMzC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IAI/C,KAAK,CAAC,IAAI,EAAE,iBAAiB;IAY7B,IAAI;IAQV;;;;;;;;;;;;;OAaG;IACG,UAAU,CACd,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,WAAW,CAAC,kBAAkB,CAAC,EACxC,mBAAmB,EAAE,MAAM,IAAI,GAC9B,OAAO,CAAC,iBAAiB,CAAC;CA0J9B"}
package/dist/errors.d.ts CHANGED
@@ -4,18 +4,55 @@ export declare class DougongError extends Error {
4
4
  readonly code: string;
5
5
  constructor(code: string, message: string, options?: ErrorOptions);
6
6
  }
7
+ /** Bounded diagnostic values, with no references to the failed object graph. */
8
+ export interface ErrorSnapshot {
9
+ readonly name: string;
10
+ readonly message: string;
11
+ readonly code?: string;
12
+ readonly stack?: string;
13
+ readonly cause?: ErrorSnapshot;
14
+ readonly errors?: ReadonlyArray<ErrorSnapshot>;
15
+ readonly manifestName?: string;
16
+ readonly denied?: ReadonlyArray<string>;
17
+ readonly issues?: ReadonlyArray<{
18
+ readonly message: string;
19
+ readonly path?: ReadonlyArray<string | number>;
20
+ }>;
21
+ readonly truncated?: true;
22
+ }
7
23
  /**
8
- * A primitive-only record of an Error for terminal objects that must not retain
9
- * the original stack, cause, subclass fields or the object graph behind them.
24
+ * A terminal failure is a record, never a reconstruction of the original class.
25
+ * Operations still reject with their live error; retained terminal handles use
26
+ * this class so causes and custom fields cannot retain application resources.
10
27
  */
11
- export declare class ErrorSummary {
12
- #private;
28
+ export declare class RecordedFailure extends Error {
29
+ readonly name = "RecordedFailure";
30
+ readonly code: string | undefined;
31
+ readonly snapshot: ErrorSnapshot;
13
32
  constructor(error: Error);
14
- restore(createCodedError?: (code: string, message: string) => Error): TypeError;
15
33
  }
16
- /** Preserves explicit Error values and classifies non-Error rejection reasons. */
34
+ /**
35
+ * Preserves explicit Error values and classifies non-Error rejection reasons.
36
+ *
37
+ * `throw "nope"` in a Plugin must not become an unnamed failure at the Host
38
+ * boundary, so a non-Error reason is wrapped in a coded Error with the original
39
+ * kept as `cause`. A real Error is returned untouched — Core never rewrites a
40
+ * failure a Plugin author deliberately threw.
41
+ *
42
+ * The private marker class is why re-normalizing is safe: a wrapper that already
43
+ * belongs to Core can be re-coded as it passes an outer boundary instead of
44
+ * being wrapped a second time.
45
+ */
17
46
  export declare function normalizeFailure(error: unknown, code: string, message: string): Error;
18
- /** Classifies the exact signal reason or a conventional AbortError, but only after abort. */
47
+ /**
48
+ * Classifies the exact signal reason or a conventional AbortError, but only
49
+ * after abort.
50
+ *
51
+ * This is the one place Core is allowed to stop propagating a failure, so the
52
+ * test is deliberately narrow. Checking `signal.aborted` first means an
53
+ * `AbortError` thrown by unrelated code on a live signal stays a real error, and
54
+ * only a cancellation that this Lifetime actually requested is treated as one.
55
+ */
19
56
  export declare function isCancellationReason(signal: AbortSignal, error: unknown): boolean;
20
57
  export declare class ConfigValidationError extends DougongError {
21
58
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,qBAAa,YAAa,SAAQ,KAAK;IAC5B,IAAI,SAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAQlE;AAeD;;;GAGG;AACH,qBAAa,YAAY;;gBAGX,KAAK,EAAE,KAAK;IAsBxB,OAAO,CACL,gBAAgB,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,KACpB;CAepC;AAuBD,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAKrF;AAED,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,WAcvE;AAED,qBAAa,qBAAsB,SAAQ,YAAY;IAC5C,IAAI,SAA2B;IACxC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAE3C,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC;CAQ1D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,qBAAa,YAAa,SAAQ,KAAK;IAC5B,IAAI,SAAkB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAQlE;AAED,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;QAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;KAChD,CAAC,CAAC;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;CAC3B;AAED;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAkB,IAAI,qBAAqB;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;gBAErB,KAAK,EAAE,KAAK;CAUzB;AAuGD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAKrF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,WAcvE;AAED,qBAAa,qBAAsB,SAAQ,YAAY;IAC5C,IAAI,SAA2B;IACxC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAE3C,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC;CAQ1D"}
@@ -1,13 +1,24 @@
1
1
  import { Disposable, Publication, StagedResource } from './resource';
2
2
  export type EventListener<T> = (payload: T) => unknown;
3
3
  interface ListenerSlot<T> {
4
- readonly listener: EventListener<T>;
4
+ listener: EventListener<T> | undefined;
5
5
  }
6
6
  export declare class EventHub {
7
7
  #private;
8
8
  stage<T>(eventId: string, listener: EventListener<T>, release: (publication: Publication) => void): StagedResource<Disposable>;
9
9
  add<T>(eventId: string, slot: ListenerSlot<T>): void;
10
10
  delete<T>(eventId: string, slot: ListenerSlot<T>): void;
11
+ /**
12
+ * Every still-subscribed listener runs, then failures are aggregated. Three details, all
13
+ * deliberate:
14
+ *
15
+ * - the listener set is copied first; a new subscription does not join this
16
+ * emission. A disposed slot is skipped if its callback has not started;
17
+ * - each call is wrapped in a resolved promise, so a listener that throws
18
+ * synchronously is collected like one that rejects;
19
+ * - `allSettled`, so one broken listener cannot stop the others from being
20
+ * told. The emitter still learns about it — every error comes back.
21
+ */
11
22
  emit<T>(eventId: string, payload: T): Promise<void>;
12
23
  }
13
24
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"event-hub.d.ts","sourceRoot":"","sources":["../src/event-hub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnG,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC;AAEvD,UAAU,YAAY,CAAC,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CACrC;AAqED,qBAAa,QAAQ;;IAGnB,KAAK,CAAC,CAAC,EACL,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,GAC1C,cAAc,CAAC,UAAU,CAAC;IAK7B,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAM7C,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAO1C,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;CAe1C"}
1
+ {"version":3,"file":"event-hub.d.ts","sourceRoot":"","sources":["../src/event-hub.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnG,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC;AAEvD,UAAU,YAAY,CAAC,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACxC;AAsED,qBAAa,QAAQ;;IAGnB,KAAK,CAAC,CAAC,EACL,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,GAC1C,cAAc,CAAC,UAAU,CAAC;IAK7B,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAM7C,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAOhD;;;;;;;;;;OAUG;IACG,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;CAa1C"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * One explicit transaction shared by every nested Group configure callback.
3
+ *
4
+ * Nested `group()` calls join the outer session instead of opening their own, so
5
+ * a whole tree of groups declared in one statement commits once. A failure
6
+ * anywhere in that tree fails the session, which is why `fail()` records the
7
+ * first error and later calls return it unchanged: the cause of a collapsed tree
8
+ * is the first thing that went wrong, not the last.
9
+ */
10
+ export declare class GroupConfigurationSession<Draft> {
11
+ #private;
12
+ constructor(draft: Draft, discard: (draft: Draft, error: unknown) => void, normalize: (error: unknown) => Error);
13
+ get failure(): Error | undefined;
14
+ requireDraft(): Draft;
15
+ assertOpen(): void;
16
+ fail(error: unknown): Error;
17
+ seal(): Draft;
18
+ discard(error: unknown): void;
19
+ }
20
+ //# sourceMappingURL=group-configuration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-configuration.d.ts","sourceRoot":"","sources":["../src/group-configuration.ts"],"names":[],"mappings":"AAeA;;;;;;;;GAQG;AACH,qBAAa,yBAAyB,CAAC,KAAK;;gBAIxC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EAC/C,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK;IAKtC,IAAI,OAAO,sBAEV;IAED,YAAY;IAOZ,UAAU;IAIV,IAAI,CAAC,KAAK,EAAE,OAAO;IAcnB,IAAI;IAQJ,OAAO,CAAC,KAAK,EAAE,OAAO;CAOvB"}
@@ -1,6 +1,7 @@
1
1
  import { Group, Installation, PluginConfigArguments } from './host-api';
2
2
  import { ChangeSetDraft, ChangeOperation } from './change-set';
3
- import { GroupConfigurationSession, GroupNode } from './group';
3
+ import { GroupNode } from './group';
4
+ import { GroupConfigurationSession } from './group-configuration';
4
5
  import { InstallationRecord } from './installation';
5
6
  import { LifecycleStatus } from './lifecycle-status';
6
7
  import { AnyPlugin, NormalizedPlugin } from './plugin';
@@ -30,7 +31,18 @@ declare class GroupFacade implements Group {
30
31
  group(name: string, configure: (group: Group) => void): GroupFacade;
31
32
  remove(): Promise<void>;
32
33
  }
33
- /** Owns the complete structural Group model and compiles it to Installation changes. */
34
+ /**
35
+ * Owns the complete structural Group model and compiles it to Installation
36
+ * changes.
37
+ *
38
+ * Groups are structure, and the Engine only understands installations, so
39
+ * everything here ends as a `ChangeOperation` list. Removing a Group is not its
40
+ * own kind of command — it is the removal of every Installation the subtree
41
+ * contains, followed by detaching the nodes.
42
+ *
43
+ * Lifecycles and facades are held in WeakMaps keyed by node rather than as node
44
+ * fields, so `GroupNode` stays pure structure and a revoked facade releases both.
45
+ */
34
46
  export declare class GroupCoordinator {
35
47
  #private;
36
48
  readonly root: GroupNode;
@@ -38,6 +50,12 @@ export declare class GroupCoordinator {
38
50
  nodes(): GroupNode[];
39
51
  install<Declaration extends AnyPlugin>(group: GroupNode, plugin: Declaration, ...config: PluginConfigArguments<Declaration>): Installation<Declaration>;
40
52
  stageConfigurationInstall<Declaration extends AnyPlugin>(group: GroupNode, configuration: GroupConfigurationSession<ChangeSetDraft>, plugin: Declaration, ...config: PluginConfigArguments<Declaration>): Installation<Declaration>;
53
+ /**
54
+ * `deferred` tracking exists for `create()`. A Group being configured must not
55
+ * mark itself pending on each nested install, because the whole configuration
56
+ * commits once; the coordinator attaches that single operation to every node in
57
+ * the finished subtree instead.
58
+ */
41
59
  change(group: GroupNode, tracking?: "immediate" | "deferred"): ChangeSetDraft;
42
60
  create(parent: GroupNode, name: string, configure: (group: Group) => void, inherited?: GroupConfigurationSession<ChangeSetDraft>): GroupFacade;
43
61
  ready(group: GroupNode): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"group-coordinator.d.ts","sourceRoot":"","sources":["../src/group-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"group-coordinator.d.ts","sourceRoot":"","sources":["../src/group-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAGL,cAAc,EACd,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC3D,QAAQ,CAAC,WAAW,EAAE,CACpB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,OAAO,KACZ;QAAE,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAA;KAAE,CAAC;IACvF,QAAQ,CAAC,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC3E,QAAQ,CAAC,cAAc,EAAE,CACvB,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,KACvC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,kBAAkB,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACxE,QAAQ,CAAC,mBAAmB,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzF,QAAQ,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,QAAQ,CAAC,mBAAmB,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;CACpC;AAkBD,cAAM,WAAY,YAAW,KAAK;;gBAK9B,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,SAAS,EACf,aAAa,CAAC,EAAE,yBAAyB,CAAC,cAAc,CAAC;IAoB3D,IAAI,EAAE,WAEL;IAED,IAAI,IAAI,WAEP;IAED,IAAI,MAAM,oBAGT;IAED,KAAK;IAOL,OAAO,CAAC,WAAW,SAAS,SAAS,EACnC,MAAM,EAAE,WAAW,EACnB,GAAG,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC;IAc/C,MAAM;IAON,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;IAWrD,MAAM;CAaP;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB;;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;gBAKb,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB;IASxD,KAAK;IAIL,OAAO,CAAC,WAAW,SAAS,SAAS,EACnC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,WAAW,EACnB,GAAG,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC5C,YAAY,CAAC,WAAW,CAAC;IAO5B,yBAAyB,CAAC,WAAW,SAAS,SAAS,EACrD,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,yBAAyB,CAAC,cAAc,CAAC,EACxD,MAAM,EAAE,WAAW,EACnB,GAAG,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC,GAC5C,YAAY,CAAC,WAAW,CAAC;IAa5B;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,GAAE,WAAW,GAAG,UAAwB;IA+BzE,MAAM,CACJ,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EACjC,SAAS,CAAC,EAAE,yBAAyB,CAAC,cAAc,CAAC;IAoDjD,KAAK,CAAC,KAAK,EAAE,SAAS;IAM5B,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe;IAKzC,MAAM,CAAC,KAAK,EAAE,SAAS;CAsExB"}
@@ -12,6 +12,19 @@ export declare class GroupLifecycle {
12
12
  constructor(node: GroupNode, initialState: "new" | "established", notifyChanged: () => void);
13
13
  status(contents: LifecycleStatus): LifecycleStatus;
14
14
  ready(readyContents: () => Promise<void>): Promise<void>;
15
+ /**
16
+ * `preserveCommittedState` is the whole point of this class.
17
+ *
18
+ * A Group that has already committed something is established, and a later
19
+ * failed change does not un-establish it — the transaction rolled back, so the
20
+ * state the Group describes is still the one that was committed. Such a
21
+ * failure leaves the phase at `established` and does not rethrow, because the
22
+ * caller of the failed change already has the error.
23
+ *
24
+ * A Group whose *first* change fails never had a committed state, so it does
25
+ * become `failed` and the failure propagates: there is nothing to report but
26
+ * the failure.
27
+ */
15
28
  track(operation: Promise<void>): void;
16
29
  release(): void;
17
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"group-lifecycle.d.ts","sourceRoot":"","sources":["../src/group-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;GAIG;AACH,qBAAa,cAAc;;IAKvB,QAAQ,CAAC,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACxB,YAAY,EAAE,KAAK,GAAG,aAAa,EACnC,aAAa,EAAE,MAAM,IAAI;IAM3B,MAAM,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe;IAQ5C,KAAK,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAU9C,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC;IAwC9B,OAAO;CASR;AAaD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,gBAEjD"}
1
+ {"version":3,"file":"group-lifecycle.d.ts","sourceRoot":"","sources":["../src/group-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;GAIG;AACH,qBAAa,cAAc;;IAKvB,QAAQ,CAAC,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACxB,YAAY,EAAE,KAAK,GAAG,aAAa,EACnC,aAAa,EAAE,MAAM,IAAI;IAM3B,MAAM,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe;IAQ5C,KAAK,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAU9C;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC;IAwC9B,OAAO;CASR;AAaD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,gBAEjD"}
package/dist/group.d.ts CHANGED
@@ -1,17 +1,11 @@
1
- /** One explicit transaction shared by every nested Group configure callback. */
2
- export declare class GroupConfigurationSession<Draft> {
3
- #private;
4
- constructor(draft: Draft, discard: (draft: Draft, error: unknown) => void, normalize: (error: unknown) => Error);
5
- get failure(): Error | undefined;
6
- requireDraft(): Draft;
7
- assertOpen(): void;
8
- fail(error: unknown): Error;
9
- seal(): Draft;
10
- discard(error: unknown): void;
11
- }
12
1
  /**
13
2
  * A Group is an ownership tree over installations, never a capability scope.
14
3
  * Service resolution and ExtensionPoint/Event visibility remain Host-wide.
4
+ *
5
+ * So a Plugin inside a Group sees exactly what it would see outside one: the
6
+ * same providers, the same contributions. The only thing membership decides is
7
+ * what gets removed together. Ids are paths (`/ui/panels`) because a position in
8
+ * this tree is the whole meaning of a Group.
15
9
  */
16
10
  export declare class GroupNode {
17
11
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAeA,gFAAgF;AAChF,qBAAa,yBAAyB,CAAC,KAAK;;gBAIxC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EAC/C,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK;IAKtC,IAAI,OAAO,sBAEV;IAED,YAAY;IAOZ,UAAU;IAIV,IAAI,CAAC,KAAK,EAAE,OAAO;IAcnB,IAAI;IAQJ,OAAO,CAAC,KAAK,EAAE,OAAO;CAOvB;AAUD;;;GAGG;AACH,qBAAa,SAAS;;IAKlB,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAFvB,OAAO;IAQP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;IAIxB,IAAI,QAAQ,YAEX;IAED,IAAI,QAAQ,IAAI,aAAa,CAAC,SAAS,CAAC,CAEvC;IAED,IAAI,MAAM,IAAI,SAAS,GAAG,SAAS,CAGlC;IAED,MAAM,CAAC,IAAI,EAAE,MAAM;IAWnB,QAAQ,CAAC,SAAS,EAAE,SAAS;IAQ7B,cAAc;IAMd,MAAM;IASN,IAAI;CAYL"}
1
+ {"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,qBAAa,SAAS;;IAKlB,QAAQ,CAAC,EAAE,EAAE,MAAM;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAFvB,OAAO;IAQP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;IAIxB,IAAI,QAAQ,YAEX;IAED,IAAI,QAAQ,IAAI,aAAa,CAAC,SAAS,CAAC,CAEvC;IAED,IAAI,MAAM,IAAI,SAAS,GAAG,SAAS,CAGlC;IAED,MAAM,CAAC,IAAI,EAAE,MAAM;IAWnB,QAAQ,CAAC,SAAS,EAAE,SAAS;IAO7B,cAAc;IAUd,MAAM;IASN,IAAI;CAYL"}
@@ -21,7 +21,18 @@ type AnyPluginInstallationUpdate = {
21
21
  readonly plugin?: never;
22
22
  readonly config: unknown;
23
23
  };
24
+ /**
25
+ * What one `update()` may change. The union requires at least one of `plugin`
26
+ * and `config`, so an empty update is a compile error rather than a transaction
27
+ * that commits nothing. Replacing the Plugin keeps the Installation's identity
28
+ * and position — only its declaration moves.
29
+ */
24
30
  export type InstallationUpdate<Declaration extends AnyPlugin = AnyPlugin> = Declaration extends Plugin<infer Config, infer Requires, infer Provides, infer ConfigInput> ? DeclaredInstallationUpdate<Config, Requires, Provides, ConfigInput> : AnyPluginInstallationUpdate;
31
+ /**
32
+ * Makes the config argument required exactly when the Plugin declares one, so
33
+ * `install(needsConfig)` fails to compile while `install(needsNothing)` stays a
34
+ * one-argument call.
35
+ */
25
36
  export type PluginConfigArguments<Declaration extends AnyPlugin> = Declaration extends Plugin<infer _Config, infer _Requires, infer _Provides, infer ConfigInput> ? [ConfigInput] extends [void] ? [config?: ConfigInput] : [config: ConfigInput] : [config?: unknown];
26
37
  /**
27
38
  * One installed Plugin, as a stable identity. The declaration behind it may be
@@ -47,6 +58,14 @@ export interface Installation<Declaration extends AnyPlugin = AnyPlugin> {
47
58
  readonly update: (update: InstallationUpdate<Declaration>) => Promise<void>;
48
59
  remove(): Promise<void>;
49
60
  }
61
+ /**
62
+ * One transaction. Staged operations apply together or not at all, so a batch
63
+ * that would leave a missing dependency between two of its own steps is valid —
64
+ * only the committed end state has to resolve.
65
+ *
66
+ * `group()` is deliberately absent: a ChangeSet moves installations, and Group
67
+ * structure is created through an `Installer`.
68
+ */
50
69
  export interface ChangeSet extends Pick<Installer, "install"> {
51
70
  update<Declaration extends AnyPlugin>(installation: Installation<Declaration>, update: InstallationUpdate<Declaration>): void;
52
71
  remove<Declaration extends AnyPlugin>(installation: Installation<Declaration>): void;
@@ -55,6 +74,11 @@ export interface ChangeSet extends Pick<Installer, "install"> {
55
74
  export interface HostOptions {
56
75
  readonly name?: string;
57
76
  readonly logger?: Logger;
77
+ /**
78
+ * Terminal sink for failures with nowhere left to propagate — a background
79
+ * task's rejection, a diagnostics subscriber that threw. It does not see
80
+ * errors from `start()` or `commit()`; those are returned to their caller.
81
+ */
58
82
  readonly onError?: (error: unknown) => Awaitable<void>;
59
83
  }
60
84
  /** Capability to install into an ownership position without controlling Host execution. */
@@ -71,6 +95,15 @@ export interface Group extends Installer {
71
95
  ready(): Promise<void>;
72
96
  remove(): Promise<void>;
73
97
  }
98
+ /**
99
+ * The execution boundary Dougong owns: commands, transactions, orchestration.
100
+ *
101
+ * `get()` and `contributions()` are for application code — the code that embeds
102
+ * Dougong from outside the graph. A Plugin never reaches its dependencies this
103
+ * way; it declares them in `requires` and receives them as context. That is the
104
+ * difference between a declared dependency and a Service Locator, and it is why
105
+ * `Host` is not reachable from `PluginContext`.
106
+ */
74
107
  export interface Host extends Installer {
75
108
  readonly name: string;
76
109
  readonly status: HostStatus;