summaryrefslogtreecommitdiff
path: root/src/background/settings-service.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/background/settings-service.js')
-rw-r--r--src/background/settings-service.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/background/settings-service.js b/src/background/settings-service.js
new file mode 100644
index 0000000..2687921
--- /dev/null
+++ b/src/background/settings-service.js
@@ -0,0 +1,82 @@
+/**
+ * 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);
+ }
+ });
+} \ No newline at end of file