type ConnectedCallback = (component: ConnectedComponent) => void; export type ConnectedComponent = Record & { __onConnected__: (callback: ConnectedCallback) => void; __onDisconnected__: (callback: ConnectedCallback) => void; __connectedCallbackCalls__?: Set; __disconnectedCallbackCalls__?: Set; }; function onConnected(this: ConnectedComponent, callback: ConnectedCallback) { if (!this.__connectedCallbackCalls__) { this.__connectedCallbackCalls__ = new Set(); } this.__connectedCallbackCalls__.add(callback); } function onDisconnected(this: ConnectedComponent, callback: ConnectedCallback) { if (!this.__disconnectedCallbackCalls__) { this.__disconnectedCallbackCalls__ = new Set(); } this.__disconnectedCallbackCalls__.add(callback); } export function setSubscribable(target: any) { if (target.__is__setSubscribable__) return; target.__is__setSubscribable__ = true; target.__onConnected__ = onConnected; target.__onDisconnected__ = onDisconnected; const originalConnectedCallback = target.connectedCallback; target.connectedCallback = function (this: any) { originalConnectedCallback?.call(this); if (this.__connectedCallbackCalls__) { this.__connectedCallbackCalls__.forEach((callback: ConnectedCallback) => callback(this) ); } }; const originalDisconnectedCallback = target.disconnectedCallback; target.disconnectedCallback = function (this: any) { originalDisconnectedCallback?.call(this); if (this.__disconnectedCallbackCalls__) { this.__disconnectedCallbackCalls__.forEach( (callback: ConnectedCallback) => callback(this) ); } }; }