/** * part of Hachette * Storage manager, lighter than the previous one. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. */ /* * IMPORTS_START * IMPORT TYPE_PREFIX * IMPORT raw_storage * IMPORT is_mozilla * IMPORT observables */ 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); } } 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); } function storage_change_callback(changes, area) { if (is_mozilla && area !== "local") {console.log("area", area);return;} 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; } const observe_var = name => observe(TYPE_PREFIX.VAR, name); function no_observe(observable) { no_listen(...created_observables.get(observable) || []); created_observables.delete(observable); } const light_storage = {}; Object.assign(light_storage, raw_storage); Object.assign(light_storage, {listen, no_listen, observe, observe_var, no_observe}); /* * EXPORTS_START * EXPORT light_storage * EXPORTS_END */ .Felix Gruber 2024-03-07gnu: xonsh: Update to 0.15.1...arkhan 2024-02-20gnu: rust-reqwest: Move to (gnu packages crates-web)....Efraim Flashner 2024-02-20gnu: rust-digest: Move to (gnu packages crates-crypto)....Efraim Flashner 2024-02-20gnu: rust-nu-ansi-term-0.46: Move to (gnu packages shells)....Efraim Flashner 2024-02-20gnu: Add rust-nu-ansi-term-0.49....Jaeme Sifat 2024-02-20gnu: rust-dunce-1: Move to (gnu packages crates-windows)....Efraim Flashner 2024-01-28gnu: fish: Update to 3.7.0....Rostislav Svoboda 2024-01-14gnu: fish-foreign-env: Update to 0.20230823....Tanguy Le Carrour 2023-12-03gnu: xonsh: Update to 0.14.2....Greg Hogan 2023-11-19gnu: loksh: Update to 7.4....Tobias Geerinckx-Rice izes.Ludovic Courtès * nix/libutil/hash.cc (parseHash): Show the hash algorithm name and expected size in the error message. * tests/derivations.scm ("fixed-output derivation, invalid hash size"): New test. 2022-12-18daemon: Make "opening file" error messages distinguishable.Ludovic Courtès * nix/libstore/build.cc (DerivationGoal::openLogFile): Customize "opening file" error message. * nix/libutil/hash.cc (hashFile): Likewise. * nix/libutil/util.cc (readFile, writeFile): Likewise.