| 1 |
|
| 2 |
* GoingsOn - View Cache Module |
| 3 |
* Generation-based invalidation cache for view switches. |
| 4 |
* Prevents redundant fetches when switching back to an already-loaded view. |
| 5 |
* |
| 6 |
* Usage: |
| 7 |
* if (GoingsOn.cache.isFresh('tasks')) return; |
| 8 |
* // ... fetch data ... |
| 9 |
* GoingsOn.cache.markLoaded('tasks'); |
| 10 |
* |
| 11 |
* // After a mutation: |
| 12 |
* GoingsOn.cache.invalidate('tasks'); |
| 13 |
|
| 14 |
|
| 15 |
(function() { |
| 16 |
'use strict'; |
| 17 |
|
| 18 |
const STALE_MS = 30000; |
| 19 |
|
| 20 |
|
| 21 |
const generations = {}; |
| 22 |
|
| 23 |
|
| 24 |
const entries = {}; |
| 25 |
|
| 26 |
|
| 27 |
* Check if cached data for an entity type is still fresh. |
| 28 |
* @param {string} entity - Entity type ('tasks', 'emails', etc.) |
| 29 |
* @returns {boolean} True if data is fresh and a refetch can be skipped |
| 30 |
|
| 31 |
function isFresh(entity) { |
| 32 |
const entry = entries[entity]; |
| 33 |
if (!entry) return false; |
| 34 |
if (entry.generation !== (generations[entity] || 0)) return false; |
| 35 |
if (Date.now() - entry.timestamp > STALE_MS) return false; |
| 36 |
return true; |
| 37 |
} |
| 38 |
|
| 39 |
|
| 40 |
* Mark an entity type as freshly loaded. Call after a successful data fetch. |
| 41 |
* @param {string} entity - Entity type |
| 42 |
|
| 43 |
function markLoaded(entity) { |
| 44 |
entries[entity] = { |
| 45 |
generation: generations[entity] || 0, |
| 46 |
timestamp: Date.now(), |
| 47 |
}; |
| 48 |
} |
| 49 |
|
| 50 |
|
| 51 |
* Invalidate one or more entity types, forcing the next load to refetch. |
| 52 |
* @param {...string} entities - Entity types to invalidate |
| 53 |
|
| 54 |
function invalidate(...entities) { |
| 55 |
for (const entity of entities) { |
| 56 |
generations[entity] = (generations[entity] || 0) + 1; |
| 57 |
} |
| 58 |
} |
| 59 |
|
| 60 |
|
| 61 |
* Invalidate all cached entity types (full cache bust). |
| 62 |
|
| 63 |
function invalidateAll() { |
| 64 |
for (const key of Object.keys(generations)) { |
| 65 |
generations[key]++; |
| 66 |
} |
| 67 |
for (const key of Object.keys(entries)) { |
| 68 |
if (!(key in generations)) { |
| 69 |
generations[key] = 1; |
| 70 |
} |
| 71 |
} |
| 72 |
} |
| 73 |
|
| 74 |
GoingsOn.cache = { |
| 75 |
isFresh, |
| 76 |
markLoaded, |
| 77 |
invalidate, |
| 78 |
invalidateAll, |
| 79 |
}; |
| 80 |
|
| 81 |
})(); |
| 82 |
|