"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ChangeNotificationService_exports = {};
__export(ChangeNotificationService_exports, {
  ChangeNotificationService: () => ChangeNotificationService
});
module.exports = __toCommonJS(ChangeNotificationService_exports);
var import_EndpointLifecycle = require("#endpoint/properties/EndpointLifecycle.js");
var import_general = require("@matter/general");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class ChangeNotificationService {
  #change = new import_general.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 import_general.ObserverGroup();
    this.#observers.set(node, observers);
    observers.on(node.lifecycle.changed, (type, endpoint) => {
      switch (type) {
        case import_EndpointLifecycle.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 import_general.InternalError("Change notification initialization order is broken");
    }
    observers.on(node.peers.added, this.#beginNodeObservation.bind(this));
  }
}
//# sourceMappingURL=ChangeNotificationService.js.map
