updateStorageAtomically function infrastructure exported ✓ 90.9%

Last updated: 2026-03-05T10:53:28.866Z

Metrics

LOC: 28 Complexity: 2 Params: 3 Coverage: 90.9% (10/11 lines, 0x executed)

Signature

updateStorageAtomically( key: StorageKey, defaultValue: T, updater: (current: T) => T, ): : Promise<T>

Summary

Atomically reads, transforms, and writes a storage key. Uses a per-key write queue to prevent race conditions when multiple async operations modify the same key concurrently.

Tags

#@param key - Storage key to update#@param defaultValue - Default value if key does not exist yet#@param updater - Pure function that receives current value and returns the next#@returns The new value after the update

Source Code

export async function updateStorageAtomically<T>(
  key: StorageKey,
  defaultValue: T,
  updater: (current: T) => T,
): Promise<T> {
  const previous = writeQueues.get(key) ?? Promise.resolve();
  let nextValue = defaultValue;

  const currentWrite = previous.then(async () => {
    const current = await getFromStorage<T>(key, defaultValue);
    nextValue = updater(current);
    await setToStorage(key, nextValue);
  });

  const guardedWrite = withTimeout(currentWrite, WRITE_TIMEOUT_MS).catch(
    (err) => {
      log.warn(`Atomic update for key "${key}" failed:`, err);
    },
  );

  writeQueues.set(
    key,
    guardedWrite.then(() => {}),
  );

  await currentWrite;
  return nextValue;
}

Dependencies (Outgoing)

graph LR updateStorageAtomically["updateStorageAtomically"] setToStorage["setToStorage"] withTimeout["withTimeout"] updateStorageAtomically -->|calls| setToStorage updateStorageAtomically -->|calls| withTimeout style updateStorageAtomically fill:#dbeafe,stroke:#2563eb,stroke-width:2px click updateStorageAtomically "bf2f57323401fa98.html" click setToStorage "c4192294ba99b656.html" click withTimeout "fc7affbaf585b37b.html"
TargetType
setToStorage calls
withTimeout calls
key dynamic_call

Impact (Incoming)

graph LR updateStorageAtomically["updateStorageAtomically"] getDemoFlows["getDemoFlows"] getFieldDetectionCache["getFieldDetectionCache"] saveFieldDetectionCacheForUrl["saveFieldDetectionCacheForUrl"] deleteFieldDetectionCacheForUrl["deleteFieldDetectionCacheForUrl"] clearFieldDetectionCache["clearFieldDetectionCache"] getSavedForms["getSavedForms"] saveForm["saveForm"] deleteForm["deleteForm"] setDefaultForm["setDefaultForm"] getIgnoredFields["getIgnoredFields"] addIgnoredField["addIgnoredField"] removeIgnoredField["removeIgnoredField"] getRules["getRules"] saveRule["saveRule"] deleteRule["deleteRule"] getSettings["getSettings"] saveSettings["saveSettings"] getDemoFlows -->|uses| updateStorageAtomically getFieldDetectionCache -->|uses| updateStorageAtomically saveFieldDetectionCacheForUrl -->|calls| updateStorageAtomically deleteFieldDetectionCacheForUrl -->|calls| updateStorageAtomically clearFieldDetectionCache -->|calls| updateStorageAtomically getSavedForms -->|uses| updateStorageAtomically saveForm -->|calls| updateStorageAtomically deleteForm -->|calls| updateStorageAtomically setDefaultForm -->|calls| updateStorageAtomically getIgnoredFields -->|uses| updateStorageAtomically addIgnoredField -->|calls| updateStorageAtomically removeIgnoredField -->|calls| updateStorageAtomically getRules -->|uses| updateStorageAtomically saveRule -->|calls| updateStorageAtomically deleteRule -->|calls| updateStorageAtomically getSettings -->|uses| updateStorageAtomically saveSettings -->|calls| updateStorageAtomically style updateStorageAtomically fill:#dbeafe,stroke:#2563eb,stroke-width:2px click updateStorageAtomically "bf2f57323401fa98.html" click getDemoFlows "7a890fea8b78bfa5.html" click getFieldDetectionCache "8f2869c3e935ff86.html" click saveFieldDetectionCacheForUrl "5f18074b51936498.html" click deleteFieldDetectionCacheForUrl "209937c4802c2009.html" click clearFieldDetectionCache "592635f6ea1eb5e3.html" click getSavedForms "9a1357b95618ee5e.html" click saveForm "639eb913ec8fd306.html" click deleteForm "a61dc3e1000e0f40.html" click setDefaultForm "a474b5e75cb3500a.html" click getIgnoredFields "4ae1979d28b4e80b.html" click addIgnoredField "4434c375c8a8a862.html" click removeIgnoredField "d8b20d34effbbe04.html" click getRules "69aeb172cce4aa1c.html" click saveRule "63edd701c4b09a38.html" click deleteRule "a510ce97ee47641a.html" click getSettings "99db54620b94a08b.html" click saveSettings "36c97425aad183c5.html"