File size: 1,950 Bytes
a1e3907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Data access. Paths resolve against the origin (the viewer may be served at /viewer/ or embedded).
const cache = new Map();

function get(path) {
  const url = new URL(path, location.origin).toString();
  if (!cache.has(url)) {
    const p = fetch(url, { headers: { Accept: "application/json" } }).then((r) => {
      if (!r.ok) throw new Error(`${r.status} ${r.statusText || ""} · ${path}`.trim());
      return r.json();
    });
    p.catch(() => cache.delete(url));
    cache.set(url, p);
  }
  return cache.get(url);
}

const enc = encodeURIComponent;
export const getTasks = () => get("/api/tasks");
export const getTask = (id) => get(`/api/tasks/${enc(id)}`);
export const getReference = (id) => get(`/api/tasks/${enc(id)}/reference`);
export const getRuns = () => get("/api/runs").catch(() => []);
export const getRun = (run) => get(`/api/runs/${enc(run)}`);
export const getEpisode = (run, model, taskId) => get(`/api/runs/${enc(run)}/episode?model=${enc(model)}&task_id=${enc(taskId)}`);

/** Every episode of every run, each tagged with its run name. */
export async function getAllEpisodes() {
  const runs = (await getRuns()) || [];
  const details = await Promise.all(runs.map((r) => getRun(r.run).catch(() => null)));
  const out = [];
  details.forEach((d, i) => {
    if (!d) return;
    for (const e of d.episodes || []) out.push({ ...e, run: d.run || runs[i].run });
  });
  return { runs, episodes: out };
}

/** Live endpoints are polled, so they bypass the cache. */
async function fresh(path) {
  const r = await fetch(new URL(path, location.origin).toString(), { headers: { Accept: "application/json" }, cache: "no-store" });
  if (!r.ok) {
    const err = new Error(`${r.status} ${r.statusText || ""} · ${path}`.trim());
    err.status = r.status;
    throw err;
  }
  return r.json();
}
export const getLiveEpisodes = () => fresh("/api/episodes");
export const getLiveEpisode = (id) => fresh(`/api/episodes/${enc(id)}`);