@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.
- package/LICENSE.md +7 -0
- package/README.md +144 -2
- package/dist/driver/ExpectationActor.d.ts +56 -0
- package/dist/driver/ExpectationActor.d.ts.map +1 -0
- package/dist/driver/ExpectationActor.js +210 -0
- package/dist/driver/ExpectationActor.js.map +1 -0
- package/dist/driver/PEWDriver.d.ts +144 -0
- package/dist/driver/PEWDriver.d.ts.map +1 -0
- package/dist/driver/PEWDriver.js +303 -0
- package/dist/driver/PEWDriver.js.map +1 -0
- package/dist/driver/PEWDriverConnection.d.ts +139 -0
- package/dist/driver/PEWDriverConnection.d.ts.map +1 -0
- package/dist/driver/PEWDriverConnection.js +298 -0
- package/dist/driver/PEWDriverConnection.js.map +1 -0
- package/dist/driver/actor-machine.d.ts +28 -0
- package/dist/driver/actor-machine.d.ts.map +1 -0
- package/dist/driver/actor-machine.js +50 -0
- package/dist/driver/actor-machine.js.map +1 -0
- package/dist/driver/connection-miss.d.ts +9 -0
- package/dist/driver/connection-miss.d.ts.map +1 -0
- package/dist/driver/connection-miss.js +13 -0
- package/dist/driver/connection-miss.js.map +1 -0
- package/dist/driver/index.d.ts +6 -0
- package/dist/driver/index.d.ts.map +1 -0
- package/dist/driver/index.js +5 -0
- package/dist/driver/index.js.map +1 -0
- package/dist/error-with-invariant.d.ts +9 -0
- package/dist/error-with-invariant.d.ts.map +1 -0
- package/dist/error-with-invariant.js +12 -0
- package/dist/error-with-invariant.js.map +1 -0
- package/dist/executor/index.d.ts +4 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +4 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/kernel-intern.d.ts +16 -0
- package/dist/executor/kernel-intern.d.ts.map +1 -0
- package/dist/executor/kernel-intern.js +98 -0
- package/dist/executor/kernel-intern.js.map +1 -0
- package/dist/executor/orchestrator.d.ts +97 -0
- package/dist/executor/orchestrator.d.ts.map +1 -0
- package/dist/executor/orchestrator.js +465 -0
- package/dist/executor/orchestrator.js.map +1 -0
- package/dist/executor/types.d.ts +8 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +2 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/connection.d.ts +4 -0
- package/dist/schemas/connection.d.ts.map +1 -0
- package/dist/schemas/connection.js +4 -0
- package/dist/schemas/connection.js.map +1 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/shared/attention.d.ts +27 -0
- package/dist/shared/attention.d.ts.map +1 -0
- package/dist/shared/attention.js +116 -0
- package/dist/shared/attention.js.map +1 -0
- package/dist/shared/control.d.ts +4 -0
- package/dist/shared/control.d.ts.map +1 -0
- package/dist/shared/control.js +2 -0
- package/dist/shared/control.js.map +1 -0
- package/dist/shared/index.d.ts +7 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +7 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/map-field-awareness.d.ts +19 -0
- package/dist/shared/map-field-awareness.d.ts.map +1 -0
- package/dist/shared/map-field-awareness.js +58 -0
- package/dist/shared/map-field-awareness.js.map +1 -0
- package/dist/shared/models/ApprovableExpectation.d.ts +15 -0
- package/dist/shared/models/ApprovableExpectation.d.ts.map +1 -0
- package/dist/shared/models/ApprovableExpectation.js +138 -0
- package/dist/shared/models/ApprovableExpectation.js.map +1 -0
- package/dist/shared/models/ConnectionSpec.d.ts +44 -0
- package/dist/shared/models/ConnectionSpec.d.ts.map +1 -0
- package/dist/shared/models/ConnectionSpec.js +180 -0
- package/dist/shared/models/ConnectionSpec.js.map +1 -0
- package/dist/shared/models/DriverSpec.d.ts +45 -0
- package/dist/shared/models/DriverSpec.d.ts.map +1 -0
- package/dist/shared/models/DriverSpec.js +221 -0
- package/dist/shared/models/DriverSpec.js.map +1 -0
- package/dist/shared/models/IntrospectingPlexusModel.d.ts +8 -0
- package/dist/shared/models/IntrospectingPlexusModel.d.ts.map +1 -0
- package/dist/shared/models/IntrospectingPlexusModel.js +48 -0
- package/dist/shared/models/IntrospectingPlexusModel.js.map +1 -0
- package/dist/shared/models/Job.d.ts +85 -0
- package/dist/shared/models/Job.d.ts.map +1 -0
- package/dist/shared/models/Job.js +261 -0
- package/dist/shared/models/Job.js.map +1 -0
- package/dist/shared/models/ProgrammaticJob.d.ts +6 -0
- package/dist/shared/models/ProgrammaticJob.d.ts.map +1 -0
- package/dist/shared/models/ProgrammaticJob.js +80 -0
- package/dist/shared/models/ProgrammaticJob.js.map +1 -0
- package/dist/shared/models/WorkContainer.d.ts +36 -0
- package/dist/shared/models/WorkContainer.d.ts.map +1 -0
- package/dist/shared/models/WorkContainer.js +140 -0
- package/dist/shared/models/WorkContainer.js.map +1 -0
- package/dist/shared/models/WorkExpectation.d.ts +63 -0
- package/dist/shared/models/WorkExpectation.d.ts.map +1 -0
- package/dist/shared/models/WorkExpectation.js +290 -0
- package/dist/shared/models/WorkExpectation.js.map +1 -0
- package/dist/shared/models/WorkExpectationWithIntrospection.d.ts +4 -0
- package/dist/shared/models/WorkExpectationWithIntrospection.d.ts.map +1 -0
- package/dist/shared/models/WorkExpectationWithIntrospection.js +28 -0
- package/dist/shared/models/WorkExpectationWithIntrospection.js.map +1 -0
- package/dist/shared/models/index.d.ts +7 -0
- package/dist/shared/models/index.d.ts.map +1 -0
- package/dist/shared/models/index.js +6 -0
- package/dist/shared/models/index.js.map +1 -0
- package/dist/shared/models/jsonRecord.d.ts +14 -0
- package/dist/shared/models/jsonRecord.d.ts.map +1 -0
- package/dist/shared/models/jsonRecord.js +46 -0
- package/dist/shared/models/jsonRecord.js.map +1 -0
- package/dist/shared/resolution.d.ts +39 -0
- package/dist/shared/resolution.d.ts.map +1 -0
- package/dist/shared/resolution.js +124 -0
- package/dist/shared/resolution.js.map +1 -0
- package/dist/shared/revalidation-demand.d.ts +27 -0
- package/dist/shared/revalidation-demand.d.ts.map +1 -0
- package/dist/shared/revalidation-demand.js +116 -0
- package/dist/shared/revalidation-demand.js.map +1 -0
- package/dist/shared/role.d.ts +12 -0
- package/dist/shared/role.d.ts.map +1 -0
- package/dist/shared/role.js +21 -0
- package/dist/shared/role.js.map +1 -0
- package/dist/shared/types.d.ts +43 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +12 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +79 -3
- package/src/driver/ExpectationActor.ts +244 -0
- package/src/driver/PEWDriver.ts +302 -0
- package/src/driver/actor-machine.ts +54 -0
- package/src/driver/connection-miss.ts +13 -0
- package/src/driver/index.ts +5 -0
- package/src/executor/index.ts +3 -0
- package/src/executor/kernel-intern.ts +121 -0
- package/src/executor/orchestrator.ts +463 -0
- package/src/executor/types.ts +3 -0
- package/src/index.ts +1 -0
- package/src/schemas/connection.ts +4 -0
- package/src/schemas/index.ts +1 -0
- package/src/shared/control.ts +4 -0
- package/src/shared/index.ts +6 -0
- package/src/shared/map-field-awareness.ts +65 -0
- package/src/shared/models/ConnectionSpec.ts +84 -0
- package/src/shared/models/DriverSpec.ts +102 -0
- package/src/shared/models/Job.ts +192 -0
- package/src/shared/models/WorkContainer.ts +90 -0
- package/src/shared/models/WorkExpectation.ts +229 -0
- package/src/shared/models/index.ts +6 -0
- package/src/shared/models/jsonRecord.ts +49 -0
- package/src/shared/revalidation-demand.ts +121 -0
- package/src/shared/role.ts +32 -0
- package/src/shared/types.ts +57 -0
|
@@ -0,0 +1,303 @@
|
|
|
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 { DefaultedWeakMap } from "@here.build/collections";
|
|
36
|
+
import { action, computed, observable, toJS } from "mobx";
|
|
37
|
+
import { pewConfigurationSchema, pewSecretsSchema } from "../schemas/connection.js";
|
|
38
|
+
import { revalidationDemandOf } from "../shared/revalidation-demand.js";
|
|
39
|
+
const EMPTY_SECRETS = { get: () => undefined };
|
|
40
|
+
/** Module-graph duplication breaks instanceof; the elevation gate checks this brand too. */
|
|
41
|
+
// eslint-disable-next-line no-secrets/no-secrets -- package identity tag, not a secret
|
|
42
|
+
export const PEW_DRIVER_BRAND = "@inhuman.tools/plexus-expectations:PEWDriver@1";
|
|
43
|
+
/**
|
|
44
|
+
* Driver extras the orchestrator mirrors onto `spec.live`.
|
|
45
|
+
* Core process facts live on `readyState` / `error` / `offers`.
|
|
46
|
+
*/
|
|
47
|
+
export function extraLiveFromState(state) {
|
|
48
|
+
const extra = {};
|
|
49
|
+
for (const [key, value] of Object.entries(state)) {
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
extra[key] = toJS(value);
|
|
53
|
+
}
|
|
54
|
+
return extra;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The CLASS is the driver (one loaded module per driver name).
|
|
58
|
+
* The INSTANCE is a live connection (one per connection id).
|
|
59
|
+
*
|
|
60
|
+
* CLAIM DOES NOT LIVE HERE. Which WorkExpectation classes this driver handles
|
|
61
|
+
* lives on the advertised driver record (`can`): dynamically loaded code does
|
|
62
|
+
* not get to declare its own authority.
|
|
63
|
+
*
|
|
64
|
+
* Live state is report only — no machinery branches on it. Instance bootstrap
|
|
65
|
+
* truth is `bootstrapDone` / `bootstrapPending`. Drivers read {@link attention}
|
|
66
|
+
* as the reduced token, never clientIds.
|
|
67
|
+
*
|
|
68
|
+
* YAML doors ({@link configurationSchema} / {@link secretsSchema}) parse
|
|
69
|
+
* without `new`. Secrets stay a live view — the host may replace it (reauth).
|
|
70
|
+
*/
|
|
71
|
+
let PEWDriver = (() => {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
let _instanceExtraInitializers = [];
|
|
74
|
+
let _readyState_decorators;
|
|
75
|
+
let _readyState_initializers = [];
|
|
76
|
+
let _readyState_extraInitializers = [];
|
|
77
|
+
let _error_decorators;
|
|
78
|
+
let _error_initializers = [];
|
|
79
|
+
let _error_extraInitializers = [];
|
|
80
|
+
let _state_decorators;
|
|
81
|
+
let _state_initializers = [];
|
|
82
|
+
let _state_extraInitializers = [];
|
|
83
|
+
let _awareness_decorators;
|
|
84
|
+
let _awareness_initializers = [];
|
|
85
|
+
let _awareness_extraInitializers = [];
|
|
86
|
+
let _get_revalidationDemand_decorators;
|
|
87
|
+
let _ensureBootstrapStarted_decorators;
|
|
88
|
+
let _failReady_decorators;
|
|
89
|
+
return class PEWDriver {
|
|
90
|
+
static {
|
|
91
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
92
|
+
__esDecorate(this, null, _readyState_decorators, { kind: "accessor", name: "readyState", static: false, private: false, access: { has: obj => "readyState" in obj, get: obj => obj.readyState, set: (obj, value) => { obj.readyState = value; } }, metadata: _metadata }, _readyState_initializers, _readyState_extraInitializers);
|
|
93
|
+
__esDecorate(this, null, _error_decorators, { kind: "accessor", name: "error", static: false, private: false, access: { has: obj => "error" in obj, get: obj => obj.error, set: (obj, value) => { obj.error = value; } }, metadata: _metadata }, _error_initializers, _error_extraInitializers);
|
|
94
|
+
__esDecorate(this, null, _state_decorators, { kind: "accessor", name: "state", static: false, private: false, access: { has: obj => "state" in obj, get: obj => obj.state, set: (obj, value) => { obj.state = value; } }, metadata: _metadata }, _state_initializers, _state_extraInitializers);
|
|
95
|
+
__esDecorate(this, null, _awareness_decorators, { kind: "accessor", name: "awareness", static: false, private: false, access: { has: obj => "awareness" in obj, get: obj => obj.awareness, set: (obj, value) => { obj.awareness = value; } }, metadata: _metadata }, _awareness_initializers, _awareness_extraInitializers);
|
|
96
|
+
__esDecorate(this, null, _get_revalidationDemand_decorators, { kind: "getter", name: "revalidationDemand", static: false, private: false, access: { has: obj => "revalidationDemand" in obj, get: obj => obj.revalidationDemand }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
97
|
+
__esDecorate(this, null, _ensureBootstrapStarted_decorators, { kind: "method", name: "ensureBootstrapStarted", static: false, private: false, access: { has: obj => "ensureBootstrapStarted" in obj, get: obj => obj.ensureBootstrapStarted }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
98
|
+
__esDecorate(this, null, _failReady_decorators, { kind: "method", name: "failReady", static: false, private: false, access: { has: obj => "failReady" in obj, get: obj => obj.failReady }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
99
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
100
|
+
}
|
|
101
|
+
connectionId = __runInitializers(this, _instanceExtraInitializers);
|
|
102
|
+
// ── driver side (the CLASS is the driver) ─────────────────────────────
|
|
103
|
+
static pewBrand = PEW_DRIVER_BRAND;
|
|
104
|
+
/**
|
|
105
|
+
* YAML settings shape. Default is a passthrough record — subclasses replace
|
|
106
|
+
* this with a real object schema (transforms included). First issue message
|
|
107
|
+
* is what construct / parse throw.
|
|
108
|
+
*/
|
|
109
|
+
static configurationSchema = pewConfigurationSchema;
|
|
110
|
+
static configurationLabel = "";
|
|
111
|
+
static configurationError(message) {
|
|
112
|
+
const label = this.configurationLabel.trim();
|
|
113
|
+
return label === "" ? `connection config invalid: ${message}` : `${label} connection config invalid: ${message}`;
|
|
114
|
+
}
|
|
115
|
+
/** YAML settings door. Does not construct an instance. */
|
|
116
|
+
static parseConfiguration(settings = {}) {
|
|
117
|
+
const result = this.configurationSchema.safeParse(settings ?? {});
|
|
118
|
+
if (result.success)
|
|
119
|
+
return result.data;
|
|
120
|
+
const message = result.error.issues[0]?.message ?? "invalid";
|
|
121
|
+
throw new Error(this.configurationError(message));
|
|
122
|
+
}
|
|
123
|
+
static secretsSchema = pewSecretsSchema;
|
|
124
|
+
static secretsError(message) {
|
|
125
|
+
const label = this.configurationLabel.trim();
|
|
126
|
+
return label === "" ? `connection secrets invalid: ${message}` : `${label} connection secrets invalid: ${message}`;
|
|
127
|
+
}
|
|
128
|
+
/** YAML secrets door. Does not construct an instance. */
|
|
129
|
+
static parseSecrets(secrets = {}) {
|
|
130
|
+
const result = this.secretsSchema.safeParse(secrets ?? {});
|
|
131
|
+
if (result.success)
|
|
132
|
+
return result.data;
|
|
133
|
+
const message = result.error.issues[0]?.message ?? "invalid";
|
|
134
|
+
throw new Error(this.secretsError(message));
|
|
135
|
+
}
|
|
136
|
+
/** Shared on the prototype chain — own extras per subclass. */
|
|
137
|
+
static state = {};
|
|
138
|
+
/**
|
|
139
|
+
* A plain list, or a getter over observable state when the driver keeps its
|
|
140
|
+
* offers fresh (local detection). The orchestrator mirrors it onto
|
|
141
|
+
* `DriverSpec.offers` with a reaction, which is also what observes it.
|
|
142
|
+
*/
|
|
143
|
+
static offers = [];
|
|
144
|
+
/** Kernel-plane occupancy hub. Orchestrator assignment is own-per-class. */
|
|
145
|
+
static awareness;
|
|
146
|
+
static driverName = "";
|
|
147
|
+
/**
|
|
148
|
+
* A getter, not `@computed` — MobX: the decorator's initializer pins to the
|
|
149
|
+
* declaring class, so subclasses would share one computed.
|
|
150
|
+
*/
|
|
151
|
+
static get revalidationDemand() {
|
|
152
|
+
const hub = this.awareness;
|
|
153
|
+
const name = this.driverName;
|
|
154
|
+
if (hub === undefined || name === "")
|
|
155
|
+
return "none";
|
|
156
|
+
return revalidationDemandOf(hub, { kind: "driver", name });
|
|
157
|
+
}
|
|
158
|
+
#readyState_accessor_storage = __runInitializers(this, _readyState_initializers, null);
|
|
159
|
+
// ── connection side (the INSTANCE is the connection) ──────────────────
|
|
160
|
+
get readyState() { return this.#readyState_accessor_storage; }
|
|
161
|
+
set readyState(value) { this.#readyState_accessor_storage = value; }
|
|
162
|
+
#error_accessor_storage = (__runInitializers(this, _readyState_extraInitializers), __runInitializers(this, _error_initializers, ""));
|
|
163
|
+
get error() { return this.#error_accessor_storage; }
|
|
164
|
+
set error(value) { this.#error_accessor_storage = value; }
|
|
165
|
+
#state_accessor_storage = (__runInitializers(this, _error_extraInitializers), __runInitializers(this, _state_initializers, {}));
|
|
166
|
+
/**
|
|
167
|
+
* MobX: shallow — extras (models, tools, account) are replaced wholesale.
|
|
168
|
+
* Override the accessor with a wider literal to add driver facts.
|
|
169
|
+
*/
|
|
170
|
+
get state() { return this.#state_accessor_storage; }
|
|
171
|
+
set state(value) { this.#state_accessor_storage = value; }
|
|
172
|
+
#awareness_accessor_storage = (__runInitializers(this, _state_extraInitializers), __runInitializers(this, _awareness_initializers, undefined));
|
|
173
|
+
get awareness() { return this.#awareness_accessor_storage; }
|
|
174
|
+
set awareness(value) { this.#awareness_accessor_storage = value; }
|
|
175
|
+
get revalidationDemand() {
|
|
176
|
+
const hub = this.awareness;
|
|
177
|
+
if (hub === undefined)
|
|
178
|
+
return "none";
|
|
179
|
+
return revalidationDemandOf(hub, { kind: "connection", id: this.connectionId });
|
|
180
|
+
}
|
|
181
|
+
constructor(connectionId, settings = {}, secrets = EMPTY_SECRETS) {
|
|
182
|
+
this.connectionId = connectionId;
|
|
183
|
+
const cls = new.target;
|
|
184
|
+
this.settings = cls.parseConfiguration(settings);
|
|
185
|
+
const view = typeof secrets.get === "function"
|
|
186
|
+
? secrets
|
|
187
|
+
: {
|
|
188
|
+
get: (field) => secrets[field],
|
|
189
|
+
all: () => secrets,
|
|
190
|
+
};
|
|
191
|
+
cls.parseSecrets(view.all?.() ?? {});
|
|
192
|
+
this.secrets = view;
|
|
193
|
+
}
|
|
194
|
+
settings = __runInitializers(this, _awareness_extraInitializers);
|
|
195
|
+
/** Live view. The host may replace it (reauth). */
|
|
196
|
+
secrets;
|
|
197
|
+
/**
|
|
198
|
+
* Host binds the disk writer for this connection's settings bag.
|
|
199
|
+
* Parsed settings stay readonly; a driver that learns a value overrides this.
|
|
200
|
+
*/
|
|
201
|
+
bindSettingsWriter(_write) { }
|
|
202
|
+
bootstrapDone = false;
|
|
203
|
+
bootstrapPending = null;
|
|
204
|
+
/** `resolve()` threw — the connection is broken, not the work. */
|
|
205
|
+
broken = false;
|
|
206
|
+
/** Concurrent callers share one promise. Async settlement is its own MobX action. */
|
|
207
|
+
ensureBootstrapStarted() {
|
|
208
|
+
if (this.bootstrapDone)
|
|
209
|
+
return Promise.resolve();
|
|
210
|
+
if (this.bootstrapPending)
|
|
211
|
+
return this.bootstrapPending;
|
|
212
|
+
this.readyState = "bootstrapping";
|
|
213
|
+
this.error = "";
|
|
214
|
+
this.bootstrapPending = this.bootstrap().then(action(() => {
|
|
215
|
+
this.bootstrapDone = true;
|
|
216
|
+
this.readyState = "ready";
|
|
217
|
+
this.error = "";
|
|
218
|
+
}), action((error) => {
|
|
219
|
+
this.readyState = "failed";
|
|
220
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
221
|
+
throw error;
|
|
222
|
+
}));
|
|
223
|
+
return this.bootstrapPending;
|
|
224
|
+
}
|
|
225
|
+
failReady(error) {
|
|
226
|
+
this.broken = true;
|
|
227
|
+
this.readyState = "failed";
|
|
228
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
229
|
+
}
|
|
230
|
+
/** Nothing in PEW calls this; hosts or tests may. */
|
|
231
|
+
async [(_readyState_decorators = [observable], _error_decorators = [observable], _state_decorators = [(_a = observable).shallow.bind(_a)], _awareness_decorators = [(_b = observable).ref.bind(_b)], _get_revalidationDemand_decorators = [computed], _ensureBootstrapStarted_decorators = [action], _failReady_decorators = [action], Symbol.asyncDispose)]() { }
|
|
232
|
+
actors = new DefaultedWeakMap((expectation) => {
|
|
233
|
+
const actor = this.resolve(expectation);
|
|
234
|
+
this.liveActors.add(actor);
|
|
235
|
+
return actor;
|
|
236
|
+
});
|
|
237
|
+
liveActors = new Set();
|
|
238
|
+
has(expectation) {
|
|
239
|
+
return this.actors.has(expectation);
|
|
240
|
+
}
|
|
241
|
+
resolveExpectation(expectation) {
|
|
242
|
+
return this.actors.get(expectation);
|
|
243
|
+
}
|
|
244
|
+
release(expectation) {
|
|
245
|
+
if (!this.actors.has(expectation))
|
|
246
|
+
return;
|
|
247
|
+
const actor = this.actors.get(expectation);
|
|
248
|
+
this.actors.delete(expectation);
|
|
249
|
+
this.liveActors.delete(actor);
|
|
250
|
+
actor.leave();
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Logout/drop aborts interned work. Not park. Subclasses abort `#inflight`.
|
|
254
|
+
*/
|
|
255
|
+
abortOnDrop(reason) {
|
|
256
|
+
for (const actor of this.liveActors)
|
|
257
|
+
actor.abort(reason);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Honor one demand.
|
|
261
|
+
* `resolve()` throwing is a broken connection, not a failed expectation.
|
|
262
|
+
*/
|
|
263
|
+
handle(expectation) {
|
|
264
|
+
if (this.broken)
|
|
265
|
+
return;
|
|
266
|
+
if (expectation.isDone)
|
|
267
|
+
return;
|
|
268
|
+
if (this.has(expectation)) {
|
|
269
|
+
const existing = this.resolveExpectation(expectation);
|
|
270
|
+
if (!existing.started)
|
|
271
|
+
existing.start();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
let actor;
|
|
275
|
+
try {
|
|
276
|
+
actor = this.resolveExpectation(expectation);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
this.failReady(error);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// Awareness / host policy may have sealed the work while resolve() ran.
|
|
283
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- resolve() can seal via spawn hooks
|
|
284
|
+
if (expectation.isDone) {
|
|
285
|
+
actor.leave();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (!actor.started) {
|
|
289
|
+
actor.start();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
})();
|
|
294
|
+
export { PEWDriver };
|
|
295
|
+
export function isDriverConnectionClass(value) {
|
|
296
|
+
if (typeof value !== "function")
|
|
297
|
+
return false;
|
|
298
|
+
if (value.pewBrand === PEW_DRIVER_BRAND)
|
|
299
|
+
return true;
|
|
300
|
+
return (typeof value.prototype === "object" &&
|
|
301
|
+
value.prototype instanceof PEWDriver);
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=PEWDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PEWDriver.js","sourceRoot":"","sources":["../../src/driver/PEWDriver.ts"],"names":[],"mappings":"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","sourcesContent":["import { DefaultedWeakMap } from \"@here.build/collections\";\nimport type { PlexusAwareness } from \"@here.build/plexus\";\nimport { action, computed, observable, toJS } from \"mobx\";\n\nimport type { ExpectationActor } from \"./ExpectationActor.js\";\nimport { pewConfigurationSchema, pewSecretsSchema } from \"../schemas/connection.js\";\nimport type { AnyWorkExpectation, WorkExpectation } from \"../shared/models/WorkExpectation.js\";\nimport { revalidationDemandOf, type RevalidationDemand } from \"../shared/revalidation-demand.js\";\nimport type { ReadyState } from \"../shared/types.js\";\n\n/** Duck-typed — drivers may ship a different Zod major than this package. */\nexport type ConfigurationSchema = {\n safeParse(\n data: unknown,\n ):\n | { readonly success: true; readonly data: unknown }\n | { readonly success: false; readonly error: { readonly issues: ReadonlyArray<{ readonly message?: string }> } };\n};\n\n/** Process-local. Secrets are never a Plexus field. */\nexport type ConnectionSecretsView = {\n readonly revision?: number;\n get(field: string): unknown | undefined;\n /** MCP env_* enumerates deposited fields. */\n all?(): Readonly<Record<string, unknown>> | undefined;\n /** Hosts that persist a refreshed session (reauth) implement this. */\n replace?(secrets: Readonly<Record<string, string>>): void;\n};\n\nconst EMPTY_SECRETS: ConnectionSecretsView = { get: () => undefined };\n\n/** Module-graph duplication breaks instanceof; the elevation gate checks this brand too. */\n// eslint-disable-next-line no-secrets/no-secrets -- package identity tag, not a secret\nexport const PEW_DRIVER_BRAND = \"@inhuman.tools/plexus-expectations:PEWDriver@1\";\n\n/** A connection construction the driver already knows will work. */\nexport type DriverOffer = {\n readonly name: string;\n readonly description: string;\n readonly live: boolean;\n readonly adoptable: boolean;\n readonly settings: Readonly<Record<string, unknown>>;\n};\n\n/**\n * Driver extras the orchestrator mirrors onto `spec.live`.\n * Core process facts live on `readyState` / `error` / `offers`.\n */\nexport function extraLiveFromState(state: object): Record<string, unknown> {\n const extra: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(state)) {\n if (value === undefined) continue;\n extra[key] = toJS(value);\n }\n return extra;\n}\n\n/**\n * The CLASS is the driver (one loaded module per driver name).\n * The INSTANCE is a live connection (one per connection id).\n *\n * CLAIM DOES NOT LIVE HERE. Which WorkExpectation classes this driver handles\n * lives on the advertised driver record (`can`): dynamically loaded code does\n * not get to declare its own authority.\n *\n * Live state is report only — no machinery branches on it. Instance bootstrap\n * truth is `bootstrapDone` / `bootstrapPending`. Drivers read {@link attention}\n * as the reduced token, never clientIds.\n *\n * YAML doors ({@link configurationSchema} / {@link secretsSchema}) parse\n * without `new`. Secrets stay a live view — the host may replace it (reauth).\n */\nexport abstract class PEWDriver<\n E extends AnyWorkExpectation = AnyWorkExpectation,\n C = Readonly<Record<string, unknown>>,\n> implements AsyncDisposable {\n // ── driver side (the CLASS is the driver) ─────────────────────────────\n static readonly pewBrand: string = PEW_DRIVER_BRAND;\n\n /**\n * YAML settings shape. Default is a passthrough record — subclasses replace\n * this with a real object schema (transforms included). First issue message\n * is what construct / parse throw.\n */\n static readonly configurationSchema: ConfigurationSchema = pewConfigurationSchema;\n\n static readonly configurationLabel: string = \"\";\n\n static configurationError(message: string): string {\n const label = this.configurationLabel.trim();\n return label === \"\" ? `connection config invalid: ${message}` : `${label} connection config invalid: ${message}`;\n }\n\n /** YAML settings door. Does not construct an instance. */\n static parseConfiguration(settings: unknown = {}): unknown {\n const result = this.configurationSchema.safeParse(settings ?? {});\n if (result.success) return result.data;\n const message = result.error.issues[0]?.message ?? \"invalid\";\n throw new Error(this.configurationError(message));\n }\n\n static readonly secretsSchema: ConfigurationSchema = pewSecretsSchema;\n\n static secretsError(message: string): string {\n const label = this.configurationLabel.trim();\n return label === \"\" ? `connection secrets invalid: ${message}` : `${label} connection secrets invalid: ${message}`;\n }\n\n /** YAML secrets door. Does not construct an instance. */\n static parseSecrets(secrets: unknown = {}): unknown {\n const result = this.secretsSchema.safeParse(secrets ?? {});\n if (result.success) return result.data;\n const message = result.error.issues[0]?.message ?? \"invalid\";\n throw new Error(this.secretsError(message));\n }\n\n /** Shared on the prototype chain — own extras per subclass. */\n static readonly state: Record<string, unknown> = {};\n /**\n * A plain list, or a getter over observable state when the driver keeps its\n * offers fresh (local detection). The orchestrator mirrors it onto\n * `DriverSpec.offers` with a reaction, which is also what observes it.\n */\n static readonly offers: readonly DriverOffer[] = [];\n\n /** Kernel-plane occupancy hub. Orchestrator assignment is own-per-class. */\n static awareness: PlexusAwareness | undefined;\n static driverName = \"\";\n\n /**\n * A getter, not `@computed` — MobX: the decorator's initializer pins to the\n * declaring class, so subclasses would share one computed.\n */\n static get revalidationDemand(): RevalidationDemand {\n const hub = this.awareness;\n const name = this.driverName;\n if (hub === undefined || name === \"\") return \"none\";\n return revalidationDemandOf(hub, { kind: \"driver\", name });\n }\n\n // ── connection side (the INSTANCE is the connection) ──────────────────\n @observable accessor readyState: ReadyState = null;\n @observable accessor error: string = \"\";\n /**\n * MobX: shallow — extras (models, tools, account) are replaced wholesale.\n * Override the accessor with a wider literal to add driver facts.\n */\n @observable.shallow accessor state: Record<string, unknown> = {};\n\n @observable.ref accessor awareness: PlexusAwareness | undefined = undefined;\n\n @computed\n get revalidationDemand(): RevalidationDemand {\n const hub = this.awareness;\n if (hub === undefined) return \"none\";\n return revalidationDemandOf(hub, { kind: \"connection\", id: this.connectionId });\n }\n\n constructor(\n public readonly connectionId: string,\n settings: unknown = {},\n secrets: ConnectionSecretsView | Readonly<Record<string, unknown>> = EMPTY_SECRETS,\n ) {\n const cls = new.target as typeof PEWDriver;\n this.settings = cls.parseConfiguration(settings) as C;\n const view: ConnectionSecretsView =\n typeof (secrets as ConnectionSecretsView).get === \"function\"\n ? (secrets as ConnectionSecretsView)\n : {\n get: (field) => (secrets as Readonly<Record<string, unknown>>)[field],\n all: () => secrets as Readonly<Record<string, unknown>>,\n };\n cls.parseSecrets(view.all?.() ?? {});\n this.secrets = view;\n }\n readonly settings: C;\n /** Live view. The host may replace it (reauth). */\n secrets: ConnectionSecretsView;\n\n /**\n * Host binds the disk writer for this connection's settings bag.\n * Parsed settings stay readonly; a driver that learns a value overrides this.\n */\n bindSettingsWriter(_write: (patch: Readonly<Record<string, unknown>>) => void): void {}\n\n abstract bootstrap(): Promise<void>;\n\n bootstrapDone = false;\n bootstrapPending: Promise<void> | null = null;\n /** `resolve()` threw — the connection is broken, not the work. */\n broken = false;\n /** Concurrent callers share one promise. Async settlement is its own MobX action. */\n @action\n ensureBootstrapStarted(): Promise<void> {\n if (this.bootstrapDone) return Promise.resolve();\n if (this.bootstrapPending) return this.bootstrapPending;\n this.readyState = \"bootstrapping\";\n this.error = \"\";\n this.bootstrapPending = this.bootstrap().then(\n action(() => {\n this.bootstrapDone = true;\n this.readyState = \"ready\";\n this.error = \"\";\n }),\n action((error: unknown) => {\n this.readyState = \"failed\";\n this.error = error instanceof Error ? error.message : String(error);\n throw error;\n }),\n );\n return this.bootstrapPending;\n }\n\n @action\n failReady(error: unknown): void {\n this.broken = true;\n this.readyState = \"failed\";\n this.error = error instanceof Error ? error.message : String(error);\n }\n\n protected abstract resolve(expectation: E): ExpectationActor<E>;\n /** Nothing in PEW calls this; hosts or tests may. */\n async [Symbol.asyncDispose](): Promise<void> {}\n\n private readonly actors = new DefaultedWeakMap<WorkExpectation, ExpectationActor<any>>((expectation: WorkExpectation): ExpectationActor<any> => {\n const actor = this.resolve(expectation as E);\n this.liveActors.add(actor);\n return actor;\n});\n private readonly liveActors = new Set<ExpectationActor<any>>();\n\n has(expectation: WorkExpectation): boolean {\n return this.actors.has(expectation);\n }\n resolveExpectation<T extends AnyWorkExpectation>(expectation: T): ExpectationActor<T> {\n return this.actors.get(expectation);\n }\n release(expectation: WorkExpectation): void {\n if (!this.actors.has(expectation)) return;\n const actor = this.actors.get(expectation);\n this.actors.delete(expectation);\n this.liveActors.delete(actor);\n actor.leave();\n }\n\n /**\n * Logout/drop aborts interned work. Not park. Subclasses abort `#inflight`.\n */\n abortOnDrop(reason: unknown): void {\n for (const actor of this.liveActors) actor.abort(reason);\n }\n\n /**\n * Honor one demand.\n * `resolve()` throwing is a broken connection, not a failed expectation.\n */\n handle(expectation: WorkExpectation): void {\n if (this.broken) return;\n if (expectation.isDone) return;\n if (this.has(expectation)) {\n const existing = this.resolveExpectation(expectation);\n if (!existing.started) existing.start();\n return;\n }\n\n let actor: ExpectationActor<any>;\n try {\n actor = this.resolveExpectation(expectation);\n } catch (error) {\n this.failReady(error);\n return;\n }\n\n // Awareness / host policy may have sealed the work while resolve() ran.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- resolve() can seal via spawn hooks\n if (expectation.isDone) {\n actor.leave();\n return;\n }\n\n if (!actor.started) {\n actor.start();\n }\n }\n}\n\n/**\n * A concrete `PEWDriver` subclass — constructable, not abstract.\n * `loadDriverModule` returns `unknown`; {@link isDriverConnectionClass} is the gate.\n */\nexport type DriverConnectionClass = {\n [K in keyof typeof PEWDriver]: (typeof PEWDriver)[K];\n} & (new (...args: ConstructorParameters<typeof PEWDriver>) => PEWDriver);\n\nexport function isDriverConnectionClass(value: unknown): value is DriverConnectionClass {\n if (typeof value !== \"function\") return false;\n if ((value as { pewBrand?: unknown }).pewBrand === PEW_DRIVER_BRAND) return true;\n return (\n typeof (value as { prototype?: unknown }).prototype === \"object\" &&\n (value as { prototype: object }).prototype instanceof PEWDriver\n );\n}\n"]}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { PlexusAwareness } from "@here.build/plexus";
|
|
2
|
+
import type { ExpectationActor } from "./ExpectationActor.js";
|
|
3
|
+
import { type Attention } from "../shared/attention.js";
|
|
4
|
+
import type { AnyWorkExpectation, WorkExpectation } from "../shared/models/WorkExpectation.js";
|
|
5
|
+
import type { ReadyState } from "../shared/types.js";
|
|
6
|
+
/** Duck-typed — drivers may ship a different Zod major than this package. */
|
|
7
|
+
export type ConfigurationSchema = {
|
|
8
|
+
safeParse(data: unknown): {
|
|
9
|
+
readonly success: true;
|
|
10
|
+
readonly data: unknown;
|
|
11
|
+
} | {
|
|
12
|
+
readonly success: false;
|
|
13
|
+
readonly error: {
|
|
14
|
+
readonly issues: ReadonlyArray<{
|
|
15
|
+
readonly message?: string;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/** Process-local. Secrets are never a Plexus field. */
|
|
21
|
+
export type ConnectionSecretsView = {
|
|
22
|
+
readonly revision?: number;
|
|
23
|
+
get(field: string): unknown | undefined;
|
|
24
|
+
/** MCP env_* enumerates deposited fields. */
|
|
25
|
+
all?(): Readonly<Record<string, unknown>> | undefined;
|
|
26
|
+
/** Hosts that persist a refreshed session (reauth) implement this. */
|
|
27
|
+
replace?(secrets: Readonly<Record<string, string>>): void;
|
|
28
|
+
};
|
|
29
|
+
/** Module-graph duplication breaks instanceof; the elevation gate checks this brand too. */
|
|
30
|
+
export declare const PEW_DRIVER_CONNECTION_BRAND = "@inhuman.tools/plexus-expectations:PEWDriverConnection@1";
|
|
31
|
+
/** A connection construction the driver already knows will work. */
|
|
32
|
+
export type DriverOffer = {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly description: string;
|
|
35
|
+
readonly live: boolean;
|
|
36
|
+
readonly adoptable: boolean;
|
|
37
|
+
readonly settings: Readonly<Record<string, unknown>>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Driver extras the orchestrator mirrors onto `spec.live`.
|
|
41
|
+
* Core process facts live on `readyState` / `error` / `offers`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function extraLiveFromState(state: object): Record<string, unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* The CLASS is the driver (one loaded module per driver name).
|
|
46
|
+
* The INSTANCE is a live connection (one per connection id).
|
|
47
|
+
*
|
|
48
|
+
* CLAIM DOES NOT LIVE HERE. Which WorkExpectation classes this driver handles
|
|
49
|
+
* lives on the advertised driver record (`can`): dynamically loaded code does
|
|
50
|
+
* not get to declare its own authority.
|
|
51
|
+
*
|
|
52
|
+
* Live state is report only — no machinery branches on it. Instance bootstrap
|
|
53
|
+
* truth is `bootstrapDone` / `bootstrapPending`. Drivers read {@link attention}
|
|
54
|
+
* as the reduced token, never clientIds.
|
|
55
|
+
*
|
|
56
|
+
* YAML doors ({@link configurationSchema} / {@link secretsSchema}) parse
|
|
57
|
+
* without `new`. Secrets stay a live view — the host may replace it (reauth).
|
|
58
|
+
*/
|
|
59
|
+
export declare abstract class PEWDriverConnection<E extends AnyWorkExpectation = AnyWorkExpectation, C = Readonly<Record<string, unknown>>> implements AsyncDisposable {
|
|
60
|
+
readonly connectionId: string;
|
|
61
|
+
static readonly pewBrand: string;
|
|
62
|
+
/**
|
|
63
|
+
* YAML settings shape. Default is a passthrough record — subclasses replace
|
|
64
|
+
* this with a real object schema (transforms included). First issue message
|
|
65
|
+
* is what construct / parse throw.
|
|
66
|
+
*/
|
|
67
|
+
static readonly configurationSchema: ConfigurationSchema;
|
|
68
|
+
static readonly configurationLabel: string;
|
|
69
|
+
static configurationError(message: string): string;
|
|
70
|
+
/** YAML settings door. Does not construct an instance. */
|
|
71
|
+
static parseConfiguration(settings?: unknown): unknown;
|
|
72
|
+
static readonly secretsSchema: ConfigurationSchema;
|
|
73
|
+
static secretsError(message: string): string;
|
|
74
|
+
/** YAML secrets door. Does not construct an instance. */
|
|
75
|
+
static parseSecrets(secrets?: unknown): unknown;
|
|
76
|
+
/** Shared on the prototype chain — own extras per subclass. */
|
|
77
|
+
static readonly state: Record<string, unknown>;
|
|
78
|
+
static readonly offers: readonly DriverOffer[];
|
|
79
|
+
/** Kernel-plane occupancy hub. Orchestrator assignment is own-per-class. */
|
|
80
|
+
static awareness: PlexusAwareness | undefined;
|
|
81
|
+
static driverName: string;
|
|
82
|
+
/**
|
|
83
|
+
* A getter, not `@computed` — MobX: the decorator's initializer pins to the
|
|
84
|
+
* declaring class, so subclasses would share one computed.
|
|
85
|
+
*/
|
|
86
|
+
static get attention(): Attention;
|
|
87
|
+
accessor readyState: ReadyState;
|
|
88
|
+
accessor error: string;
|
|
89
|
+
/**
|
|
90
|
+
* MobX: shallow — extras (models, tools, account) are replaced wholesale.
|
|
91
|
+
* Override the accessor with a wider literal to add driver facts.
|
|
92
|
+
*/
|
|
93
|
+
accessor state: Record<string, unknown>;
|
|
94
|
+
accessor awareness: PlexusAwareness | undefined;
|
|
95
|
+
get attention(): Attention;
|
|
96
|
+
constructor(connectionId: string, settings?: unknown, secrets?: ConnectionSecretsView | Readonly<Record<string, unknown>>);
|
|
97
|
+
readonly settings: C;
|
|
98
|
+
/** Live view. The host may replace it (reauth). */
|
|
99
|
+
secrets: ConnectionSecretsView;
|
|
100
|
+
/**
|
|
101
|
+
* Host binds the disk writer for this connection's settings bag.
|
|
102
|
+
* Parsed settings stay readonly; a driver that learns a value overrides this.
|
|
103
|
+
*/
|
|
104
|
+
bindSettingsWriter(_write: (patch: Readonly<Record<string, unknown>>) => void): void;
|
|
105
|
+
abstract bootstrap(): Promise<void>;
|
|
106
|
+
bootstrapDone: boolean;
|
|
107
|
+
bootstrapPending: Promise<void> | null;
|
|
108
|
+
/** `resolve()` threw — the connection is broken, not the work. */
|
|
109
|
+
broken: boolean;
|
|
110
|
+
/** Concurrent callers share one promise. Async settlement is its own MobX action. */
|
|
111
|
+
ensureBootstrapStarted(): Promise<void>;
|
|
112
|
+
failReady(error: unknown): void;
|
|
113
|
+
protected abstract resolve(expectation: E): ExpectationActor<E>;
|
|
114
|
+
/** Nothing in PEW calls this; hosts or tests may. */
|
|
115
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
116
|
+
private readonly actors;
|
|
117
|
+
private readonly liveActors;
|
|
118
|
+
has(expectation: WorkExpectation): boolean;
|
|
119
|
+
resolveExpectation<T extends AnyWorkExpectation>(expectation: T): ExpectationActor<T>;
|
|
120
|
+
release(expectation: WorkExpectation): void;
|
|
121
|
+
/**
|
|
122
|
+
* Logout/drop aborts interned work. Not park. Subclasses abort `#inflight`.
|
|
123
|
+
*/
|
|
124
|
+
abortOnDrop(reason: unknown): void;
|
|
125
|
+
/**
|
|
126
|
+
* Honor one demand.
|
|
127
|
+
* `resolve()` throwing is a broken connection, not a failed expectation.
|
|
128
|
+
*/
|
|
129
|
+
handle(expectation: WorkExpectation): void;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A concrete `PEWDriverConnection` subclass — constructable, not abstract.
|
|
133
|
+
* `loadDriverModule` returns `unknown`; {@link isDriverConnectionClass} is the gate.
|
|
134
|
+
*/
|
|
135
|
+
export type DriverConnectionClass = {
|
|
136
|
+
[K in keyof typeof PEWDriverConnection]: (typeof PEWDriverConnection)[K];
|
|
137
|
+
} & (new (...args: ConstructorParameters<typeof PEWDriverConnection>) => PEWDriverConnection);
|
|
138
|
+
export declare function isDriverConnectionClass(value: unknown): value is DriverConnectionClass;
|
|
139
|
+
//# sourceMappingURL=PEWDriverConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PEWDriverConnection.d.ts","sourceRoot":"","sources":["../../src/driver/PEWDriverConnection.ts"],"names":[],"mappings":"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"}
|