Chrome Extension MV3 migration : How to convert background script that uses window and document to service worker?

I have a chrome extension which was built on v2 version. I’m using background script to initialise my app. Then in popup.js I’m using runtime.getBackgroundPages() to get the instance from background page and perform some operation.

background.js


class Client {
  constructor() {
    this.settings = { env: "qa" };
  }
  init() {
    <iframe
      id="inlineFrameExample"
      title="Inline Frame Example"
      width="300"
      height="200"
      src="src"
    ></iframe>;
  }
}

class App {
  constructor() {
    this.app = new Client();
  }

  render() {}
}

window.app = new App();


the reason for keeping app is that it acts as single source of truth. All session data, settings etc are stored here. Other part of the extension like popup.js use this instance to read and update values.

popup.js

 
class Popup{
    constructor(){
        this.app = chrome.runtime.getBackgroundPage(); // this is not working
        this.app.init();
    }
 
  // remianing logic

} 


Now since in v3 , the background script has been removed and service worker should be used. Service worker doesn’t have access to dom , document , window objects.

Hence I’m facing difficulties in migrating. I tried storing the app instance in chrome storage. But due to serialization, the methods are getting removed from the value.

here is how I’m trying in mv3 :

// workaround 1 . (background.js)
  
const app = new App(); 
 
chrome.storage.local.set({ instance: app }).then(() => {
  console.log("Value is set to " , app);
});

// in popup.js trying to read 

chrome.storage.local.get(["instance"]).then((result) => {
  console.log("Value currently is ", result);
  result.instance.init(); // init method doesn't exists 
});

Really confused how should I redesign it ?

Any help will be highly appreciated.