pi-radar 0.2.0 → 0.4.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/README.md +10 -4
- package/dist/extension/baseline.js +333 -394
- package/dist/extension/radar-client.js +126 -11
- package/dist/extension/radar-communication.js +39 -0
- package/dist/extension/radar-execution.js +169 -382
- package/dist/extension/radar-launch.js +18 -13
- package/dist/extension/radar-publication.js +161 -298
- package/dist/extension/radar-runtime.js +1 -1
- package/dist/index.js +356 -407
- package/extension/baseline.ts +2 -0
- package/extension/generated-contracts.ts +1310 -10
- package/extension/radar-client.ts +191 -23
- package/extension/radar-communication.ts +66 -0
- package/extension/radar-execution.ts +11 -58
- package/extension/radar-launch.ts +29 -22
- package/extension/radar-publication.ts +211 -410
- package/extension/radar-runtime.ts +4 -1
- package/index.ts +1 -0
- package/package.json +9 -5
- package/schema/public/v1/handoff-inbox.deserialize.schema.json +18 -0
- package/schema/public/v1/handoff-inbox.serialize.schema.json +18 -0
- package/schema/public/v1/handoff-publish-params.deserialize.schema.json +33 -0
- package/schema/public/v1/handoff-publish-params.serialize.schema.json +33 -0
- package/schema/public/v1/handoff-receipt.deserialize.schema.json +66 -0
- package/schema/public/v1/handoff-receipt.serialize.schema.json +66 -0
- package/schema/public/v1/handoff.deserialize.schema.json +84 -0
- package/schema/public/v1/handoff.serialize.schema.json +84 -0
- package/schema/public/v1/observation-get-params.deserialize.schema.json +46 -0
- package/schema/public/v1/observation-get-params.serialize.schema.json +52 -0
- package/schema/public/v1/observation-get-response.deserialize.schema.json +2731 -0
- package/schema/public/v1/observation-get-response.serialize.schema.json +2862 -0
- package/schema/public/v1/observation-snapshot.deserialize.schema.json +2616 -0
- package/schema/public/v1/observation-snapshot.serialize.schema.json +2741 -0
- package/schema/public/v1/presence-answer.deserialize.schema.json +40 -0
- package/schema/public/v1/presence-answer.serialize.schema.json +40 -0
- package/schema/public/v1/presence-release.deserialize.schema.json +51 -0
- package/schema/public/v1/presence-release.serialize.schema.json +52 -0
- package/schema/public/v1/presence-report.deserialize.schema.json +149 -0
- package/schema/public/v1/presence-report.serialize.schema.json +157 -0
- package/extension/radar-session-marker.ts +0 -146
- package/schema/public/v1/launch-identity-marker.deserialize.schema.json +0 -32
- package/schema/public/v1/launch-identity-marker.serialize.schema.json +0 -32
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
var radar_client_exports = {};
|
|
9
9
|
__export(radar_client_exports, {
|
|
10
10
|
RADAR_CALL_TIMEOUT_MS: () => RADAR_CALL_TIMEOUT_MS,
|
|
11
|
+
RADAR_COMMUNICATION_CONTRACT: () => RADAR_COMMUNICATION_CONTRACT,
|
|
11
12
|
RADAR_EVENTS_CONTRACT: () => RADAR_EVENTS_CONTRACT,
|
|
12
13
|
RADAR_EVENT_RETRY_MS: () => RADAR_EVENT_RETRY_MS,
|
|
13
14
|
RADAR_MAX_AWAITED: () => RADAR_MAX_AWAITED,
|
|
@@ -45,6 +46,7 @@ var RADAR_SPAWN_CONTRACT = "spawn.v1";
|
|
|
45
46
|
var RADAR_SPAWN_CLOSE_CONTRACT = "spawn.close.v1";
|
|
46
47
|
var RADAR_SPAWN_LAUNCH_CONTEXT_CONTRACT = "spawn.launch_context.v1";
|
|
47
48
|
var RADAR_EVENTS_CONTRACT = "events.v1";
|
|
49
|
+
var RADAR_COMMUNICATION_CONTRACT = "communication.handoff.v1";
|
|
48
50
|
var RADAR_REQUESTER = "pi-radar";
|
|
49
51
|
var RADAR_MAX_LINE_BYTES = 1024 * 1024;
|
|
50
52
|
var RADAR_CALL_TIMEOUT_MS = 2e3;
|
|
@@ -142,6 +144,25 @@ function recordAt(value, field) {
|
|
|
142
144
|
function isUuid(value) {
|
|
143
145
|
return typeof value === "string" && UUID.test(value);
|
|
144
146
|
}
|
|
147
|
+
function decodePresenceAnswer(value) {
|
|
148
|
+
const registrationId = recordAt(value, "registration_id");
|
|
149
|
+
const claimId = recordAt(value, "claim_id");
|
|
150
|
+
const standing = recordAt(value, "standing");
|
|
151
|
+
const subjectId = recordAt(value, "subject_id");
|
|
152
|
+
if (!isUuid(registrationId) || !isUuid(claimId) || !["pending", "granted", "duplicate", "released"].includes(String(standing)) || subjectId !== void 0 && !isUuid(subjectId) || standing === "granted" && !isUuid(subjectId))
|
|
153
|
+
return protocol("presence reply carries no valid claim standing");
|
|
154
|
+
return { ok: true, value };
|
|
155
|
+
}
|
|
156
|
+
function managementAt(value) {
|
|
157
|
+
const field = recordAt(value, "management");
|
|
158
|
+
const state = stringAt(field, "state");
|
|
159
|
+
if (state === "managed") {
|
|
160
|
+
const subjectId = stringAt(field, "subject_id");
|
|
161
|
+
return subjectId === void 0 ? void 0 : { state, subject_id: subjectId };
|
|
162
|
+
}
|
|
163
|
+
if (state === "duplicate" || state === "pending" || state === "unmanaged") return { state };
|
|
164
|
+
return void 0;
|
|
165
|
+
}
|
|
145
166
|
function stringAt(value, field) {
|
|
146
167
|
if (typeof value !== "object" || value === null) return void 0;
|
|
147
168
|
const found = value[field];
|
|
@@ -152,6 +173,28 @@ function numberAt(value, field) {
|
|
|
152
173
|
const found = value[field];
|
|
153
174
|
return typeof found === "number" && Number.isFinite(found) ? found : void 0;
|
|
154
175
|
}
|
|
176
|
+
function handoffAt(value) {
|
|
177
|
+
const version = numberAt(value, "version");
|
|
178
|
+
const id = stringAt(value, "id");
|
|
179
|
+
const sender = recordAt(value, "sender");
|
|
180
|
+
const senderGeneration = numberAt(sender, "execution_generation");
|
|
181
|
+
const target = stringAt(value, "recipient_subject_id");
|
|
182
|
+
const summary = stringAt(value, "summary");
|
|
183
|
+
const content = stringAt(value, "content");
|
|
184
|
+
const published = numberAt(value, "published_at_unix_ms");
|
|
185
|
+
const correlation = typeof value === "object" && value !== null ? value.correlation_id : void 0;
|
|
186
|
+
if (version !== 1 || !isUuid(id) || !isUuid(stringAt(sender, "registration_id")) || !isUuid(stringAt(sender, "session_id")) || !isUuid(stringAt(sender, "subject_id")) || !isUuid(stringAt(sender, "execution_id")) || !Number.isSafeInteger(senderGeneration) || (senderGeneration ?? 0) < 1 || !isUuid(target) || summary === void 0 || content === void 0 || published === void 0 || !Number.isSafeInteger(published) || published < 0 || correlation !== void 0 && correlation !== null && (typeof correlation !== "string" || correlation.length === 0 || Buffer.byteLength(correlation, "utf8") > 256 || new RegExp("\\p{Cc}", "u").test(correlation))) return void 0;
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
function handoffReceiptAt(value) {
|
|
190
|
+
const version = numberAt(value, "version");
|
|
191
|
+
const handoffId = stringAt(value, "handoff_id");
|
|
192
|
+
const recipient = recordAt(value, "recipient");
|
|
193
|
+
const generation = numberAt(recipient, "execution_generation");
|
|
194
|
+
const received = numberAt(value, "received_at_unix_ms");
|
|
195
|
+
if (version !== 1 || !isUuid(handoffId) || !isUuid(stringAt(recipient, "registration_id")) || !isUuid(stringAt(recipient, "session_id")) || !isUuid(stringAt(recipient, "subject_id")) || !isUuid(stringAt(recipient, "execution_id")) || !Number.isSafeInteger(generation) || (generation ?? 0) < 1 || received === void 0 || !Number.isSafeInteger(received) || received < 0) return void 0;
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
155
198
|
function writerBinding(value) {
|
|
156
199
|
const handle = stringAt(value, "handle");
|
|
157
200
|
const source = stringAt(value, "source");
|
|
@@ -261,7 +304,8 @@ var RADAR_SPAWN_TOKEN_ENV = "PI_RADAR_SPAWN_TOKEN";
|
|
|
261
304
|
var RADAR_MANAGED_IDENTITY_ENV = /* @__PURE__ */ new Set([
|
|
262
305
|
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
263
306
|
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
264
|
-
"PI_RADAR_MANAGED_EXECUTION_GENERATION"
|
|
307
|
+
"PI_RADAR_MANAGED_EXECUTION_GENERATION",
|
|
308
|
+
"PI_RADAR_MANAGED_PARENT_SUBJECT_ID"
|
|
265
309
|
]);
|
|
266
310
|
function unresolvedSpawn(requestId, detail) {
|
|
267
311
|
return {
|
|
@@ -306,7 +350,7 @@ function spawnEdge(value) {
|
|
|
306
350
|
const bound = recordAt(value, "bound");
|
|
307
351
|
const source = stringAt(bound, "source");
|
|
308
352
|
const incarnation = stringAt(bound, "incarnation");
|
|
309
|
-
const agentId = stringAt(bound, "
|
|
353
|
+
const agentId = stringAt(bound, "registration_id");
|
|
310
354
|
const exit = exitAt(recordAt(value, "exit_observation"));
|
|
311
355
|
return {
|
|
312
356
|
ok: true,
|
|
@@ -320,7 +364,7 @@ function spawnEdge(value) {
|
|
|
320
364
|
bound: {
|
|
321
365
|
source,
|
|
322
366
|
incarnation,
|
|
323
|
-
...isUuid(agentId) ? {
|
|
367
|
+
...isUuid(agentId) ? { registration_id: agentId } : {}
|
|
324
368
|
}
|
|
325
369
|
} : {},
|
|
326
370
|
...exit !== void 0 ? { exit_observation: exit } : {}
|
|
@@ -718,6 +762,22 @@ function createRadarClient(options = {}) {
|
|
|
718
762
|
return {
|
|
719
763
|
socketPath,
|
|
720
764
|
ping,
|
|
765
|
+
async presence(request) {
|
|
766
|
+
return withRegistry(async () => {
|
|
767
|
+
const answer = await call("agent.presence", { ...request });
|
|
768
|
+
if (!answer.ok) return answer;
|
|
769
|
+
return decodePresenceAnswer(answer.value);
|
|
770
|
+
});
|
|
771
|
+
},
|
|
772
|
+
async releasePresence(request) {
|
|
773
|
+
return withRegistry(async () => {
|
|
774
|
+
const answer = await call("agent.release", { ...request });
|
|
775
|
+
if (!answer.ok) return answer;
|
|
776
|
+
const decoded = decodePresenceAnswer(answer.value);
|
|
777
|
+
if (!decoded.ok) return decoded;
|
|
778
|
+
return decoded.value.standing === "released" ? decoded : protocol("release reply did not confirm the claim release");
|
|
779
|
+
});
|
|
780
|
+
},
|
|
721
781
|
async register(registration) {
|
|
722
782
|
return withRegistry(async () => {
|
|
723
783
|
const answer = await call("agent.register", {
|
|
@@ -733,15 +793,15 @@ function createRadarClient(options = {}) {
|
|
|
733
793
|
});
|
|
734
794
|
if (answer.ok === false) return answer;
|
|
735
795
|
const record = answer.value.registration;
|
|
736
|
-
const agentId = stringAt(record, "
|
|
737
|
-
if (!isUuid(agentId)) return protocol("registration reply carries no
|
|
738
|
-
return { ok: true, value: {
|
|
796
|
+
const agentId = stringAt(record, "registration_id");
|
|
797
|
+
if (!isUuid(agentId)) return protocol("registration reply carries no registration_id");
|
|
798
|
+
return { ok: true, value: { registration_id: agentId } };
|
|
739
799
|
});
|
|
740
800
|
},
|
|
741
801
|
async acquire(request) {
|
|
742
802
|
return withRegistryChannel(request.channel, async () => {
|
|
743
803
|
const answer = await call("agent.acquire", {
|
|
744
|
-
|
|
804
|
+
registration_id: request.registration_id,
|
|
745
805
|
channel: request.channel,
|
|
746
806
|
publisher: request.publisher,
|
|
747
807
|
...request.replace !== void 0 ? { replace: request.replace } : {}
|
|
@@ -770,7 +830,7 @@ function createRadarClient(options = {}) {
|
|
|
770
830
|
}
|
|
771
831
|
return withRegistryChannel(request.channel, async () => {
|
|
772
832
|
const answer = await call("agent.publish", {
|
|
773
|
-
|
|
833
|
+
registration_id: request.registration_id,
|
|
774
834
|
channel: request.channel,
|
|
775
835
|
writer_handle: request.writer_handle,
|
|
776
836
|
sequence: request.sequence,
|
|
@@ -789,7 +849,7 @@ function createRadarClient(options = {}) {
|
|
|
789
849
|
async context(request) {
|
|
790
850
|
return withRegistry(async () => {
|
|
791
851
|
const answer = await call("agent.context", {
|
|
792
|
-
|
|
852
|
+
registration_id: request.registration_id,
|
|
793
853
|
publisher: request.publisher,
|
|
794
854
|
...request.writer_handle !== void 0 ? { writer_handle: request.writer_handle } : {},
|
|
795
855
|
...request.replace !== void 0 ? { replace: request.replace } : {},
|
|
@@ -805,9 +865,14 @@ function createRadarClient(options = {}) {
|
|
|
805
865
|
if (writer === void 0)
|
|
806
866
|
return protocol("context reply carries no writer binding");
|
|
807
867
|
const warning = stringAt(answer.value, "warning");
|
|
868
|
+
const management = managementAt(answer.value);
|
|
808
869
|
return {
|
|
809
870
|
ok: true,
|
|
810
|
-
value: {
|
|
871
|
+
value: {
|
|
872
|
+
writer,
|
|
873
|
+
...warning !== void 0 ? { warning } : {},
|
|
874
|
+
...management !== void 0 ? { management } : {}
|
|
875
|
+
}
|
|
811
876
|
};
|
|
812
877
|
});
|
|
813
878
|
},
|
|
@@ -884,7 +949,7 @@ function createRadarClient(options = {}) {
|
|
|
884
949
|
message: "agent.get requires a canonical agent UUID"
|
|
885
950
|
};
|
|
886
951
|
return withRegistry(async () => {
|
|
887
|
-
const answer = await call("agent.get", {
|
|
952
|
+
const answer = await call("agent.get", { registration_id: agentId });
|
|
888
953
|
if (answer.ok === false) return answer;
|
|
889
954
|
return agentProcessAt(recordAt(answer.value, "agent"));
|
|
890
955
|
});
|
|
@@ -935,6 +1000,56 @@ function createRadarClient(options = {}) {
|
|
|
935
1000
|
return protocol("spawn.close reply carries no close outcome");
|
|
936
1001
|
});
|
|
937
1002
|
},
|
|
1003
|
+
async communicationPublish(request) {
|
|
1004
|
+
return withContract(RADAR_COMMUNICATION_CONTRACT, async () => {
|
|
1005
|
+
const answer = await call("communication.publish", {
|
|
1006
|
+
sender_registration_id: request.sender_registration_id,
|
|
1007
|
+
recipient_subject_id: request.recipient_subject_id,
|
|
1008
|
+
...request.correlation_id !== void 0 ? { correlation_id: request.correlation_id } : {},
|
|
1009
|
+
summary: request.summary,
|
|
1010
|
+
content: request.content
|
|
1011
|
+
}, request.request_id);
|
|
1012
|
+
if (answer.ok === false) return answer;
|
|
1013
|
+
const handoff = handoffAt(recordAt(answer.value, "handoff"));
|
|
1014
|
+
const created = recordAt(answer.value, "created");
|
|
1015
|
+
if (handoff === void 0 || typeof created !== "boolean")
|
|
1016
|
+
return protocol("communication.publish reply carries no handoff");
|
|
1017
|
+
return { ok: true, value: { handoff, created } };
|
|
1018
|
+
});
|
|
1019
|
+
},
|
|
1020
|
+
async communicationInbox(request) {
|
|
1021
|
+
return withContract(RADAR_COMMUNICATION_CONTRACT, async () => {
|
|
1022
|
+
const answer = await call("communication.inbox", request);
|
|
1023
|
+
if (answer.ok === false) return answer;
|
|
1024
|
+
const handoffIds = recordAt(answer.value, "handoff_ids");
|
|
1025
|
+
if (!Array.isArray(handoffIds) || handoffIds.some((id) => !isUuid(id)))
|
|
1026
|
+
return protocol("communication.inbox reply carries malformed handoff IDs");
|
|
1027
|
+
return { ok: true, value: answer.value };
|
|
1028
|
+
});
|
|
1029
|
+
},
|
|
1030
|
+
async communicationGet(request) {
|
|
1031
|
+
return withContract(RADAR_COMMUNICATION_CONTRACT, async () => {
|
|
1032
|
+
const answer = await call("communication.get", request);
|
|
1033
|
+
if (answer.ok === false) return answer;
|
|
1034
|
+
const handoff = handoffAt(recordAt(answer.value, "handoff"));
|
|
1035
|
+
const receiptValue = recordAt(answer.value, "receipt");
|
|
1036
|
+
const receipt = receiptValue === null ? null : handoffReceiptAt(receiptValue);
|
|
1037
|
+
if (handoff === void 0 || receiptValue !== null && receipt === void 0)
|
|
1038
|
+
return protocol("communication.get reply carries malformed content or receipt");
|
|
1039
|
+
return { ok: true, value: { handoff, receipt: receipt ?? null } };
|
|
1040
|
+
});
|
|
1041
|
+
},
|
|
1042
|
+
async communicationAck(request) {
|
|
1043
|
+
return withContract(RADAR_COMMUNICATION_CONTRACT, async () => {
|
|
1044
|
+
const answer = await call("communication.ack", request);
|
|
1045
|
+
if (answer.ok === false) return answer;
|
|
1046
|
+
const receipt = handoffReceiptAt(recordAt(answer.value, "receipt"));
|
|
1047
|
+
const created = recordAt(answer.value, "created");
|
|
1048
|
+
if (receipt === void 0 || typeof created !== "boolean")
|
|
1049
|
+
return protocol("communication.ack reply carries no receipt");
|
|
1050
|
+
return { ok: true, value: { receipt, created } };
|
|
1051
|
+
});
|
|
1052
|
+
},
|
|
938
1053
|
async events(request) {
|
|
939
1054
|
if (!Number.isSafeInteger(request.after) || request.after < 0 || !Number.isSafeInteger(request.wait_ms) || request.wait_ms < 0 || request.wait_ms > RADAR_EVENT_WAIT_MS)
|
|
940
1055
|
return {
|
|
@@ -1155,6 +1270,47 @@ function boundedRadarSnapshot(snapshot) {
|
|
|
1155
1270
|
};
|
|
1156
1271
|
}
|
|
1157
1272
|
|
|
1273
|
+
// extension/radar-communication.ts
|
|
1274
|
+
var radar_communication_exports = {};
|
|
1275
|
+
__export(radar_communication_exports, {
|
|
1276
|
+
createRadarHandoffPort: () => createRadarHandoffPort
|
|
1277
|
+
});
|
|
1278
|
+
function createRadarHandoffPort(client, publication, parentSubjectId = () => process.env.PI_RADAR_MANAGED_PARENT_SUBJECT_ID) {
|
|
1279
|
+
async function agentId() {
|
|
1280
|
+
const subject = await publication.subject();
|
|
1281
|
+
return subject === void 0 ? { ok: false, code: "absent", message: "this process has no current Radar registration" } : { ok: true, value: subject.registration_id };
|
|
1282
|
+
}
|
|
1283
|
+
return {
|
|
1284
|
+
async publish(request) {
|
|
1285
|
+
const identity = await agentId();
|
|
1286
|
+
if (identity.ok === false) return identity;
|
|
1287
|
+
const parent = parentSubjectId();
|
|
1288
|
+
if (parent === void 0)
|
|
1289
|
+
return { ok: false, code: "absent", message: "this managed execution has no Radar parent subject" };
|
|
1290
|
+
return client.communicationPublish({
|
|
1291
|
+
...request,
|
|
1292
|
+
sender_registration_id: identity.value,
|
|
1293
|
+
recipient_subject_id: parent
|
|
1294
|
+
});
|
|
1295
|
+
},
|
|
1296
|
+
async inbox() {
|
|
1297
|
+
const identity = await agentId();
|
|
1298
|
+
if (identity.ok === false) return identity;
|
|
1299
|
+
return client.communicationInbox({ registration_id: identity.value });
|
|
1300
|
+
},
|
|
1301
|
+
async get(handoff_id) {
|
|
1302
|
+
const identity = await agentId();
|
|
1303
|
+
if (identity.ok === false) return identity;
|
|
1304
|
+
return client.communicationGet({ registration_id: identity.value, handoff_id });
|
|
1305
|
+
},
|
|
1306
|
+
async ack(handoff_id) {
|
|
1307
|
+
const identity = await agentId();
|
|
1308
|
+
if (identity.ok === false) return identity;
|
|
1309
|
+
return client.communicationAck({ registration_id: identity.value, handoff_id });
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1158
1314
|
// extension/radar-execution.ts
|
|
1159
1315
|
var radar_execution_exports = {};
|
|
1160
1316
|
__export(radar_execution_exports, {
|
|
@@ -1193,77 +1349,7 @@ import {
|
|
|
1193
1349
|
writeSync
|
|
1194
1350
|
} from "node:fs";
|
|
1195
1351
|
import { dirname as dirname2, join as join2, parse, resolve, sep } from "node:path";
|
|
1196
|
-
|
|
1197
|
-
// extension/radar-session-marker.ts
|
|
1198
|
-
var RADAR_LAUNCH_MARKER_TYPE = "pi-radar.launch-identity";
|
|
1199
|
-
var RADAR_LAUNCH_MARKER_VERSION = 1;
|
|
1200
|
-
var RADAR_MAX_EXECUTION_GENERATION = 4294967295;
|
|
1201
|
-
var RADAR_MANAGED_SUBJECT_ENV = "PI_RADAR_MANAGED_SUBJECT_ID";
|
|
1202
|
-
var RADAR_MANAGED_LAUNCH_ENV = "PI_RADAR_MANAGED_LAUNCH_ID";
|
|
1203
|
-
var RADAR_MANAGED_GENERATION_ENV = "PI_RADAR_MANAGED_EXECUTION_GENERATION";
|
|
1204
|
-
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
1205
|
-
function decodeRadarLaunchMarker(value) {
|
|
1206
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
1207
|
-
const record = value;
|
|
1208
|
-
if (Object.keys(record).sort().join(",") !== "execution_generation,launch_id,subject_id,version") {
|
|
1209
|
-
return void 0;
|
|
1210
|
-
}
|
|
1211
|
-
if (record.version !== RADAR_LAUNCH_MARKER_VERSION || typeof record.subject_id !== "string" || !UUID2.test(record.subject_id) || typeof record.launch_id !== "string" || !UUID2.test(record.launch_id) || !Number.isSafeInteger(record.execution_generation) || record.execution_generation < 1 || record.execution_generation > RADAR_MAX_EXECUTION_GENERATION) {
|
|
1212
|
-
return void 0;
|
|
1213
|
-
}
|
|
1214
|
-
return {
|
|
1215
|
-
version: RADAR_LAUNCH_MARKER_VERSION,
|
|
1216
|
-
subject_id: record.subject_id,
|
|
1217
|
-
launch_id: record.launch_id,
|
|
1218
|
-
execution_generation: record.execution_generation
|
|
1219
|
-
};
|
|
1220
|
-
}
|
|
1221
|
-
function appendRadarLaunchMarker(appendEntry, marker) {
|
|
1222
|
-
const validated = decodeRadarLaunchMarker(marker);
|
|
1223
|
-
if (!validated) throw new Error("invalid Radar launch identity marker");
|
|
1224
|
-
appendEntry(RADAR_LAUNCH_MARKER_TYPE, validated);
|
|
1225
|
-
}
|
|
1226
|
-
function latestRadarLaunchMarker(branch) {
|
|
1227
|
-
let latest;
|
|
1228
|
-
for (const entry of branch) {
|
|
1229
|
-
if (entry.type === "custom" && entry.customType === RADAR_LAUNCH_MARKER_TYPE) {
|
|
1230
|
-
latest = entry;
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
if (!latest) return { status: "absent" };
|
|
1234
|
-
const marker = decodeRadarLaunchMarker(latest.data);
|
|
1235
|
-
return marker ? { status: "valid", marker } : { status: "invalid" };
|
|
1236
|
-
}
|
|
1237
|
-
function radarLaunchMarkerFromEnvironment(env = process.env) {
|
|
1238
|
-
const rawGeneration = env[RADAR_MANAGED_GENERATION_ENV];
|
|
1239
|
-
if (env[RADAR_MANAGED_SUBJECT_ENV] === void 0 || env[RADAR_MANAGED_LAUNCH_ENV] === void 0 || rawGeneration === void 0 || !/^[1-9][0-9]*$/.test(rawGeneration)) {
|
|
1240
|
-
return void 0;
|
|
1241
|
-
}
|
|
1242
|
-
return decodeRadarLaunchMarker({
|
|
1243
|
-
version: RADAR_LAUNCH_MARKER_VERSION,
|
|
1244
|
-
subject_id: env[RADAR_MANAGED_SUBJECT_ENV],
|
|
1245
|
-
launch_id: env[RADAR_MANAGED_LAUNCH_ENV],
|
|
1246
|
-
execution_generation: Number(rawGeneration)
|
|
1247
|
-
});
|
|
1248
|
-
}
|
|
1249
|
-
function activeRadarLaunchMarker(host) {
|
|
1250
|
-
if (!host.sessionManager) return { status: "absent" };
|
|
1251
|
-
return latestRadarLaunchMarker(host.sessionManager.getBranch());
|
|
1252
|
-
}
|
|
1253
|
-
function persistRadarLaunchMarker(host, env = process.env) {
|
|
1254
|
-
const marker = radarLaunchMarkerFromEnvironment(env);
|
|
1255
|
-
if (!marker) return "absent";
|
|
1256
|
-
if (!host.appendEntry || !host.sessionManager) return "unsupported";
|
|
1257
|
-
const current = latestRadarLaunchMarker(host.sessionManager.getBranch());
|
|
1258
|
-
if (current.status === "valid" && sameMarker(current.marker, marker)) return "unchanged";
|
|
1259
|
-
appendRadarLaunchMarker(host.appendEntry, marker);
|
|
1260
|
-
return "written";
|
|
1261
|
-
}
|
|
1262
|
-
function sameMarker(a, b) {
|
|
1263
|
-
return a.version === b.version && a.subject_id === b.subject_id && a.launch_id === b.launch_id && a.execution_generation === b.execution_generation;
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
// extension/radar-publication.ts
|
|
1352
|
+
var DUPLICATE_SESSION_DIAGNOSTIC = "Radar rejected this session claim as a duplicate; reload or resume the session before retrying";
|
|
1267
1353
|
var RADAR_PUBLICATION_VERSION = 1;
|
|
1268
1354
|
var RADAR_LEASE_MS = 3e4;
|
|
1269
1355
|
var RADAR_HEARTBEAT_MS = 15e3;
|
|
@@ -1288,7 +1374,7 @@ function readProcessBirth() {
|
|
|
1288
1374
|
return void 0;
|
|
1289
1375
|
}
|
|
1290
1376
|
}
|
|
1291
|
-
var RECORD_NAME = /^(?:subjects|channels|context|bindings)\/[a-z0-9-]{1,64}\.json$/;
|
|
1377
|
+
var RECORD_NAME = /^(?:registrations|presence|subjects|channels|context|bindings)\/[a-z0-9-]{1,64}\.json$/;
|
|
1292
1378
|
var MAX_RECORD_BYTES = 64 * 1024;
|
|
1293
1379
|
var PRIVATE_MODE = 448;
|
|
1294
1380
|
var RECORD_MODE = 384;
|
|
@@ -1573,39 +1659,6 @@ function pendingAt(value, keys = PENDING_KEYS, codec = executionCodec) {
|
|
|
1573
1659
|
return void 0;
|
|
1574
1660
|
return { sequence, snapshot, lease_ms: lease, observed_at: observed };
|
|
1575
1661
|
}
|
|
1576
|
-
var CONTEXT_PENDING_KEYS = "lease_ms,observed_at,sequence,session";
|
|
1577
|
-
var CONTEXT_PENDING_MARKED_KEYS = "launch_identity,lease_ms,observed_at,sequence,session";
|
|
1578
|
-
var CONTEXT_ACCEPTED_KEYS = "lease_ms,observed_at,sent_at,sequence,session";
|
|
1579
|
-
var CONTEXT_ACCEPTED_MARKED_KEYS = "launch_identity,lease_ms,observed_at,sent_at,sequence,session";
|
|
1580
|
-
function sessionAt(value) {
|
|
1581
|
-
if (typeof value !== "object" || value === null) return void 0;
|
|
1582
|
-
const found = value.session;
|
|
1583
|
-
if (found === null) return null;
|
|
1584
|
-
return typeof found === "string" ? found : void 0;
|
|
1585
|
-
}
|
|
1586
|
-
function sameLaunchIdentity(a, b) {
|
|
1587
|
-
return a === b || a !== void 0 && b !== void 0 && a.version === b.version && a.subject_id === b.subject_id && a.launch_id === b.launch_id && a.execution_generation === b.execution_generation;
|
|
1588
|
-
}
|
|
1589
|
-
function contextReportAt(value, keys, markedKeys) {
|
|
1590
|
-
const marked = exactKeys(value, markedKeys);
|
|
1591
|
-
if (!exactKeys(value, keys) && !marked) return void 0;
|
|
1592
|
-
const sequence = numberAt2(value, "sequence");
|
|
1593
|
-
const lease = numberAt2(value, "lease_ms");
|
|
1594
|
-
const observed = textAt(value, "observed_at");
|
|
1595
|
-
const session = sessionAt(value);
|
|
1596
|
-
if (sequence === void 0 || sequence < 1) return void 0;
|
|
1597
|
-
if (lease === void 0 || observed === void 0 || session === void 0)
|
|
1598
|
-
return void 0;
|
|
1599
|
-
const marker = marked ? decodeRadarLaunchMarker(value.launch_identity) : void 0;
|
|
1600
|
-
if (marked && marker === void 0) return void 0;
|
|
1601
|
-
return {
|
|
1602
|
-
sequence,
|
|
1603
|
-
session,
|
|
1604
|
-
lease_ms: lease,
|
|
1605
|
-
observed_at: observed,
|
|
1606
|
-
...marker !== void 0 ? { launch_identity: marker } : {}
|
|
1607
|
-
};
|
|
1608
|
-
}
|
|
1609
1662
|
function createChannelWriter(input) {
|
|
1610
1663
|
const { store, client, scheduler, recordName, channel, publisher } = input;
|
|
1611
1664
|
const codec = input.codec ?? executionCodec;
|
|
@@ -1621,7 +1674,7 @@ function createChannelWriter(input) {
|
|
|
1621
1674
|
function blank(agentId) {
|
|
1622
1675
|
return {
|
|
1623
1676
|
version: RADAR_PUBLICATION_VERSION,
|
|
1624
|
-
|
|
1677
|
+
registration_id: agentId,
|
|
1625
1678
|
channel,
|
|
1626
1679
|
publisher,
|
|
1627
1680
|
sequence: 0
|
|
@@ -1629,7 +1682,7 @@ function createChannelWriter(input) {
|
|
|
1629
1682
|
}
|
|
1630
1683
|
function loadRecord() {
|
|
1631
1684
|
const value = store.read(recordName);
|
|
1632
|
-
const agentId = textAt(value, "
|
|
1685
|
+
const agentId = textAt(value, "registration_id");
|
|
1633
1686
|
const storedPublisher = recordAt2(value, "publisher");
|
|
1634
1687
|
if (numberAt2(value, "version") !== RADAR_PUBLICATION_VERSION || agentId === void 0 || !isUuid(agentId) || textAt(value, "channel") !== channel || textAt(storedPublisher, "source") !== publisher.source || textAt(storedPublisher, "incarnation") !== publisher.incarnation || textAt(storedPublisher, "reporting_owner") !== publisher.reporting_owner)
|
|
1635
1688
|
return blank("");
|
|
@@ -1644,7 +1697,7 @@ function createChannelWriter(input) {
|
|
|
1644
1697
|
const sentAt = numberAt2(acceptedValue, "sent_at");
|
|
1645
1698
|
return {
|
|
1646
1699
|
version: RADAR_PUBLICATION_VERSION,
|
|
1647
|
-
|
|
1700
|
+
registration_id: agentId,
|
|
1648
1701
|
channel,
|
|
1649
1702
|
publisher,
|
|
1650
1703
|
...handle !== void 0 && generation !== void 0 ? { writer: { handle, generation } } : {},
|
|
@@ -1685,12 +1738,12 @@ function createChannelWriter(input) {
|
|
|
1685
1738
|
if (record.writer !== void 0) return true;
|
|
1686
1739
|
const agentId = await input.subject(recovering);
|
|
1687
1740
|
if (agentId === void 0) return false;
|
|
1688
|
-
if (record.
|
|
1741
|
+
if (record.registration_id !== agentId) {
|
|
1689
1742
|
record = blank(agentId);
|
|
1690
1743
|
save();
|
|
1691
1744
|
}
|
|
1692
1745
|
const answer = await client.acquire({
|
|
1693
|
-
|
|
1746
|
+
registration_id: agentId,
|
|
1694
1747
|
channel,
|
|
1695
1748
|
publisher
|
|
1696
1749
|
});
|
|
@@ -1720,7 +1773,7 @@ function createChannelWriter(input) {
|
|
|
1720
1773
|
const writer = record.writer;
|
|
1721
1774
|
if (writer === void 0) return;
|
|
1722
1775
|
const answer = await client.publish({
|
|
1723
|
-
|
|
1776
|
+
registration_id: record.registration_id,
|
|
1724
1777
|
channel,
|
|
1725
1778
|
writer_handle: writer.handle,
|
|
1726
1779
|
sequence: pending.sequence,
|
|
@@ -1814,9 +1867,9 @@ function createChannelWriter(input) {
|
|
|
1814
1867
|
stopPump();
|
|
1815
1868
|
const writer = record.writer;
|
|
1816
1869
|
if (writer === void 0) return;
|
|
1817
|
-
const agentId = record.
|
|
1870
|
+
const agentId = record.registration_id;
|
|
1818
1871
|
try {
|
|
1819
|
-
void client.retire({
|
|
1872
|
+
void client.retire({ registration_id: agentId, channel, writer_handle: writer.handle }).then((answer) => {
|
|
1820
1873
|
if (answer.ok === true) {
|
|
1821
1874
|
try {
|
|
1822
1875
|
record.retired_at = new Date(scheduler.now()).toISOString();
|
|
@@ -1839,214 +1892,127 @@ function createChannelWriter(input) {
|
|
|
1839
1892
|
diagnostic: () => record.diagnostic
|
|
1840
1893
|
};
|
|
1841
1894
|
}
|
|
1842
|
-
function
|
|
1843
|
-
const { store, client, scheduler, recordName
|
|
1844
|
-
let
|
|
1845
|
-
let
|
|
1846
|
-
let
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
function blank(agentId) {
|
|
1854
|
-
return {
|
|
1855
|
-
version: RADAR_PUBLICATION_VERSION,
|
|
1856
|
-
agent_id: agentId,
|
|
1857
|
-
publisher,
|
|
1858
|
-
sequence: 0
|
|
1859
|
-
};
|
|
1860
|
-
}
|
|
1861
|
-
function loadRecord() {
|
|
1862
|
-
const value = store.read(recordName);
|
|
1863
|
-
const agentId = textAt(value, "agent_id");
|
|
1864
|
-
const storedPublisher = recordAt2(value, "publisher");
|
|
1865
|
-
if (numberAt2(value, "version") !== RADAR_PUBLICATION_VERSION || agentId === void 0 || !isUuid(agentId) && agentId !== "" || textAt(storedPublisher, "source") !== publisher.source || textAt(storedPublisher, "incarnation") !== publisher.incarnation || textAt(storedPublisher, "reporting_owner") !== publisher.reporting_owner)
|
|
1866
|
-
return blank("");
|
|
1867
|
-
const writer = recordAt2(value, "writer");
|
|
1868
|
-
const handle = textAt(writer, "handle");
|
|
1869
|
-
const generation = numberAt2(writer, "generation");
|
|
1870
|
-
if (writer !== void 0 && (!exactKeys(writer, WRITER_KEYS) || !isUuid(handle) || generation === void 0))
|
|
1871
|
-
return blank(agentId);
|
|
1872
|
-
const pending = contextReportAt(
|
|
1873
|
-
recordAt2(value, "pending"),
|
|
1874
|
-
CONTEXT_PENDING_KEYS,
|
|
1875
|
-
CONTEXT_PENDING_MARKED_KEYS
|
|
1876
|
-
);
|
|
1877
|
-
const acceptedValue = recordAt2(value, "accepted");
|
|
1878
|
-
const accepted = contextReportAt(
|
|
1879
|
-
acceptedValue,
|
|
1880
|
-
CONTEXT_ACCEPTED_KEYS,
|
|
1881
|
-
CONTEXT_ACCEPTED_MARKED_KEYS
|
|
1882
|
-
);
|
|
1883
|
-
const sentAt = numberAt2(acceptedValue, "sent_at");
|
|
1884
|
-
return {
|
|
1885
|
-
version: RADAR_PUBLICATION_VERSION,
|
|
1886
|
-
agent_id: agentId,
|
|
1887
|
-
publisher,
|
|
1888
|
-
...handle !== void 0 && generation !== void 0 ? { writer: { handle, generation } } : {},
|
|
1889
|
-
sequence: numberAt2(value, "sequence") ?? 0,
|
|
1890
|
-
...pending !== void 0 ? { pending } : {},
|
|
1891
|
-
...accepted !== void 0 && sentAt !== void 0 ? { accepted: { ...accepted, sent_at: sentAt } } : {},
|
|
1892
|
-
...textAt(value, "diagnostic") !== void 0 ? { diagnostic: textAt(value, "diagnostic") } : {}
|
|
1893
|
-
};
|
|
1894
|
-
}
|
|
1895
|
-
function note(message) {
|
|
1896
|
-
if (record.diagnostic !== void 0) return;
|
|
1897
|
-
record.diagnostic = message.slice(0, 256);
|
|
1898
|
-
save();
|
|
1895
|
+
function createPresenceReporter(input) {
|
|
1896
|
+
const { store, client, scheduler, recordName } = input;
|
|
1897
|
+
let state;
|
|
1898
|
+
let standing;
|
|
1899
|
+
let diagnostic;
|
|
1900
|
+
try {
|
|
1901
|
+
const saved = store.read(recordName);
|
|
1902
|
+
if (saved?.version === 2 && isUuid(saved.claim_id) && isUuid(saved.session) && Array.isArray(saved.releases))
|
|
1903
|
+
state = saved;
|
|
1904
|
+
} catch (error) {
|
|
1905
|
+
diagnostic = `presence storage unavailable: ${String(error)}`;
|
|
1899
1906
|
}
|
|
1907
|
+
let timer;
|
|
1908
|
+
let stopped = false;
|
|
1909
|
+
let running;
|
|
1900
1910
|
function save() {
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
function startPump() {
|
|
1909
|
-
if (pump !== void 0 || stopped || fenced) return;
|
|
1910
|
-
pump = scheduler.setInterval(() => kick(), input.heartbeatMs);
|
|
1911
|
-
pump.unref?.();
|
|
1912
|
-
}
|
|
1913
|
-
function stopPump() {
|
|
1914
|
-
if (pump === void 0) return;
|
|
1915
|
-
scheduler.clearInterval(pump);
|
|
1916
|
-
pump = void 0;
|
|
1911
|
+
try {
|
|
1912
|
+
if (state) store.write(recordName, state);
|
|
1913
|
+
return true;
|
|
1914
|
+
} catch (error) {
|
|
1915
|
+
diagnostic = `presence storage unavailable: ${String(error)}`;
|
|
1916
|
+
return false;
|
|
1917
|
+
}
|
|
1917
1918
|
}
|
|
1918
|
-
async function
|
|
1919
|
-
if (
|
|
1920
|
-
const
|
|
1921
|
-
if (
|
|
1922
|
-
|
|
1923
|
-
|
|
1919
|
+
async function releasePending() {
|
|
1920
|
+
if (!state) return;
|
|
1921
|
+
const registration = await input.registration();
|
|
1922
|
+
if (!registration?.process) return;
|
|
1923
|
+
for (const release of [...state.releases]) {
|
|
1924
|
+
const answer = await client.releasePresence({ ...release, process: registration.process });
|
|
1925
|
+
if (!answer.ok) return;
|
|
1926
|
+
state.releases = state.releases.filter((r) => r.claim_id !== release.claim_id);
|
|
1924
1927
|
save();
|
|
1925
1928
|
}
|
|
1926
|
-
return true;
|
|
1927
1929
|
}
|
|
1928
|
-
function
|
|
1929
|
-
|
|
1930
|
+
function schedule() {
|
|
1931
|
+
if (stopped || timer) return;
|
|
1932
|
+
timer = scheduler.setTimeout(() => {
|
|
1933
|
+
timer = void 0;
|
|
1934
|
+
void ensure();
|
|
1935
|
+
}, input.heartbeatMs);
|
|
1936
|
+
timer.unref?.();
|
|
1930
1937
|
}
|
|
1931
|
-
async function
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1938
|
+
async function ensure() {
|
|
1939
|
+
if (running) return running;
|
|
1940
|
+
if (stopped || !state) return void 0;
|
|
1941
|
+
const claim = state;
|
|
1942
|
+
if (!save()) return void 0;
|
|
1943
|
+
running = (async () => {
|
|
1944
|
+
await releasePending();
|
|
1945
|
+
const registration = await input.registration();
|
|
1946
|
+
if (!registration?.process || state !== claim || stopped) return void 0;
|
|
1947
|
+
const answer = await client.presence({
|
|
1948
|
+
...registration,
|
|
1949
|
+
process: registration.process,
|
|
1950
|
+
session_id: claim.session,
|
|
1951
|
+
claim_id: claim.claim_id,
|
|
1952
|
+
...claim.registration_id ? { registration_id: claim.registration_id } : {},
|
|
1953
|
+
...claim.subject_id ? { subject_id: claim.subject_id } : {}
|
|
1954
|
+
});
|
|
1955
|
+
if (state !== claim) return void 0;
|
|
1956
|
+
if (!answer.ok) {
|
|
1957
|
+
if (!["absent", "timeout", "transport"].includes(answer.code)) diagnostic = answer.message;
|
|
1958
|
+
return void 0;
|
|
1945
1959
|
}
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
handle: answer.value.writer.handle,
|
|
1951
|
-
generation: answer.value.writer.generation
|
|
1952
|
-
};
|
|
1953
|
-
record.sequence = Math.max(record.sequence, answer.value.writer.sequence);
|
|
1954
|
-
record.accepted = {
|
|
1955
|
-
...pending,
|
|
1956
|
-
sent_at: answer.value.warning === void 0 ? scheduler.now() : record.accepted?.sent_at ?? scheduler.now()
|
|
1957
|
-
};
|
|
1958
|
-
record.pending = void 0;
|
|
1960
|
+
claim.registration_id = answer.value.registration_id;
|
|
1961
|
+
claim.subject_id = answer.value.standing === "granted" ? answer.value.subject_id ?? void 0 : void 0;
|
|
1962
|
+
standing = answer.value.standing === "granted" ? { state: "managed", subject_id: claim.subject_id } : answer.value.standing === "duplicate" ? { state: "duplicate" } : answer.value.standing === "pending" ? { state: "pending" } : { state: "unmanaged" };
|
|
1963
|
+
diagnostic = answer.value.standing === "duplicate" ? DUPLICATE_SESSION_DIAGNOSTIC : void 0;
|
|
1959
1964
|
save();
|
|
1960
|
-
return;
|
|
1961
|
-
}
|
|
1962
|
-
if (answer.code === "refused" || answer.code === "bad_params" || // A daemon that speaks the registry but does not serve this record would
|
|
1963
|
-
// refuse every retry the same way; one diagnostic beats a silent retry
|
|
1964
|
-
// loop once per heartbeat.
|
|
1965
|
-
answer.code === "unknown_method") {
|
|
1966
|
-
fence(answer.message);
|
|
1967
|
-
return;
|
|
1968
|
-
}
|
|
1969
|
-
if (answer.code === "not_found") {
|
|
1970
|
-
record = blank("");
|
|
1971
|
-
recovering = true;
|
|
1972
|
-
save();
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
async function stage(session, launchIdentity) {
|
|
1977
|
-
const pending = {
|
|
1978
|
-
sequence: record.sequence + 1,
|
|
1979
|
-
session,
|
|
1980
|
-
lease_ms: input.leaseMs,
|
|
1981
|
-
observed_at: new Date(scheduler.now()).toISOString(),
|
|
1982
|
-
...launchIdentity !== void 0 ? { launch_identity: launchIdentity } : {}
|
|
1983
|
-
};
|
|
1984
|
-
record.pending = pending;
|
|
1985
|
-
save();
|
|
1986
|
-
await send(pending);
|
|
1987
|
-
}
|
|
1988
|
-
async function drainOnce() {
|
|
1989
|
-
if (fenced) return;
|
|
1990
|
-
if (record.pending !== void 0) {
|
|
1991
|
-
await send(record.pending);
|
|
1992
|
-
return;
|
|
1993
|
-
}
|
|
1994
|
-
if (desired === void 0) return;
|
|
1995
|
-
if (!await ensureSubject()) return;
|
|
1996
|
-
if (fenced) return;
|
|
1997
|
-
if (record.writer === void 0 || record.accepted === void 0 || record.accepted.session !== desired || !sameLaunchIdentity(record.accepted.launch_identity, desiredMarker)) {
|
|
1998
|
-
await stage(desired, desiredMarker);
|
|
1999
|
-
return;
|
|
2000
|
-
}
|
|
2001
|
-
if (heartbeatDue()) await stage(record.accepted.session, desiredMarker);
|
|
2002
|
-
}
|
|
2003
|
-
async function drain() {
|
|
2004
|
-
if (running || stopped || fenced) return;
|
|
2005
|
-
running = true;
|
|
1965
|
+
return claim.registration_id;
|
|
1966
|
+
})();
|
|
2006
1967
|
try {
|
|
2007
|
-
await
|
|
1968
|
+
return await running;
|
|
2008
1969
|
} catch (error) {
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
try {
|
|
2012
|
-
note(`context storage failure: ${String(error).slice(0, 180)}`);
|
|
2013
|
-
} catch {
|
|
2014
|
-
}
|
|
1970
|
+
diagnostic = `presence unavailable: ${String(error)}`;
|
|
1971
|
+
return void 0;
|
|
2015
1972
|
} finally {
|
|
2016
|
-
running =
|
|
2017
|
-
if (
|
|
2018
|
-
|
|
2019
|
-
kick();
|
|
2020
|
-
}
|
|
1973
|
+
running = void 0;
|
|
1974
|
+
if (!stopped && state !== claim) void ensure();
|
|
1975
|
+
else schedule();
|
|
2021
1976
|
}
|
|
2022
1977
|
}
|
|
2023
|
-
function kick() {
|
|
2024
|
-
if (stopped || fenced) return;
|
|
2025
|
-
startPump();
|
|
2026
|
-
if (running) {
|
|
2027
|
-
again = true;
|
|
2028
|
-
return;
|
|
2029
|
-
}
|
|
2030
|
-
void drain().catch(() => void 0);
|
|
2031
|
-
}
|
|
2032
1978
|
return {
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
1979
|
+
report(session) {
|
|
1980
|
+
const releases = [...state?.releases ?? []];
|
|
1981
|
+
if (state?.registration_id && !releases.some((release) => release.claim_id === state.claim_id)) {
|
|
1982
|
+
releases.push({ registration_id: state.registration_id, claim_id: state.claim_id });
|
|
1983
|
+
}
|
|
1984
|
+
standing = void 0;
|
|
1985
|
+
state = { version: 2, session, claim_id: randomUUID2(), releases };
|
|
1986
|
+
save();
|
|
1987
|
+
stopped = false;
|
|
1988
|
+
void ensure();
|
|
1989
|
+
},
|
|
1990
|
+
ensure,
|
|
1991
|
+
async release() {
|
|
1992
|
+
const releasing = state;
|
|
1993
|
+
standing = void 0;
|
|
1994
|
+
stopped = true;
|
|
1995
|
+
if (timer) scheduler.clearTimeout(timer);
|
|
1996
|
+
timer = void 0;
|
|
1997
|
+
if (running) await running;
|
|
1998
|
+
if (state === releasing) standing = void 0;
|
|
1999
|
+
if (releasing?.registration_id && !releasing.releases.some((r) => r.claim_id === releasing.claim_id)) {
|
|
2000
|
+
releasing.releases.push({ registration_id: releasing.registration_id, claim_id: releasing.claim_id });
|
|
2001
|
+
if (!save()) return;
|
|
2002
|
+
}
|
|
2003
|
+
await releasePending();
|
|
2040
2004
|
},
|
|
2041
2005
|
stop() {
|
|
2042
2006
|
stopped = true;
|
|
2043
|
-
|
|
2007
|
+
if (timer) scheduler.clearTimeout(timer);
|
|
2008
|
+
timer = void 0;
|
|
2044
2009
|
},
|
|
2045
2010
|
reopen() {
|
|
2046
2011
|
stopped = false;
|
|
2047
|
-
|
|
2012
|
+
void ensure();
|
|
2048
2013
|
},
|
|
2049
|
-
|
|
2014
|
+
management: () => standing,
|
|
2015
|
+
diagnostic: () => diagnostic
|
|
2050
2016
|
};
|
|
2051
2017
|
}
|
|
2052
2018
|
var STORE_IDENTITY = /* @__PURE__ */ new WeakMap();
|
|
@@ -2075,10 +2041,13 @@ function unavailablePublication(error) {
|
|
|
2075
2041
|
};
|
|
2076
2042
|
return {
|
|
2077
2043
|
execution: writer,
|
|
2078
|
-
|
|
2079
|
-
|
|
2044
|
+
presence: {
|
|
2045
|
+
report: () => void 0,
|
|
2046
|
+
ensure: async () => void 0,
|
|
2047
|
+
release: async () => void 0,
|
|
2080
2048
|
stop: () => void 0,
|
|
2081
2049
|
reopen: () => void 0,
|
|
2050
|
+
management: () => void 0,
|
|
2082
2051
|
diagnostic: () => diagnostic
|
|
2083
2052
|
},
|
|
2084
2053
|
facts: { ...writer, update: () => void 0 },
|
|
@@ -2105,33 +2074,29 @@ function createRadarPublicationInner(options) {
|
|
|
2105
2074
|
cached.reopen();
|
|
2106
2075
|
return cached;
|
|
2107
2076
|
}
|
|
2108
|
-
const
|
|
2077
|
+
const registrationName = `registrations/${createHash("sha256").update(`${options.registration.source}\0${incarnation}`).digest("hex").slice(0, 32)}.json`;
|
|
2109
2078
|
const channelRecord = (channel, target) => `channels/${createHash("sha256").update(`${channel}\0${incarnation}\0${target ?? ""}`).digest("hex").slice(0, 32)}.json`;
|
|
2110
|
-
const
|
|
2111
|
-
function
|
|
2112
|
-
const value = store.read(
|
|
2079
|
+
const presenceRecord = `presence/${createHash("sha256").update(`presence\0${incarnation}`).digest("hex").slice(0, 32)}.json`;
|
|
2080
|
+
function readRegistration() {
|
|
2081
|
+
const value = store.read(registrationName);
|
|
2113
2082
|
const registration = recordAt2(value, "registration");
|
|
2114
2083
|
if (numberAt2(value, "version") !== RADAR_PUBLICATION_VERSION || textAt(registration, "source") !== options.registration.source || textAt(registration, "incarnation") !== incarnation)
|
|
2115
2084
|
return void 0;
|
|
2116
|
-
const storedAgentId = textAt(value, "
|
|
2085
|
+
const storedAgentId = textAt(value, "registration_id");
|
|
2117
2086
|
return {
|
|
2118
2087
|
version: RADAR_PUBLICATION_VERSION,
|
|
2119
2088
|
registration,
|
|
2120
|
-
...storedAgentId !== void 0 && isUuid(storedAgentId) ? {
|
|
2089
|
+
...storedAgentId !== void 0 && isUuid(storedAgentId) ? { registration_id: storedAgentId } : {}
|
|
2121
2090
|
};
|
|
2122
2091
|
}
|
|
2123
|
-
const stored =
|
|
2124
|
-
let
|
|
2092
|
+
const stored = readRegistration();
|
|
2093
|
+
let processRecord = stored;
|
|
2125
2094
|
let registrationDiagnostic;
|
|
2126
2095
|
let registrationRecord;
|
|
2127
2096
|
async function ensureRegistration() {
|
|
2128
|
-
if (
|
|
2097
|
+
if (processRecord !== void 0) return processRecord;
|
|
2129
2098
|
registrationRecord ??= (async () => {
|
|
2130
2099
|
const resolution = options.location ? await options.location() : { state: "absent", reason: "this process publishes no location" };
|
|
2131
|
-
if (resolution.state === "pending") {
|
|
2132
|
-
registrationDiagnostic = `location bootstrap pending: ${resolution.reason}`.slice(0, 256);
|
|
2133
|
-
return void 0;
|
|
2134
|
-
}
|
|
2135
2100
|
const built = {
|
|
2136
2101
|
version: RADAR_PUBLICATION_VERSION,
|
|
2137
2102
|
registration: {
|
|
@@ -2142,13 +2107,13 @@ function createRadarPublicationInner(options) {
|
|
|
2142
2107
|
}
|
|
2143
2108
|
};
|
|
2144
2109
|
try {
|
|
2145
|
-
store.write(
|
|
2110
|
+
store.write(registrationName, built);
|
|
2146
2111
|
} catch (error) {
|
|
2147
2112
|
registrationDiagnostic ??= `private storage unavailable: ${String(error)}`.slice(0, 256);
|
|
2148
2113
|
return void 0;
|
|
2149
2114
|
}
|
|
2150
2115
|
registrationDiagnostic = void 0;
|
|
2151
|
-
|
|
2116
|
+
processRecord = built;
|
|
2152
2117
|
return built;
|
|
2153
2118
|
})();
|
|
2154
2119
|
try {
|
|
@@ -2157,11 +2122,10 @@ function createRadarPublicationInner(options) {
|
|
|
2157
2122
|
registrationRecord = void 0;
|
|
2158
2123
|
}
|
|
2159
2124
|
}
|
|
2160
|
-
let agentId = stored?.
|
|
2125
|
+
let agentId = stored?.registration_id;
|
|
2161
2126
|
let subjectReady;
|
|
2162
2127
|
async function ensureSubject(recheck) {
|
|
2163
|
-
if (recheck
|
|
2164
|
-
if (agentId !== void 0) return agentId;
|
|
2128
|
+
if (!recheck && agentId !== void 0) return agentId;
|
|
2165
2129
|
subjectReady ??= (async () => {
|
|
2166
2130
|
const ready = await client.ping();
|
|
2167
2131
|
if (ready.ok === false) {
|
|
@@ -2171,18 +2135,11 @@ function createRadarPublicationInner(options) {
|
|
|
2171
2135
|
}
|
|
2172
2136
|
const record = await ensureRegistration();
|
|
2173
2137
|
if (record === void 0) return void 0;
|
|
2174
|
-
const
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
}
|
|
2178
|
-
|
|
2179
|
-
if (answer.code !== "absent" && answer.code !== "timeout" && answer.code !== "transport")
|
|
2180
|
-
registrationDiagnostic ??= `subject registration refused: ${answer.message}`.slice(0, 256);
|
|
2181
|
-
return void 0;
|
|
2182
|
-
}
|
|
2183
|
-
agentId = answer.value.agent_id;
|
|
2184
|
-
subject = { ...record, agent_id: agentId };
|
|
2185
|
-
store.write(subjectName, subject);
|
|
2138
|
+
const registered = await presence.ensure();
|
|
2139
|
+
if (registered === void 0) return void 0;
|
|
2140
|
+
agentId = registered;
|
|
2141
|
+
processRecord = { ...record, registration_id: agentId };
|
|
2142
|
+
store.write(registrationName, processRecord);
|
|
2186
2143
|
if (options.binding !== void 0) writeBinding(options.binding);
|
|
2187
2144
|
return agentId;
|
|
2188
2145
|
})();
|
|
@@ -2196,7 +2153,7 @@ function createRadarPublicationInner(options) {
|
|
|
2196
2153
|
if (agentId === void 0) return;
|
|
2197
2154
|
store.write(`bindings/${binding.key}.json`, {
|
|
2198
2155
|
version: RADAR_PUBLICATION_VERSION,
|
|
2199
|
-
|
|
2156
|
+
registration_id: agentId,
|
|
2200
2157
|
incarnation,
|
|
2201
2158
|
run: binding.run,
|
|
2202
2159
|
owner: binding.owner,
|
|
@@ -2220,14 +2177,22 @@ function createRadarPublicationInner(options) {
|
|
|
2220
2177
|
leaseMs: options.leaseMs ?? RADAR_LEASE_MS,
|
|
2221
2178
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
2222
2179
|
});
|
|
2223
|
-
const
|
|
2180
|
+
const presence = createPresenceReporter({
|
|
2224
2181
|
store,
|
|
2225
2182
|
client,
|
|
2226
2183
|
scheduler,
|
|
2227
|
-
recordName:
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2184
|
+
recordName: presenceRecord,
|
|
2185
|
+
registration: async () => {
|
|
2186
|
+
const record = await ensureRegistration();
|
|
2187
|
+
if (!record) return void 0;
|
|
2188
|
+
const location = await options.location?.();
|
|
2189
|
+
const { location: _initialLocation, ...identity } = record.registration;
|
|
2190
|
+
return {
|
|
2191
|
+
...identity,
|
|
2192
|
+
...location?.state === "resolved" ? { location: location.location } : {},
|
|
2193
|
+
...spawnToken ? { spawn_token: spawnToken } : {}
|
|
2194
|
+
};
|
|
2195
|
+
},
|
|
2231
2196
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
2232
2197
|
});
|
|
2233
2198
|
const facts = createChannelWriter({
|
|
@@ -2245,7 +2210,7 @@ function createRadarPublicationInner(options) {
|
|
|
2245
2210
|
const assignmentWriters = /* @__PURE__ */ new Map();
|
|
2246
2211
|
const publication = {
|
|
2247
2212
|
execution,
|
|
2248
|
-
|
|
2213
|
+
presence,
|
|
2249
2214
|
facts,
|
|
2250
2215
|
assignment(target, reportingOwner) {
|
|
2251
2216
|
const existing = assignmentWriters.get(target);
|
|
@@ -2260,7 +2225,7 @@ function createRadarPublicationInner(options) {
|
|
|
2260
2225
|
publisher: publisher("herdsman-owner", reportingOwner),
|
|
2261
2226
|
codec: assignmentCodec,
|
|
2262
2227
|
// The owner publishes about a subject it did not register: the exact
|
|
2263
|
-
//
|
|
2228
|
+
// registration_id from the child's sidecar is the whole correlation.
|
|
2264
2229
|
subject: async () => target,
|
|
2265
2230
|
leaseMs: options.leaseMs ?? RADAR_LEASE_MS,
|
|
2266
2231
|
heartbeatMs: options.heartbeatMs ?? RADAR_HEARTBEAT_MS
|
|
@@ -2280,7 +2245,7 @@ function createRadarPublicationInner(options) {
|
|
|
2280
2245
|
registrationDiagnostic ??= `Radar binding unavailable: ${String(error).slice(0, 180)}`;
|
|
2281
2246
|
return void 0;
|
|
2282
2247
|
}
|
|
2283
|
-
const bound = textAt(value, "
|
|
2248
|
+
const bound = textAt(value, "registration_id");
|
|
2284
2249
|
const boundIncarnation = textAt(value, "incarnation");
|
|
2285
2250
|
const run = textAt(value, "run");
|
|
2286
2251
|
const owner = textAt(value, "owner");
|
|
@@ -2290,7 +2255,7 @@ function createRadarPublicationInner(options) {
|
|
|
2290
2255
|
return void 0;
|
|
2291
2256
|
return {
|
|
2292
2257
|
version: RADAR_PUBLICATION_VERSION,
|
|
2293
|
-
|
|
2258
|
+
registration_id: bound,
|
|
2294
2259
|
incarnation: boundIncarnation,
|
|
2295
2260
|
run,
|
|
2296
2261
|
owner,
|
|
@@ -2306,23 +2271,27 @@ function createRadarPublicationInner(options) {
|
|
|
2306
2271
|
if (agentId2 === void 0) return void 0;
|
|
2307
2272
|
const record = await ensureRegistration();
|
|
2308
2273
|
if (record === void 0) return void 0;
|
|
2309
|
-
const
|
|
2274
|
+
const currentLocation = await options.location?.();
|
|
2275
|
+
const location = currentLocation?.state === "resolved" ? currentLocation.location : void 0;
|
|
2276
|
+
const standing = presence.management();
|
|
2277
|
+
const subjectId = standing?.state === "managed" ? standing.subject_id : void 0;
|
|
2310
2278
|
return {
|
|
2311
|
-
|
|
2279
|
+
registration_id: agentId2,
|
|
2280
|
+
...subjectId !== void 0 ? { subject_id: subjectId } : {},
|
|
2312
2281
|
...location !== void 0 ? { location } : {}
|
|
2313
2282
|
};
|
|
2314
2283
|
},
|
|
2315
|
-
diagnostic: () => registrationDiagnostic ?? execution.diagnostic() ??
|
|
2284
|
+
diagnostic: () => registrationDiagnostic ?? execution.diagnostic() ?? presence.diagnostic() ?? facts.diagnostic(),
|
|
2316
2285
|
stop() {
|
|
2317
2286
|
for (const writer of assignmentWriters.values()) writer.stop();
|
|
2318
2287
|
execution.stop();
|
|
2319
|
-
|
|
2288
|
+
presence.stop();
|
|
2320
2289
|
facts.stop();
|
|
2321
2290
|
},
|
|
2322
2291
|
reopen() {
|
|
2323
2292
|
for (const writer of assignmentWriters.values()) writer.reopen();
|
|
2324
2293
|
execution.reopen();
|
|
2325
|
-
|
|
2294
|
+
presence.reopen();
|
|
2326
2295
|
facts.reopen();
|
|
2327
2296
|
}
|
|
2328
2297
|
};
|
|
@@ -2360,10 +2329,13 @@ function unavailablePublication2() {
|
|
|
2360
2329
|
return {
|
|
2361
2330
|
execution: writer,
|
|
2362
2331
|
facts: { ...writer, update: () => void 0 },
|
|
2363
|
-
|
|
2364
|
-
|
|
2332
|
+
presence: {
|
|
2333
|
+
report: () => void 0,
|
|
2365
2334
|
stop: () => void 0,
|
|
2366
2335
|
reopen: () => void 0,
|
|
2336
|
+
management: () => void 0,
|
|
2337
|
+
ensure: async () => void 0,
|
|
2338
|
+
release: async () => void 0,
|
|
2367
2339
|
diagnostic: () => "Radar private storage is unavailable"
|
|
2368
2340
|
},
|
|
2369
2341
|
assignment: () => writer,
|
|
@@ -2446,11 +2418,11 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
2446
2418
|
...lastOutcome !== void 0 ? { last_outcome: lastOutcome } : {}
|
|
2447
2419
|
};
|
|
2448
2420
|
}
|
|
2449
|
-
function reportSession(context
|
|
2421
|
+
function reportSession(context) {
|
|
2450
2422
|
const session = context?.sessionManager?.getSessionId?.();
|
|
2451
2423
|
if (!isUuid(session)) return;
|
|
2452
2424
|
try {
|
|
2453
|
-
publication.
|
|
2425
|
+
publication.presence.report(session);
|
|
2454
2426
|
} catch {
|
|
2455
2427
|
}
|
|
2456
2428
|
}
|
|
@@ -2514,38 +2486,8 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
2514
2486
|
})
|
|
2515
2487
|
);
|
|
2516
2488
|
on("session_start", (_event, context) => {
|
|
2517
|
-
const sessionHost = {
|
|
2518
|
-
appendEntry: pi.appendEntry ? (customType, data) => pi.appendEntry?.(customType, data) : void 0,
|
|
2519
|
-
sessionManager: context?.sessionManager
|
|
2520
|
-
};
|
|
2521
|
-
let launchIdentity;
|
|
2522
|
-
try {
|
|
2523
|
-
const result = persistRadarLaunchMarker(
|
|
2524
|
-
sessionHost,
|
|
2525
|
-
options.markerEnvironment
|
|
2526
|
-
);
|
|
2527
|
-
if (result === "written" || result === "unchanged") {
|
|
2528
|
-
const expected = radarLaunchMarkerFromEnvironment(options.markerEnvironment);
|
|
2529
|
-
const activeMarker = activeRadarLaunchMarker(sessionHost);
|
|
2530
|
-
if (expected && activeMarker.status === "valid" && JSON.stringify(activeMarker.marker) === JSON.stringify(expected)) {
|
|
2531
|
-
launchIdentity = activeMarker.marker;
|
|
2532
|
-
} else {
|
|
2533
|
-
options.diagnostic?.("Radar launch marker was not visible on the active Pi session branch");
|
|
2534
|
-
}
|
|
2535
|
-
} else if (result === "unsupported") {
|
|
2536
|
-
options.diagnostic?.("Pi host does not support Radar launch identity session entries");
|
|
2537
|
-
} else if (options.markerEnvironment && [
|
|
2538
|
-
"PI_RADAR_MANAGED_SUBJECT_ID",
|
|
2539
|
-
"PI_RADAR_MANAGED_LAUNCH_ID",
|
|
2540
|
-
"PI_RADAR_MANAGED_EXECUTION_GENERATION"
|
|
2541
|
-
].some((key) => options.markerEnvironment?.[key] !== void 0)) {
|
|
2542
|
-
options.diagnostic?.("incomplete or invalid Radar launch identity environment");
|
|
2543
|
-
}
|
|
2544
|
-
} catch (error) {
|
|
2545
|
-
options.diagnostic?.(`could not persist Radar launch marker: ${String(error)}`);
|
|
2546
|
-
}
|
|
2547
2489
|
rootSession = true;
|
|
2548
|
-
reportSession(context
|
|
2490
|
+
reportSession(context);
|
|
2549
2491
|
publishFacts(context);
|
|
2550
2492
|
publication.reopen();
|
|
2551
2493
|
active = context?.isIdle?.() === false;
|
|
@@ -2576,8 +2518,9 @@ function createRadarExecutionAdapter(pi, options) {
|
|
|
2576
2518
|
}
|
|
2577
2519
|
emit();
|
|
2578
2520
|
});
|
|
2579
|
-
on("session_shutdown", () => {
|
|
2521
|
+
on("session_shutdown", async () => {
|
|
2580
2522
|
suspend();
|
|
2523
|
+
await publication.presence.release();
|
|
2581
2524
|
});
|
|
2582
2525
|
function suspend() {
|
|
2583
2526
|
if (stopped) return;
|
|
@@ -2785,7 +2728,7 @@ function trajectory(reason) {
|
|
|
2785
2728
|
return `the daemon's current record of this launch's child is ${reason}`;
|
|
2786
2729
|
}
|
|
2787
2730
|
async function observeRadarChild(client, provenance) {
|
|
2788
|
-
if (provenance.
|
|
2731
|
+
if (provenance.registration_id === void 0)
|
|
2789
2732
|
return unknownChild("not bound to a child by this launch");
|
|
2790
2733
|
if (provenance.pane_id === void 0)
|
|
2791
2734
|
return unknownChild("without a pane this launch recorded for it");
|
|
@@ -2796,11 +2739,11 @@ async function observeRadarChild(client, provenance) {
|
|
|
2796
2739
|
);
|
|
2797
2740
|
const topology = read.value;
|
|
2798
2741
|
const edge = topology.edge;
|
|
2799
|
-
if (edge.bound === void 0 || edge.bound.
|
|
2742
|
+
if (edge.bound === void 0 || edge.bound.registration_id === void 0)
|
|
2800
2743
|
return unknownChild("not bound to a child by the daemon");
|
|
2801
|
-
if (edge.bound.
|
|
2744
|
+
if (edge.bound.registration_id !== provenance.registration_id)
|
|
2802
2745
|
return unknownChild(
|
|
2803
|
-
`bound to another subject (${edge.bound.
|
|
2746
|
+
`bound to another subject (${edge.bound.registration_id}), not to ${provenance.registration_id}`
|
|
2804
2747
|
);
|
|
2805
2748
|
if (edge.location?.pane === void 0)
|
|
2806
2749
|
return unknownChild("recorded without a pane");
|
|
@@ -2818,7 +2761,7 @@ async function observeRadarChild(client, provenance) {
|
|
|
2818
2761
|
return unknownChild(
|
|
2819
2762
|
`not currently placed (state ${topology.state ?? "unreported"})`
|
|
2820
2763
|
);
|
|
2821
|
-
const reply = await client.agentGet(edge.bound.
|
|
2764
|
+
const reply = await client.agentGet(edge.bound.registration_id);
|
|
2822
2765
|
if (reply.ok === false)
|
|
2823
2766
|
return unknownChild(
|
|
2824
2767
|
`process verdict not readable (${reply.code}: ${reply.message})`
|
|
@@ -2846,7 +2789,7 @@ async function observeRadarChild(client, provenance) {
|
|
|
2846
2789
|
kind: "live",
|
|
2847
2790
|
evidence: {
|
|
2848
2791
|
request_id: provenance.request_id,
|
|
2849
|
-
|
|
2792
|
+
registration_id: edge.bound.registration_id,
|
|
2850
2793
|
source: edge.bound.source,
|
|
2851
2794
|
incarnation: edge.bound.incarnation,
|
|
2852
2795
|
pane_id: edge.location.pane
|
|
@@ -2906,19 +2849,24 @@ async function launchRadarWorker(options) {
|
|
|
2906
2849
|
const deadline = Date.now() + options.timeoutMs;
|
|
2907
2850
|
const remaining = () => Math.max(0, deadline - Date.now());
|
|
2908
2851
|
const pane = launch.parent.location?.pane;
|
|
2909
|
-
if (!isUuid(launch.parent.
|
|
2852
|
+
if (!isUuid(launch.parent.registration_id))
|
|
2910
2853
|
return refusedLaunch(
|
|
2911
2854
|
"the launch has no exact parent registration to spawn under"
|
|
2912
2855
|
);
|
|
2856
|
+
if (!isUuid(launch.parent.subject_id))
|
|
2857
|
+
return refusedLaunch(
|
|
2858
|
+
"the launch has no managed Radar subject for its parent"
|
|
2859
|
+
);
|
|
2913
2860
|
if (pane === void 0 || pane === "")
|
|
2914
2861
|
return refusedLaunch(
|
|
2915
2862
|
"this process's Radar registration names no pane, so it cannot be a spawn parent"
|
|
2916
2863
|
);
|
|
2917
2864
|
const spawned = await client.spawn({
|
|
2918
2865
|
request_id: launch.request_id,
|
|
2919
|
-
parent: launch.parent.
|
|
2866
|
+
parent: launch.parent.registration_id,
|
|
2920
2867
|
parent_session_id: launch.parent_session_id,
|
|
2921
2868
|
executable: launch.executable,
|
|
2869
|
+
managed: { parent_subject_id: launch.parent.subject_id },
|
|
2922
2870
|
argv: launch.argv,
|
|
2923
2871
|
...launch.cwd !== "" ? { cwd: launch.cwd } : {},
|
|
2924
2872
|
...Object.keys(launch.env).length > 0 ? { env: launch.env } : {}
|
|
@@ -2940,10 +2888,10 @@ async function launchRadarWorker(options) {
|
|
|
2940
2888
|
...signal !== void 0 ? { signal } : {}
|
|
2941
2889
|
});
|
|
2942
2890
|
if (bound.kind !== "bound") return bound;
|
|
2943
|
-
const agentId = bound.
|
|
2891
|
+
const agentId = bound.registration_id;
|
|
2944
2892
|
if (launch.onBound !== void 0) {
|
|
2945
2893
|
try {
|
|
2946
|
-
launch.onBound({
|
|
2894
|
+
launch.onBound({ registration_id: agentId, pane_id: bound.pane_id });
|
|
2947
2895
|
} catch (error) {
|
|
2948
2896
|
return unresolvedLaunch(
|
|
2949
2897
|
launch.request_id,
|
|
@@ -2971,7 +2919,7 @@ async function launchRadarWorker(options) {
|
|
|
2971
2919
|
kind: "ready",
|
|
2972
2920
|
value: {
|
|
2973
2921
|
request_id: launch.request_id,
|
|
2974
|
-
|
|
2922
|
+
registration_id: agentId,
|
|
2975
2923
|
pane_id: bound.pane_id,
|
|
2976
2924
|
bound_process: {
|
|
2977
2925
|
source: bound.source,
|
|
@@ -3017,7 +2965,7 @@ async function waitForChild(client, requestId, options) {
|
|
|
3017
2965
|
requestId,
|
|
3018
2966
|
"the daemon observed the launched child's process exit"
|
|
3019
2967
|
);
|
|
3020
|
-
const agentId = edge.bound?.
|
|
2968
|
+
const agentId = edge.bound?.registration_id;
|
|
3021
2969
|
if (agentId !== void 0 && isUuid(agentId)) {
|
|
3022
2970
|
const source = edge.bound?.source;
|
|
3023
2971
|
const incarnation = edge.bound?.incarnation;
|
|
@@ -3028,7 +2976,7 @@ async function waitForChild(client, requestId, options) {
|
|
|
3028
2976
|
);
|
|
3029
2977
|
return {
|
|
3030
2978
|
kind: "bound",
|
|
3031
|
-
|
|
2979
|
+
registration_id: agentId,
|
|
3032
2980
|
pane_id: pane,
|
|
3033
2981
|
source,
|
|
3034
2982
|
incarnation
|
|
@@ -3056,7 +3004,7 @@ __export(radar_runtime_exports, {
|
|
|
3056
3004
|
requestRadarRuntime: () => requestRadarRuntime
|
|
3057
3005
|
});
|
|
3058
3006
|
var RADAR_RUNTIME_REQUEST = "pi-radar/runtime-request";
|
|
3059
|
-
var RADAR_RUNTIME_VERSION =
|
|
3007
|
+
var RADAR_RUNTIME_VERSION = 2;
|
|
3060
3008
|
function lazyRadarRuntime(start) {
|
|
3061
3009
|
let pending;
|
|
3062
3010
|
return {
|
|
@@ -3091,6 +3039,7 @@ function isRadarRuntimeHandle(value) {
|
|
|
3091
3039
|
}
|
|
3092
3040
|
export {
|
|
3093
3041
|
radar_client_exports as client,
|
|
3042
|
+
radar_communication_exports as communication,
|
|
3094
3043
|
radar_execution_exports as execution,
|
|
3095
3044
|
radar_inspection_exports as inspection,
|
|
3096
3045
|
radar_launch_exports as launch,
|