( ids: AppConfigProfileIdentifiers, parse: (json: unknown) => T )
| 134 | * is empty/unseeded or the first fetch fails. |
| 135 | */ |
| 136 | export async function fetchAppConfigProfile<T>( |
| 137 | ids: AppConfigProfileIdentifiers, |
| 138 | parse: (json: unknown) => T |
| 139 | ): Promise<T | null> { |
| 140 | const key = cacheKey(ids) |
| 141 | const entry = (cache.get(key) as CacheEntry<T> | undefined) ?? { |
| 142 | value: null, |
| 143 | loaded: false, |
| 144 | nextToken: undefined, |
| 145 | expiresAt: 0, |
| 146 | inflight: null, |
| 147 | } |
| 148 | cache.set(key, entry) |
| 149 | |
| 150 | // Cold: never polled — await a single shared poll so concurrent callers don't |
| 151 | // each hit AppConfig (and don't race the rotating session token). |
| 152 | if (!entry.loaded) { |
| 153 | entry.inflight ??= poll(ids, parse, entry).finally(() => { |
| 154 | entry.inflight = null |
| 155 | }) |
| 156 | return entry.inflight |
| 157 | } |
| 158 | |
| 159 | // Warm but stale: serve cached value, refresh once in the background. |
| 160 | if (Date.now() >= entry.expiresAt && !entry.inflight) { |
| 161 | entry.inflight = poll(ids, parse, entry).finally(() => { |
| 162 | entry.inflight = null |
| 163 | }) |
| 164 | } |
| 165 | |
| 166 | return entry.value |
| 167 | } |
no test coverage detected