@iobroker/js-controller-adapter 7.2.3-alpha.13-20260807-e528bb438 → 7.2.3-alpha.14-20260808-bfc2bfaa4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -573,8 +573,6 @@ export declare class AdapterClass extends EventEmitter {
573
573
  private readonly startedInCompactMode;
574
574
  /** List of instances which want our logs */
575
575
  private readonly logList;
576
- private readonly aliases;
577
- private readonly aliasPatterns;
578
576
  private enums;
579
577
  private eventLoopLags;
580
578
  private overwriteLogLevel;
@@ -648,7 +646,6 @@ export declare class AdapterClass extends EventEmitter {
648
646
  /** latitude configured in system.config, only available if requested via AdapterOptions `useFormatDate`*/
649
647
  latitude?: number;
650
648
  private _defaultObjs?;
651
- private _aliasObjectsSubscribed?;
652
649
  config: ioBroker.AdapterConfig;
653
650
  host?: string;
654
651
  common?: ioBroker.InstanceCommon;
@@ -2351,20 +2348,6 @@ export declare class AdapterClass extends EventEmitter {
2351
2348
  user?: ioBroker.ObjectIDs.User;
2352
2349
  } | null | undefined, callback: ioBroker.GetStatesCallback): void;
2353
2350
  private _getForeignStates;
2354
- /**
2355
- * Add a subscription for a given alias, if it is not a state, it will be ignored
2356
- *
2357
- * @param aliasObj the alias object
2358
- * @param pattern pattern to subscribe for
2359
- */
2360
- private _addAliasSubscribe;
2361
- /**
2362
- * Remove an alias subscribe
2363
- *
2364
- * @param sourceId id of the source object
2365
- * @param aliasObjOrIdx the alias target or the index of the targets array
2366
- */
2367
- private _removeAliasSubscribe;
2368
2351
  /**
2369
2352
  * Subscribe for changes on all states of all adapters (and system states), that pass the pattern
2370
2353
  *
@@ -56,6 +56,7 @@ var import_plugin_base = require("@iobroker/plugin-base");
56
56
  var import_userInterfaceMessagingController = require("../../lib/adapter/userInterfaceMessagingController.js");
57
57
  var import_asyncAdapter = require("../../lib/adapter/asyncAdapter.js");
58
58
  var import_CertificateManager = require("../../lib/adapter/managers/CertificateManager.js");
59
+ var import_AliasManager = require("../../lib/adapter/managers/AliasManager.js");
59
60
  var import_constants2 = require("@iobroker/js-controller-common-db/constants");
60
61
  var import_tools = require("@iobroker/js-controller-common-db/tools");
61
62
  const controllerVersion = import_package.default.version;
@@ -82,8 +83,6 @@ class AdapterClass extends import_node_events.EventEmitter {
82
83
  startedInCompactMode;
83
84
  /** List of instances which want our logs */
84
85
  logList = /* @__PURE__ */ new Set();
85
- aliases = /* @__PURE__ */ new Map();
86
- aliasPatterns = /* @__PURE__ */ new Set();
87
86
  enums = {};
88
87
  eventLoopLags = [];
89
88
  overwriteLogLevel = false;
@@ -159,7 +158,6 @@ class AdapterClass extends import_node_events.EventEmitter {
159
158
  /** latitude configured in system.config, only available if requested via AdapterOptions `useFormatDate`*/
160
159
  latitude;
161
160
  _defaultObjs;
162
- _aliasObjectsSubscribed;
163
161
  config = {};
164
162
  host;
165
163
  common;
@@ -194,6 +192,11 @@ class AdapterClass extends import_node_events.EventEmitter {
194
192
  #context;
195
193
  #async;
196
194
  #certWatchers = /* @__PURE__ */ new Map();
195
+ #aliasInstance;
196
+ /** Lazily-constructed alias subscription manager. */
197
+ get #alias() {
198
+ return this.#aliasInstance ??= new import_AliasManager.AliasManager(this.#context, (id, allowSystem, options) => this._utils.validateId(id, allowSystem, options));
199
+ }
197
200
  /** True once `system.certificates` is subscribed, i.e. certificates have been requested */
198
201
  #certObjectSubscribed = false;
199
202
  /** True once a certificate change scheduled a restart, so concurrent changes schedule only one */
@@ -6420,76 +6423,6 @@ class AdapterClass extends import_node_events.EventEmitter {
6420
6423
  }
6421
6424
  }
6422
6425
  }
