@le-space/ui 0.3.32 → 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/package.json +3 -3
- package/react/index.d.ts +14 -0
- package/react/index.js +144 -441
- package/shared/index.d.ts +18 -2
- package/shared/index.js +144 -440
package/shared/index.js
CHANGED
|
@@ -7,6 +7,16 @@ var ROOTFS_MISSING_STATE = {
|
|
|
7
7
|
label: "manifest missing",
|
|
8
8
|
detail: "Provide a manifest URL or paste manifest JSON."
|
|
9
9
|
};
|
|
10
|
+
var RELAY_PING_IDLE_STATE = {
|
|
11
|
+
tone: "idle",
|
|
12
|
+
sent: false,
|
|
13
|
+
received: false,
|
|
14
|
+
lastPeerId: null,
|
|
15
|
+
lastLatencyMs: null,
|
|
16
|
+
lastSentAt: null,
|
|
17
|
+
lastReceivedAt: null,
|
|
18
|
+
error: null
|
|
19
|
+
};
|
|
10
20
|
var IDLE_DEPLOYMENT_PROGRESS = {
|
|
11
21
|
stage: "idle",
|
|
12
22
|
label: "Ready",
|
|
@@ -18,6 +28,7 @@ var IDLE_DEPLOYMENT_PROGRESS = {
|
|
|
18
28
|
timestamp: Date.now()
|
|
19
29
|
};
|
|
20
30
|
var REFRESH_INTERVAL_MS = 3e4;
|
|
31
|
+
var RELAY_PING_INTERVAL_MS = 2e4;
|
|
21
32
|
var MANIFEST_SOURCE_REFRESH_DEBOUNCE_MS = 400;
|
|
22
33
|
var INSTANCE_RUNTIME_READY_REFRESH_MS = 3e4;
|
|
23
34
|
var INSTANCE_RUNTIME_PENDING_REFRESH_MS = 45e3;
|
|
@@ -27,7 +38,7 @@ var RECENT_INSTANCE_RUNTIME_GRACE_MS = 10 * 60 * 1e3;
|
|
|
27
38
|
var DEPLOYMENT_PENDING_WARNING_MS = 3 * 60 * 1e3;
|
|
28
39
|
|
|
29
40
|
// src/shared/package-version.ts
|
|
30
|
-
var UI_PACKAGE_VERSION = "0.
|
|
41
|
+
var UI_PACKAGE_VERSION = "0.4.0";
|
|
31
42
|
|
|
32
43
|
// src/shared/format.ts
|
|
33
44
|
function shortHash(value, head = 8, tail = 6) {
|
|
@@ -1236,6 +1247,16 @@ function normalizeBroadcastStatus(httpStatus, responseStatus) {
|
|
|
1236
1247
|
if (httpStatus === 202) return "pending";
|
|
1237
1248
|
return normalizeMessageStatus2(responseStatus);
|
|
1238
1249
|
}
|
|
1250
|
+
function isInvalidMessageFormatResponse2(response, payload) {
|
|
1251
|
+
if (response.status !== 422) return false;
|
|
1252
|
+
const details = payload?.details;
|
|
1253
|
+
if (typeof details === "string" && details.includes("InvalidMessageFormat")) return true;
|
|
1254
|
+
if (details && typeof details === "object") {
|
|
1255
|
+
const detailMessage = details.message;
|
|
1256
|
+
if (typeof detailMessage === "string" && detailMessage.includes("InvalidMessageFormat")) return true;
|
|
1257
|
+
}
|
|
1258
|
+
return false;
|
|
1259
|
+
}
|
|
1239
1260
|
function isRetryableBroadcastFailure(response, payload) {
|
|
1240
1261
|
if (response.status >= 500) return true;
|
|
1241
1262
|
const publicationStatus = payload?.publication_status?.status;
|
|
@@ -1257,22 +1278,25 @@ async function postBroadcastPayload2(body, options) {
|
|
|
1257
1278
|
};
|
|
1258
1279
|
}
|
|
1259
1280
|
async function broadcastAlephMessage2(message, options) {
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1281
|
+
const attempts = [
|
|
1282
|
+
{ sync: options.sync ?? false, message },
|
|
1283
|
+
{ ...message, sync: options.sync ?? false },
|
|
1284
|
+
{ ...message }
|
|
1285
|
+
];
|
|
1286
|
+
for (let index = 0; index < attempts.length; index += 1) {
|
|
1287
|
+
const result = await postBroadcastPayload2(attempts[index], {
|
|
1264
1288
|
apiHost: options.apiHost,
|
|
1265
1289
|
fetch: options.fetch
|
|
1266
1290
|
});
|
|
1267
1291
|
if (result.httpStatus === 202 || normalizeBroadcastStatus(result.httpStatus, result.response?.message_status) !== "unknown" || result.httpStatus >= 200 && result.httpStatus < 300) {
|
|
1268
1292
|
return result;
|
|
1269
1293
|
}
|
|
1270
|
-
const canRetry = index <
|
|
1294
|
+
const canRetry = index < attempts.length - 1 && (isInvalidMessageFormatResponse2({ status: result.httpStatus }, result.response) || isRetryableBroadcastFailure({ status: result.httpStatus }, result.response));
|
|
1271
1295
|
if (!canRetry) {
|
|
1272
1296
|
throw new Error(`Broadcast failed: ${result.httpStatus} ${JSON.stringify(result.response ?? {})}`);
|
|
1273
1297
|
}
|
|
1274
1298
|
}
|
|
1275
|
-
throw new Error("Broadcast failed:
|
|
1299
|
+
throw new Error("Broadcast failed: no compatible request format was accepted");
|
|
1276
1300
|
}
|
|
1277
1301
|
|
|
1278
1302
|
// ../core/src/forget.ts
|
|
@@ -1877,13 +1901,6 @@ async function waitForVmRuntime(args) {
|
|
|
1877
1901
|
}
|
|
1878
1902
|
|
|
1879
1903
|
// ../core/src/guest.ts
|
|
1880
|
-
function proxyHostnameFromUrl(value) {
|
|
1881
|
-
try {
|
|
1882
|
-
return value ? new URL(value).hostname : null;
|
|
1883
|
-
} catch {
|
|
1884
|
-
return null;
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
1904
|
async function defaultHttpProbe(fetch2, url, timeoutMs = 1e4) {
|
|
1888
1905
|
try {
|
|
1889
1906
|
const controller = new AbortController();
|
|
@@ -2125,59 +2142,6 @@ async function fetchUcGoPeerMetadata(args) {
|
|
|
2125
2142
|
`Relay metadata did not become ready after ${attempts} attempts: ${lastError ? lastError : typeof lastPayload === "string" ? lastPayload : JSON.stringify(lastPayload ?? {})}`
|
|
2126
2143
|
);
|
|
2127
2144
|
}
|
|
2128
|
-
async function verifyUcGoPeerReachability(args) {
|
|
2129
|
-
const checks = {};
|
|
2130
|
-
const mappedPorts2 = args.mappedPorts ?? {};
|
|
2131
|
-
const hostIpv4 = args.hostIpv4;
|
|
2132
|
-
const skippedInternalPorts = new Set(
|
|
2133
|
-
(args.skipInternalPorts ?? ["80"]).map((value) => String(value))
|
|
2134
|
-
);
|
|
2135
|
-
const httpProbe = args.httpProbe ?? ((url, timeoutMs) => defaultHttpProbe(args.fetch, url, timeoutMs));
|
|
2136
|
-
if (hostIpv4) {
|
|
2137
|
-
for (const [internalPort, mapping] of Object.entries(mappedPorts2)) {
|
|
2138
|
-
if (skippedInternalPorts.has(String(internalPort))) continue;
|
|
2139
|
-
if (mapping?.tcp === true && mapping?.host) {
|
|
2140
|
-
checks[`tcp:${internalPort}`] = {
|
|
2141
|
-
host: hostIpv4,
|
|
2142
|
-
port: mapping.host,
|
|
2143
|
-
...await args.tcpProbe(
|
|
2144
|
-
hostIpv4,
|
|
2145
|
-
mapping.host,
|
|
2146
|
-
Number(args.tcpTimeoutMs ?? 5e3)
|
|
2147
|
-
)
|
|
2148
|
-
};
|
|
2149
|
-
} else if (mapping?.udp === true && mapping?.host) {
|
|
2150
|
-
checks[`udp:${internalPort}`] = {
|
|
2151
|
-
host: hostIpv4,
|
|
2152
|
-
port: mapping.host,
|
|
2153
|
-
ok: null,
|
|
2154
|
-
note: "UDP mapping published; CI does not perform an application-level UDP handshake probe."
|
|
2155
|
-
};
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2158
|
-
}
|
|
2159
|
-
if (args.proxyUrl && args.verifyProxyHttp !== false) {
|
|
2160
|
-
checks["https:proxy"] = await httpProbe(
|
|
2161
|
-
args.proxyUrl,
|
|
2162
|
-
Number(args.httpTimeoutMs ?? 1e4)
|
|
2163
|
-
);
|
|
2164
|
-
}
|
|
2165
|
-
const proxyHostname = proxyHostnameFromUrl(args.proxyUrl);
|
|
2166
|
-
if (proxyHostname) {
|
|
2167
|
-
checks["tcp:proxy-443"] = await args.tcpProbe(
|
|
2168
|
-
proxyHostname,
|
|
2169
|
-
443,
|
|
2170
|
-
Number(args.tcpTimeoutMs ?? 5e3)
|
|
2171
|
-
);
|
|
2172
|
-
}
|
|
2173
|
-
const failedChecks = Object.entries(checks).filter(
|
|
2174
|
-
([, value]) => value?.ok === false
|
|
2175
|
-
);
|
|
2176
|
-
return {
|
|
2177
|
-
ok: failedChecks.length === 0,
|
|
2178
|
-
checks
|
|
2179
|
-
};
|
|
2180
|
-
}
|
|
2181
2145
|
|
|
2182
2146
|
// ../aleph-bootstrap/src/index.ts
|
|
2183
2147
|
import { recoverMessageAddress } from "viem";
|
|
@@ -2719,16 +2683,6 @@ async function publishRelayBootstrapRegistration(args) {
|
|
|
2719
2683
|
|
|
2720
2684
|
// ../core/src/bootstrap-config.ts
|
|
2721
2685
|
var VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY = "vm-bootstrap-config";
|
|
2722
|
-
var VM_BOOTSTRAP_CONFIG_SIGNAL_REF = "vm-bootstrap-config";
|
|
2723
|
-
var VM_BOOTSTRAP_CONFIG_SIGNAL_POST_TYPE = "vm-bootstrap-config-status";
|
|
2724
|
-
function parseJsonObject(value) {
|
|
2725
|
-
try {
|
|
2726
|
-
const parsed = JSON.parse(value);
|
|
2727
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
2728
|
-
} catch {
|
|
2729
|
-
return null;
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
2686
|
async function fetchVmBootstrapConfigAggregate(address, options) {
|
|
2733
2687
|
const requestUrl = new URL(`/api/v0/aggregates/${address}.json`, options.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2734
2688
|
requestUrl.searchParams.set("keys", VM_BOOTSTRAP_CONFIG_AGGREGATE_KEY);
|
|
@@ -2848,89 +2802,6 @@ async function deleteVmBootstrapConfig(args) {
|
|
|
2848
2802
|
aggregate: content
|
|
2849
2803
|
};
|
|
2850
2804
|
}
|
|
2851
|
-
function normalizeVmBootstrapConfigSignalRecord(value) {
|
|
2852
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
2853
|
-
const candidate = value;
|
|
2854
|
-
const deploymentToken = typeof candidate.deploymentToken === "string" ? candidate.deploymentToken.trim() : "";
|
|
2855
|
-
const status = typeof candidate.status === "string" ? candidate.status.trim() : "";
|
|
2856
|
-
const profile = typeof candidate.profile === "string" ? candidate.profile.trim() : "";
|
|
2857
|
-
const ownerAddress = typeof candidate.ownerAddress === "string" ? candidate.ownerAddress.trim() : "";
|
|
2858
|
-
const instanceItemHash = typeof candidate.instanceItemHash === "string" ? candidate.instanceItemHash.trim() : "";
|
|
2859
|
-
const updatedAt = typeof candidate.updatedAt === "string" ? candidate.updatedAt.trim() : "";
|
|
2860
|
-
if (!deploymentToken || !status || !profile || !ownerAddress || !instanceItemHash || !updatedAt) {
|
|
2861
|
-
return null;
|
|
2862
|
-
}
|
|
2863
|
-
return {
|
|
2864
|
-
deploymentToken,
|
|
2865
|
-
status,
|
|
2866
|
-
profile,
|
|
2867
|
-
ownerAddress,
|
|
2868
|
-
instanceItemHash,
|
|
2869
|
-
updatedAt,
|
|
2870
|
-
publisherAddress: typeof candidate.publisherAddress === "string" && candidate.publisherAddress.trim() ? candidate.publisherAddress.trim() : null,
|
|
2871
|
-
authorization: candidate.authorization,
|
|
2872
|
-
peerId: typeof candidate.peerId === "string" && candidate.peerId.trim() ? candidate.peerId.trim() : null,
|
|
2873
|
-
probeMultiaddrs: Array.isArray(candidate.probeMultiaddrs) ? candidate.probeMultiaddrs.filter(
|
|
2874
|
-
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
2875
|
-
) : [],
|
|
2876
|
-
browserBootstrapMultiaddrs: Array.isArray(candidate.browserBootstrapMultiaddrs) ? candidate.browserBootstrapMultiaddrs.filter(
|
|
2877
|
-
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
2878
|
-
) : []
|
|
2879
|
-
};
|
|
2880
|
-
}
|
|
2881
|
-
async function fetchVmBootstrapConfigSignals(args) {
|
|
2882
|
-
const requestUrl = new URL("/api/v0/posts.json", args.apiHost ?? DEFAULT_ALEPH_API_HOST2);
|
|
2883
|
-
requestUrl.searchParams.set("refs", args.ref ?? VM_BOOTSTRAP_CONFIG_SIGNAL_REF);
|
|
2884
|
-
requestUrl.searchParams.set("types", args.postType ?? VM_BOOTSTRAP_CONFIG_SIGNAL_POST_TYPE);
|
|
2885
|
-
requestUrl.searchParams.set("pagination", String(Math.max(1, Number(args.pagination ?? 100))));
|
|
2886
|
-
requestUrl.searchParams.set("page", String(Math.max(1, Number(args.page ?? 1))));
|
|
2887
|
-
requestUrl.searchParams.set("sortOrder", "-1");
|
|
2888
|
-
const response = await args.fetch(requestUrl.toString(), { cache: "no-cache" });
|
|
2889
|
-
if (!response.ok) {
|
|
2890
|
-
throw new Error(`VM bootstrap config signal request failed: ${response.status}`);
|
|
2891
|
-
}
|
|
2892
|
-
const payload = await response.json();
|
|
2893
|
-
const expectedDeploymentToken = args.deploymentToken?.trim() ?? "";
|
|
2894
|
-
const expectedOwnerAddress = args.ownerAddress?.trim().toLowerCase() ?? "";
|
|
2895
|
-
const expectedInstanceItemHash = args.instanceItemHash?.trim() ?? "";
|
|
2896
|
-
return (payload.posts ?? []).map((entry) => {
|
|
2897
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return null;
|
|
2898
|
-
const parsed = "content" in entry && entry.content && typeof entry.content === "object" && !Array.isArray(entry.content) ? entry.content : "item_content" in entry && typeof entry.item_content === "string" ? parseJsonObject(entry.item_content) : null;
|
|
2899
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
2900
|
-
const content = "deploymentToken" in parsed ? parsed : "content" in parsed && parsed.content && typeof parsed.content === "object" && !Array.isArray(parsed.content) ? parsed.content : null;
|
|
2901
|
-
if (!content || typeof content !== "object" || Array.isArray(content)) return null;
|
|
2902
|
-
return normalizeVmBootstrapConfigSignalRecord(content);
|
|
2903
|
-
}).filter((entry) => {
|
|
2904
|
-
if (!entry) return false;
|
|
2905
|
-
if (expectedDeploymentToken && entry.deploymentToken !== expectedDeploymentToken) return false;
|
|
2906
|
-
if (expectedOwnerAddress && entry.ownerAddress.toLowerCase() !== expectedOwnerAddress) return false;
|
|
2907
|
-
if (expectedInstanceItemHash && entry.instanceItemHash !== expectedInstanceItemHash) return false;
|
|
2908
|
-
return true;
|
|
2909
|
-
});
|
|
2910
|
-
}
|
|
2911
|
-
async function waitForVmBootstrapConfigSignal(args) {
|
|
2912
|
-
const attempts = Math.max(1, Number(args.attempts ?? 24));
|
|
2913
|
-
const delayMs = Math.max(0, Number(args.delayMs ?? 2500));
|
|
2914
|
-
const sleep2 = args.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
2915
|
-
const expectedStatus = args.expectedStatus ?? "applied";
|
|
2916
|
-
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
2917
|
-
const signals = await fetchVmBootstrapConfigSignals({
|
|
2918
|
-
deploymentToken: args.deploymentToken,
|
|
2919
|
-
ownerAddress: args.ownerAddress,
|
|
2920
|
-
instanceItemHash: args.instanceItemHash,
|
|
2921
|
-
fetch: args.fetch,
|
|
2922
|
-
apiHost: args.apiHost,
|
|
2923
|
-
ref: args.ref,
|
|
2924
|
-
postType: args.postType
|
|
2925
|
-
}).catch(() => []);
|
|
2926
|
-
const match = signals.find((entry) => entry.status === expectedStatus) ?? null;
|
|
2927
|
-
if (match) return match;
|
|
2928
|
-
if (attempt < attempts - 1) {
|
|
2929
|
-
await sleep2(delayMs);
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
return null;
|
|
2933
|
-
}
|
|
2934
2805
|
|
|
2935
2806
|
// ../core/src/bootstrap-reconcile.ts
|
|
2936
2807
|
function createRelayBootstrapRegistrationId(profile, instanceName, itemHash) {
|
|
@@ -3072,6 +2943,7 @@ function defaultState(props = {}) {
|
|
|
3072
2943
|
instances: [],
|
|
3073
2944
|
bootstrapRegistrations: [],
|
|
3074
2945
|
orphanBootstrapRegistrations: [],
|
|
2946
|
+
relayPing: RELAY_PING_IDLE_STATE,
|
|
3075
2947
|
lastDeploymentHash: null,
|
|
3076
2948
|
deploymentProgress: IDLE_DEPLOYMENT_PROGRESS
|
|
3077
2949
|
};
|
|
@@ -3298,12 +3170,61 @@ function compatibleCrnsForTier(crns, state) {
|
|
|
3298
3170
|
);
|
|
3299
3171
|
return filterDeployableCrns(crns, { spec });
|
|
3300
3172
|
}
|
|
3173
|
+
async function pingPeer(libp2p) {
|
|
3174
|
+
if (!libp2p || typeof libp2p !== "object") {
|
|
3175
|
+
return RELAY_PING_IDLE_STATE;
|
|
3176
|
+
}
|
|
3177
|
+
const candidate = libp2p;
|
|
3178
|
+
const peers = candidate.getPeers?.() ?? [];
|
|
3179
|
+
const firstPeer = peers[0];
|
|
3180
|
+
if (!firstPeer) {
|
|
3181
|
+
return {
|
|
3182
|
+
...RELAY_PING_IDLE_STATE,
|
|
3183
|
+
tone: "caution",
|
|
3184
|
+
error: "No connected relay peers available."
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
const sentAt = Date.now();
|
|
3188
|
+
try {
|
|
3189
|
+
const pingFn = candidate.services?.ping?.ping?.bind(candidate.services.ping) ?? candidate.ping?.bind(candidate);
|
|
3190
|
+
if (!pingFn) {
|
|
3191
|
+
return {
|
|
3192
|
+
...RELAY_PING_IDLE_STATE,
|
|
3193
|
+
tone: "caution",
|
|
3194
|
+
sent: true,
|
|
3195
|
+
lastPeerId: String(firstPeer),
|
|
3196
|
+
lastSentAt: sentAt,
|
|
3197
|
+
error: "libp2p ping service not available."
|
|
3198
|
+
};
|
|
3199
|
+
}
|
|
3200
|
+
const latency = await pingFn(firstPeer);
|
|
3201
|
+
return {
|
|
3202
|
+
tone: "ok",
|
|
3203
|
+
sent: true,
|
|
3204
|
+
received: true,
|
|
3205
|
+
lastPeerId: String(firstPeer),
|
|
3206
|
+
lastLatencyMs: Number(latency),
|
|
3207
|
+
lastSentAt: sentAt,
|
|
3208
|
+
lastReceivedAt: Date.now(),
|
|
3209
|
+
error: null
|
|
3210
|
+
};
|
|
3211
|
+
} catch (error) {
|
|
3212
|
+
return {
|
|
3213
|
+
tone: "error",
|
|
3214
|
+
sent: true,
|
|
3215
|
+
received: false,
|
|
3216
|
+
lastPeerId: String(firstPeer),
|
|
3217
|
+
lastLatencyMs: null,
|
|
3218
|
+
lastSentAt: sentAt,
|
|
3219
|
+
lastReceivedAt: null,
|
|
3220
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3221
|
+
};
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3301
3224
|
var UI_DEPLOY_WAIT_ATTEMPTS = 60;
|
|
3302
3225
|
var UI_DEPLOY_WAIT_DELAY_MS = 5e3;
|
|
3303
3226
|
var UI_RUNTIME_WAIT_ATTEMPTS = 40;
|
|
3304
3227
|
var UI_RUNTIME_WAIT_DELAY_MS = 5e3;
|
|
3305
|
-
var UI_REACHABILITY_VERIFY_ATTEMPTS = 25;
|
|
3306
|
-
var UI_REACHABILITY_VERIFY_DELAY_MS = 3e3;
|
|
3307
3228
|
function hasUsableRuntime(details) {
|
|
3308
3229
|
return Boolean(details.hostIpv4) || Boolean(details.vmIpv4) || details.mappedPorts.length > 0 || Boolean(details.webUrl) || Boolean(details.execution);
|
|
3309
3230
|
}
|
|
@@ -3330,6 +3251,7 @@ var SponsorRelayController = class {
|
|
|
3330
3251
|
subscribers = /* @__PURE__ */ new Set();
|
|
3331
3252
|
client;
|
|
3332
3253
|
refreshTimer = null;
|
|
3254
|
+
pingTimer = null;
|
|
3333
3255
|
manifestRefreshTimer = null;
|
|
3334
3256
|
stopWalletWatch = null;
|
|
3335
3257
|
props;
|
|
@@ -3385,7 +3307,8 @@ var SponsorRelayController = class {
|
|
|
3385
3307
|
...patch,
|
|
3386
3308
|
busy: patch.busy ? { ...this.state.busy, ...patch.busy } : this.state.busy,
|
|
3387
3309
|
wallet: patch.wallet ? { ...this.state.wallet, ...patch.wallet } : this.state.wallet,
|
|
3388
|
-
pricingSummary: patch.pricingSummary ? { ...this.state.pricingSummary, ...patch.pricingSummary } : this.state.pricingSummary
|
|
3310
|
+
pricingSummary: patch.pricingSummary ? { ...this.state.pricingSummary, ...patch.pricingSummary } : this.state.pricingSummary,
|
|
3311
|
+
relayPing: patch.relayPing ? { ...this.state.relayPing, ...patch.relayPing } : this.state.relayPing
|
|
3389
3312
|
};
|
|
3390
3313
|
this.emit();
|
|
3391
3314
|
}
|
|
@@ -3410,21 +3333,19 @@ var SponsorRelayController = class {
|
|
|
3410
3333
|
this.progressEmitter.emit(nextEvent);
|
|
3411
3334
|
}
|
|
3412
3335
|
async configureRelayBootstrapRegistration(args) {
|
|
3413
|
-
let runtime = args.runtime;
|
|
3414
3336
|
const profile = relayProfileForManifest(this.state.manifest);
|
|
3415
3337
|
if (!profile) return;
|
|
3416
3338
|
if (!this.state.wallet.address) {
|
|
3417
3339
|
throw new Error("A connected wallet is required to register relay bootstrap addresses.");
|
|
3418
3340
|
}
|
|
3419
|
-
if (!runtime.hostIpv4) {
|
|
3341
|
+
if (!args.runtime.hostIpv4) {
|
|
3420
3342
|
throw new Error("Relay runtime did not expose a host IPv4 address.");
|
|
3421
3343
|
}
|
|
3422
|
-
|
|
3344
|
+
const mappedPorts2 = args.runtime.mappedPorts ?? {};
|
|
3423
3345
|
const setupPort = mappedPorts2["80"]?.host ?? null;
|
|
3424
3346
|
if (!setupPort) {
|
|
3425
3347
|
throw new Error("Relay runtime did not expose the temporary setup endpoint.");
|
|
3426
3348
|
}
|
|
3427
|
-
let bootstrapSignalRelayMetadata = null;
|
|
3428
3349
|
if (profile === "orbitdb-relay-pinner") {
|
|
3429
3350
|
this.emitProgress({
|
|
3430
3351
|
stage: "deployment-confirmed",
|
|
@@ -3435,7 +3356,7 @@ var SponsorRelayController = class {
|
|
|
3435
3356
|
detail: "Waiting for the guest setup endpoint before collecting relay metadata."
|
|
3436
3357
|
});
|
|
3437
3358
|
const setupHealth = await waitForSetupEndpoint({
|
|
3438
|
-
hostIpv4: runtime.hostIpv4,
|
|
3359
|
+
hostIpv4: args.runtime.hostIpv4,
|
|
3439
3360
|
setupPort,
|
|
3440
3361
|
fetch: (url, init) => fetch(url, init),
|
|
3441
3362
|
attempts: 15,
|
|
@@ -3461,12 +3382,12 @@ var SponsorRelayController = class {
|
|
|
3461
3382
|
throw new Error("OrbitDB relay runtime is missing required mapped TCP/WS ports.");
|
|
3462
3383
|
}
|
|
3463
3384
|
const configureResult = await configureOrbitdbRelaySetup2({
|
|
3464
|
-
hostIpv4: runtime.hostIpv4,
|
|
3465
|
-
publicIpv6: runtime.ipv6,
|
|
3385
|
+
hostIpv4: args.runtime.hostIpv4,
|
|
3386
|
+
publicIpv6: args.runtime.ipv6,
|
|
3466
3387
|
setupPort,
|
|
3467
3388
|
tcpPort,
|
|
3468
3389
|
wsPort,
|
|
3469
|
-
proxyUrl: runtime.proxyUrl ?? void 0,
|
|
3390
|
+
proxyUrl: args.runtime.proxyUrl ?? void 0,
|
|
3470
3391
|
metricsPort: mappedPorts2["9090"]?.host ?? null,
|
|
3471
3392
|
metricsHttpsPort: mappedPorts2["443"]?.host ?? null,
|
|
3472
3393
|
webrtcPort: mappedPorts2["9093"]?.host ?? null,
|
|
@@ -3483,54 +3404,6 @@ var SponsorRelayController = class {
|
|
|
3483
3404
|
if (!args.deploymentToken) {
|
|
3484
3405
|
throw new Error("Missing deployment token for Aleph bootstrap config handoff.");
|
|
3485
3406
|
}
|
|
3486
|
-
if (runtime.proxyUrl && runtime.webAccess?.active !== true) {
|
|
3487
|
-
this.emitProgress({
|
|
3488
|
-
stage: "deployment-confirmed",
|
|
3489
|
-
label: "Waiting for HTTPS route",
|
|
3490
|
-
progress: 93,
|
|
3491
|
-
status: "warning",
|
|
3492
|
-
itemHash: args.itemHash,
|
|
3493
|
-
detail: "The relay received a 2n6 hostname, but it is not active yet. Waiting before handing HTTPS config to the guest."
|
|
3494
|
-
});
|
|
3495
|
-
let latestRuntime = runtime;
|
|
3496
|
-
for (let attempt = 0; attempt < UI_RUNTIME_WAIT_ATTEMPTS; attempt += 1) {
|
|
3497
|
-
if (latestRuntime.webAccess?.active === true) {
|
|
3498
|
-
break;
|
|
3499
|
-
}
|
|
3500
|
-
await new Promise(
|
|
3501
|
-
(resolve) => globalThis.setTimeout(resolve, UI_RUNTIME_WAIT_DELAY_MS)
|
|
3502
|
-
);
|
|
3503
|
-
latestRuntime = await fetchVmRuntime({
|
|
3504
|
-
itemHash: args.itemHash,
|
|
3505
|
-
fetch: (url, init) => fetch(url, init),
|
|
3506
|
-
crnHash: runtime.selectedCrn?.hash ?? runtime.allocation?.crnHash ?? void 0,
|
|
3507
|
-
crns: this.state.crns,
|
|
3508
|
-
crnListUrl: this.props.crnListUrl
|
|
3509
|
-
}).catch(() => latestRuntime);
|
|
3510
|
-
this.emitProgress({
|
|
3511
|
-
stage: "deployment-confirmed",
|
|
3512
|
-
label: "Waiting for HTTPS route",
|
|
3513
|
-
progress: 93,
|
|
3514
|
-
status: latestRuntime.webAccess?.active === true ? "info" : "warning",
|
|
3515
|
-
itemHash: args.itemHash,
|
|
3516
|
-
detail: `2n6 activation ${attempt + 1}/${UI_RUNTIME_WAIT_ATTEMPTS}: ${latestRuntime.webAccess?.active === true ? "active" : "still pending"} for ${latestRuntime.proxyUrl ?? runtime.proxyUrl ?? "reserved proxy URL"}.`
|
|
3517
|
-
});
|
|
3518
|
-
this.trace("deploy:bootstrap-proxy-activation", {
|
|
3519
|
-
itemHash: args.itemHash,
|
|
3520
|
-
attempt: attempt + 1,
|
|
3521
|
-
attempts: UI_RUNTIME_WAIT_ATTEMPTS,
|
|
3522
|
-
active: latestRuntime.webAccess?.active === true,
|
|
3523
|
-
proxyUrl: latestRuntime.proxyUrl ?? null
|
|
3524
|
-
});
|
|
3525
|
-
}
|
|
3526
|
-
runtime = latestRuntime;
|
|
3527
|
-
mappedPorts2 = runtime.mappedPorts ?? mappedPorts2;
|
|
3528
|
-
}
|
|
3529
|
-
if (!runtime.hostIpv4) {
|
|
3530
|
-
throw new Error("Relay runtime lost its host IPv4 address while waiting for HTTPS activation.");
|
|
3531
|
-
}
|
|
3532
|
-
const runtimeHostIpv4 = runtime.hostIpv4;
|
|
3533
|
-
const activeProxyUrl = runtime.webAccess?.active === true ? runtime.proxyUrl ?? null : null;
|
|
3534
3407
|
this.emitProgress({
|
|
3535
3408
|
stage: "deployment-confirmed",
|
|
3536
3409
|
label: "Publishing relay config",
|
|
@@ -3548,9 +3421,9 @@ var SponsorRelayController = class {
|
|
|
3548
3421
|
expiresAt: new Date(Date.now() + 30 * 6e4).toISOString(),
|
|
3549
3422
|
status: "pending",
|
|
3550
3423
|
runtime: {
|
|
3551
|
-
publicIpv4:
|
|
3552
|
-
publicIpv6: runtime.ipv6 ?? null,
|
|
3553
|
-
proxyUrl:
|
|
3424
|
+
publicIpv4: args.runtime.hostIpv4,
|
|
3425
|
+
publicIpv6: args.runtime.ipv6 ?? null,
|
|
3426
|
+
proxyUrl: args.runtime.proxyUrl ?? null,
|
|
3554
3427
|
mappedPorts: mappedPorts2
|
|
3555
3428
|
},
|
|
3556
3429
|
bootstrap: {
|
|
@@ -3579,164 +3452,49 @@ var SponsorRelayController = class {
|
|
|
3579
3452
|
aggregateItemHash: bootstrapConfigPublication.aggregateItemHash,
|
|
3580
3453
|
aggregateStatus: bootstrapConfigPublication.aggregateStatus
|
|
3581
3454
|
});
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
bootstrapConfigSignal
|
|
3603
|
-
});
|
|
3604
|
-
if (!bootstrapConfigSignal) {
|
|
3605
|
-
throw new Error(
|
|
3606
|
-
"The relay VM did not confirm that it applied the Aleph bootstrap config in time."
|
|
3607
|
-
);
|
|
3608
|
-
}
|
|
3609
|
-
bootstrapSignalRelayMetadata = typeof bootstrapConfigSignal.peerId === "string" && bootstrapConfigSignal.peerId.length > 0 && Array.isArray(bootstrapConfigSignal.probeMultiaddrs) && bootstrapConfigSignal.probeMultiaddrs.length > 0 ? {
|
|
3610
|
-
peerId: bootstrapConfigSignal.peerId,
|
|
3611
|
-
probeMultiaddrs: bootstrapConfigSignal.probeMultiaddrs,
|
|
3612
|
-
browserBootstrapMultiaddrs: bootstrapConfigSignal.browserBootstrapMultiaddrs ?? []
|
|
3613
|
-
} : null;
|
|
3614
|
-
if (runtime.proxyUrl && runtime.webAccess?.active !== true) {
|
|
3615
|
-
this.trace("deploy:bootstrap-proxy-fallback", {
|
|
3616
|
-
itemHash: args.itemHash,
|
|
3617
|
-
deploymentToken: args.deploymentToken,
|
|
3618
|
-
proxyUrl: runtime.proxyUrl,
|
|
3619
|
-
bootstrapSignalRelayMetadata
|
|
3620
|
-
});
|
|
3621
|
-
this.emitProgress({
|
|
3622
|
-
stage: "deployment-confirmed",
|
|
3623
|
-
label: "Continuing without HTTPS route",
|
|
3624
|
-
progress: 94,
|
|
3625
|
-
status: "warning",
|
|
3455
|
+
}
|
|
3456
|
+
this.emitProgress({
|
|
3457
|
+
stage: "publishing-bootstrap",
|
|
3458
|
+
label: "Reading relay multiaddrs",
|
|
3459
|
+
progress: 95,
|
|
3460
|
+
status: "info",
|
|
3461
|
+
itemHash: args.itemHash,
|
|
3462
|
+
detail: "Waiting for the relay to report its final public multiaddrs."
|
|
3463
|
+
});
|
|
3464
|
+
const relayMetadata = await fetchRelayMetadataForRuntime({
|
|
3465
|
+
runtime: args.runtime,
|
|
3466
|
+
fetch: (url, init) => fetch(url, init),
|
|
3467
|
+
preferSecureMetadata: profile === "uc-go-peer",
|
|
3468
|
+
attempts: 80,
|
|
3469
|
+
delayMs: 3e3,
|
|
3470
|
+
timeoutMs: 24e4,
|
|
3471
|
+
onAttempt: (result) => {
|
|
3472
|
+
const payload = result.payload && typeof result.payload === "object" ? result.payload : null;
|
|
3473
|
+
const metadata = payload?.metadata && typeof payload.metadata === "object" ? payload.metadata : null;
|
|
3474
|
+
this.trace("deploy:relay-metadata-attempt", {
|
|
3626
3475
|
itemHash: args.itemHash,
|
|
3627
|
-
|
|
3476
|
+
attempt: result.attempt,
|
|
3477
|
+
attempts: result.attempts,
|
|
3478
|
+
requestUrl: result.requestUrl,
|
|
3479
|
+
metadataUrl: result.metadataUrl,
|
|
3480
|
+
hostIpv4: result.hostIpv4,
|
|
3481
|
+
setupPort: result.setupPort,
|
|
3482
|
+
ok: result.ok,
|
|
3483
|
+
status: result.status,
|
|
3484
|
+
ready: result.ready,
|
|
3485
|
+
error: result.error ?? null,
|
|
3486
|
+
payloadStatus: payload && typeof payload.status === "string" ? payload.status : null,
|
|
3487
|
+
peerId: metadata && typeof metadata.peer_id === "string" ? metadata.peer_id : null,
|
|
3488
|
+
probeMultiaddrCount: Array.isArray(metadata?.probe_multiaddrs) ? metadata.probe_multiaddrs.length : 0,
|
|
3489
|
+
browserBootstrapMultiaddrCount: Array.isArray(
|
|
3490
|
+
metadata?.browser_bootstrap_multiaddrs
|
|
3491
|
+
) ? metadata.browser_bootstrap_multiaddrs.length : 0
|
|
3628
3492
|
});
|
|
3629
|
-
runtime = {
|
|
3630
|
-
...runtime,
|
|
3631
|
-
proxyUrl: null,
|
|
3632
|
-
webAccess: runtime.webAccess ? {
|
|
3633
|
-
...runtime.webAccess,
|
|
3634
|
-
active: false
|
|
3635
|
-
} : runtime.webAccess
|
|
3636
|
-
};
|
|
3637
3493
|
}
|
|
3638
|
-
}
|
|
3639
|
-
let relayMetadata = bootstrapSignalRelayMetadata;
|
|
3640
|
-
if (relayMetadata) {
|
|
3641
|
-
this.trace("deploy:relay-metadata-from-bootstrap-signal", {
|
|
3642
|
-
itemHash: args.itemHash,
|
|
3643
|
-
peerId: relayMetadata.peerId,
|
|
3644
|
-
probeMultiaddrCount: relayMetadata.probeMultiaddrs.length,
|
|
3645
|
-
browserBootstrapMultiaddrCount: relayMetadata.browserBootstrapMultiaddrs.length
|
|
3646
|
-
});
|
|
3647
|
-
} else {
|
|
3648
|
-
this.emitProgress({
|
|
3649
|
-
stage: "publishing-bootstrap",
|
|
3650
|
-
label: "Reading relay multiaddrs",
|
|
3651
|
-
progress: 95,
|
|
3652
|
-
status: "info",
|
|
3653
|
-
itemHash: args.itemHash,
|
|
3654
|
-
detail: "Waiting for the relay to report its final public multiaddrs."
|
|
3655
|
-
});
|
|
3656
|
-
relayMetadata = await fetchRelayMetadataForRuntime({
|
|
3657
|
-
runtime,
|
|
3658
|
-
fetch: (url, init) => fetch(url, init),
|
|
3659
|
-
preferSecureMetadata: profile === "uc-go-peer" && Boolean(runtime.proxyUrl),
|
|
3660
|
-
attempts: 80,
|
|
3661
|
-
delayMs: 3e3,
|
|
3662
|
-
timeoutMs: 24e4,
|
|
3663
|
-
onAttempt: (result) => {
|
|
3664
|
-
const payload = result.payload && typeof result.payload === "object" ? result.payload : null;
|
|
3665
|
-
const metadata = payload?.metadata && typeof payload.metadata === "object" ? payload.metadata : null;
|
|
3666
|
-
this.trace("deploy:relay-metadata-attempt", {
|
|
3667
|
-
itemHash: args.itemHash,
|
|
3668
|
-
attempt: result.attempt,
|
|
3669
|
-
attempts: result.attempts,
|
|
3670
|
-
requestUrl: result.requestUrl,
|
|
3671
|
-
metadataUrl: result.metadataUrl,
|
|
3672
|
-
hostIpv4: result.hostIpv4,
|
|
3673
|
-
setupPort: result.setupPort,
|
|
3674
|
-
ok: result.ok,
|
|
3675
|
-
status: result.status,
|
|
3676
|
-
ready: result.ready,
|
|
3677
|
-
error: result.error ?? null,
|
|
3678
|
-
payloadStatus: payload && typeof payload.status === "string" ? payload.status : null,
|
|
3679
|
-
peerId: metadata && typeof metadata.peer_id === "string" ? metadata.peer_id : null,
|
|
3680
|
-
probeMultiaddrCount: Array.isArray(metadata?.probe_multiaddrs) ? metadata.probe_multiaddrs.length : 0,
|
|
3681
|
-
browserBootstrapMultiaddrCount: Array.isArray(
|
|
3682
|
-
metadata?.browser_bootstrap_multiaddrs
|
|
3683
|
-
) ? metadata.browser_bootstrap_multiaddrs.length : 0
|
|
3684
|
-
});
|
|
3685
|
-
}
|
|
3686
|
-
});
|
|
3687
|
-
}
|
|
3494
|
+
});
|
|
3688
3495
|
if (!relayMetadata) {
|
|
3689
3496
|
throw new Error("Relay metadata did not include a peer ID and public multiaddrs.");
|
|
3690
3497
|
}
|
|
3691
|
-
if (profile === "uc-go-peer" && runtime.proxyUrl) {
|
|
3692
|
-
this.emitProgress({
|
|
3693
|
-
stage: "publishing-bootstrap",
|
|
3694
|
-
label: "Verifying reachability",
|
|
3695
|
-
progress: 96,
|
|
3696
|
-
status: "info",
|
|
3697
|
-
itemHash: args.itemHash,
|
|
3698
|
-
detail: "Checking that the secure relay endpoint is reachable before trusting the deployment as ready."
|
|
3699
|
-
});
|
|
3700
|
-
const verificationUrl = (() => {
|
|
3701
|
-
try {
|
|
3702
|
-
return new URL("/bootstrap/metadata", runtime.proxyUrl).toString();
|
|
3703
|
-
} catch {
|
|
3704
|
-
return runtime.proxyUrl ?? "";
|
|
3705
|
-
}
|
|
3706
|
-
})();
|
|
3707
|
-
let verificationResult = null;
|
|
3708
|
-
for (let attempt = 0; attempt < UI_REACHABILITY_VERIFY_ATTEMPTS; attempt += 1) {
|
|
3709
|
-
verificationResult = await verifyUcGoPeerReachability({
|
|
3710
|
-
proxyUrl: verificationUrl,
|
|
3711
|
-
verifyProxyHttp: true,
|
|
3712
|
-
fetch: (url, init) => fetch(url, init),
|
|
3713
|
-
tcpProbe: async () => ({ ok: null })
|
|
3714
|
-
});
|
|
3715
|
-
this.trace("deploy:reachability-verification-attempt", {
|
|
3716
|
-
itemHash: args.itemHash,
|
|
3717
|
-
attempt: attempt + 1,
|
|
3718
|
-
attempts: UI_REACHABILITY_VERIFY_ATTEMPTS,
|
|
3719
|
-
verificationUrl,
|
|
3720
|
-
ok: verificationResult.ok,
|
|
3721
|
-
checks: verificationResult.checks
|
|
3722
|
-
});
|
|
3723
|
-
const proxyHttpCheck2 = verificationResult.checks["https:proxy"];
|
|
3724
|
-
if (verificationResult.ok && proxyHttpCheck2?.ok === true) {
|
|
3725
|
-
break;
|
|
3726
|
-
}
|
|
3727
|
-
if (attempt < UI_REACHABILITY_VERIFY_ATTEMPTS - 1) {
|
|
3728
|
-
await new Promise(
|
|
3729
|
-
(resolve) => globalThis.setTimeout(resolve, UI_REACHABILITY_VERIFY_DELAY_MS)
|
|
3730
|
-
);
|
|
3731
|
-
}
|
|
3732
|
-
}
|
|
3733
|
-
const proxyHttpCheck = verificationResult?.checks["https:proxy"];
|
|
3734
|
-
if (!verificationResult?.ok || proxyHttpCheck?.ok !== true) {
|
|
3735
|
-
throw new Error(
|
|
3736
|
-
proxyHttpCheck?.error ? `Secure relay endpoint did not become reachable in time: ${proxyHttpCheck.error}` : "Secure relay endpoint did not become reachable in time."
|
|
3737
|
-
);
|
|
3738
|
-
}
|
|
3739
|
-
}
|
|
3740
3498
|
const { peerId } = relayMetadata;
|
|
3741
3499
|
const registrationId = createRelayBootstrapRegistrationId(
|
|
3742
3500
|
profile,
|
|
@@ -3854,7 +3612,6 @@ var SponsorRelayController = class {
|
|
|
3854
3612
|
const currentProgress = this.state.deploymentProgress;
|
|
3855
3613
|
const currentProgressIsForLatestHash = currentProgress.itemHash === itemHash || currentProgress.itemHash == null && currentProgress.stage !== "idle" && currentProgress.stage !== "error";
|
|
3856
3614
|
const keepTerminalSuccess = this.lastCompletedDeploymentHash === itemHash || currentProgressIsForLatestHash && currentProgress.stage === "completed" && currentProgress.status === "success";
|
|
3857
|
-
const keepSpecificInFlightProgress = currentProgressIsForLatestHash && currentProgress.stage !== "completed" && currentProgress.stage !== "error" && currentProgress.progress >= 93;
|
|
3858
3615
|
const status = latest.details.messageStatus;
|
|
3859
3616
|
if (status === "rejected") {
|
|
3860
3617
|
this.emitProgress({
|
|
@@ -3897,16 +3654,6 @@ var SponsorRelayController = class {
|
|
|
3897
3654
|
});
|
|
3898
3655
|
return;
|
|
3899
3656
|
}
|
|
3900
|
-
if (keepSpecificInFlightProgress) {
|
|
3901
|
-
this.trace("progress:retain-inflight", {
|
|
3902
|
-
reason: "latest refresh would overwrite a more specific in-flight deployment phase",
|
|
3903
|
-
itemHash,
|
|
3904
|
-
currentStage: currentProgress.stage,
|
|
3905
|
-
currentLabel: currentProgress.label,
|
|
3906
|
-
currentProgress: currentProgress.progress
|
|
3907
|
-
});
|
|
3908
|
-
return;
|
|
3909
|
-
}
|
|
3910
3657
|
this.emitProgress({
|
|
3911
3658
|
stage: "deployment-confirmed",
|
|
3912
3659
|
label: "Waiting for runtime",
|
|
@@ -3917,16 +3664,6 @@ var SponsorRelayController = class {
|
|
|
3917
3664
|
});
|
|
3918
3665
|
return;
|
|
3919
3666
|
}
|
|
3920
|
-
if (keepSpecificInFlightProgress) {
|
|
3921
|
-
this.trace("progress:retain-inflight", {
|
|
3922
|
-
reason: "latest refresh would overwrite a more specific in-flight deployment phase",
|
|
3923
|
-
itemHash,
|
|
3924
|
-
currentStage: currentProgress.stage,
|
|
3925
|
-
currentLabel: currentProgress.label,
|
|
3926
|
-
currentProgress: currentProgress.progress
|
|
3927
|
-
});
|
|
3928
|
-
return;
|
|
3929
|
-
}
|
|
3930
3667
|
this.emitProgress({
|
|
3931
3668
|
stage: "deployment-confirmed",
|
|
3932
3669
|
label: "Runtime ready",
|
|
@@ -4005,11 +3742,16 @@ var SponsorRelayController = class {
|
|
|
4005
3742
|
this.refreshTimer = setInterval(() => {
|
|
4006
3743
|
void this.refresh();
|
|
4007
3744
|
}, REFRESH_INTERVAL_MS);
|
|
3745
|
+
this.pingTimer = setInterval(() => {
|
|
3746
|
+
void this.refreshRelayPing();
|
|
3747
|
+
}, RELAY_PING_INTERVAL_MS);
|
|
3748
|
+
await this.refreshRelayPing();
|
|
4008
3749
|
this.patch({ ready: true });
|
|
4009
3750
|
this.trace("init:ready");
|
|
4010
3751
|
}
|
|
4011
3752
|
destroy() {
|
|
4012
3753
|
if (this.refreshTimer) clearInterval(this.refreshTimer);
|
|
3754
|
+
if (this.pingTimer) clearInterval(this.pingTimer);
|
|
4013
3755
|
if (this.manifestRefreshTimer) clearTimeout(this.manifestRefreshTimer);
|
|
4014
3756
|
this.stopWalletWatch?.();
|
|
4015
3757
|
}
|
|
@@ -4304,6 +4046,11 @@ var SponsorRelayController = class {
|
|
|
4304
4046
|
});
|
|
4305
4047
|
}
|
|
4306
4048
|
}
|
|
4049
|
+
async refreshRelayPing() {
|
|
4050
|
+
const relayPing = await pingPeer(this.props.libp2p);
|
|
4051
|
+
this.patch({ relayPing });
|
|
4052
|
+
this.trace("libp2p:relay-ping", relayPing);
|
|
4053
|
+
}
|
|
4307
4054
|
async deploy() {
|
|
4308
4055
|
this.trace("deploy:start", {
|
|
4309
4056
|
wallet: this.state.wallet.address,
|
|
@@ -4596,15 +4343,6 @@ var SponsorRelayController = class {
|
|
|
4596
4343
|
});
|
|
4597
4344
|
if (attemptItemHash) {
|
|
4598
4345
|
if (attemptDeploymentToken) {
|
|
4599
|
-
this.emitProgress({
|
|
4600
|
-
stage: "refreshing-instances",
|
|
4601
|
-
label: "Cleaning up failed attempt",
|
|
4602
|
-
progress: 16,
|
|
4603
|
-
status: "warning",
|
|
4604
|
-
itemHash: attemptItemHash,
|
|
4605
|
-
detail: `Removing bootstrap handoff state for failed deployment on ${attemptLabel}.`,
|
|
4606
|
-
error: lastError.message
|
|
4607
|
-
});
|
|
4608
4346
|
this.trace("deploy:bootstrap-config-cleanup-start", {
|
|
4609
4347
|
itemHash: attemptItemHash,
|
|
4610
4348
|
deploymentToken: attemptDeploymentToken
|
|
@@ -4630,26 +4368,8 @@ var SponsorRelayController = class {
|
|
|
4630
4368
|
deploymentToken: attemptDeploymentToken,
|
|
4631
4369
|
error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
4632
4370
|
});
|
|
4633
|
-
this.emitProgress({
|
|
4634
|
-
stage: "refreshing-instances",
|
|
4635
|
-
label: "Cleanup warning",
|
|
4636
|
-
progress: 16,
|
|
4637
|
-
status: "warning",
|
|
4638
|
-
itemHash: attemptItemHash,
|
|
4639
|
-
detail: `Bootstrap cleanup reported an issue for ${attemptLabel}, but retry cleanup will continue.`,
|
|
4640
|
-
error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
4641
|
-
});
|
|
4642
4371
|
});
|
|
4643
4372
|
}
|
|
4644
|
-
this.emitProgress({
|
|
4645
|
-
stage: "refreshing-instances",
|
|
4646
|
-
label: "Discarding failed deployment",
|
|
4647
|
-
progress: 17,
|
|
4648
|
-
status: "warning",
|
|
4649
|
-
itemHash: attemptItemHash,
|
|
4650
|
-
detail: `Forgetting failed deployment ${attemptItemHash.slice(0, 12)} on ${attemptLabel} before retrying.`,
|
|
4651
|
-
error: lastError.message
|
|
4652
|
-
});
|
|
4653
4373
|
this.trace("deploy:forget-failed-attempt-start", {
|
|
4654
4374
|
itemHash: attemptItemHash,
|
|
4655
4375
|
crnHash: candidateCrn.hash,
|
|
@@ -4672,30 +4392,12 @@ var SponsorRelayController = class {
|
|
|
4672
4392
|
itemHash: attemptItemHash,
|
|
4673
4393
|
error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
4674
4394
|
});
|
|
4675
|
-
this.emitProgress({
|
|
4676
|
-
stage: "refreshing-instances",
|
|
4677
|
-
label: "Cleanup warning",
|
|
4678
|
-
progress: 17,
|
|
4679
|
-
status: "warning",
|
|
4680
|
-
itemHash: attemptItemHash,
|
|
4681
|
-
detail: `Failed deployment cleanup reported an issue for ${attemptLabel}.`,
|
|
4682
|
-
error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
4683
|
-
});
|
|
4684
4395
|
});
|
|
4685
4396
|
this.trace("deploy:forget-failed-attempt-complete", {
|
|
4686
4397
|
itemHash: attemptItemHash,
|
|
4687
4398
|
crnHash: candidateCrn.hash,
|
|
4688
4399
|
crnName: candidateCrn.name
|
|
4689
4400
|
});
|
|
4690
|
-
this.emitProgress({
|
|
4691
|
-
stage: "refreshing-instances",
|
|
4692
|
-
label: "Cleanup complete",
|
|
4693
|
-
progress: 18,
|
|
4694
|
-
status: "info",
|
|
4695
|
-
itemHash: attemptItemHash,
|
|
4696
|
-
detail: `Finished cleaning up failed deployment on ${attemptLabel}.`,
|
|
4697
|
-
error: null
|
|
4698
|
-
});
|
|
4699
4401
|
}
|
|
4700
4402
|
if (candidateIndex < orderedCrns.length - 1) {
|
|
4701
4403
|
this.emitProgress({
|
|
@@ -4876,6 +4578,8 @@ export {
|
|
|
4876
4578
|
MANIFEST_SOURCE_REFRESH_DEBOUNCE_MS,
|
|
4877
4579
|
RECENT_INSTANCE_RUNTIME_GRACE_MS,
|
|
4878
4580
|
REFRESH_INTERVAL_MS,
|
|
4581
|
+
RELAY_PING_IDLE_STATE,
|
|
4582
|
+
RELAY_PING_INTERVAL_MS,
|
|
4879
4583
|
ROOTFS_MISSING_STATE,
|
|
4880
4584
|
STALE_INSTANCE_ALLOCATION_COOLDOWN_MS,
|
|
4881
4585
|
SponsorRelayController,
|