@inhuman.tools/plexus-expectations 0.0.0-stage → 0.1.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 (160) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +144 -2
  3. package/dist/driver/ExpectationActor.d.ts +56 -0
  4. package/dist/driver/ExpectationActor.d.ts.map +1 -0
  5. package/dist/driver/ExpectationActor.js +210 -0
  6. package/dist/driver/ExpectationActor.js.map +1 -0
  7. package/dist/driver/PEWDriver.d.ts +144 -0
  8. package/dist/driver/PEWDriver.d.ts.map +1 -0
  9. package/dist/driver/PEWDriver.js +303 -0
  10. package/dist/driver/PEWDriver.js.map +1 -0
  11. package/dist/driver/PEWDriverConnection.d.ts +139 -0
  12. package/dist/driver/PEWDriverConnection.d.ts.map +1 -0
  13. package/dist/driver/PEWDriverConnection.js +298 -0
  14. package/dist/driver/PEWDriverConnection.js.map +1 -0
  15. package/dist/driver/actor-machine.d.ts +28 -0
  16. package/dist/driver/actor-machine.d.ts.map +1 -0
  17. package/dist/driver/actor-machine.js +50 -0
  18. package/dist/driver/actor-machine.js.map +1 -0
  19. package/dist/driver/connection-miss.d.ts +9 -0
  20. package/dist/driver/connection-miss.d.ts.map +1 -0
  21. package/dist/driver/connection-miss.js +13 -0
  22. package/dist/driver/connection-miss.js.map +1 -0
  23. package/dist/driver/index.d.ts +6 -0
  24. package/dist/driver/index.d.ts.map +1 -0
  25. package/dist/driver/index.js +5 -0
  26. package/dist/driver/index.js.map +1 -0
  27. package/dist/error-with-invariant.d.ts +9 -0
  28. package/dist/error-with-invariant.d.ts.map +1 -0
  29. package/dist/error-with-invariant.js +12 -0
  30. package/dist/error-with-invariant.js.map +1 -0
  31. package/dist/executor/index.d.ts +4 -0
  32. package/dist/executor/index.d.ts.map +1 -0
  33. package/dist/executor/index.js +4 -0
  34. package/dist/executor/index.js.map +1 -0
  35. package/dist/executor/kernel-intern.d.ts +16 -0
  36. package/dist/executor/kernel-intern.d.ts.map +1 -0
  37. package/dist/executor/kernel-intern.js +98 -0
  38. package/dist/executor/kernel-intern.js.map +1 -0
  39. package/dist/executor/orchestrator.d.ts +97 -0
  40. package/dist/executor/orchestrator.d.ts.map +1 -0
  41. package/dist/executor/orchestrator.js +465 -0
  42. package/dist/executor/orchestrator.js.map +1 -0
  43. package/dist/executor/types.d.ts +8 -0
  44. package/dist/executor/types.d.ts.map +1 -0
  45. package/dist/executor/types.js +2 -0
  46. package/dist/executor/types.js.map +1 -0
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +2 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/schemas/connection.d.ts +4 -0
  52. package/dist/schemas/connection.d.ts.map +1 -0
  53. package/dist/schemas/connection.js +4 -0
  54. package/dist/schemas/connection.js.map +1 -0
  55. package/dist/schemas/index.d.ts +2 -0
  56. package/dist/schemas/index.d.ts.map +1 -0
  57. package/dist/schemas/index.js +2 -0
  58. package/dist/schemas/index.js.map +1 -0
  59. package/dist/shared/attention.d.ts +27 -0
  60. package/dist/shared/attention.d.ts.map +1 -0
  61. package/dist/shared/attention.js +116 -0
  62. package/dist/shared/attention.js.map +1 -0
  63. package/dist/shared/control.d.ts +4 -0
  64. package/dist/shared/control.d.ts.map +1 -0
  65. package/dist/shared/control.js +2 -0
  66. package/dist/shared/control.js.map +1 -0
  67. package/dist/shared/index.d.ts +7 -0
  68. package/dist/shared/index.d.ts.map +1 -0
  69. package/dist/shared/index.js +7 -0
  70. package/dist/shared/index.js.map +1 -0
  71. package/dist/shared/map-field-awareness.d.ts +19 -0
  72. package/dist/shared/map-field-awareness.d.ts.map +1 -0
  73. package/dist/shared/map-field-awareness.js +58 -0
  74. package/dist/shared/map-field-awareness.js.map +1 -0
  75. package/dist/shared/models/ApprovableExpectation.d.ts +15 -0
  76. package/dist/shared/models/ApprovableExpectation.d.ts.map +1 -0
  77. package/dist/shared/models/ApprovableExpectation.js +138 -0
  78. package/dist/shared/models/ApprovableExpectation.js.map +1 -0
  79. package/dist/shared/models/ConnectionSpec.d.ts +44 -0
  80. package/dist/shared/models/ConnectionSpec.d.ts.map +1 -0
  81. package/dist/shared/models/ConnectionSpec.js +180 -0
  82. package/dist/shared/models/ConnectionSpec.js.map +1 -0
  83. package/dist/shared/models/DriverSpec.d.ts +45 -0
  84. package/dist/shared/models/DriverSpec.d.ts.map +1 -0
  85. package/dist/shared/models/DriverSpec.js +221 -0
  86. package/dist/shared/models/DriverSpec.js.map +1 -0
  87. package/dist/shared/models/IntrospectingPlexusModel.d.ts +8 -0
  88. package/dist/shared/models/IntrospectingPlexusModel.d.ts.map +1 -0
  89. package/dist/shared/models/IntrospectingPlexusModel.js +48 -0
  90. package/dist/shared/models/IntrospectingPlexusModel.js.map +1 -0
  91. package/dist/shared/models/Job.d.ts +85 -0
  92. package/dist/shared/models/Job.d.ts.map +1 -0
  93. package/dist/shared/models/Job.js +261 -0
  94. package/dist/shared/models/Job.js.map +1 -0
  95. package/dist/shared/models/ProgrammaticJob.d.ts +6 -0
  96. package/dist/shared/models/ProgrammaticJob.d.ts.map +1 -0
  97. package/dist/shared/models/ProgrammaticJob.js +80 -0
  98. package/dist/shared/models/ProgrammaticJob.js.map +1 -0
  99. package/dist/shared/models/WorkContainer.d.ts +36 -0
  100. package/dist/shared/models/WorkContainer.d.ts.map +1 -0
  101. package/dist/shared/models/WorkContainer.js +140 -0
  102. package/dist/shared/models/WorkContainer.js.map +1 -0
  103. package/dist/shared/models/WorkExpectation.d.ts +63 -0
  104. package/dist/shared/models/WorkExpectation.d.ts.map +1 -0
  105. package/dist/shared/models/WorkExpectation.js +290 -0
  106. package/dist/shared/models/WorkExpectation.js.map +1 -0
  107. package/dist/shared/models/WorkExpectationWithIntrospection.d.ts +4 -0
  108. package/dist/shared/models/WorkExpectationWithIntrospection.d.ts.map +1 -0
  109. package/dist/shared/models/WorkExpectationWithIntrospection.js +28 -0
  110. package/dist/shared/models/WorkExpectationWithIntrospection.js.map +1 -0
  111. package/dist/shared/models/index.d.ts +7 -0
  112. package/dist/shared/models/index.d.ts.map +1 -0
  113. package/dist/shared/models/index.js +6 -0
  114. package/dist/shared/models/index.js.map +1 -0
  115. package/dist/shared/models/jsonRecord.d.ts +14 -0
  116. package/dist/shared/models/jsonRecord.d.ts.map +1 -0
  117. package/dist/shared/models/jsonRecord.js +46 -0
  118. package/dist/shared/models/jsonRecord.js.map +1 -0
  119. package/dist/shared/resolution.d.ts +39 -0
  120. package/dist/shared/resolution.d.ts.map +1 -0
  121. package/dist/shared/resolution.js +124 -0
  122. package/dist/shared/resolution.js.map +1 -0
  123. package/dist/shared/revalidation-demand.d.ts +27 -0
  124. package/dist/shared/revalidation-demand.d.ts.map +1 -0
  125. package/dist/shared/revalidation-demand.js +116 -0
  126. package/dist/shared/revalidation-demand.js.map +1 -0
  127. package/dist/shared/role.d.ts +12 -0
  128. package/dist/shared/role.d.ts.map +1 -0
  129. package/dist/shared/role.js +21 -0
  130. package/dist/shared/role.js.map +1 -0
  131. package/dist/shared/types.d.ts +43 -0
  132. package/dist/shared/types.d.ts.map +1 -0
  133. package/dist/shared/types.js +12 -0
  134. package/dist/shared/types.js.map +1 -0
  135. package/package.json +79 -3
  136. package/src/driver/ExpectationActor.ts +244 -0
  137. package/src/driver/PEWDriver.ts +302 -0
  138. package/src/driver/actor-machine.ts +54 -0
  139. package/src/driver/connection-miss.ts +13 -0
  140. package/src/driver/index.ts +5 -0
  141. package/src/executor/index.ts +3 -0
  142. package/src/executor/kernel-intern.ts +121 -0
  143. package/src/executor/orchestrator.ts +463 -0
  144. package/src/executor/types.ts +3 -0
  145. package/src/index.ts +1 -0
  146. package/src/schemas/connection.ts +4 -0
  147. package/src/schemas/index.ts +1 -0
  148. package/src/shared/control.ts +4 -0
  149. package/src/shared/index.ts +6 -0
  150. package/src/shared/map-field-awareness.ts +65 -0
  151. package/src/shared/models/ConnectionSpec.ts +84 -0
  152. package/src/shared/models/DriverSpec.ts +102 -0
  153. package/src/shared/models/Job.ts +192 -0
  154. package/src/shared/models/WorkContainer.ts +90 -0
  155. package/src/shared/models/WorkExpectation.ts +229 -0
  156. package/src/shared/models/index.ts +6 -0
  157. package/src/shared/models/jsonRecord.ts +49 -0
  158. package/src/shared/revalidation-demand.ts +121 -0
  159. package/src/shared/role.ts +32 -0
  160. package/src/shared/types.ts +57 -0
@@ -0,0 +1,140 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ /**
36
+ * Work graph node. `work` may be a synced list or a computed getter.
37
+ * Walking `.work` from the document root is the whole out-reachable set.
38
+ *
39
+ * Brand is on this class — do not duck-type `.work`.
40
+ *
41
+ * Thenable. The fulfillment is not `this` — a thenable that resolves to itself
42
+ * never settles. This class settles when `endedAtMs` is set, fulfills
43
+ * `undefined`, and does not reject. {@link WorkExpectation} fulfills its
44
+ * outcome. {@link Job} fulfills or rejects from `result`. The promise value
45
+ * here is `unknown` so both stay containers.
46
+ */
47
+ import { PlexusModel, syncing } from "@here.build/plexus";
48
+ import { when } from "mobx";
49
+ export const workContainer = Symbol.for("work:container");
50
+ let WorkContainer = (() => {
51
+ let _classDecorators = [syncing("@inhuman.tools/plexus-expectations:WorkContainer")];
52
+ let _classDescriptor;
53
+ let _classExtraInitializers = [];
54
+ let _classThis;
55
+ let _classSuper = PlexusModel;
56
+ let _startedAtMs_decorators;
57
+ let _startedAtMs_initializers = [];
58
+ let _startedAtMs_extraInitializers = [];
59
+ let _endedAtMs_decorators;
60
+ let _endedAtMs_initializers = [];
61
+ let _endedAtMs_extraInitializers = [];
62
+ var WorkContainer = class extends _classSuper {
63
+ static { _classThis = this; }
64
+ static {
65
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
66
+ __esDecorate(this, null, _startedAtMs_decorators, { kind: "accessor", name: "startedAtMs", static: false, private: false, access: { has: obj => "startedAtMs" in obj, get: obj => obj.startedAtMs, set: (obj, value) => { obj.startedAtMs = value; } }, metadata: _metadata }, _startedAtMs_initializers, _startedAtMs_extraInitializers);
67
+ __esDecorate(this, null, _endedAtMs_decorators, { kind: "accessor", name: "endedAtMs", static: false, private: false, access: { has: obj => "endedAtMs" in obj, get: obj => obj.endedAtMs, set: (obj, value) => { obj.endedAtMs = value; } }, metadata: _metadata }, _endedAtMs_initializers, _endedAtMs_extraInitializers);
68
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
69
+ WorkContainer = _classThis = _classDescriptor.value;
70
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
71
+ __runInitializers(_classThis, _classExtraInitializers);
72
+ }
73
+ [workContainer] = true;
74
+ #settledPromise = null;
75
+ #startedAtMs_accessor_storage = __runInitializers(this, _startedAtMs_initializers, null);
76
+ /** Epoch ms. Write-once. BODY / actor start — not mint, not the guard. */
77
+ get startedAtMs() { return this.#startedAtMs_accessor_storage; }
78
+ set startedAtMs(value) { this.#startedAtMs_accessor_storage = value; }
79
+ #endedAtMs_accessor_storage = (__runInitializers(this, _startedAtMs_extraInitializers), __runInitializers(this, _endedAtMs_initializers, null));
80
+ /** Epoch ms. Write-once. Job complete / PEW succeed|fail. This class's thenable settles on this. */
81
+ get endedAtMs() { return this.#endedAtMs_accessor_storage; }
82
+ set endedAtMs(value) { this.#endedAtMs_accessor_storage = value; }
83
+ markStarted(now = Date.now()) {
84
+ if (this.startedAtMs != null)
85
+ return;
86
+ this.startedAtMs = now;
87
+ }
88
+ markEnded(now = Date.now()) {
89
+ if (this.endedAtMs != null)
90
+ return;
91
+ this.endedAtMs = now;
92
+ }
93
+ /** Live: `now - startedAtMs`. Sealed: `endedAtMs - startedAtMs`. Null if start was never stamped. */
94
+ durationMs(now = Date.now()) {
95
+ if (this.startedAtMs == null || !Number.isFinite(this.startedAtMs))
96
+ return null;
97
+ const end = this.endedAtMs != null && Number.isFinite(this.endedAtMs) ? this.endedAtMs : now;
98
+ return Math.max(0, end - this.startedAtMs);
99
+ }
100
+ then(onfulfilled, onrejected) {
101
+ return this.#settled().then(onfulfilled, onrejected);
102
+ }
103
+ catch(onrejected) {
104
+ return this.#settled().catch(onrejected);
105
+ }
106
+ finally(onfinally) {
107
+ return this.#settled().finally(onfinally);
108
+ }
109
+ get [(_startedAtMs_decorators = [syncing], _endedAtMs_decorators = [syncing], Symbol.toStringTag)]() {
110
+ return "WorkContainer";
111
+ }
112
+ #settled() {
113
+ if (this.#settledPromise != null)
114
+ return this.#settledPromise;
115
+ const fulfill = () => undefined;
116
+ this.#settledPromise =
117
+ this.endedAtMs != null ? Promise.resolve(fulfill()) : when(() => this.endedAtMs != null).then(fulfill);
118
+ return this.#settledPromise;
119
+ }
120
+ constructor() {
121
+ super(...arguments);
122
+ __runInitializers(this, _endedAtMs_extraInitializers);
123
+ }
124
+ };
125
+ return WorkContainer = _classThis;
126
+ })();
127
+ export { WorkContainer };
128
+ /** Preorder walk of `.work`, cycle-safe. `item === container` stops a leaf `[this]` from recursing. */
129
+ export function* walkWork(container, seen = new Set()) {
130
+ for (const item of container.work) {
131
+ if (seen.has(item))
132
+ continue;
133
+ seen.add(item);
134
+ yield item;
135
+ if (item === container)
136
+ continue;
137
+ yield* walkWork(item, seen);
138
+ }
139
+ }
140
+ //# sourceMappingURL=WorkContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkContainer.js","sourceRoot":"","sources":["../../../src/shared/models/WorkContainer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Work graph node. `work` may be a synced list or a computed getter.\n * Walking `.work` from the document root is the whole out-reachable set.\n *\n * Brand is on this class — do not duck-type `.work`.\n *\n * Thenable. The fulfillment is not `this` — a thenable that resolves to itself\n * never settles. This class settles when `endedAtMs` is set, fulfills\n * `undefined`, and does not reject. {@link WorkExpectation} fulfills its\n * outcome. {@link Job} fulfills or rejects from `result`. The promise value\n * here is `unknown` so both stay containers.\n */\nimport { PlexusModel, syncing } from \"@here.build/plexus\";\nimport { when } from \"mobx\";\n\nexport const workContainer: unique symbol = Symbol.for(\"work:container\") as never;\n\n/** Base promise value. An expectation narrows it to the outcome; a job narrows it per class. */\nexport type WorkFulfillment = unknown;\n\n@syncing(\"@inhuman.tools/plexus-expectations:WorkContainer\")\nexport abstract class WorkContainer extends PlexusModel implements Promise<WorkFulfillment> {\n readonly [workContainer] = true as const;\n #settledPromise: Promise<WorkFulfillment> | null = null;\n\n /** Epoch ms. Write-once. BODY / actor start — not mint, not the guard. */\n @syncing accessor startedAtMs: number | null = null;\n /** Epoch ms. Write-once. Job complete / PEW succeed|fail. This class's thenable settles on this. */\n @syncing accessor endedAtMs: number | null = null;\n\n abstract readonly work: readonly WorkContainer[];\n\n markStarted(now = Date.now()): void {\n if (this.startedAtMs != null) return;\n this.startedAtMs = now;\n }\n\n markEnded(now = Date.now()): void {\n if (this.endedAtMs != null) return;\n this.endedAtMs = now;\n }\n\n /** Live: `now - startedAtMs`. Sealed: `endedAtMs - startedAtMs`. Null if start was never stamped. */\n durationMs(now = Date.now()): number | null {\n if (this.startedAtMs == null || !Number.isFinite(this.startedAtMs)) return null;\n const end =\n this.endedAtMs != null && Number.isFinite(this.endedAtMs) ? this.endedAtMs : now;\n return Math.max(0, end - this.startedAtMs);\n }\n\n then<TFulfilled = WorkFulfillment, TRejected = never>(\n onfulfilled?: ((value: WorkFulfillment) => TFulfilled | PromiseLike<TFulfilled>) | null,\n onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null,\n ): Promise<TFulfilled | TRejected> {\n return this.#settled().then(onfulfilled, onrejected);\n }\n\n catch<TRejected = never>(\n onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null,\n ): Promise<WorkFulfillment | TRejected> {\n return this.#settled().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<WorkFulfillment> {\n return this.#settled().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return \"WorkContainer\";\n }\n\n #settled(): Promise<WorkFulfillment> {\n if (this.#settledPromise != null) return this.#settledPromise;\n const fulfill = (): WorkFulfillment => undefined;\n this.#settledPromise =\n this.endedAtMs != null ? Promise.resolve(fulfill()) : when(() => this.endedAtMs != null).then(fulfill);\n return this.#settledPromise;\n }\n}\n\n/** Preorder walk of `.work`, cycle-safe. `item === container` stops a leaf `[this]` from recursing. */\nexport function* walkWork(container: WorkContainer, seen: Set<WorkContainer> = new Set()): Generator<WorkContainer> {\n for (const item of container.work) {\n if (seen.has(item)) continue;\n seen.add(item);\n yield item;\n if (item === container) continue;\n yield* walkWork(item, seen);\n }\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { type PlexusAwareness } from "@here.build/plexus";
2
+ import { type EndCause, type ExpectationOutcome } from "../control.js";
3
+ import type { SessionAwareness, SessionPlexus } from "../types.js";
4
+ import { WorkContainer } from "./WorkContainer.js";
5
+ /**
6
+ * Awareness: empty string occupies the role map without a report frame.
7
+ * Retract drops the uuid. Not a durable outcome.
8
+ */
9
+ export declare const ROLE_LANE_OCCUPIED = "";
10
+ export declare abstract class WorkExpectation<TResult = unknown, TReport = unknown> extends WorkContainer implements Promise<ExpectationOutcome> {
11
+ #private;
12
+ /**
13
+ * Kernel catalog key this work rides. Required at construction.
14
+ * Plexus materialization passes a symbol through unchanged.
15
+ */
16
+ accessor connectionId: string;
17
+ constructor(init: {
18
+ readonly connectionId: string;
19
+ } | symbol);
20
+ accessor outcome: ExpectationOutcome | null;
21
+ accessor endCause: EndCause | null;
22
+ accessor endDetail: string | null;
23
+ /** Durable last frame as JSON. `"null"` when the work ended without a report. */
24
+ accessor outcomeReport: string | null;
25
+ /** Last live role-map frame this process saw. Retract does not clear it. */
26
+ private accessor lastProgress;
27
+ get plexus(): SessionPlexus | null;
28
+ get awareness(): PlexusAwareness<SessionAwareness> | null;
29
+ /** Live progress as the fulfiller tells it. Awareness retract does not drop the last frame. */
30
+ get progressAwareness(): TReport | null;
31
+ /** Occupancy on the role map. Not a durable outcome. */
32
+ get workerPresent(): boolean;
33
+ get isDone(): boolean;
34
+ /** Leaf. PEW does not parent PEW. */
35
+ get work(): readonly WorkExpectation[];
36
+ /**
37
+ * Settles when {@link isDone}. Fulfills with {@link outcome} for both
38
+ * `successful` and `failed` — failure is an outcome, not a rejection.
39
+ * The fulfillment cannot be `this`: a thenable that resolves to itself
40
+ * never settles (Promise unwraps `then` forever).
41
+ */
42
+ then<TFulfilled = ExpectationOutcome, TRejected = never>(onfulfilled?: ((value: ExpectationOutcome) => TFulfilled | PromiseLike<TFulfilled>) | null, onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null): Promise<TFulfilled | TRejected>;
43
+ catch<TRejected = never>(onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null): Promise<ExpectationOutcome | TRejected>;
44
+ finally(onfinally?: (() => void) | null): Promise<ExpectationOutcome>;
45
+ get [Symbol.toStringTag](): string;
46
+ applySettlement(_result: TResult): void;
47
+ /**
48
+ * Durable outcome frame if written, else last progress seen.
49
+ * {@link ROLE_LANE_OCCUPIED} is not a frame. Retract keeps the last frame.
50
+ */
51
+ get report(): TReport | null;
52
+ succeed(cause: EndCause, detail: string, outcomeReport: string, settlement?: {
53
+ readonly result: TResult;
54
+ }): boolean;
55
+ fail(cause: EndCause, detail: string, outcomeReport: string): boolean;
56
+ }
57
+ /** Open work whose parent sealed — honor does not start these. */
58
+ export declare function isTreeOrphan(node: WorkExpectation): boolean;
59
+ /** Admits every WorkExpectation instantiation. */
60
+ export type AnyWorkExpectation = WorkExpectation<any, any>;
61
+ export type ResultOf<E extends AnyWorkExpectation> = Parameters<E["applySettlement"]>[0];
62
+ export type ReportOf<E extends AnyWorkExpectation> = Exclude<E["report"], null>;
63
+ //# sourceMappingURL=WorkExpectation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkExpectation.d.ts","sourceRoot":"","sources":["../../../src/shared/models/WorkExpectation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,290 @@
1
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
+ var useValue = arguments.length > 2;
3
+ for (var i = 0; i < initializers.length; i++) {
4
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
+ }
6
+ return useValue ? value : void 0;
7
+ };
8
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
+ var _, done = false;
14
+ for (var i = decorators.length - 1; i >= 0; i--) {
15
+ var context = {};
16
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
+ if (kind === "accessor") {
21
+ if (result === void 0) continue;
22
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
+ if (_ = accept(result.get)) descriptor.get = _;
24
+ if (_ = accept(result.set)) descriptor.set = _;
25
+ if (_ = accept(result.init)) initializers.unshift(_);
26
+ }
27
+ else if (_ = accept(result)) {
28
+ if (kind === "field") initializers.unshift(_);
29
+ else descriptor[key] = _;
30
+ }
31
+ }
32
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
+ done = true;
34
+ };
35
+ import { syncing } from "@here.build/plexus";
36
+ import { docPlexus } from "@here.build/plexus/internals";
37
+ import { comparer, computed, observable, reaction, when } from "mobx";
38
+ import invariant from "tiny-invariant";
39
+ import { roleOf } from "../role.js";
40
+ import { Job } from "./Job.js";
41
+ import { WorkContainer } from "./WorkContainer.js";
42
+ /**
43
+ * Awareness: empty string occupies the role map without a report frame.
44
+ * Retract drops the uuid. Not a durable outcome.
45
+ */
46
+ export const ROLE_LANE_OCCUPIED = "";
47
+ let WorkExpectation = (() => {
48
+ var _a, _b, _c;
49
+ let _classDecorators = [syncing("@inhuman.tools/plexus-expectations:WorkExpectation")];
50
+ let _classDescriptor;
51
+ let _classExtraInitializers = [];
52
+ let _classThis;
53
+ let _classSuper = WorkContainer;
54
+ let _instanceExtraInitializers = [];
55
+ let _connectionId_decorators;
56
+ let _connectionId_initializers = [];
57
+ let _connectionId_extraInitializers = [];
58
+ let _outcome_decorators;
59
+ let _outcome_initializers = [];
60
+ let _outcome_extraInitializers = [];
61
+ let _endCause_decorators;
62
+ let _endCause_initializers = [];
63
+ let _endCause_extraInitializers = [];
64
+ let _endDetail_decorators;
65
+ let _endDetail_initializers = [];
66
+ let _endDetail_extraInitializers = [];
67
+ let _outcomeReport_decorators;
68
+ let _outcomeReport_initializers = [];
69
+ let _outcomeReport_extraInitializers = [];
70
+ let _lastProgress_decorators;
71
+ let _lastProgress_initializers = [];
72
+ let _lastProgress_extraInitializers = [];
73
+ let _get_progressAwareness_decorators;
74
+ let _get_workerPresent_decorators;
75
+ let _get_report_decorators;
76
+ let _succeed_decorators;
77
+ let _fail_decorators;
78
+ var WorkExpectation = class extends _classSuper {
79
+ static { _classThis = this; }
80
+ static {
81
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
82
+ _get_report_decorators = [computed];
83
+ _succeed_decorators = [(_b = syncing).action.bind(_b)];
84
+ _fail_decorators = [(_c = syncing).action.bind(_c)];
85
+ __esDecorate(this, null, _connectionId_decorators, { kind: "accessor", name: "connectionId", static: false, private: false, access: { has: obj => "connectionId" in obj, get: obj => obj.connectionId, set: (obj, value) => { obj.connectionId = value; } }, metadata: _metadata }, _connectionId_initializers, _connectionId_extraInitializers);
86
+ __esDecorate(this, null, _outcome_decorators, { kind: "accessor", name: "outcome", static: false, private: false, access: { has: obj => "outcome" in obj, get: obj => obj.outcome, set: (obj, value) => { obj.outcome = value; } }, metadata: _metadata }, _outcome_initializers, _outcome_extraInitializers);
87
+ __esDecorate(this, null, _endCause_decorators, { kind: "accessor", name: "endCause", static: false, private: false, access: { has: obj => "endCause" in obj, get: obj => obj.endCause, set: (obj, value) => { obj.endCause = value; } }, metadata: _metadata }, _endCause_initializers, _endCause_extraInitializers);
88
+ __esDecorate(this, null, _endDetail_decorators, { kind: "accessor", name: "endDetail", static: false, private: false, access: { has: obj => "endDetail" in obj, get: obj => obj.endDetail, set: (obj, value) => { obj.endDetail = value; } }, metadata: _metadata }, _endDetail_initializers, _endDetail_extraInitializers);
89
+ __esDecorate(this, null, _outcomeReport_decorators, { kind: "accessor", name: "outcomeReport", static: false, private: false, access: { has: obj => "outcomeReport" in obj, get: obj => obj.outcomeReport, set: (obj, value) => { obj.outcomeReport = value; } }, metadata: _metadata }, _outcomeReport_initializers, _outcomeReport_extraInitializers);
90
+ __esDecorate(this, null, _lastProgress_decorators, { kind: "accessor", name: "lastProgress", static: false, private: false, access: { has: obj => "lastProgress" in obj, get: obj => obj.lastProgress, set: (obj, value) => { obj.lastProgress = value; } }, metadata: _metadata }, _lastProgress_initializers, _lastProgress_extraInitializers);
91
+ __esDecorate(this, null, _get_progressAwareness_decorators, { kind: "getter", name: "progressAwareness", static: false, private: false, access: { has: obj => "progressAwareness" in obj, get: obj => obj.progressAwareness }, metadata: _metadata }, null, _instanceExtraInitializers);
92
+ __esDecorate(this, null, _get_workerPresent_decorators, { kind: "getter", name: "workerPresent", static: false, private: false, access: { has: obj => "workerPresent" in obj, get: obj => obj.workerPresent }, metadata: _metadata }, null, _instanceExtraInitializers);
93
+ __esDecorate(this, null, _get_report_decorators, { kind: "getter", name: "report", static: false, private: false, access: { has: obj => "report" in obj, get: obj => obj.report }, metadata: _metadata }, null, _instanceExtraInitializers);
94
+ __esDecorate(this, null, _succeed_decorators, { kind: "method", name: "succeed", static: false, private: false, access: { has: obj => "succeed" in obj, get: obj => obj.succeed }, metadata: _metadata }, null, _instanceExtraInitializers);
95
+ __esDecorate(this, null, _fail_decorators, { kind: "method", name: "fail", static: false, private: false, access: { has: obj => "fail" in obj, get: obj => obj.fail }, metadata: _metadata }, null, _instanceExtraInitializers);
96
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
97
+ WorkExpectation = _classThis = _classDescriptor.value;
98
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
99
+ __runInitializers(_classThis, _classExtraInitializers);
100
+ }
101
+ #connectionId_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _connectionId_initializers, void 0));
102
+ /**
103
+ * Kernel catalog key this work rides. Required at construction.
104
+ * Plexus materialization passes a symbol through unchanged.
105
+ */
106
+ get connectionId() { return this.#connectionId_accessor_storage; }
107
+ set connectionId(value) { this.#connectionId_accessor_storage = value; }
108
+ constructor(init) {
109
+ if (typeof init !== "symbol") {
110
+ invariant(typeof init.connectionId === "string" && init.connectionId !== "", "WorkExpectation.connectionId is required");
111
+ }
112
+ super(init);
113
+ }
114
+ #outcome_accessor_storage = (__runInitializers(this, _connectionId_extraInitializers), __runInitializers(this, _outcome_initializers, null));
115
+ get outcome() { return this.#outcome_accessor_storage; }
116
+ set outcome(value) { this.#outcome_accessor_storage = value; }
117
+ #endCause_accessor_storage = (__runInitializers(this, _outcome_extraInitializers), __runInitializers(this, _endCause_initializers, null));
118
+ get endCause() { return this.#endCause_accessor_storage; }
119
+ set endCause(value) { this.#endCause_accessor_storage = value; }
120
+ #endDetail_accessor_storage = (__runInitializers(this, _endCause_extraInitializers), __runInitializers(this, _endDetail_initializers, null));
121
+ get endDetail() { return this.#endDetail_accessor_storage; }
122
+ set endDetail(value) { this.#endDetail_accessor_storage = value; }
123
+ #outcomeReport_accessor_storage = (__runInitializers(this, _endDetail_extraInitializers), __runInitializers(this, _outcomeReport_initializers, null));
124
+ /** Durable last frame as JSON. `"null"` when the work ended without a report. */
125
+ get outcomeReport() { return this.#outcomeReport_accessor_storage; }
126
+ set outcomeReport(value) { this.#outcomeReport_accessor_storage = value; }
127
+ #lastProgress_accessor_storage = (__runInitializers(this, _outcomeReport_extraInitializers), __runInitializers(this, _lastProgress_initializers, null));
128
+ /** Last live role-map frame this process saw. Retract does not clear it. */
129
+ get lastProgress() { return this.#lastProgress_accessor_storage; }
130
+ set lastProgress(value) { this.#lastProgress_accessor_storage = value; }
131
+ #progressCacheStarted = (__runInitializers(this, _lastProgress_extraInitializers), false);
132
+ #settledPromise = null;
133
+ get plexus() {
134
+ const doc = this.__doc__;
135
+ if (!doc)
136
+ return null;
137
+ const plexus = docPlexus.get(doc);
138
+ if (!plexus)
139
+ return null;
140
+ return plexus;
141
+ }
142
+ get awareness() {
143
+ const hub = this.plexus?.awareness ?? null;
144
+ if (hub != null)
145
+ this.#ensureProgressCache();
146
+ return hub;
147
+ }
148
+ // MobX: arm on the first `awareness` read so a later untracked read still
149
+ // sees the last frame. Dispose on done — a sealed lane is frozen; do not
150
+ // keep a reaction per expectation for the life of the document.
151
+ #ensureProgressCache() {
152
+ if (this.#progressCacheStarted)
153
+ return;
154
+ this.#progressCacheStarted = true;
155
+ reaction(() => ({ done: this.isDone, frame: this.#liveProgressFrame() }), ({ done, frame }, _previous, self) => {
156
+ if (frame !== null)
157
+ this.lastProgress = frame;
158
+ if (done)
159
+ self.dispose();
160
+ }, { fireImmediately: true, equals: comparer.structural });
161
+ }
162
+ #liveProgressFrame() {
163
+ const hub = this.awareness;
164
+ if (hub == null)
165
+ return null;
166
+ const frame = roleOf(hub, this.uuid);
167
+ if (frame == null || frame === ROLE_LANE_OCCUPIED)
168
+ return null;
169
+ return frame;
170
+ }
171
+ /** Live progress as the fulfiller tells it. Awareness retract does not drop the last frame. */
172
+ get progressAwareness() {
173
+ return this.#liveProgressFrame() ?? this.lastProgress;
174
+ }
175
+ /** Occupancy on the role map. Not a durable outcome. */
176
+ get workerPresent() {
177
+ const hub = this.awareness;
178
+ if (hub == null)
179
+ return false;
180
+ const value = roleOf(hub, this.uuid);
181
+ return value !== undefined && value !== null;
182
+ }
183
+ get isDone() {
184
+ return this.outcome != null;
185
+ }
186
+ /** Leaf. PEW does not parent PEW. */
187
+ get work() {
188
+ return [this];
189
+ }
190
+ /**
191
+ * Settles when {@link isDone}. Fulfills with {@link outcome} for both
192
+ * `successful` and `failed` — failure is an outcome, not a rejection.
193
+ * The fulfillment cannot be `this`: a thenable that resolves to itself
194
+ * never settles (Promise unwraps `then` forever).
195
+ */
196
+ then(onfulfilled, onrejected) {
197
+ return this.#settled().then(onfulfilled, onrejected);
198
+ }
199
+ catch(onrejected) {
200
+ return this.#settled().catch(onrejected);
201
+ }
202
+ finally(onfinally) {
203
+ return this.#settled().finally(onfinally);
204
+ }
205
+ get [(_connectionId_decorators = [syncing], _outcome_decorators = [syncing], _endCause_decorators = [syncing], _endDetail_decorators = [syncing], _outcomeReport_decorators = [syncing], _lastProgress_decorators = [(_a = observable).ref.bind(_a)], _get_progressAwareness_decorators = [computed], _get_workerPresent_decorators = [computed], Symbol.toStringTag)]() {
206
+ return "WorkExpectation";
207
+ }
208
+ #settled() {
209
+ if (this.#settledPromise != null)
210
+ return this.#settledPromise;
211
+ this.#settledPromise = this.isDone
212
+ ? Promise.resolve(this.#sealedOutcome())
213
+ : when(() => this.isDone).then(() => this.#sealedOutcome());
214
+ return this.#settledPromise;
215
+ }
216
+ #sealedOutcome() {
217
+ invariant(this.outcome != null, "WorkExpectation settled without outcome");
218
+ return this.outcome;
219
+ }
220
+ applySettlement(_result) { }
221
+ #parseOutcomeReport() {
222
+ if (this.outcomeReport == null)
223
+ return null;
224
+ try {
225
+ return JSON.parse(this.outcomeReport);
226
+ }
227
+ catch {
228
+ return null;
229
+ }
230
+ }
231
+ /**
232
+ * Durable outcome frame if written, else last progress seen.
233
+ * {@link ROLE_LANE_OCCUPIED} is not a frame. Retract keeps the last frame.
234
+ */
235
+ get report() {
236
+ if (this.outcomeReport != null)
237
+ return this.#parseOutcomeReport();
238
+ return this.progressAwareness;
239
+ }
240
+ succeed(cause, detail, outcomeReport, settlement) {
241
+ if (this.isDone)
242
+ return false;
243
+ if (settlement !== undefined) {
244
+ try {
245
+ this.applySettlement(settlement.result);
246
+ }
247
+ catch (error) {
248
+ this.outcome = "failed";
249
+ this.endCause = cause;
250
+ this.endDetail = `apply_error: ${String(error)}`;
251
+ this.outcomeReport = outcomeReport;
252
+ this.markEnded();
253
+ return true;
254
+ }
255
+ }
256
+ this.outcome = "successful";
257
+ this.endCause = cause;
258
+ this.endDetail = detail;
259
+ this.outcomeReport = outcomeReport;
260
+ this.markEnded();
261
+ return true;
262
+ }
263
+ fail(cause, detail, outcomeReport) {
264
+ if (this.isDone)
265
+ return false;
266
+ this.outcome = "failed";
267
+ this.endCause = cause;
268
+ this.endDetail = detail;
269
+ this.outcomeReport = outcomeReport;
270
+ this.markEnded();
271
+ return true;
272
+ }
273
+ };
274
+ return WorkExpectation = _classThis;
275
+ })();
276
+ export { WorkExpectation };
277
+ /** Open work whose parent sealed — honor does not start these. */
278
+ export function isTreeOrphan(node) {
279
+ if (node.isDone)
280
+ return false;
281
+ const parent = node.parent;
282
+ if (parent === null)
283
+ return false;
284
+ if (parent instanceof WorkExpectation)
285
+ return parent.isDone;
286
+ if (parent instanceof Job)
287
+ return parent.completed;
288
+ return false;
289
+ }
290
+ //# sourceMappingURL=WorkExpectation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkExpectation.js","sourceRoot":"","sources":["../../../src/shared/models/WorkExpectation.ts"],"names":[],"mappings":"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","sourcesContent":["import { type PlexusAwareness, syncing } from \"@here.build/plexus\";\nimport { docPlexus } from \"@here.build/plexus/internals\";\nimport { comparer, computed, observable, reaction, when } from \"mobx\";\nimport invariant from \"tiny-invariant\";\n\nimport { type EndCause, type ExpectationOutcome } from \"../control.js\";\nimport { roleOf } from \"../role.js\";\nimport type { SessionAwareness, SessionPlexus } from \"../types.js\";\nimport { Job } from \"./Job.js\";\nimport { WorkContainer } from \"./WorkContainer.js\";\n\n/**\n * Awareness: empty string occupies the role map without a report frame.\n * Retract drops the uuid. Not a durable outcome.\n */\nexport const ROLE_LANE_OCCUPIED = \"\";\n\n@syncing(\"@inhuman.tools/plexus-expectations:WorkExpectation\")\nexport abstract class WorkExpectation<TResult = unknown, TReport = unknown>\n extends WorkContainer\n implements Promise<ExpectationOutcome>\n{\n /**\n * Kernel catalog key this work rides. Required at construction.\n * Plexus materialization passes a symbol through unchanged.\n */\n @syncing\n accessor connectionId!: string;\n\n constructor(init: { readonly connectionId: string } | symbol) {\n if (typeof init !== \"symbol\") {\n invariant(\n typeof init.connectionId === \"string\" && init.connectionId !== \"\",\n \"WorkExpectation.connectionId is required\",\n );\n }\n super(init);\n }\n\n @syncing\n accessor outcome: ExpectationOutcome | null = null;\n\n @syncing\n accessor endCause: EndCause | null = null;\n\n @syncing\n accessor endDetail: string | null = null;\n\n /** Durable last frame as JSON. `\"null\"` when the work ended without a report. */\n @syncing\n accessor outcomeReport: string | null = null;\n\n /** Last live role-map frame this process saw. Retract does not clear it. */\n @observable.ref private accessor lastProgress: TReport | null = null;\n #progressCacheStarted = false;\n #settledPromise: Promise<ExpectationOutcome> | null = null;\n\n get plexus(): SessionPlexus | null {\n const doc = this.__doc__;\n if (!doc) return null;\n const plexus = docPlexus.get(doc);\n if (!plexus) return null;\n return plexus as SessionPlexus;\n }\n\n get awareness(): PlexusAwareness<SessionAwareness> | null {\n const hub = this.plexus?.awareness ?? null;\n if (hub != null) this.#ensureProgressCache();\n return hub;\n }\n\n // MobX: arm on the first `awareness` read so a later untracked read still\n // sees the last frame. Dispose on done — a sealed lane is frozen; do not\n // keep a reaction per expectation for the life of the document.\n #ensureProgressCache(): void {\n if (this.#progressCacheStarted) return;\n this.#progressCacheStarted = true;\n reaction(\n () => ({ done: this.isDone, frame: this.#liveProgressFrame() }),\n ({ done, frame }, _previous, self) => {\n if (frame !== null) this.lastProgress = frame;\n if (done) self.dispose();\n },\n { fireImmediately: true, equals: comparer.structural },\n );\n }\n\n #liveProgressFrame(): TReport | null {\n const hub = this.awareness;\n if (hub == null) return null;\n const frame = roleOf(hub, this.uuid);\n if (frame == null || frame === ROLE_LANE_OCCUPIED) return null;\n return frame as TReport;\n }\n\n /** Live progress as the fulfiller tells it. Awareness retract does not drop the last frame. */\n @computed\n get progressAwareness(): TReport | null {\n return this.#liveProgressFrame() ?? this.lastProgress;\n }\n\n /** Occupancy on the role map. Not a durable outcome. */\n @computed\n get workerPresent(): boolean {\n const hub = this.awareness;\n if (hub == null) return false;\n const value = roleOf(hub, this.uuid);\n return value !== undefined && value !== null;\n }\n\n get isDone(): boolean {\n return this.outcome != null;\n }\n\n /** Leaf. PEW does not parent PEW. */\n get work(): readonly WorkExpectation[] {\n return [this];\n }\n\n /**\n * Settles when {@link isDone}. Fulfills with {@link outcome} for both\n * `successful` and `failed` — failure is an outcome, not a rejection.\n * The fulfillment cannot be `this`: a thenable that resolves to itself\n * never settles (Promise unwraps `then` forever).\n */\n then<TFulfilled = ExpectationOutcome, TRejected = never>(\n onfulfilled?: ((value: ExpectationOutcome) => TFulfilled | PromiseLike<TFulfilled>) | null,\n onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null,\n ): Promise<TFulfilled | TRejected> {\n return this.#settled().then(onfulfilled, onrejected);\n }\n\n catch<TRejected = never>(\n onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null,\n ): Promise<ExpectationOutcome | TRejected> {\n return this.#settled().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<ExpectationOutcome> {\n return this.#settled().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return \"WorkExpectation\";\n }\n\n #settled(): Promise<ExpectationOutcome> {\n if (this.#settledPromise != null) return this.#settledPromise;\n this.#settledPromise = this.isDone\n ? Promise.resolve(this.#sealedOutcome())\n : when(() => this.isDone).then(() => this.#sealedOutcome());\n return this.#settledPromise;\n }\n\n #sealedOutcome(): ExpectationOutcome {\n invariant(this.outcome != null, \"WorkExpectation settled without outcome\");\n return this.outcome;\n }\n\n applySettlement(_result: TResult): void {}\n\n #parseOutcomeReport(): TReport | null {\n if (this.outcomeReport == null) return null;\n try {\n return JSON.parse(this.outcomeReport) as TReport | null;\n } catch {\n return null;\n }\n }\n\n /**\n * Durable outcome frame if written, else last progress seen.\n * {@link ROLE_LANE_OCCUPIED} is not a frame. Retract keeps the last frame.\n */\n @computed\n get report(): TReport | null {\n if (this.outcomeReport != null) return this.#parseOutcomeReport();\n return this.progressAwareness;\n }\n\n @syncing.action\n succeed(cause: EndCause, detail: string, outcomeReport: string, settlement?: { readonly result: TResult }): boolean {\n if (this.isDone) return false;\n if (settlement !== undefined) {\n try {\n this.applySettlement(settlement.result);\n } catch (error) {\n this.outcome = \"failed\";\n this.endCause = cause;\n this.endDetail = `apply_error: ${String(error)}`;\n this.outcomeReport = outcomeReport;\n this.markEnded();\n return true;\n }\n }\n this.outcome = \"successful\";\n this.endCause = cause;\n this.endDetail = detail;\n this.outcomeReport = outcomeReport;\n this.markEnded();\n return true;\n }\n\n @syncing.action\n fail(cause: EndCause, detail: string, outcomeReport: string): boolean {\n if (this.isDone) return false;\n this.outcome = \"failed\";\n this.endCause = cause;\n this.endDetail = detail;\n this.outcomeReport = outcomeReport;\n this.markEnded();\n return true;\n }\n}\n\n/** Open work whose parent sealed — honor does not start these. */\nexport function isTreeOrphan(node: WorkExpectation): boolean {\n if (node.isDone) return false;\n const parent = node.parent;\n if (parent === null) return false;\n if (parent instanceof WorkExpectation) return parent.isDone;\n if (parent instanceof Job) return parent.completed;\n return false;\n}\n\n/** Admits every WorkExpectation instantiation. */\nexport type AnyWorkExpectation = WorkExpectation<any, any>;\nexport type ResultOf<E extends AnyWorkExpectation> = Parameters<E[\"applySettlement\"]>[0];\nexport type ReportOf<E extends AnyWorkExpectation> = Exclude<E[\"report\"], null>;\n"]}
@@ -0,0 +1,4 @@
1
+ import { WorkExpectation } from "./WorkExpectation.js";
2
+ export declare abstract class WorkExpectationWithIntrospection<TResult = unknown, TReport = unknown, TProposal = never> extends WorkExpectation<TResult, TReport, TProposal> {
3
+ }
4
+ //# sourceMappingURL=WorkExpectationWithIntrospection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkExpectationWithIntrospection.d.ts","sourceRoot":"","sources":["../../../src/shared/models/WorkExpectationWithIntrospection.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,8BACsB,gCAAgC,CACpD,OAAO,GAAG,OAAO,EACjB,OAAO,GAAG,OAAO,EACjB,SAAS,GAAG,KAAK,CACjB,SAAQ,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC;CAAG"}
@@ -0,0 +1,28 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ /**
3
+ * Formerly IntrospectingPlexusModel — a PlexusModel helper that WorkExpectation
4
+ * extended. Flipped: this is a WorkExpectation, not a parent of one.
5
+ * `plexus` / `awareness` / `getUniqueLanePresence` live on {@link WorkExpectation}.
6
+ */
7
+ import { syncing } from "@here.build/plexus";
8
+ import { WorkExpectation } from "./WorkExpectation.js";
9
+ let WorkExpectationWithIntrospection = (() => {
10
+ let _classDecorators = [syncing("@inhuman.tools/plexus-expectations:WorkExpectationWithIntrospection")];
11
+ let _classDescriptor;
12
+ let _classExtraInitializers = [];
13
+ let _classThis;
14
+ let _classSuper = WorkExpectation;
15
+ var WorkExpectationWithIntrospection = class extends _classSuper {
16
+ static { _classThis = this; }
17
+ static {
18
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
19
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
20
+ WorkExpectationWithIntrospection = _classThis = _classDescriptor.value;
21
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
22
+ __runInitializers(_classThis, _classExtraInitializers);
23
+ }
24
+ };
25
+ return WorkExpectationWithIntrospection = _classThis;
26
+ })();
27
+ export { WorkExpectationWithIntrospection };
28
+ //# sourceMappingURL=WorkExpectationWithIntrospection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkExpectationWithIntrospection.js","sourceRoot":"","sources":["../../../src/shared/models/WorkExpectationWithIntrospection.ts"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;IAGjC,gCAAgC;4BADrD,OAAO,CAAC,qEAAqE,CAAC;;;;sBAKrE,eAAe;gDAAvB,SAAQ,WAA4C;;;;YAJtD,6KAIyD;;;YAJnC,uDAAgC;;;;;SAAhC,gCAAgC","sourcesContent":["/**\n * Formerly IntrospectingPlexusModel — a PlexusModel helper that WorkExpectation\n * extended. Flipped: this is a WorkExpectation, not a parent of one.\n * `plexus` / `awareness` / `getUniqueLanePresence` live on {@link WorkExpectation}.\n */\nimport { syncing } from \"@here.build/plexus\";\n\nimport { WorkExpectation } from \"./WorkExpectation.js\";\n\n@syncing(\"@inhuman.tools/plexus-expectations:WorkExpectationWithIntrospection\")\nexport abstract class WorkExpectationWithIntrospection<\n TResult = unknown,\n TReport = unknown,\n TProposal = never,\n> extends WorkExpectation<TResult, TReport, TProposal> {}\n"]}
@@ -0,0 +1,7 @@
1
+ export * from "./WorkContainer.js";
2
+ export * from "./WorkExpectation.js";
3
+ export * from "./Job.js";
4
+ export * from "./DriverSpec.js";
5
+ export * from "./ConnectionSpec.js";
6
+ export { type LiveFacts as LiveFacts } from "./jsonRecord.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,KAAK,SAAS,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./WorkContainer.js";
2
+ export * from "./WorkExpectation.js";
3
+ export * from "./Job.js";
4
+ export * from "./DriverSpec.js";
5
+ export * from "./ConnectionSpec.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from \"./WorkContainer.js\";\nexport * from \"./WorkExpectation.js\";\nexport * from \"./Job.js\";\nexport * from \"./DriverSpec.js\";\nexport * from \"./ConnectionSpec.js\";\nexport { type LiveFacts as LiveFacts } from \"./jsonRecord.js\";\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Plexus `@syncing.record` bags are `Record<string, string>`. Values round-trip
3
+ * through JSON.stringify; `undefined` is omitted.
4
+ */
5
+ /** Process self-report on ConnectionSpec / DriverSpec. JSON through `liveMap`. */
6
+ export type LiveFacts = {
7
+ readonly [key: string]: unknown | undefined;
8
+ readonly models?: readonly string[];
9
+ readonly tools?: unknown;
10
+ };
11
+ export declare function readJsonRecord(map: Record<string, string>): Record<string, unknown>;
12
+ export declare function writeJsonRecord(map: Record<string, string>, next: Readonly<Record<string, unknown>> | undefined): void;
13
+ export declare function deepFreeze<T>(value: T): T;
14
+ //# sourceMappingURL=jsonRecord.d.ts.map