Table of Contents

UCI Troubleshooting Tests

Console Tests

List out the current versions in the cache

(async () => {
  const solution = "SenseiControlsV1";
  const controls = ["IQ.AltusAssist", "IQ.AltusDashboard", "IQ.GridCellRenderer"];
  const targets = ["https://uci-state/", "WebResources"];
  const cacheStorage = window.caches;
  const existing = cacheStorage ? await cacheStorage.keys() : [];
  const deployed = window.SenseiIqTelemetryProperties?.SolutionVersions
    ?.find(v => String(v.solutionName).toLowerCase() === solution.toLowerCase())?.version;

  let sentinel;
  try { sentinel = JSON.parse(sessionStorage.getItem("altus.uciCacheBust") || "null"); }
  catch (e) { sentinel = `unreadable: ${e.name}`; }

  let serviceWorkerCount;
  try { serviceWorkerCount = (await navigator.serviceWorker?.getRegistrations?.() || []).length; }
  catch (e) { serviceWorkerCount = `unavailable: ${e.name}`; }

  const cacheEntryCounts = {};
  for (const name of targets) {
    cacheEntryCounts[name] = existing.includes(name)
      ? (await (await cacheStorage.open(name)).keys()).length
      : "missing";
  }

  const rows = [];
  if (existing.includes(targets[0])) {
    const cache = await cacheStorage.open(targets[0]);
    const [request] = await cache.keys();
    const response = request ? await cache.match(request) : null;
    const state = response ? await response.json() : {};
    const isTarget = name => controls.some(c =>
      String(name || "").toLowerCase().includes(c.toLowerCase()));
    const add = (kind, name, cached) => {
      if (typeof cached === "string" && cached) {
        rows.push({ kind, name, cached, deployed: deployed || "missing",
          stale: deployed ? cached !== deployed : "unknown" });
      }
    };

    for (const x of Object.values(state?.metadata?.webResources || {})) {
      if (String(x?.solutionName || "").toLowerCase() === solution.toLowerCase() && isTarget(x?.name))
        add("resource", x.name, x.solutionVersion);
    }
    for (const x of Object.values(state?.metadata?.controlManifests || {})) {
      if (String(x?.SolutionName || "").toLowerCase() === solution.toLowerCase() && isTarget(x?.ConstructorName))
        add("manifest", x.ConstructorName, x.SolutionVersion);
    }
  }

  console.log({ at: new Date().toISOString(), cacheStorageAvailable: !!cacheStorage,
    serviceWorkerCount, cacheEntryCounts, deployedVersion: deployed || "missing", sentinel });
  console.table(rows);
})().catch(console.error);

Create a UCI Cache Issue


(async () => {
  const CONTROL = "IQ.AltusDashboard";
  const SOLUTION = "SenseiControlsV1";
  const CORRUPTED_VERSION = "0.0.0.0";
  const SENTINEL = "altus.uciCacheBust";
  const cache = await caches.open("https://uci-state/");
  const requests = await cache.keys();

  if (requests.length === 0) throw new Error("No uci-state entry found.");

  const request = requests[0];
  const response = await cache.match(request);

  if (!response) throw new Error("Unable to read uci-state entry.");

  const state = JSON.parse(await response.text());

  let changed = 0;

  const isTargetSolution = (value) =>
    typeof value === "string" && value.toLowerCase() === SOLUTION.toLowerCase();

  for (const resource of Object.values(state.metadata?.webResources ?? {})) {
    if (
      resource?.name?.startsWith(`cc_${CONTROL}/`) &&
      isTargetSolution(resource.solutionName)
    ) {
      resource.solutionVersion = CORRUPTED_VERSION;
      changed++;
    }
  }

  for (const manifest of Object.values(
    state.metadata?.controlManifests ?? {},
  )) {
    if (
      manifest?.ConstructorName === CONTROL &&
      isTargetSolution(manifest.SolutionName)
    ) {
      manifest.SolutionVersion = CORRUPTED_VERSION;
      changed++;
    }
  }

  if (changed === 0) {
    throw new Error(`No cached entries found for ${CONTROL}.`);
  }

  await cache.put(
    request,
    new Response(JSON.stringify(state), {
      headers: { "Content-Type": "application/json" },
    }),
  );

  sessionStorage.removeItem(SENTINEL);

  console.table({
    control: CONTROL,
    corruptedEntries: changed,
    corruptedVersion: CORRUPTED_VERSION,
    stateEntry: request.url,
  });
  location.reload();
})().catch(console.error);

Cleanup after testing


(async () => {

    await caches.delete("https://uci-state/");

    await caches.delete("WebResources");

    sessionStorage.removeItem("altus.uciCacheBust");

    location.reload();

})();