blob: 55d2a8f6859eee64502d3312b2851a7fe488d8d6 (
plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/**
* Settings service (background): storage access with validation.
*
* Load flow (Design.md §17.2):
* 1. generate default settings
* 2. read storage
* 3. merge
* 4. validate
* 5. invalid values fall back to defaults
*
* The validated cache is refreshed on storage.onChanged.
*/
import { sanitizeSettings, defaultSettings } from '../shared/settings-schema.js';
const STORAGE_KEY = 'settings';
/** @type {object|null} cached validated settings */
let cache = null;
/**
* @param {object} [browserApi] injectable browser API (defaults to globalThis.browser)
* @returns {object}
*/
function api(browserApi) {
return browserApi || globalThis.browser;
}
/**
* Load settings from storage.local, sanitize and cache them.
* @param {object} [browserApi]
* @returns {Promise<object>} validated settings
*/
export async function loadSettings(browserApi) {
const b = api(browserApi);
let stored = null;
try {
const result = await b.storage.local.get({ settings: null });
stored = result.settings;
} catch {
stored = null;
}
cache = sanitizeSettings(stored);
return cache;
}
/**
* Save settings. Values are sanitized before writing.
* @param {object} settings raw settings object from the UI
* @param {object} [browserApi]
* @returns {Promise<object>} the validated settings actually stored
*/
export async function saveSettings(settings, browserApi) {
const b = api(browserApi);
const validated = sanitizeSettings(settings);
await b.storage.local.set({ settings: validated });
cache = validated;
return validated;
}
/**
* @param {object} [browserApi]
* @returns {Promise<object>} current validated settings (cached when possible)
*/
export async function getSettings(browserApi) {
if (cache) return cache;
return loadSettings(browserApi);
}
/**
* Register the storage.onChanged listener that keeps the cache in sync.
* Must be called once from the background entry point.
* @param {object} [browserApi]
*/
export function watchSettings(browserApi) {
const b = api(browserApi);
b.storage.onChanged.addListener((changes, areaName) => {
if (areaName === 'local' && changes.settings) {
cache = sanitizeSettings(changes.settings.newValue);
}
});
}
/**
* Test-only: clear the module-level settings cache so each test starts from
* storage state instead of inheriting the previous test's cache.
* @visibleForTesting
*/
export function __resetCacheForTests() {
cache = null;
}
|