File size: 2,636 Bytes
bc1328f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// api-client.jsx — fetch wrapper for CRUD operations
// Reads from /backend/data/*.json (static files on Azure).
// Writes fall back to in-memory ISSUES/PRS/DOCS arrays + localStorage delta.
// mock-api.jsx intercepts /api/* and handles mutations in-memory.

// Pre-load JSON data from static backend files on first load
(async function seedFromBackend() {
  const tryLoad = async (url, globalName) => {
    try {
      const r = await window._realFetch(url);
      if (!r.ok) return;
      const data = await r.json();
      if (Array.isArray(data) && typeof window[globalName] !== 'undefined') {
        // Merge: backend is source of truth; localStorage deltas layered on top
        const delta = JSON.parse(localStorage.getItem('meridian-delta-' + globalName) || '{}');
        window[globalName].length = 0;
        data.forEach(item => {
          window[globalName].push(delta[item.id] ? { ...item, ...delta[item.id] } : item);
        });
        // Append any newly created items stored only in delta
        Object.values(delta).forEach(d => {
          if (d._new && !window[globalName].find(i => i.id === d.id)) {
            window[globalName].push(d);
          }
        });
        console.log(`[api-client] Loaded ${window[globalName].length} items for ${globalName} from backend`);
      }
    } catch(e) {
      console.log(`[api-client] Backend not available for ${globalName}, using built-in data`);
    }
  };

  // Stash real fetch before mock-api overrides it
  window._realFetch = window._realFetch || window.fetch.bind(window);

  await Promise.allSettled([
    tryLoad('/backend/data/issues.json', 'ISSUES'),
    tryLoad('/backend/data/prs.json', 'PRS'),
    tryLoad('/backend/data/docs.json', 'DOCS'),
    tryLoad('/backend/data/projects.json', 'PROJECTS'),
    tryLoad('/backend/data/people.json', 'PEOPLE'),
    tryLoad('/backend/data/inbox.json', 'INBOX'),
  ]);
})();

window.apiFetch = async (method, path, body) => {
  const opts = { method, headers: { 'Content-Type': 'application/json' } };
  if (body !== undefined) opts.body = JSON.stringify(body);
  const res = await fetch(path, opts); // mock-api intercepts /api/* mutations
  if (!res.ok) throw new Error(res.status);
  return res.json();
};

// Persist a mutation delta to localStorage so it survives refresh
window.persistDelta = (collection, item) => {
  const key = 'meridian-delta-' + collection;
  const delta = JSON.parse(localStorage.getItem(key) || '{}');
  delta[item.id] = item;
  localStorage.setItem(key, JSON.stringify(delta));
};

window.meridianRefresh = () =>
  document.dispatchEvent(new CustomEvent('meridian:refresh'));