/** * This file is part of Haketilo. * * Function: Storage manager, lighter than the previous one. * * Copyright (C) 2021 Wojtek Kosior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * As additional permission under GNU GPL version 3 section 7, you * may distribute forms of that code without the copy of the GNU * GPL normally required by section 4, provided you include this * license notice and, in case of non-source distribution, a URL * through which recipients can access the Corresponding Source. * If you modify file(s) with this exception, you may extend this * exception to your version of the file(s), but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * As a special exception to the GPL, any HTML file which merely * makes function calls to this code, and for that purpose * includes it by reference shall be deemed a separate work for * copyright law purposes. If you modify this code, you may extend * this exception to your version of the code, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * I, Wojtek Kosior, thereby promise not to sue for violation of this file's * license. Although I request that you do not make use this code in a * proprietary program, I am not going to enforce this in court. */ #IMPORT common/storage_raw.js AS raw_storage #IMPORT common/observables.js #FROM common/stored_types.js IMPORT TYPE_PREFIX const reg_spec = new Set(["\\", "[", "]", "(", ")", "{", "}", ".", "*", "+"]); const escape_reg_special = c => reg_spec.has(c) ? "\\" + c : c; function make_regex(name) { return new RegExp(`^${name.split("").map(escape_reg_special).join("")}\$`); } const listeners_by_callback = new Map(); function listen(callback, prefix, name) { let by_prefix = listeners_by_callback.get(callback); if (!by_prefix) { by_prefix = new Map(); listeners_by_callback.set(callback, by_prefix); } let by_name = by_prefix.get(prefix); if (!by_name) { by_name = new Map(); by_prefix.set(prefix, by_name); } let name_reg = by_name.get(name); if (!name_reg) { name_reg = name.test ? name : make_regex(name); by_name.set(name, name_reg); } } #EXPORT listen function no_listen(callback, prefix, name) { const by_prefix = listeners_by_callback.get(callback); if (!by_prefix) return; const by_name = by_prefix.get(prefix); if (!by_name) return; const name_reg = by_name.get(name); if (!name_reg) return; by_name.delete(name); if (by_name.size === 0) by_prefix.delete(prefix); if (by_prefix.size === 0) listeners_by_callback.delete(callback); } #EXPORT no_listen function storage_change_callback(changes, area) { #IF MOZILLA if (area !== "local") { console.warn("change in storage area", area); return; } #ENDIF for (const item of Object.keys(changes)) { for (const [callback, by_prefix] of listeners_by_callback.entries()) { const by_name = by_prefix.get(item[0]); if (!by_name) continue; for (const reg of by_name.values()) { if (!reg.test(item.substring(1))) continue; try { callback(item, changes[item]); } catch(e) { console.error(e); } } } } } raw_storage.listen(storage_change_callback); const created_observables = new Map(); async function observe(prefix, name) { const observable = observables.make(); const callback = (it, ch) => observables.set(observable, ch.newValue); listen(callback, prefix, name); created_observables.set(observable, [callback, prefix, name]); observables.silent_set(observable, await raw_storage.get(prefix + name)); return observable; } #EXPORT observe #EXPORT name => observe(TYPE_PREFIX.VAR, name) AS observe_var function no_observe(observable) { no_listen(...created_observables.get(observable) || []); created_observables.delete(observable); } #EXPORT no_observe #EXPORT raw_storage.set AS set #EXPORT raw_storage.set_var AS set_var #EXPORT raw_storage.get_var AS get_var ail'>...Ludovic Courtès 2018-09-23system: Mention '--skip-checks' in initrd diagnostics....Ludovic Courtès 2018-07-29linux-initrd: Report only missing modules, not all needed modules....Ludovic Courtès 2018-07-29linux-initrd: Try several file names when looking up modules....Ludovic Courtès 2018-07-29linux-initrd: Improve check of initrd modules....Ludovic Courtès 2018-06-14linux-initrd: Module check correctly handles hyphen vs. underscore....Ludovic Courtès 2018-03-15linux-initrd: Autoload known-module-aliases, again....Mark H Weaver 2018-03-15linux-initrd: Move 'check-device-initrd-modules' elsewhere....Ludovic Courtès 2018-03-07linux-initrd: Factorize 'check-device-initrd-modules'....Ludovic Courtès 2018-03-02guix system: Check for the lack of modules in the initrd....Ludovic Courtès