Repository: pyscript/pyscript
File: pyscriptjs/src/plugins/pyterminal.ts (TypeScript)

Code before:
        outElem: HTMLDivElement;
        _moduleResolved: boolean;
        xtermReadyPromise: Promise<TerminalType>;
        xterm: TerminalType;
        cachedStdOut: Array<string>;
        cachedStdErr: Array<string>;
        _xterm_cdn_base_url = 'https://cdn.jsdelivr.net/npm/xterm@5.1.0';

        constructor() {
            super();
            this.cachedStdOut = [];
            this.cachedStdErr = [];

            // While this is false, store writes to stdout/stderr to a buffer
            // when the xterm.js is actually ready, we will "replay" those writes
            // and set this to true
            this._moduleResolved = false;

            //Required to make xterm appear properly
            this.style.width = '100%';
            this.style.height = '100%';
        }

        async connectedCallback() {
            //guard against initializing a tag twice
            if (knownPyTerminalTags.has(this)) return;

            this.outElem = document.createElement('div');
            //this.outElem.className = 'py-terminal';
            this.appendChild(this.outElem);

            this.setupPosition(app);

            this.xtermReadyPromise = this._setupXterm();
            await this.xtermReadyPromise;
            knownPyTerminalTags.add(this);
        }

        /**
         * Fetch the xtermjs library from CDN an initialize it.
         * @private
         * @returns the associated xterm.js Terminal
         */
        async _setupXterm() {
            // eslint-disable-next-line
            // @ts-ignore
            if (globalThis.Terminal == undefined) {
                //xterm module proper
                //eslint-disable-next-line
                //@ts-ignore
                await import(this._xterm_cdn_base_url + '/lib/xterm.js');

Review comment (suggestion):
I have the feeling we can all share the same *WeakSet* for all same-cases we have out there ... nothing to change in here, something to think about as I'd expect this dance to be identical for every plugin.

Code after:
        outElem: HTMLDivElement;
        _moduleResolved: boolean;
        xtermReady: Promise<TerminalType>;
        xterm: TerminalType;
        cachedStdOut: Array<string>;
        cachedStdErr: Array<string>;
        _xterm_cdn_base_url = 'https://cdn.jsdelivr.net/npm/xterm@5.1.0';

        constructor() {
            super();
            this.cachedStdOut = [];
            this.cachedStdErr = [];

            // While this is false, store writes to stdout/stderr to a buffer
            // when the xterm.js is actually ready, we will "replay" those writes
            // and set this to true
            this._moduleResolved = false;

            //Required to make xterm appear properly
            this.style.width = '100%';
            this.style.height = '100%';
        }

        async connectedCallback() {
            //guard against initializing a tag twice
            if (knownPyTerminalTags.has(this)) return;
            knownPyTerminalTags.add(this);

            this.outElem = document.createElement('div');
            //this.outElem.className = 'py-terminal';
            this.appendChild(this.outElem);

            this.setupPosition(app);

            this.xtermReady = this._setupXterm();
            await this.xtermReady;
        }

        /**
         * Fetch the xtermjs library from CDN an initialize it.
         * @private
         * @returns the associated xterm.js Terminal
         */
        async _setupXterm() {
            if (this.xterm == undefined) {
                //need to initialize the Terminal for this element

                // eslint-disable-next-line
                // @ts-ignore
                if (globalThis.Terminal == undefined) {
                    //load xterm module from cdn