For a Manifest 3 browser extension I need to implement local storage logic. This is because there is a lot of code that are shared between different projects that uses localStorage. To change and test all this code on different platforms will be quite a big job.
So I am trying to make a proxy of an object that implement the normal functions of the localStorage object. In the extension I need to use async functions like chrome.storage.local.get.
This gives me a lot of problems with the Promise logic in different ways as getItem return a promise (not intended) or I get runtime errors like "await is only valid in async functions and the top level bodies of modules" etc.
The code below is one such try:
var localStorageTarget = {};
localStorageTarget.getItem = async function(keyname)
{
const internalGetItem = async () =>
{
return new Promise((resolve, reject) =>
{
chrome.storage.local.get([keyname], function (result)
{
if (result[keyname] === undefined)
{
reject();
}
else
{
resolve(result[keyname]);
}
});
});
}
return await internalGetItem();
};
localStorageTarget.setItem = function(keyname, keyvalue)
{
chrome.storage.local.set({keyname: keyvalue});
return true;
};
localStorageTarget.removeItem = function(keyname)
{
chrome.storage.local.remove([keyname]);
return true; // deleteProperty need this
};
const localStorage = new Proxy(localStorageTarget,
{
get: function(obj, name)
{
//console.log('Read request to ' + name + ' property with ' + obj[name] + ' value');
return obj.getItem(name);
},
set: function(obj, name, value)
{
//console.log('Write request to ' + name + ' property with ' + value + ' value');
return obj.setItem(name, value);
},
deleteProperty(obj, name)
{
//console.log('Delete request to ' + name + ' property with ' + obj[name] + ' value');
return obj.removeItem(name);
}
});
localStorage['qqqq'] = 'test2';
console.log(localStorage.getItem('qqqq'));
console.log(localStorage['qqqq']);
delete localStorage['qqqq'];
In advance thank you for for any hint or help
/Benny
You're not going to get around the fact that if the getter returns a Promise, you have to await that promise at the top level:
console.log(await localStorage['qqqq']);
Since chrome.storage.local.get()
returns a promise if you don't pass a callback, you can simplify your code:
localStorageTarget.getItem = function(keyname) {
return chrome.storage.local.get([ keyname ]);
}
And lastly, I think that you want expand keyname
into a property name:
chrome.storage.local.set({ [ keyname ]: keyvalue });