import {PublisherProxy} from "@supersoniks/concorde/core/utils/PublisherProxy"; import {Subscriber} from "@supersoniks/concorde/mixins"; import {Objects, PublisherManager} from "@supersoniks/concorde/utils"; import {LitElement, html, css} from "lit"; import {customElement, property} from "lit/decorators.js"; import {PublisherInterface, PublisherContentType} from "@supersoniks/concorde/core/_types/types"; type Composition = Record; type Listener = {publisher: PublisherInterface; subscriber: (v: T) => void}; @customElement("sonic-mix") export default class SonicMix extends Subscriber(LitElement) { static styles = [ css` :host { display: contents; } `, ]; private _composition: Composition = {}; @property({type: Object}) get composition() { return this._composition; } set composition(value: Composition) { this._composition = value; this.updateComposition(); } connectedCallback(): void { super.connectedCallback(); this.updateComposition(); } disconnectedCallback(): void { this.removePublisherListeners(); super.disconnectedCallback(); } updateComposition() { this.removePublisherListeners(); if (!this.publisher) return; this.publisher.set({}); this.parseComposition(this.composition, this.publisher); } listeners: Listener[] = []; removePublisherListeners() { const listeners = this.listeners; this.listeners = []; listeners.forEach((listener) => { this.publisher.offAssign(listener.subscriber); }); } parseComposition( composition: Composition, publisher: PublisherInterface ) { if (!composition) return; for (const z in composition) { const value = composition[z]; if (typeof value === "string") { const split = value.split("."); const first = split.shift(); if (!first) continue; let publisherSource = PublisherManager.get(first); publisherSource = Objects.traverse(publisherSource, split); const publisherSubscriber = { publisher: publisherSource, subscriber: (v: T) => { publisher[z] = v; }, }; this.listeners.push(publisherSubscriber); publisherSource.onAssign(publisherSubscriber.subscriber); publisher._proxies_.set(z, publisherSource); } else { this.publisher[z] = {}; const newPublisher: PublisherInterface = new PublisherProxy({}, publisher); publisher._proxies_.set(z, newPublisher); const publisherSubscriber = { publisher: newPublisher, subscriber: (v: T) => { publisher[z] = v; }, }; this.listeners.push(publisherSubscriber); newPublisher.onAssign(publisherSubscriber.subscriber); this.parseComposition(value as Composition, newPublisher); } } } render() { return html``; } }