/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { EndpointLifecycle } from "#endpoint/properties/EndpointLifecycle.js";
import { InternalError, Observable, ObserverGroup } from "@matter/general";
class ChangeNotificationService {
  #change = new Observable();
  #observers = /* @__PURE__ */ new Map();
  constructor(node) {
    this.#beginNodeObservation(node);
    if (node.lifecycle.isReady) {
      this.#beginPeerObservation(node);
    } else {
      node.lifecycle.ready.once(() => this.#beginPeerObservation(node));
    }
  }
  /**
   * Change event source.
   */
  get change() {
    return this.#change;
  }
  /**
   * Invoked by the {@link BehaviorBacking} when state changes.
   */
  broadcastUpdate(backing, properties) {
    const { endpoint, type: behavior } = backing;
    this.#change.emit({
      kind: "update",
      endpoint,
      behavior,
      version: backing.datasource.version,
      properties
    });
  }
  /**
   * Invoked by {@link Events} or {@link ClientEventEmitter} as events occur.
   */
  broadcastEvent(endpoint, behavior, event, occurrence) {
    this.#change.emit({
      kind: "event",
      endpoint,
      behavior,
      event,
      ...occurrence
    });
  }
  close() {
    for (const observers of this.#observers.values()) {
      observers.close();
    }
    this.#observers.clear();
  }
  #beginNodeObservation(node) {
    const observers = new ObserverGroup();
    this.#observers.set(node, observers);
    observers.on(node.lifecycle.changed, (type, endpoint) => {
      switch (type) {
        case EndpointLifecycle.Change.Destroyed:
          this.#change.emit({
            kind: "delete",
            endpoint
          });
          if (endpoint === node) {
            observers.close();
            this.#observers.delete(node);
          }
          break;
      }
    });
  }
  #beginPeerObservation(node) {
    const observers = this.#observers.get(node);
    if (observers === void 0) {
      throw new InternalError("Change notification initialization order is broken");
    }
    observers.on(node.peers.added, this.#beginNodeObservation.bind(this));
  }
}
export {
  ChangeNotificationService
};
//# sourceMappingURL=ChangeNotificationService.js.map
