From 261548ff184926567a623e90df7954aeef842d59 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 30 Jun 2021 12:28:05 +0200 Subject: emply an sh-based build system; make some changes to blocking --- common/storage_client.js | 360 ++++++++++++++++++++++++----------------------- 1 file changed, 183 insertions(+), 177 deletions(-) (limited to 'common/storage_client.js') diff --git a/common/storage_client.js b/common/storage_client.js index 1bc9a88..2bbddb6 100644 --- a/common/storage_client.js +++ b/common/storage_client.js @@ -5,182 +5,188 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - -(() => { - const CONNECTION_TYPE = window.CONNECTION_TYPE; - const TYPE_PREFIX = window.TYPE_PREFIX; - const list_prefixes = window.list_prefixes; - const make_once = window.make_once; - const browser = window.browser; - - var call_id = 0; - var port; - var calls_waiting = new Map(); - - function set_call_callback(resolve, reject, func, args) - { - port.postMessage([call_id, func, args]); - calls_waiting.set(call_id++, [resolve, reject]); - } - - async function remote_call(func, args) - { - return new Promise((resolve, reject) => - set_call_callback(resolve, reject, func, args)); - } - - function handle_message(message) - { - let callbacks = calls_waiting.get(message.call_id); - if (callbacks === undefined) { - handle_change(message); - return; - } - - let [resolve, reject] = callbacks; - calls_waiting.delete(message.call_id); - if (message.error !== undefined) - setTimeout(reject, 0, message.error); - else - setTimeout(resolve, 0, message.result); - } - - function list(name, prefix) - { - return {prefix, name, listeners : new Set()}; - } - - var scripts = list("scripts", TYPE_PREFIX.SCRIPT); - var bags = list("bags", TYPE_PREFIX.BAG); - var pages = list("pages", TYPE_PREFIX.PAGE); - - const list_by_prefix = { - [TYPE_PREFIX.SCRIPT] : scripts, - [TYPE_PREFIX.BAG] : bags, - [TYPE_PREFIX.PAGE] : pages - }; - - var resolve_init; - - function handle_first_message(message) - { - for (let prefix of Object.keys(message)) - list_by_prefix[prefix].map = new Map(message[prefix]); - - port.onMessage.removeListener(handle_first_message); - port.onMessage.addListener(handle_message); - - resolve_init(); - } - - function handle_change(change) - { - let list = list_by_prefix[change.prefix]; - - if (change.new_val === undefined) - list.map.delete(change.item); - else - list.map.set(change.item, change.new_val); - - for (let listener_callback of list.listeners) - listener_callback(change); - } - - var exports = {}; - - function start_connection(resolve) - { - resolve_init = resolve; - port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE}); - port.onMessage.addListener(handle_first_message); - } - - async function init() { - await new Promise((resolve, reject) => start_connection(resolve)); - return exports; - } - - for (let call_name of ["set", "remove", "replace", "clear"]) - exports [call_name] = (...args) => remote_call(call_name, args); - - // TODO: Much of the code below is copy-pasted from /background/storage.mjs. - // This should later be refactored into a separate module - // to avoid duplication. - - /* - * Facilitate listening to changes - */ - - exports.add_change_listener = function (cb, prefixes=list_prefixes) - { - if (typeof(prefixes) === "string") - prefixes = [prefixes]; - - for (let prefix of prefixes) - list_by_prefix[prefix].listeners.add(cb); - } - - exports.remove_change_listener = function (cb, prefixes=list_prefixes) - { - if (typeof(prefixes) === "string") - prefixes = [prefixes]; - - for (let prefix of prefixes) - list_by_prefix[prefix].listeners.delete(cb); - } - - /* Prepare some hepler functions to get elements of a list */ - - function list_items_it(list, with_values=false) - { - return with_values ? list.map.entries() : list.map.keys(); - } - - function list_entries_it(list) - { - return list_items_it(list, true); - } - - function list_items(list, with_values=false) - { - let array = []; - - for (let item of list_items_it(list, with_values)) - array.push(item); - - return array; - } - - function list_entries(list) - { - return list_items(list, true); - } - - exports.get = function (prefix, item) - { - return list_by_prefix[prefix].map.get(item); - } - - exports.get_all_names = function (prefix) - { - return list_items(list_by_prefix[prefix]); - } - - exports.get_all_names_it = function (prefix) - { - return list_items_it(list_by_prefix[prefix]); - } - - exports.get_all = function (prefix) - { - return list_entries(list_by_prefix[prefix]); - } +/* + * IMPORTS_START + * IMPORT CONNECTION_TYPE + * IMPORT TYPE_PREFIX + * IMPORT list_prefixes + * IMPORT make_once + * IMPORT browser + * IMPORTS_END + */ - exports.get_all_it = function (prefix) - { - return list_entries_it(list_by_prefix[prefix]); - } +var call_id = 0; +var port; +var calls_waiting = new Map(); + +function set_call_callback(resolve, reject, func, args) +{ + port.postMessage([call_id, func, args]); + calls_waiting.set(call_id++, [resolve, reject]); +} + +async function remote_call(func, args) +{ + return new Promise((resolve, reject) => + set_call_callback(resolve, reject, func, args)); +} + +function handle_message(message) +{ + let callbacks = calls_waiting.get(message.call_id); + if (callbacks === undefined) { + handle_change(message); + return; + } + + let [resolve, reject] = callbacks; + calls_waiting.delete(message.call_id); + if (message.error !== undefined) + setTimeout(reject, 0, message.error); + else + setTimeout(resolve, 0, message.result); +} + +function list(name, prefix) +{ + return {prefix, name, listeners : new Set()}; +} + +var scripts = list("scripts", TYPE_PREFIX.SCRIPT); +var bags = list("bags", TYPE_PREFIX.BAG); +var pages = list("pages", TYPE_PREFIX.PAGE); + +const list_by_prefix = { + [TYPE_PREFIX.SCRIPT] : scripts, + [TYPE_PREFIX.BAG] : bags, + [TYPE_PREFIX.PAGE] : pages +}; + +var resolve_init; + +function handle_first_message(message) +{ + for (let prefix of Object.keys(message)) + list_by_prefix[prefix].map = new Map(message[prefix]); + + port.onMessage.removeListener(handle_first_message); + port.onMessage.addListener(handle_message); + + resolve_init(); +} + +function handle_change(change) +{ + let list = list_by_prefix[change.prefix]; + + if (change.new_val === undefined) + list.map.delete(change.item); + else + list.map.set(change.item, change.new_val); + + for (let listener_callback of list.listeners) + listener_callback(change); +} + +var exports = {}; + +function start_connection(resolve) +{ + resolve_init = resolve; + port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE}); + port.onMessage.addListener(handle_first_message); +} + +async function init() { + await new Promise((resolve, reject) => start_connection(resolve)); + return exports; +} + +for (let call_name of ["set", "remove", "replace", "clear"]) + exports [call_name] = (...args) => remote_call(call_name, args); + +// TODO: Much of the code below is copy-pasted from /background/storage.mjs. +// This should later be refactored into a separate module +// to avoid duplication. + +/* + * Facilitate listening to changes + */ - window.get_storage = make_once(init); -})(); +exports.add_change_listener = function (cb, prefixes=list_prefixes) +{ + if (typeof(prefixes) === "string") + prefixes = [prefixes]; + + for (let prefix of prefixes) + list_by_prefix[prefix].listeners.add(cb); +} + +exports.remove_change_listener = function (cb, prefixes=list_prefixes) +{ + if (typeof(prefixes) === "string") + prefixes = [prefixes]; + + for (let prefix of prefixes) + list_by_prefix[prefix].listeners.delete(cb); +} + +/* Prepare some hepler functions to get elements of a list */ + +function list_items_it(list, with_values=false) +{ + return with_values ? list.map.entries() : list.map.keys(); +} + +function list_entries_it(list) +{ + return list_items_it(list, true); +} + +function list_items(list, with_values=false) +{ + let array = []; + + for (let item of list_items_it(list, with_values)) + array.push(item); + + return array; +} + +function list_entries(list) +{ + return list_items(list, true); +} + +exports.get = function (prefix, item) +{ + return list_by_prefix[prefix].map.get(item); +} + +exports.get_all_names = function (prefix) +{ + return list_items(list_by_prefix[prefix]); +} + +exports.get_all_names_it = function (prefix) +{ + return list_items_it(list_by_prefix[prefix]); +} + +exports.get_all = function (prefix) +{ + return list_entries(list_by_prefix[prefix]); +} + +exports.get_all_it = function (prefix) +{ + return list_entries_it(list_by_prefix[prefix]); +} + +const get_remote_storage = make_once(init); + +/* + * EXPORTS_START + * EXPORT get_remote_storage + * EXPORTS_END + */ -- cgit v1.2.3