@impeccable/reviews 0.1.31 → 0.1.32

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/dist/hosting.js CHANGED
@@ -33,7 +33,24 @@ export function hostingOf(state, repo) {
33
33
  return [{ key, liveUrl: address(a.liveUrl), previews }];
34
34
  });
35
35
  const unread = Array.isArray(hosting.unread) ? hosting.unread.flatMap((u) => text(u) ?? []) : [];
36
- return { apps, readAt: text(hosting.readAt), unread };
36
+ return { apps, readAt: text(hosting.readAt), unread, ...(hosting.readPending === true ? { readPending: true } : {}) };
37
+ }
38
+ /**
39
+ * The record once it is whole: while the state says a read of it is pending, the state is read again every few seconds,
40
+ * up to a minute by the clock, each read bounded by what is left of it. Past that, its previews are left out and it
41
+ * counts as never read, so each host tool reads its previews itself, as it does without a record; the live addresses stay.
42
+ */
43
+ export async function settledHosting(first, repo, readState, opts = {}) {
44
+ const { everyMs = 3_000, upToMs = 60_000, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), now = Date.now } = opts;
45
+ const deadline = now() + upToMs;
46
+ let hosting = hostingOf(first, repo);
47
+ while (hosting?.readPending && now() + everyMs < deadline) {
48
+ await sleep(everyMs);
49
+ const state = await readState(deadline - now());
50
+ if (state.ok)
51
+ hosting = hostingOf(state.data, repo) ?? hosting;
52
+ }
53
+ return hosting?.readPending ? { apps: hosting.apps.map((a) => ({ ...a, previews: [] })), readAt: null, unread: hosting.unread } : hosting;
37
54
  }
38
55
  /** The reports each host's previews are read from, besides the deployments every read takes. */
39
56
  const REPORTS = { netlify: ['statuses', 'comments'], cloudflare: ['check-runs', 'comments'], render: [] };
package/dist/main.js CHANGED
@@ -7,7 +7,7 @@ import { runAgent } from './agent.js';
7
7
  import { runSkillCommand } from './skill.js';
8
8
  import { fenceExtension, guardedFileOperations, hostsAgreed, placeOf, previewRetryState } from './fence.js';
9
9
  import { accountsSaved, focusInstructions, focusState, severalApps, signInItem } from './focus.js';
10
- import { hostingOf } from './hosting.js';
10
+ import { settledHosting } from './hosting.js';
11
11
  import { requestJson } from './http.js';
12
12
  import { copyText, letTabsHear, openBrowser, progressPage, screenPrompt, setupAuth, signIn } from './login.js';
13
13
  import { checkoutJournal } from './leftovers.js';
@@ -234,6 +234,8 @@ export async function main(argv) {
234
234
  ]);
235
235
  if (!instructions.ok || !state.ok)
236
236
  throw new UserError(`Impeccable's setup API did not answer: ${instructions.error ?? state.error}.`);
237
+ // A hosting record behind GitHub is read again while the questions below are asked (hosting.ts `settledHosting`).
238
+ const hosting = settledHosting(state.data, token.repository.name, (timeoutMs) => requestJson(`${setupApi}/state`, { token: token.access_token, timeoutMs }, log));
237
239
  // When the checkout cannot tell, the setup state's own verdict decides. When it has a web front end Impeccable skipped, the person adds it first.
238
240
  if (stateSaysNoFrontEnd(state.data, token.repository.name)) {
239
241
  if (frontEnd === 'unknown')
@@ -395,7 +397,7 @@ export async function main(argv) {
395
397
  sandbox,
396
398
  pushAccess: push.outcome,
397
399
  severalApps: severalApps(state.data),
398
- hosting: hostingOf(state.data, token.repository.name),
400
+ hosting: await hosting,
399
401
  ...(flags.app ? { app: flags.app } : {}),
400
402
  start: checkout.start,
401
403
  ...(flags.signedInTestDrive ? { signedInTestDrive: { accountsSaved: accountsSaved(state.data, token.repository.name) } } : {}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impeccable/reviews",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "Set up a repository for Impeccable for PRs from your terminal.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "private": false,