Securely Sharing State Between Instances Of Unrelated JavaScript Classes

Securely sharing state between instances of unrelated JavaScript classes can easily be accomplished by using a simple variation on the sub-class pattern of the “insider properties” model.

Designate one of your classes to handle the role of the “base” class. This class is responsible for creating the shared state object and controlling distribution of access. This class should use the standard “base class” pattern.

All other classes should implement a variation on the standard “sub-class” pattern that accepts (and stores) a base-class instance-reference and uses that for access instead of this.

The variation looks like this:

import { Base } from './insider-trusted.js';

export const Partner = (() => {
    const cls = Object.freeze(class Partner { // ** Unrelated to Base **
        static #insiderBaton;
        #baseInstance; // Reference instance (instead of `this`)
        #insider;

        constructor (baseInstance) {
            // Accept base instance parameter instead of using `this`
            this.#baseInstance = baseInstance;
            Base._getInsider(cls, baseInstance, () => this.#insider = cls.#insiderBaton);
            // Insider properties (this.#insider.prop) now available here
        }

        // Standard handoff-pattern class-method
        static _passInsider (insider, receiver) {
            this.#insiderBaton = insider;
            receiver();
            this.#insiderBaton = null;
        }
    });
    Object.freeze(cls.prototype);
    return cls;
})();

Make sure the Partner class is included in the trust configuration (represented by the insider-trusted.js file in this example).

Accessing #insider For Other Instances

The #insider state of other instances can be access in one of two ways (via another Partner object or another Base object):

export const cls = /* ... */ class Partner {
    // ...
    #getOtherInsider (other) {
        // Native JS cross-instance private #insider access
        if (other instanceof cls) return other.#insider;

        // Cross-class cross-instance #insider access
        if (other instanceof Base) {
            let insider;
            Base._getInsider(cls, other, () => insider = cls.#insiderBaton);
            return insider;
        }
    }
} // ...

Resources

This code is also available on GitHub at https://github.com/bkatzung/insider-js.

Related

JavaScript Object Property Encapsulation: Beyond Public, Protected, And Private (Insider Properties)

Leave a Reply