HeyPuter / puter

🌐 The Internet OS! Free, Open-Source, and Self-Hostable.
https://puter.com
GNU Affero General Public License v3.0
25.53k stars 1.68k forks source link

Implement Cloud-Backed `localStorage` Using Puter.js's KV Store #789

Closed jelveh closed 4 days ago

jelveh commented 2 weeks ago

I propose implementing a feature that transforms the browser's localStorage API into a cloud-backed storage solution using Puter.js's Key-Value (KV) store. This enhancement would allow existing web applications to use cloud storage without modifying their codebase.

Feature Details:

  1. Overload localStorage Methods:

    • Intercept and override all localStorage methods and properties.
    • Implement each method to use Puter's KV store as the primary storage mechanism.
  2. Use localStorage as a Caching Layer:

    • Within each overloaded method, attempt to use the original localStorage functions.
    • This approach allows localStorage to serve as a local cache, potentially improving performance for frequently accessed data.
  3. Simple Integration:

    • Existing code using localStorage should continue to work without modifications.
    • Data will be automatically synchronized between the local cache and Puter's KV store.
  4. Methods to Implement:

    • setItem(key, value)
    • getItem(key)
    • removeItem(key)
    • clear()
    • key(index)
    • length property

Implementation Considerations:

The following is a naive implementation which I think could be used as inspiration:

// Add this to the Puter.js API
puter.enableCloudBackedLocalStorage = function(enable = true) {
  if (enable) {
    // Enable KV-backed localStorage
    window.originalLocalStorage = window.localStorage;
    window.localStorage = {
      setItem: async function(key, value) {
        window.originalLocalStorage.setItem(key, value);
        await puter.kv.set(key, value);
      },
      getItem: async function(key) {
        const localValue = window.originalLocalStorage.getItem(key);
        const cloudValue = await puter.kv.get(key);
        if (cloudValue !== null && cloudValue !== localValue) {
          window.originalLocalStorage.setItem(key, cloudValue);
          return cloudValue;
        }
        return localValue;
      },
      removeItem: async function(key) {
        window.originalLocalStorage.removeItem(key);
        await puter.kv.del(key);
      },
      clear: async function() {
        window.originalLocalStorage.clear();
        await puter.kv.flush();
      },
      // Add other localStorage methods as needed
    };
  } else {
    // Disable KV-backed localStorage and revert to original
    if (window.originalLocalStorage) {
      window.localStorage = window.originalLocalStorage;
    }
  }
};

// Usage
puter.enableCloudBackedLocalStorage(); // Enable KV-backed localStorage
// or
puter.enableCloudBackedLocalStorage(false); // Disable KV-backed localStorage
recursionbane commented 2 weeks ago

Great idea! It seems closely related to a recent idea I proposed in the discussion here: Issue #790. I believe you would need the data to be global for this idea to work. Would you mind taking a look and letting me know your thoughts?

jelveh commented 4 days ago

Welp, seems like this is not possible since we can't override localStorage. WAs a cool idea though :')