@tinycloud/cli 1.2.0-beta.9 → 1.2.1-beta.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.
@@ -929,6 +929,9 @@ async function courierNode(profile) {
929
929
  const key = loadKey();
930
930
  const grant = loadGrant();
931
931
  if (profile.status === "awaiting-space") {
932
+ if (profile.spacePending) {
933
+ throw new CourierError("no-space", `TinyCloud "${COURIER_SPACE}" space is still being set up by OpenKey; run \`${cmd("init --resume")}\`.`);
934
+ }
932
935
  throw new CourierError("no-space", `TinyCloud "${COURIER_SPACE}" space is missing; after hosting it, run \`${cmd("init --resume")}\`.`);
933
936
  }
934
937
  if (!grant || profile.status === "awaiting-grant") {
@@ -1289,6 +1292,27 @@ async function verifySpaceReady(node) {
1289
1292
  throw error;
1290
1293
  }
1291
1294
  }
1295
+ async function waitForSpaceReady(probe, options = {}) {
1296
+ const timeoutMs = options.timeoutMs ?? 15e4;
1297
+ const delaysMs = options.delaysMs ?? [2e3, 3e3, 5e3, 8e3, 13e3];
1298
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
1299
+ const now = options.now ?? Date.now;
1300
+ const started = now();
1301
+ const deadline = started + timeoutMs;
1302
+ let attempt = 0;
1303
+ for (; ; ) {
1304
+ if (await probe())
1305
+ return true;
1306
+ const current = now();
1307
+ if (current >= deadline)
1308
+ return false;
1309
+ options.onWait?.(current - started);
1310
+ await sleep(Math.min(delaysMs[attempt++] ?? 15e3, deadline - current));
1311
+ }
1312
+ }
1313
+ function pendingSpaceError(profile) {
1314
+ return new CourierError("no-space", `OpenKey is still setting up your TinyCloud "${COURIER_SPACE}" space on ${profile.host}. This can take a few minutes. Run \`${cmd("init --resume")}\` shortly; no new approval is needed. If it still isn't ready after a few minutes, run \`${cmd("init")}\` to approve again, and OpenKey will retry the setup.`);
1315
+ }
1292
1316
  function noSpaceError(profile) {
1293
1317
  return new CourierError("no-space", `Your TinyCloud "${COURIER_SPACE}" space is not set up on ${profile.host}, so the approved grant can't be used yet. Courier will not create it. If OpenKey auto-sign didn't host it, sign in once at the Share view (https://share.tinycloud.xyz) or, from a wallet profile, run \`tc space host ${COURIER_SPACE}\`. Then run \`${cmd("init --resume")}\`. No new approval is needed.`);
1294
1318
  }
@@ -1335,11 +1359,21 @@ async function installGrant(profile, key, payload) {
1335
1359
  saveGrant(grant);
1336
1360
  applyGrantToProfile(profile, grant);
1337
1361
  if (!await verifySpaceReady(node)) {
1362
+ const pending = payload.spacePending === true && payload.spaceReady === null;
1338
1363
  profile.status = "awaiting-space";
1364
+ if (pending)
1365
+ profile.spacePending = true;
1366
+ else
1367
+ delete profile.spacePending;
1339
1368
  saveProfile(profile);
1340
- throw noSpaceError(profile);
1369
+ if (!pending)
1370
+ throw noSpaceError(profile);
1371
+ console.error(`OpenKey is setting up your TinyCloud "${COURIER_SPACE}" space; waiting up to 2.5 minutes\u2026`);
1372
+ if (!await waitForSpaceReady(() => verifySpaceReady(node)))
1373
+ throw pendingSpaceError(profile);
1341
1374
  }
1342
1375
  profile.status = "ready";
1376
+ delete profile.spacePending;
1343
1377
  saveProfile(profile);
1344
1378
  }
1345
1379
  async function resumeGrant(profile, key) {
@@ -1354,12 +1388,14 @@ async function resumeGrant(profile, key) {
1354
1388
  throw new CourierError("bad-grant", `Saved grant space is not ${COURIER_SPACE}.`);
1355
1389
  }
1356
1390
  const { node } = await restoreVerifiedGrant(profile, key, payload);
1357
- if (!await verifySpaceReady(node)) {
1391
+ const ready = profile.spacePending ? await waitForSpaceReady(() => verifySpaceReady(node), { timeoutMs: 6e4 }) : await verifySpaceReady(node);
1392
+ if (!ready) {
1358
1393
  profile.status = "awaiting-space";
1359
1394
  saveProfile(profile);
1360
- throw noSpaceError(profile);
1395
+ throw profile.spacePending ? pendingSpaceError(profile) : noSpaceError(profile);
1361
1396
  }
1362
1397
  profile.status = "ready";
1398
+ delete profile.spacePending;
1363
1399
  applyGrantToProfile(profile, grant);
1364
1400
  saveProfile(profile);
1365
1401
  }