6423
- /**
6424
- * Add a subscription for a given alias, if it is not a state, it will be ignored
6425
- *
6426
- * @param aliasObj the alias object
6427
- * @param pattern pattern to subscribe for
6428
- */
6429
- async _addAliasSubscribe(aliasObj, pattern) {
6430
- if (aliasObj.type !== "state") {
6431
- return;
6432
- }
6433
- if (!aliasObj.common?.alias?.id) {
6434
- this._logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);
6435
- throw new Error(`Alias ${aliasObj._id} has no target`);
6436
- }
6437
- const sourceId = import_js_controller_common.tools.isObject(aliasObj.common.alias.id) ? aliasObj.common.alias.id.read : aliasObj.common.alias.id;
6438
- try {
6439
- this._utils.validateId(sourceId, true, null);
6440
- } catch (e) {
6441
- throw new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`);
6442
- }
6443
- const targetEntry = {
6444
- alias: (0, import_deep_clone.default)(aliasObj.common.alias),
6445
- id: aliasObj._id,
6446
- pattern,
6447
- type: aliasObj.common.type,
6448
- max: aliasObj.common.max,
6449
- min: aliasObj.common.min,
6450
- unit: aliasObj.common.unit
6451
- };
6452
- let aliasDetails;
6453
- if (!this.aliases.has(sourceId)) {
6454
- aliasDetails = { targets: [] };
6455
- this.aliases.set(sourceId, aliasDetails);
6456
- } else {
6457
- aliasDetails = this.aliases.get(sourceId);
6458
- }
6459
- if (!aliasDetails.source) {
6460
- await this.#states.subscribe(sourceId);
6461
- const sourceObj = await this.#objects.getObject(sourceId, { user: import_constants.SYSTEM_ADMIN_USER });
6462
- if (sourceObj?.common && this.aliases.has(sourceObj._id)) {
6463
- aliasDetails.source = {
6464
- min: sourceObj.common.min,
6465
- max: sourceObj.common.max,
6466
- type: sourceObj.common.type,
6467
- unit: sourceObj.common.unit
6468
- };
6469
- }
6470
- }
6471
- aliasDetails.targets.push(targetEntry);
6472
- }
6473
- /**
6474
- * Remove an alias subscribe
6475
- *
6476
- * @param sourceId id of the source object
6477
- * @param aliasObjOrIdx the alias target or the index of the targets array
6478
- */
6479
- async _removeAliasSubscribe(sourceId, aliasObjOrIdx) {
6480
- if (!this.aliases.has(sourceId)) {
6481
- return;
6482
- }
6483
- const alias = this.aliases.get(sourceId);
6484
- const pos = typeof aliasObjOrIdx === "number" ? aliasObjOrIdx : alias.targets.indexOf(aliasObjOrIdx);
6485
- if (pos !== -1) {
6486
- alias.targets.splice(pos, 1);
6487
- if (!alias.targets.length) {
6488
- this.aliases.delete(sourceId);
6489
- await this.#states.unsubscribe(sourceId);
6490
- }
6491
- }
6492
- }
6493
6426
  /**
6494
6427
  * Subscribe for changes on all states of all adapters (and system states), that pass the pattern
6495
6428
  *
@@ -6562,20 +6495,17 @@ class AdapterClass extends import_node_events.EventEmitter {
6562
6495
  const aliasesIds = pattern.map((id) => id.startsWith(import_constants.ALIAS_STARTS_WITH) ? id : null).filter((id) => id);
6563
6496
  const nonAliasesIds = pattern.map((id) => !id.startsWith(import_constants.ALIAS_STARTS_WITH) ? id : null).filter((id) => id);
6564
6497
  for (const aliasPattern of pattern) {
6565
- if ((aliasPattern.startsWith(import_constants.ALIAS_STARTS_WITH) || aliasPattern.includes("*")) && !this.aliasPatterns.has(aliasPattern)) {
6566
- this.aliasPatterns.add(aliasPattern);
6498
+ if ((aliasPattern.startsWith(import_constants.ALIAS_STARTS_WITH) || aliasPattern.includes("*")) && !this.#alias.hasPattern(aliasPattern)) {
6499
+ this.#alias.addPattern(aliasPattern);
6567
6500
  }
6568
6501
  }
6569
6502
  const promises = [];
6570
6503
  if (aliasesIds.length) {
6571
- if (!this._aliasObjectsSubscribed) {
6572
- this._aliasObjectsSubscribed = true;
6573
- this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
6574
- }
6504
+ this.#alias.ensureAliasObjectSubscription();
6575
6505
  const aliasObjs = await this._getObjectsByArray(aliasesIds, options);
6576
6506
  for (const aliasObj of aliasObjs) {
6577
6507
  if (aliasObj) {
6578
- promises.push(this._addAliasSubscribe(aliasObj, aliasObj._id));
6508
+ promises.push(this.#alias.addAliasSubscribe(aliasObj, aliasObj._id));
6579
6509
  }
6580
6510
  }
6581
6511
  }
@@ -6592,20 +6522,17 @@ class AdapterClass extends import_node_events.EventEmitter {
6592
6522
  return import_js_controller_common.tools.maybeCallback(callback);
6593
6523
  } else if (pattern.includes("*")) {
6594
6524
  if (pattern === "*" || pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
6595
- if (!this._aliasObjectsSubscribed) {
6596
- this._aliasObjectsSubscribed = true;
6597
- this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
6598
- }
6525
+ this.#alias.ensureAliasObjectSubscription();
6599
6526
  try {
6600
6527
  const objs = await this.getForeignObjectsAsync(pattern, null, null, options);
6601
6528
  const promises = [];
6602
- if (!this.aliasPatterns.has(pattern)) {
6603
- this.aliasPatterns.add(pattern);
6529
+ if (!this.#alias.hasPattern(pattern)) {
6530
+ this.#alias.addPattern(pattern);
6604
6531
  }
6605
6532
  for (const id of Object.keys(objs)) {
6606
6533
  if (id.startsWith(import_constants.ALIAS_STARTS_WITH)) {
6607
6534
  const aliasObj = objs[id];
6608
- promises.push(this._addAliasSubscribe(aliasObj, pattern));
6535
+ promises.push(this.#alias.addAliasSubscribe(aliasObj, pattern));
6609
6536
  }
6610
6537
  }
6611
6538
  try {
@@ -6629,14 +6556,11 @@ class AdapterClass extends import_node_events.EventEmitter {
6629
6556
  return callback ? this.#states.subscribeUser(pattern, callback) : this.#states.subscribeUser(pattern);
6630
6557
  }
6631
6558
  } else if (pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
6632
- if (!this._aliasObjectsSubscribed) {
6633
- this._aliasObjectsSubscribed = true;
6634
- this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
6635
- }
6559
+ this.#alias.ensureAliasObjectSubscription();
6636
6560
  try {
6637
6561
  const aliasObj = await this.#objects.getObject(pattern, options);
6638
6562
  if (aliasObj) {
6639
- await this._addAliasSubscribe(aliasObj, pattern);
6563
+ await this.#alias.addAliasSubscribe(aliasObj, pattern);
6640
6564
  return import_js_controller_common.tools.maybeCallback(callback);
6641
6565
  }
6642
6566
  return import_js_controller_common.tools.maybeCallback(callback);
@@ -6742,20 +6666,11 @@ class AdapterClass extends import_node_events.EventEmitter {
6742
6666
  promises.push(this.#states.unsubscribeUser(pattern));
6743
6667
  }
6744
6668
  if (aliasPattern) {
6745
- this.aliasPatterns.delete(aliasPattern);
6746
- for (const [sourceId, alias] of this.aliases) {
6747
- for (let i = alias.targets.length - 1; i >= 0; i--) {
6748
- if (alias.targets[i].pattern === aliasPattern) {
6749
- promises.push(this._removeAliasSubscribe(sourceId, i));
6750
- }
6751
- }
6752
- }
6669
+ this.#alias.deletePattern(aliasPattern);
6670
+ promises.push(this.#alias.removeTargetsForPattern(aliasPattern));
6753
6671
  }
6754
6672
  await Promise.all(promises);
6755
- if (!this.aliases.size && this._aliasObjectsSubscribed) {
6756
- this._aliasObjectsSubscribed = false;
6757
- this.#objects.unsubscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
6758
- }
6673
+ this.#alias.maybeDropAliasObjectSubscription();
6759
6674
  return import_js_controller_common.tools.maybeCallback(callback);
6760
6675
  }
6761
6676
  /**
@@ -7390,31 +7305,12 @@ class AdapterClass extends import_node_events.EventEmitter {
7390
7305
  }
7391
7306
  }
7392
7307
  }
7393
- } else if (!this._stopInProgress && this.adapterReady && this.aliases.has(id)) {
7394
- const alias = this.aliases.get(id);
7395
- const uniqueTargets = /* @__PURE__ */ new Set();
7396
- for (const target of alias.targets) {
7397
- const targetId = target.id;
7398
- if (uniqueTargets.has(targetId)) {
7399
- continue;
7400
- }
7401
- uniqueTargets.add(targetId);
7402
- const source = alias.source;
7403
- const aState = state ? import_js_controller_common.tools.formatAliasValue({
7404
- sourceCommon: source,
7405
- targetCommon: target,
7406
- state: (0, import_deep_clone.default)(state),
7407
- logger: this._logger,
7408
- logNamespace: this.namespaceLog,
7409
- sourceId: id,
7410
- targetId
7411
- }) : null;
7412
- if (aState || !state) {
7413
- if (typeof this._options.stateChange === "function") {
7414
- Promise.resolve(this._options.stateChange(targetId, aState)).catch((e) => this._logger.error(`${this.namespaceLog} Error in stateChange handler: ${e.message}`));
7415
- } else {
7416
- setImmediate(() => this.emit("stateChange", targetId, aState));
7417
- }
7308
+ } else if (!this._stopInProgress && this.adapterReady && this.#alias.hasSource(id)) {
7309
+ for (const { targetId, state: aState } of this.#alias.resolveSourceChange(id, state)) {
7310
+ if (typeof this._options.stateChange === "function") {
7311
+ Promise.resolve(this._options.stateChange(targetId, aState)).catch((e) => this._logger.error(`${this.namespaceLog} Error in stateChange handler: ${e.message}`));
7312
+ } else {
7313
+ setImmediate(() => this.emit("stateChange", targetId, aState));
7418
7314
  }
7419
7315
  }
7420
7316
  }
@@ -7538,44 +7434,7 @@ class AdapterClass extends import_node_events.EventEmitter {
7538
7434
  this.defaultHistory = obj.common.defaultHistory;
7539
7435
  }
7540
7436
  if (id.startsWith(import_constants.ALIAS_STARTS_WITH)) {
7541
- let isNewAlias = true;
7542
- for (const [sourceId, alias] of this.aliases) {
7543
- const targetAlias = alias.targets.find((entry) => entry.id === id);
7544
- if (targetAlias) {
7545
- isNewAlias = false;
7546
- if (obj?.common?.alias?.id) {
7547
- const newSourceId = typeof obj.common.alias.id.read === "string" ? obj.common.alias.id.read : obj.common.alias.id;
7548
- if (newSourceId !== sourceId) {
7549
- await this._removeAliasSubscribe(sourceId, targetAlias);
7550
- try {
7551
- await this._addAliasSubscribe(obj, targetAlias.pattern);
7552
- } catch (e) {
7553
- this._logger.error(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
7554
- }
7555
- } else {
7556
- targetAlias.min = obj.common.min;
7557
- targetAlias.max = obj.common.max;
7558
- targetAlias.type = obj.common.type;
7559
- targetAlias.alias = (0, import_deep_clone.default)(obj.common.alias);
7560
- }
7561
- } else {
7562
- await this._removeAliasSubscribe(sourceId, targetAlias);
7563
- }
7564
- }
7565
- }
7566
- if (isNewAlias && obj) {
7567
- for (const aliasPattern of this.aliasPatterns) {
7568
- const testPattern = aliasPattern.slice(-1) === "*" ? new RegExp(import_js_controller_common.tools.pattern2RegEx(aliasPattern)) : aliasPattern;
7569
- if (typeof testPattern === "string" && aliasPattern === id || testPattern instanceof RegExp && testPattern.test(id)) {
7570
- try {
7571
- await this._addAliasSubscribe(obj, id);
7572
- } catch (e) {
7573
- this._logger.warn(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
7574
- }
7575
- break;
7576
- }
7577
- }
7578
- }
7437
+ await this.#alias.handleAliasObjectChange(id, obj);
7579
7438
  }
7580
7439
  if (id.startsWith("system.adapter.")) {
7581
7440
  if (obj?.common?.subscribable) {