/**
 * pacem v0.51.10-faraday (https://js.pacem.it)
 * Copyright 2025 Pacem (https://pacem.it)
 * Licensed under Apache-2.0
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/// <reference path="../../../dist/js/pacem-core.d.ts" />
/// <reference path="types.ts" />
var Pacem;
(function (Pacem) {
    var Components;
    (function (Components) {
        var Networking;
        (function (Networking) {
            const consts = { API_JS: 'https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.7/signalr.min.js' };
            let PacemHubListenerElement = class PacemHubListenerElement extends Components.PacemItemElement {
                constructor() {
                    super(...arguments);
                    this._receiveHandler = (...args) => {
                        this.dispatchEvent(new CustomEvent('receive', { detail: Array.from(args) }));
                    };
                    this._completeHandler = () => {
                        this.dispatchEvent(new Event('complete'));
                    };
                    this._errorHandler = (error) => {
                        this.dispatchEvent(new CustomEvent('error', { detail: error }));
                    };
                    this._connectedHandler = (e) => {
                        if (e.detail.propertyName === 'connected' && e.detail.currentValue === true) {
                            this._start();
                        }
                    };
                }
                #streamSubscription;
                get _isConnected() {
                    return this.container instanceof PacemHubProxyElement && this.container.connected || false;
                }
                get _connection() {
                    return this.container instanceof PacemHubProxyElement && this.container.connection || null;
                }
                /** Start listening, if not disabled. */
                start() {
                    if (!this.disabled) {
                        this._start();
                    }
                }
                /** Stop listening. */
                stop() {
                    this._stop();
                }
                _stop(method = this.method, isStreaming = this.stream) {
                    if (!this._isConnected) {
                        return;
                    }
                    const conn = this._connection;
                    if (!Pacem.Utils.isNullOrEmpty(method)) {
                        if (!isStreaming) {
                            conn.off(method, this._receiveHandler);
                        }
                        else {
                            this.#streamSubscription?.dispose();
                        }
                    }
                }
                _start(method = this.method, isStreaming = this.stream) {
                    if (!this._isConnected) {
                        return;
                    }
                    const conn = this._connection;
                    if (!Pacem.Utils.isNullOrEmpty(method)) {
                        if (!isStreaming) {
                            conn.on(method, this._receiveHandler);
                        }
                        else {
                            const args = this.arguments || [];
                            const streamResult = signalR.HubConnection.prototype.stream.apply(conn, [method].concat(args));
                            this.#streamSubscription = streamResult.subscribe({
                                next: this._receiveHandler,
                                complete: this._completeHandler,
                                error: this._errorHandler
                            });
                        }
                    }
                }
                viewActivatedCallback() {
                    super.viewActivatedCallback();
                    const container = this.container;
                    if (!Pacem.Utils.isNull(container)) {
                        container.addEventListener(Pacem.PropertyChangeEventName, this._connectedHandler, false);
                    }
                    this.start();
                }
                disconnectedCallback() {
                    const container = this.container;
                    if (!Pacem.Utils.isNull(container)) {
                        container.removeEventListener(Pacem.PropertyChangeEventName, this._connectedHandler, false);
                    }
                    super.disconnectedCallback();
                }
                propertyChangedCallback(name, old, val, first) {
                    super.propertyChangedCallback(name, old, val, first);
                    switch (name) {
                        case 'arguments':
                            this._stop();
                            this._start();
                            break;
                        case 'method':
                            if (!Pacem.Utils.isNullOrEmpty(old)) {
                                this._stop(old, this.stream);
                            }
                            if (!Pacem.Utils.isNullOrEmpty(val)) {
                                this._start(val, this.stream);
                            }
                            break;
                        case 'stream':
                            const m = this.method;
                            if (!Pacem.Utils.isNullOrEmpty(m)) {
                                this._stop(m, old);
                                this._start(m, val);
                            }
                            break;
                        case 'disabled':
                            if (!Pacem.Utils.isNullOrEmpty(this.method)) {
                                let toggle = val ? this._stop : this._start;
                                toggle();
                            }
                            break;
                    }
                }
            };
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.String })
            ], PacemHubListenerElement.prototype, "method", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Boolean })
            ], PacemHubListenerElement.prototype, "stream", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.Json })
            ], PacemHubListenerElement.prototype, "arguments", void 0);
            PacemHubListenerElement = __decorate([
                Pacem.CustomElement({ tagName: Pacem.P + '-hub-listener' })
            ], PacemHubListenerElement);
            Networking.PacemHubListenerElement = PacemHubListenerElement;
            let PacemHubProxyElement = class PacemHubProxyElement extends Components.PacemItemsContainerElement {
                validate(item) {
                    return item instanceof PacemHubListenerElement;
                }
                get connection() {
                    return this._hub;
                }
                invoke(method, ...args) {
                    if (this.connected) {
                        return this._hub.invoke.apply(this._hub, arguments);
                    }
                    throw 'Hub is not connected. Cannot call `invoke` method.';
                }
                send(method, ...args) {
                    if (this.connected) {
                        return this._hub.send.apply(this._hub, arguments);
                    }
                    throw 'Hub is not connected. Cannot call `send` method.';
                }
                start() {
                    return this._resetProxy();
                }
                async stop() {
                    if (this.connected) {
                        await this._hub.stop();
                    }
                }
                propertyChangedCallback(name, old, val, first) {
                    super.propertyChangedCallback(name, old, val, first);
                    //
                    if (first) {
                        return;
                    }
                    if (name === 'url' || name === 'disabled' || name === 'accesstoken') {
                        this._resetProxy();
                    }
                }
                viewActivatedCallback() {
                    super.viewActivatedCallback();
                    this.start();
                }
                disconnectedCallback() {
                    // this will (likely) never complete, being an asynchrounous call...
                    // TODO: think about it.
                    this.stop();
                    super.disconnectedCallback();
                }
                async _resetProxy() {
                    if (!Pacem.Utils.isNull(this._hub)) {
                        await this._hub.stop();
                        //this.connected = false;
                    }
                    this._setupProxy();
                }
                async _initialize() {
                    if ('signalR' in window) {
                        // already available, skip import
                        return;
                    }
                    await Pacem.CustomElementUtils.importjs(consts.API_JS);
                }
                async _setupProxy() {
                    const listeners = this.items || [];
                    if (!this.disabled && !Pacem.Utils.isNullOrEmpty(this.url)) {
                        await this._initialize();
                        const connBuilder = new signalR.HubConnectionBuilder();
                        connBuilder.withUrl(this.url, {
                            accessTokenFactory: () => this.accesstoken
                        });
                        const h = this._hub = connBuilder.build();
                        h.onclose(() => {
                            for (var item of listeners) {
                                item.stop();
                            }
                            this.connected = false;
                            this._hub = null;
                        });
                        await h.start();
                        this.connected = true;
                    }
                }
            };
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.String })
            ], PacemHubProxyElement.prototype, "url", void 0);
            __decorate([
                Pacem.Watch({ emit: false, converter: Pacem.PropertyConverters.String })
            ], PacemHubProxyElement.prototype, "accesstoken", void 0);
            __decorate([
                Pacem.Watch({ converter: Pacem.PropertyConverters.Boolean })
            ], PacemHubProxyElement.prototype, "connected", void 0);
            PacemHubProxyElement = __decorate([
                Pacem.CustomElement({ tagName: Pacem.P + '-hub-proxy' })
            ], PacemHubProxyElement);
            Networking.PacemHubProxyElement = PacemHubProxyElement;
        })(Networking = Components.Networking || (Components.Networking = {}));
    })(Components = Pacem.Components || (Pacem.Components = {}));
})(Pacem || (Pacem = {}));
