Adrià Vilanova MartÃnez | f7e8685 | 2024-05-11 14:16:38 +0200 | [diff] [blame^] | 1 | import { Mutex, MutexInterface, withTimeout } from 'async-mutex'; |
| 2 | |
| 3 | import { getOptions } from './optionsUtils'; |
| 4 | import { OptionCodename, OptionValues } from './optionsPrototype'; |
| 5 | |
| 6 | export default class OptionsProvider { |
| 7 | private optionValues: OptionValues; |
| 8 | private isStale = true; |
| 9 | private mutex: MutexInterface = withTimeout(new Mutex(), 60 * 1000); |
| 10 | |
| 11 | constructor() { |
| 12 | // If the extension settings change, set the current cached value as stale. |
| 13 | // We could try only doing this only when we're sure it has changed, but |
| 14 | // there are many factors (if the user has changed it manually, if a kill |
| 15 | // switch was activated, etc.) so we'll do it every time. |
| 16 | chrome.storage.onChanged.addListener((_, areaName) => { |
| 17 | if (areaName !== 'sync') return; |
| 18 | console.debug('[optionsWatcher] Marking options as stale.'); |
| 19 | this.isStale = true; |
| 20 | }); |
| 21 | } |
| 22 | |
| 23 | // Returns a promise resolving to the value of option |option|. |
| 24 | getOption<O extends OptionCodename>(option: O): Promise<OptionValues[O]> { |
| 25 | // When the cached value is marked as stale, it might be possible that there |
| 26 | // is a flood of calls to isEnabled(), which in turn causes a flood of calls |
| 27 | // to getOptions() because it takes some time for it to be marked as not |
| 28 | // stale. Thus, hiding the logic behind a mutex fixes this. |
| 29 | return this.mutex.runExclusive(async () => { |
| 30 | if (!this.isStale) return Promise.resolve(this.optionValues[option]); |
| 31 | |
| 32 | this.optionValues = await getOptions(); |
| 33 | this.isStale = false; |
| 34 | return this.optionValues[option]; |
| 35 | }); |
| 36 | } |
| 37 | |
| 38 | // Returns a promise resolving to whether the |feature| is enabled. |
| 39 | async isEnabled(option: OptionCodename) { |
| 40 | const value = await this.getOption(option); |
| 41 | return value === true; |
| 42 | } |
| 43 | } |