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
Seeking Guidance for Serverless Bi-directional Sync Between Two Dexie.js Instances #1978
Comments
Would it be an option to encapsulate the Dexie calls via a service that uses chrome messaging api instead? It could either be built around your needs or it could mirror Dexie 's api (or parts of it) and be implemented by sending async messages and responding to them on the "server" post. That way you would not be reliant on sync and your extension would be less intrusive since it would not be using up storage quota from visited sites. And if having sync, you might experience situations when one of the parts are being cleaned up and the other is still there. I suppose troubleshooting would be harder. But if you want to try, you can actually implement sync using chrome's messaging api without the need of a network server. Use runtime.sendMessage on the client and runtime.onMessage on the "server". https://developer.chrome.com/docs/extensions/develop/concepts/messaging but there's a lot to implement on the server part. I don't have an easy example implementation but maybe you could take the old concept from https://github.com/dexie/Dexie.js/blob/master/samples/remote-sync/websocket/WebSocketSyncServer.js and translate it to using runtime.onMessage and to querying a Dexie instance instead of its dummy tables. |
I had the same initial thought of effectively doing a REST design. Client sends everything related to Dexie db to background via messaging. However a few downsides emerge related to reusable components, reactive queries, reusable code. Take liveQuery in a svelte component as an example. The component works anywhere with a chrome://{extensionId} host origin, but not in context script "client". I'd then have to run liveQuery in background context for any "client" component, but a ton of boiler plate for managing the liveQuery subscription based on "client" component lifecycle. It's doable, a ton of code, but it doesn't feel elegant. As far as the WebSocket code examples, I actually tried to recreate the solution using messaging passing, however the issue I found was I still needed to call |
This is an interesting use case. I still think propagating calls and liveQueries over messaging would be the most optimal solution (conceptually). If there were some 3rd party library capable of exposing service methods returning promises or observables and translating them to messages and providing a corresponding client proxy - then queries could be performed on the server in the service and the client could use the proxy. Not saying it would be trivial to implement though unless someone has already done it. |
I have a similar use case. I'm trying to create an extension that will store data on a Indexed DB instance on another origin. On my case the client is not a content script, but an actual webpage. Not sure if its feasible though. |
After a handful of experiments, I went with encapsulation and message passing. This turned out to be much simpler than any alternative. There was some additional overhead of handling client disconnects (ie tab/window closed), and component life cycles but overall straightforward. @glundgren93 the logic for webpage or content script will be the same. ie If the URL is different than chrome-extension://{extensionId} message passing is the way to go. I'll post my solution tomorrow so you can work off that if needed. |
Nice. It would really help a lot to see how you managed to do it! |
Here it is, in my particular use case I wanted a seamless interface with svelte stores. For any future readers, feel free to replace svelte specifics for some other framework. Start with Dexie db Init
Then I init a svelte store interface for "friends" data.
Here is dexieStorageAdapter which is what makes the Svelte store interface reactive & handles creating the active subscription between the content script and other pages to background context. I promisfied the implementation so I can have a loading state, not necessary for latency time detection but nice to know if result was loaded when it's empty. The code sends a message to the background page and registers a listener to receive state updates from the background page.
Here is the code that handles receiving the above messages, ignore "registerEvents" that's just a small wrapper on my end so I don't have to have all messages listeners in one big file for background page messages. All this does is listen for events to add/delete subscriptions.
And finally the actually Dexie implementation for liveQuery. I'm not sold on my filters implementation of using an object literal, but it's simple enough for my use case that I left it in here.
And the background page event listeners for svelte store methods above ("addFriend", "updateName")
Small note, asyncHandle and sendMessage are just small wrapper convenience functions. asyncHandle returns error as a value since the response get serialized with sendResponse, throwing errors from background to content script isn't possible. At the end here is how implementation works.
And to have store with filters, just instantiate a new one with key names of the filters in FILTERS_REF.
|
Hello,
I am developing a Chrome extension that operates in a cross-origin setup due to the way extension work. The content script ("client") runs under the host origin (e.g., example.com), while the background page ("server") operates under chrome-extension://{extensionId} origin. Communication between these environments is managed via Chrome's messaging API.
My challenge is to implement a shared database between these environments, however due to cross-origin policies It's not possible to share a single Indexed DB. Although Chrome provides a simple key/value storage API accessible to both environments, it does not meet my needs for more complex data handling.
I am exploring local synchronization options for two instances of Dexie.js. The standard approach, using a custom ISyncProtocol as detailed in the Dexie.Syncable documentation, and the sync_client library, both seem to require a server-based backend, utilizing connections to hosted URL endpoints (see source code).
Is there a straightforward method or existing workaround to achieve bi-directional synchronization between two local Dexie.js databases within this Chrome extension setup? Any suggestions or advice would be highly appreciated.
Thank you.
The text was updated successfully, but these errors were encountered: