Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended Storage (per domain) #696

Open
dvlden opened this issue Jun 2, 2024 · 7 comments
Open

Extended Storage (per domain) #696

dvlden opened this issue Jun 2, 2024 · 7 comments
Labels

Comments

@dvlden
Copy link
Contributor

dvlden commented Jun 2, 2024

Feature Request

An easy way to the Storage implementation to support site based preferences instead of global.

Is your feature request related to a bug?

N/A

What are the alternatives?

No alternatives available, as far as I know.

Additional context

Some extensions may have some preferences where a simple array of domains as items is enough. For example, adblocking... An option to "disable for this website" is pretty simple to make.

However, creating a Storage implementation inside of WXT that supports global and per domain functionality, might be amazing. I'm personally in a need of this feature as my extension offers a handful of options where each one works globally atm, but it makes more sense that each one works per domain instead.

@dvlden dvlden added the feature label Jun 2, 2024
@aklinker1
Copy link
Collaborator

Do you have an idea what this API might look like? I don't really understand exactly what you're asking, do you just want a simpler way to prefix storage keys with namespaces, like domain names?

Basically replace this:

storage.getItem('local:enabled')
storage.getItem('local:google.com:enabled')
storage.getItem('local:reddit.com:enabled')

With a built-in way of accomplishing the same?

const enabled = defineNamespacedStorageItem('local:{namespace}:enabled')
enabled.get()
enabled.get('google.com')
enabled.get('reddit.com')

@aklinker1
Copy link
Collaborator

aklinker1 commented Jun 3, 2024

Hmm, you could use metadata for this, but scaling to a potentially infinite number of namespaces, one for every domain name, makes using regular storage a bad idea, because of its limited quota.

const enabled = storage.defineIrem('local:enabled')
enabled.getValue()
enabled.getMeta('google.com')
enabled.getMeta('reddit.com')

I would recommend using IndexedDB to store an unknown amount of data. I guess you could request unlimited storage, but I don't know how well extension storage scales. If you have 10000 keys, is it still fast enough?

I know IndexedDB scales really well, to the millions of rows

@dvlden
Copy link
Contributor Author

dvlden commented Jun 3, 2024

Hmmm, not quite, I think. It'd require necessary permissions (storage + tabs) and do that automatically.

So something like calling storage.defineDomainItem('local:enabled') would automatically do it for that specific tab in question. But I think maybe define cannot work in this case, right? Cause tabs payload comes at later point. So maybe just direct set/get instead.

I guess I can make a wrapper myself to achieve this, but thought it might be good idea to have a built-in implementation, as this is potentionally a necessity that isn't natively supported by the browsers.

Personally unsure if it would slow down the extension or the browser if there are so many rows (which will be def. true). Did not test it, just yet.

Did not even know that I can use IndexedDB within the extension. Is it true for both MV2 and MV3 and is not accessible by other extensions?

@aklinker1
Copy link
Collaborator

aklinker1 commented Jun 3, 2024

Hmm, I can kinda see what you're looking for, but I don't understand where you plan on storing the data. If not in browser.storage.local with the domains as apart of the keys, then how?

So something like calling storage.defineDomainItem('local:enabled') would automatically do it for that specific tab in question. But I think maybe define cannot work in this case, right? Cause tabs payload comes at later point. So maybe just direct set/get instead.

I mean, you could just do this:

const enabled = storage.defineItem(`local:${globalThis.location?.hostname ?? 'default'}:enabled`)

Then wherever the module is run at, it will use the hostname if available.

Did not even know that I can use IndexedDB within the extension. Is it true for both MV2 and MV3 and is not accessible by other extensions?

Since HTML 5 storage isn't shared between contexts, each contexy has its down IndexedDB instance. You have to use the background to host the database, then ask the background to get data from it.

@dvlden
Copy link
Contributor Author

dvlden commented Jun 3, 2024

To my understanding, I can only rely on Tabs API inside of popup and background? The only part where location.hostname is accessible is content-script, no?

So I think it's more complicated than the example line from your last reply. Unless, I'm wrong?

@aklinker1
Copy link
Collaborator

aklinker1 commented Jun 3, 2024

OK, I see, you mentioned creating an adblock that could be disabled for some websites. I don't think all extensions care about this, the majority of extensions don't have access to all websites. I would rather leave this up to the community to release a NPM package for this instead.

Eventually, I'm going to extract wxt/storage into it's own NPM package that could be built on top of... but I'm currently focusing on improving docs right now. I'm getting too many basic questions that it's clear the docs suck.

@dvlden
Copy link
Contributor Author

dvlden commented Jun 4, 2024

Yea. I mean, Adblock was basic example. That one would work fine with global storage, by checking if domain exists in an array of items.

I'm more thinking for advanced extensions that would work way better if storage was saving settings per domain, instead of global.

Sounds good. I have to build this for my extension, so I'll see how I get around it without wxt/storage being separate package. If you have any ideas/tips as in which direction to go, please let me know.

Makes sense, docs should be priority indeed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants