@iobroker/js-controller-adapter 7.2.3 → 8.0.0-alpha.1-20260921-e5941ca8a

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.
Files changed (101) hide show
  1. package/build/cjs/index.d.ts +0 -1
  2. package/build/cjs/index.js +5 -8
  3. package/build/cjs/index.js.map +2 -2
  4. package/build/cjs/lib/_Types.d.ts +394 -63
  5. package/build/cjs/lib/adapter/adapter.d.ts +1818 -177
  6. package/build/cjs/lib/adapter/adapter.js +715 -1035
  7. package/build/cjs/lib/adapter/adapter.js.map +2 -2
  8. package/build/cjs/lib/adapter/asyncAdapter.d.ts +124 -0
  9. package/build/cjs/lib/adapter/asyncAdapter.js +184 -0
  10. package/build/cjs/lib/adapter/asyncAdapter.js.map +7 -0
  11. package/build/cjs/lib/adapter/context.d.ts +34 -0
  12. package/build/cjs/lib/adapter/context.js +17 -0
  13. package/build/cjs/lib/adapter/context.js.map +7 -0
  14. package/build/cjs/lib/adapter/defaultObjs.d.ts +5 -0
  15. package/build/cjs/lib/adapter/defaultObjs.js +2 -0
  16. package/build/cjs/lib/adapter/defaultObjs.js.map +2 -2
  17. package/build/cjs/lib/adapter/log.d.ts +25 -0
  18. package/build/cjs/lib/adapter/log.js +29 -0
  19. package/build/cjs/lib/adapter/log.js.map +2 -2
  20. package/build/cjs/lib/adapter/managers/AdapterContextBase.d.ts +49 -0
  21. package/build/cjs/lib/adapter/managers/AdapterContextBase.js +98 -0
  22. package/build/cjs/lib/adapter/managers/AdapterContextBase.js.map +7 -0
  23. package/build/cjs/lib/adapter/managers/AliasManager.d.ts +103 -0
  24. package/build/cjs/lib/adapter/managers/AliasManager.js +293 -0
  25. package/build/cjs/lib/adapter/managers/AliasManager.js.map +7 -0
  26. package/build/cjs/lib/adapter/managers/CertificateManager.d.ts +50 -0
  27. package/build/cjs/lib/adapter/managers/CertificateManager.js +174 -0
  28. package/build/cjs/lib/adapter/managers/CertificateManager.js.map +7 -0
  29. package/build/cjs/lib/adapter/managers/MessagingManager.d.ts +58 -0
  30. package/build/cjs/lib/adapter/managers/MessagingManager.js +289 -0
  31. package/build/cjs/lib/adapter/managers/MessagingManager.js.map +7 -0
  32. package/build/cjs/lib/adapter/managers/SubscriptionManager.d.ts +107 -0
  33. package/build/cjs/lib/adapter/managers/SubscriptionManager.js +349 -0
  34. package/build/cjs/lib/adapter/managers/SubscriptionManager.js.map +7 -0
  35. package/build/cjs/lib/adapter/userInterfaceMessagingController.d.ts +10 -0
  36. package/build/cjs/lib/adapter/userInterfaceMessagingController.js +9 -2
  37. package/build/cjs/lib/adapter/userInterfaceMessagingController.js.map +2 -2
  38. package/build/cjs/lib/adapter/utils.js +15 -1
  39. package/build/cjs/lib/adapter/utils.js.map +2 -2
  40. package/build/cjs/lib/adapter/validator.d.ts +10 -5
  41. package/build/cjs/lib/adapter/validator.js +6 -5
  42. package/build/cjs/lib/adapter/validator.js.map +2 -2
  43. package/build/esm/index.d.ts +0 -1
  44. package/build/esm/index.d.ts.map +1 -1
  45. package/build/esm/index.js +0 -1
  46. package/build/esm/index.js.map +1 -1
  47. package/build/esm/lib/_Types.d.ts +394 -63
  48. package/build/esm/lib/_Types.d.ts.map +1 -1
  49. package/build/esm/lib/adapter/adapter.d.ts +1818 -177
  50. package/build/esm/lib/adapter/adapter.d.ts.map +1 -1
  51. package/build/esm/lib/adapter/adapter.js +827 -1215
  52. package/build/esm/lib/adapter/adapter.js.map +1 -1
  53. package/build/esm/lib/adapter/asyncAdapter.d.ts +124 -0
  54. package/build/esm/lib/adapter/asyncAdapter.d.ts.map +1 -0
  55. package/build/esm/lib/adapter/asyncAdapter.js +157 -0
  56. package/build/esm/lib/adapter/asyncAdapter.js.map +1 -0
  57. package/build/esm/lib/adapter/context.d.ts +34 -0
  58. package/build/esm/lib/adapter/context.d.ts.map +1 -0
  59. package/build/esm/lib/adapter/context.js +2 -0
  60. package/build/esm/lib/adapter/context.js.map +1 -0
  61. package/build/esm/lib/adapter/defaultObjs.d.ts +5 -0
  62. package/build/esm/lib/adapter/defaultObjs.d.ts.map +1 -1
  63. package/build/esm/lib/adapter/defaultObjs.js +5 -0
  64. package/build/esm/lib/adapter/defaultObjs.js.map +1 -1
  65. package/build/esm/lib/adapter/log.d.ts +25 -0
  66. package/build/esm/lib/adapter/log.d.ts.map +1 -1
  67. package/build/esm/lib/adapter/log.js +25 -0
  68. package/build/esm/lib/adapter/log.js.map +1 -1
  69. package/build/esm/lib/adapter/managers/AdapterContextBase.d.ts +49 -0
  70. package/build/esm/lib/adapter/managers/AdapterContextBase.d.ts.map +1 -0
  71. package/build/esm/lib/adapter/managers/AdapterContextBase.js +77 -0
  72. package/build/esm/lib/adapter/managers/AdapterContextBase.js.map +1 -0
  73. package/build/esm/lib/adapter/managers/AliasManager.d.ts +103 -0
  74. package/build/esm/lib/adapter/managers/AliasManager.d.ts.map +1 -0
  75. package/build/esm/lib/adapter/managers/AliasManager.js +269 -0
  76. package/build/esm/lib/adapter/managers/AliasManager.js.map +1 -0
  77. package/build/esm/lib/adapter/managers/CertificateManager.d.ts +50 -0
  78. package/build/esm/lib/adapter/managers/CertificateManager.d.ts.map +1 -0
  79. package/build/esm/lib/adapter/managers/CertificateManager.js +142 -0
  80. package/build/esm/lib/adapter/managers/CertificateManager.js.map +1 -0
  81. package/build/esm/lib/adapter/managers/MessagingManager.d.ts +58 -0
  82. package/build/esm/lib/adapter/managers/MessagingManager.d.ts.map +1 -0
  83. package/build/esm/lib/adapter/managers/MessagingManager.js +267 -0
  84. package/build/esm/lib/adapter/managers/MessagingManager.js.map +1 -0
  85. package/build/esm/lib/adapter/managers/SubscriptionManager.d.ts +107 -0
  86. package/build/esm/lib/adapter/managers/SubscriptionManager.d.ts.map +1 -0
  87. package/build/esm/lib/adapter/managers/SubscriptionManager.js +374 -0
  88. package/build/esm/lib/adapter/managers/SubscriptionManager.js.map +1 -0
  89. package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts +10 -0
  90. package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts.map +1 -1
  91. package/build/esm/lib/adapter/userInterfaceMessagingController.js +8 -2
  92. package/build/esm/lib/adapter/userInterfaceMessagingController.js.map +1 -1
  93. package/build/esm/lib/adapter/utils.d.ts.map +1 -1
  94. package/build/esm/lib/adapter/utils.js +1 -1
  95. package/build/esm/lib/adapter/utils.js.map +1 -1
  96. package/build/esm/lib/adapter/validator.d.ts +10 -5
  97. package/build/esm/lib/adapter/validator.d.ts.map +1 -1
  98. package/build/esm/lib/adapter/validator.js +8 -5
  99. package/build/esm/lib/adapter/validator.js.map +1 -1
  100. package/build/tsconfig.build.tsbuildinfo +1 -1
  101. package/package.json +25 -20
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var AdapterContextBase_exports = {};
21
+ __export(AdapterContextBase_exports, {
22
+ AdapterContextBase: () => AdapterContextBase
23
+ });
24
+ module.exports = __toCommonJS(AdapterContextBase_exports);
25
+ var import_js_controller_common = require("@iobroker/js-controller-common");
26
+ class AdapterContextBase {
27
+ static {
28
+ __name(this, "AdapterContextBase");
29
+ }
30
+ #ctx;
31
+ /**
32
+ * @param ctx Shared adapter context providing live runtime state
33
+ */
34
+ constructor(ctx) {
35
+ this.#ctx = ctx;
36
+ }
37
+ /**
38
+ * The connected states DB client.
39
+ *
40
+ * @throws {Error} `ERROR_DB_CLOSED` when the states database is not connected.
41
+ */
42
+ get states() {
43
+ const states = this.#ctx.states;
44
+ if (!states) {
45
+ throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
46
+ }
47
+ return states;
48
+ }
49
+ /**
50
+ * The connected objects DB client.
51
+ *
52
+ * @throws {Error} `ERROR_DB_CLOSED` when the objects database is not connected.
53
+ */
54
+ get objects() {
55
+ const objects = this.#ctx.objects;
56
+ if (!objects) {
57
+ throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
58
+ }
59
+ return objects;
60
+ }
61
+ /** Current adapter common config */
62
+ get common() {
63
+ return this.#ctx.common;
64
+ }
65
+ /** Current adapter instance config (native) */
66
+ get config() {
67
+ return this.#ctx.config;
68
+ }
69
+ /** Current host name (may be undefined before init) */
70
+ get host() {
71
+ return this.#ctx.host;
72
+ }
73
+ /** Current adapter namespace, e.g. `"adapter.0"` */
74
+ get namespace() {
75
+ return this.#ctx.namespace;
76
+ }
77
+ /** Current namespace string used in log messages */
78
+ get namespaceLog() {
79
+ return this.#ctx.namespaceLog;
80
+ }
81
+ /** Logger instance */
82
+ get logger() {
83
+ return this.#ctx.logger;
84
+ }
85
+ /** Controller for UI messaging */
86
+ get uiMessagingController() {
87
+ return this.#ctx.uiMessagingController;
88
+ }
89
+ /** Increment the adapter's outbound-write counter. */
90
+ countOutput() {
91
+ this.#ctx.countOutput();
92
+ }
93
+ }
94
+ // Annotate the CommonJS export names for ESM import in node:
95
+ 0 && (module.exports = {
96
+ AdapterContextBase
97
+ });
98
+ //# sourceMappingURL=AdapterContextBase.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/lib/adapter/managers/AdapterContextBase.ts"],
4
+ "sourcesContent": ["import type { Client as StatesInRedisClient } from '@iobroker/db-states-redis';\nimport type { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport type { AdapterContext } from '@/lib/adapter/context.js';\nimport { tools } from '@iobroker/js-controller-common';\n\n/**\n * Base class for adapter managers that read from the shared {@link AdapterContext}.\n *\n * Holds the context in a private `#ctx` field so subclasses cannot bypass the connection-checked\n * getters and reach the raw (possibly null) DB clients directly. Access to `states`/`objects` goes\n * through the throwing getters, which raise `ERROR_DB_CLOSED` when the respective database is not\n * connected; the other getters pass ctx values through unchanged.\n *\n * Getters are `protected` because `#` privates are not visible to subclasses.\n */\nexport abstract class AdapterContextBase {\n readonly #ctx: AdapterContext;\n\n /**\n * @param ctx Shared adapter context providing live runtime state\n */\n constructor(ctx: AdapterContext) {\n this.#ctx = ctx;\n }\n\n /**\n * The connected states DB client.\n *\n * @throws {Error} `ERROR_DB_CLOSED` when the states database is not connected.\n */\n protected get states(): StatesInRedisClient {\n const states = this.#ctx.states;\n if (!states) {\n throw new Error(tools.ERRORS.ERROR_DB_CLOSED);\n }\n return states;\n }\n\n /**\n * The connected objects DB client.\n *\n * @throws {Error} `ERROR_DB_CLOSED` when the objects database is not connected.\n */\n protected get objects(): ObjectsInRedisClient {\n const objects = this.#ctx.objects;\n if (!objects) {\n throw new Error(tools.ERRORS.ERROR_DB_CLOSED);\n }\n return objects;\n }\n\n /** Current adapter common config */\n protected get common(): ioBroker.InstanceCommon | undefined {\n return this.#ctx.common;\n }\n\n /** Current adapter instance config (native) */\n protected get config(): ioBroker.AdapterConfig {\n return this.#ctx.config;\n }\n\n /** Current host name (may be undefined before init) */\n protected get host(): string | undefined {\n return this.#ctx.host;\n }\n\n /** Current adapter namespace, e.g. `\"adapter.0\"` */\n protected get namespace(): `${string}.${number}` {\n return this.#ctx.namespace;\n }\n\n /** Current namespace string used in log messages */\n protected get namespaceLog(): string {\n return this.#ctx.namespaceLog;\n }\n\n /** Logger instance */\n protected get logger(): AdapterContext['logger'] {\n return this.#ctx.logger;\n }\n\n /** Controller for UI messaging */\n protected get uiMessagingController(): AdapterContext['uiMessagingController'] {\n return this.#ctx.uiMessagingController;\n }\n\n /** Increment the adapter's outbound-write counter. */\n protected countOutput(): void {\n this.#ctx.countOutput();\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAGA;;;;;AAAA,kCAAsB;AAYhB,MAAgB,mBAAkB;EAZxC,OAYwC;;;EAC3B;;;;EAKT,YAAY,KAAmB;AAC3B,SAAK,OAAO;EAChB;;;;;;EAOA,IAAc,SAAM;AAChB,UAAM,SAAS,KAAK,KAAK;AACzB,QAAI,CAAC,QAAQ;AACT,YAAM,IAAI,MAAM,kCAAM,OAAO,eAAe;IAChD;AACA,WAAO;EACX;;;;;;EAOA,IAAc,UAAO;AACjB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,SAAS;AACV,YAAM,IAAI,MAAM,kCAAM,OAAO,eAAe;IAChD;AACA,WAAO;EACX;;EAGA,IAAc,SAAM;AAChB,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,SAAM;AAChB,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,OAAI;AACd,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,YAAS;AACnB,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,eAAY;AACtB,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,SAAM;AAChB,WAAO,KAAK,KAAK;EACrB;;EAGA,IAAc,wBAAqB;AAC/B,WAAO,KAAK,KAAK;EACrB;;EAGU,cAAW;AACjB,SAAK,KAAK,YAAW;EACzB;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,103 @@
1
+ import type { AliasTargetEntry } from '../../_Types.js';
2
+ import type { ValidateIdOptions } from '../../../lib/adapter/validator.js';
3
+ import type { AdapterContext } from '../../../lib/adapter/context.js';
4
+ import { AdapterContextBase } from '../../../lib/adapter/managers/AdapterContextBase.js';
5
+ /** Validates a (possibly foreign) id; throws on invalid. Bound to the adapter's Validator. */
6
+ export type ValidateId = (id: string, isForeignId: boolean, options?: ValidateIdOptions | null) => void;
7
+ /**
8
+ * Owns the alias subscription cache and its bookkeeping: which real (source) states feed which
9
+ * `alias.*` targets, the alias subscription patterns, and the single `alias.*` object subscription.
10
+ * The source-state change fan-out ({@link resolveSourceChange}) is synchronous by contract so the
11
+ * state-change handler cannot interleave a cache mutation mid-fan-out.
12
+ */
13
+ export declare class AliasManager extends AdapterContextBase {
14
+ #private;
15
+ /**
16
+ * @param ctx Shared adapter context providing live runtime state
17
+ * @param validateId Bound id validator from the adapter's Validator instance
18
+ */
19
+ constructor(ctx: AdapterContext, validateId: ValidateId);
20
+ /**
21
+ * Whether the given source (real) state id currently feeds any alias.
22
+ *
23
+ * @param id the real source state id
24
+ */
25
+ hasSource(id: string): boolean;
26
+ /** Number of tracked source states. */
27
+ get size(): number;
28
+ /**
29
+ * Whether the given subscription pattern is tracked.
30
+ *
31
+ * @param pattern the subscription pattern
32
+ */
33
+ hasPattern(pattern: string): boolean;
34
+ /**
35
+ * Track a subscription pattern.
36
+ *
37
+ * @param pattern the subscription pattern
38
+ */
39
+ addPattern(pattern: string): void;
40
+ /**
41
+ * Stop tracking a subscription pattern.
42
+ *
43
+ * @param pattern the subscription pattern
44
+ */
45
+ deletePattern(pattern: string): void;
46
+ /**
47
+ * Whether `id` falls into any tracked alias pattern (wildcards via pattern2RegEx).
48
+ *
49
+ * @param id the id to test against the tracked patterns
50
+ */
51
+ matchesAnyPattern(id: string): boolean;
52
+ /**
53
+ * Reacts to a change of an `alias.*` object: re-points, updates, or removes the target across the
54
+ * tracked sources, and picks up a newly-appeared alias that falls into a tracked pattern.
55
+ * Live-iterates the cache while awaiting add/remove — the loop lives here, with the map, to
56
+ * preserve the original mutation-during-iteration semantics exactly.
57
+ *
58
+ * @param id the changed alias object id
59
+ * @param obj the new object (null/undefined if deleted)
60
+ */
61
+ handleAliasObjectChange(id: string, obj: ioBroker.Object | null | undefined): Promise<void>;
62
+ /**
63
+ * Removes every target subscribed under the given pattern, live-iterating the cache so a removal
64
+ * mutating the map mid-loop keeps the original semantics. Awaits each removal.
65
+ *
66
+ * @param pattern the subscription pattern being unsubscribed
67
+ */
68
+ removeTargetsForPattern(pattern: string): Promise<void>;
69
+ /**
70
+ * Synchronously computes the fan-out of a source (real) state change to its alias targets.
71
+ * Returns one `{ targetId, state }` per unique target. MUST NOT await — the caller relies on the
72
+ * cache not mutating between read and emit.
73
+ *
74
+ * @param sourceId the changed real state id
75
+ * @param state the new state value (or null on deletion)
76
+ */
77
+ resolveSourceChange(sourceId: string, state: ioBroker.State | null | undefined): Array<{
78
+ targetId: string;
79
+ state: ioBroker.State | null;
80
+ }>;
81
+ /** Subscribe the `alias.*` object range once (idempotent). */
82
+ ensureAliasObjectSubscription(): void;
83
+ /** Drop the `alias.*` object subscription when no aliases remain. */
84
+ maybeDropAliasObjectSubscription(): void;
85
+ /**
86
+ * Register an alias target for its source state, subscribing the source state (and reading its
87
+ * metadata once). Preserves the create-before-await ordering and the post-await existence
88
+ * re-check that guard a concurrent removal.
89
+ *
90
+ * @param aliasObj the `alias.*` object being subscribed
91
+ * @param pattern the subscription pattern that pulled it in
92
+ */
93
+ addAliasSubscribe(aliasObj: ioBroker.AnyObject, pattern: string): Promise<void>;
94
+ /**
95
+ * Remove one alias target from its source; when the source has no targets left, delete the entry
96
+ * and unsubscribe the source state.
97
+ *
98
+ * @param sourceId the real source state id
99
+ * @param aliasObjOrIdx the target entry or its index in the targets array
100
+ */
101
+ removeAliasSubscribe(sourceId: string, aliasObjOrIdx: number | AliasTargetEntry): Promise<void>;
102
+ }
103
+ //# sourceMappingURL=AliasManager.d.ts.map
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var AliasManager_exports = {};
31
+ __export(AliasManager_exports, {
32
+ AliasManager: () => AliasManager
33
+ });
34
+ module.exports = __toCommonJS(AliasManager_exports);
35
+ var import_js_controller_common = require("@iobroker/js-controller-common");
36
+ var import_deep_clone = __toESM(require("deep-clone"), 1);
37
+ var import_AdapterContextBase = require("../../../lib/adapter/managers/AdapterContextBase.js");
38
+ var import_constants = require("../../../lib/adapter/constants.js");
39
+ class AliasManager extends import_AdapterContextBase.AdapterContextBase {
40
+ static {
41
+ __name(this, "AliasManager");
42
+ }
43
+ #aliases = /* @__PURE__ */ new Map();
44
+ #aliasPatterns = /* @__PURE__ */ new Set();
45
+ #aliasObjectsSubscribed = false;
46
+ #validateId;
47
+ /**
48
+ * @param ctx Shared adapter context providing live runtime state
49
+ * @param validateId Bound id validator from the adapter's Validator instance
50
+ */
51
+ constructor(ctx, validateId) {
52
+ super(ctx);
53
+ this.#validateId = validateId;
54
+ }
55
+ /**
56
+ * Whether the given source (real) state id currently feeds any alias.
57
+ *
58
+ * @param id the real source state id
59
+ */
60
+ hasSource(id) {
61
+ return this.#aliases.has(id);
62
+ }
63
+ /** Number of tracked source states. */
64
+ get size() {
65
+ return this.#aliases.size;
66
+ }
67
+ /**
68
+ * Whether the given subscription pattern is tracked.
69
+ *
70
+ * @param pattern the subscription pattern
71
+ */
72
+ hasPattern(pattern) {
73
+ return this.#aliasPatterns.has(pattern);
74
+ }
75
+ /**
76
+ * Track a subscription pattern.
77
+ *
78
+ * @param pattern the subscription pattern
79
+ */
80
+ addPattern(pattern) {
81
+ this.#aliasPatterns.add(pattern);
82
+ }
83
+ /**
84
+ * Stop tracking a subscription pattern.
85
+ *
86
+ * @param pattern the subscription pattern
87
+ */
88
+ deletePattern(pattern) {
89
+ this.#aliasPatterns.delete(pattern);
90
+ }
91
+ /**
92
+ * Whether `id` falls into any tracked alias pattern (wildcards via pattern2RegEx).
93
+ *
94
+ * @param id the id to test against the tracked patterns
95
+ */
96
+ matchesAnyPattern(id) {
97
+ for (const aliasPattern of this.#aliasPatterns) {
98
+ const testPattern = aliasPattern.slice(-1) === "*" ? new RegExp(import_js_controller_common.tools.pattern2RegEx(aliasPattern)) : aliasPattern;
99
+ if (typeof testPattern === "string" && aliasPattern === id || testPattern instanceof RegExp && testPattern.test(id)) {
100
+ return true;
101
+ }
102
+ }
103
+ return false;
104
+ }
105
+ /**
106
+ * Reacts to a change of an `alias.*` object: re-points, updates, or removes the target across the
107
+ * tracked sources, and picks up a newly-appeared alias that falls into a tracked pattern.
108
+ * Live-iterates the cache while awaiting add/remove — the loop lives here, with the map, to
109
+ * preserve the original mutation-during-iteration semantics exactly.
110
+ *
111
+ * @param id the changed alias object id
112
+ * @param obj the new object (null/undefined if deleted)
113
+ */
114
+ async handleAliasObjectChange(id, obj) {
115
+ let isNewAlias = true;
116
+ for (const [sourceId, alias] of this.#aliases) {
117
+ const targetAlias = alias.targets.find((entry) => entry.id === id);
118
+ if (targetAlias) {
119
+ isNewAlias = false;
120
+ if (obj?.common?.alias?.id) {
121
+ const newSourceId = typeof obj.common.alias.id.read === "string" ? obj.common.alias.id.read : obj.common.alias.id;
122
+ if (newSourceId !== sourceId) {
123
+ await this.removeAliasSubscribe(sourceId, targetAlias);
124
+ try {
125
+ await this.addAliasSubscribe(obj, targetAlias.pattern);
126
+ } catch (e) {
127
+ this.logger.error(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
128
+ }
129
+ } else {
130
+ targetAlias.min = obj.common.min;
131
+ targetAlias.max = obj.common.max;
132
+ targetAlias.type = obj.common.type;
133
+ targetAlias.alias = (0, import_deep_clone.default)(obj.common.alias);
134
+ }
135
+ } else {
136
+ await this.removeAliasSubscribe(sourceId, targetAlias);
137
+ }
138
+ }
139
+ }
140
+ if (isNewAlias && obj && this.matchesAnyPattern(id)) {
141
+ try {
142
+ await this.addAliasSubscribe(obj, id);
143
+ } catch (e) {
144
+ this.logger.warn(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
145
+ }
146
+ }
147
+ }
148
+ /**
149
+ * Removes every target subscribed under the given pattern, live-iterating the cache so a removal
150
+ * mutating the map mid-loop keeps the original semantics. Awaits each removal.
151
+ *
152
+ * @param pattern the subscription pattern being unsubscribed
153
+ */
154
+ async removeTargetsForPattern(pattern) {
155
+ const promises = new Array();
156
+ for (const [sourceId, alias] of this.#aliases) {
157
+ for (let i = alias.targets.length - 1; i >= 0; i--) {
158
+ if (alias.targets[i].pattern === pattern) {
159
+ promises.push(this.removeAliasSubscribe(sourceId, i));
160
+ }
161
+ }
162
+ }
163
+ await Promise.all(promises);
164
+ }
165
+ /**
166
+ * Synchronously computes the fan-out of a source (real) state change to its alias targets.
167
+ * Returns one `{ targetId, state }` per unique target. MUST NOT await — the caller relies on the
168
+ * cache not mutating between read and emit.
169
+ *
170
+ * @param sourceId the changed real state id
171
+ * @param state the new state value (or null on deletion)
172
+ */
173
+ resolveSourceChange(sourceId, state) {
174
+ const out = new Array();
175
+ const alias = this.#aliases.get(sourceId);
176
+ if (!alias) {
177
+ return out;
178
+ }
179
+ const uniqueTargets = /* @__PURE__ */ new Set();
180
+ for (const target of alias.targets) {
181
+ const targetId = target.id;
182
+ if (uniqueTargets.has(targetId)) {
183
+ continue;
184
+ }
185
+ uniqueTargets.add(targetId);
186
+ const aState = state ? import_js_controller_common.tools.formatAliasValue({
187
+ sourceCommon: alias.source,
188
+ targetCommon: target,
189
+ state: (0, import_deep_clone.default)(state),
190
+ logger: this.logger,
191
+ logNamespace: this.namespaceLog,
192
+ sourceId,
193
+ targetId
194
+ }) : null;
195
+ if (aState || !state) {
196
+ out.push({ targetId, state: aState });
197
+ }
198
+ }
199
+ return out;
200
+ }
201
+ /** Subscribe the `alias.*` object range once (idempotent). */
202
+ ensureAliasObjectSubscription() {
203
+ if (!this.#aliasObjectsSubscribed) {
204
+ this.#aliasObjectsSubscribed = true;
205
+ this.objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
206
+ }
207
+ }
208
+ /** Drop the `alias.*` object subscription when no aliases remain. */
209
+ maybeDropAliasObjectSubscription() {
210
+ if (!this.#aliases.size && this.#aliasObjectsSubscribed) {
211
+ this.#aliasObjectsSubscribed = false;
212
+ this.objects.unsubscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
213
+ }
214
+ }
215
+ /**
216
+ * Register an alias target for its source state, subscribing the source state (and reading its
217
+ * metadata once). Preserves the create-before-await ordering and the post-await existence
218
+ * re-check that guard a concurrent removal.
219
+ *
220
+ * @param aliasObj the `alias.*` object being subscribed
221
+ * @param pattern the subscription pattern that pulled it in
222
+ */
223
+ async addAliasSubscribe(aliasObj, pattern) {
224
+ if (aliasObj.type !== "state") {
225
+ return;
226
+ }
227
+ if (!aliasObj.common?.alias?.id) {
228
+ this.logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);
229
+ throw new Error(`Alias ${aliasObj._id} has no target`);
230
+ }
231
+ const sourceId = import_js_controller_common.tools.isObject(aliasObj.common.alias.id) ? aliasObj.common.alias.id.read : aliasObj.common.alias.id;
232
+ try {
233
+ this.#validateId(sourceId, true, null);
234
+ } catch (e) {
235
+ throw new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`);
236
+ }
237
+ const targetEntry = {
238
+ alias: (0, import_deep_clone.default)(aliasObj.common.alias),
239
+ id: aliasObj._id,
240
+ pattern,
241
+ type: aliasObj.common.type,
242
+ max: aliasObj.common.max,
243
+ min: aliasObj.common.min,
244
+ unit: aliasObj.common.unit
245
+ };
246
+ let aliasDetails;
247
+ if (!this.#aliases.has(sourceId)) {
248
+ aliasDetails = { targets: [] };
249
+ this.#aliases.set(sourceId, aliasDetails);
250
+ } else {
251
+ aliasDetails = this.#aliases.get(sourceId);
252
+ }
253
+ if (!aliasDetails.source) {
254
+ await this.states.subscribe(sourceId);
255
+ const sourceObj = await this.objects.getObject(sourceId, { user: import_constants.SYSTEM_ADMIN_USER });
256
+ if (sourceObj?.common && this.#aliases.has(sourceObj._id)) {
257
+ aliasDetails.source = {
258
+ min: sourceObj.common.min,
259
+ max: sourceObj.common.max,
260
+ type: sourceObj.common.type,
261
+ unit: sourceObj.common.unit
262
+ };
263
+ }
264
+ }
265
+ aliasDetails.targets.push(targetEntry);
266
+ }
267
+ /**
268
+ * Remove one alias target from its source; when the source has no targets left, delete the entry
269
+ * and unsubscribe the source state.
270
+ *
271
+ * @param sourceId the real source state id
272
+ * @param aliasObjOrIdx the target entry or its index in the targets array
273
+ */
274
+ async removeAliasSubscribe(sourceId, aliasObjOrIdx) {
275
+ if (!this.#aliases.has(sourceId)) {
276
+ return;
277
+ }
278
+ const alias = this.#aliases.get(sourceId);
279
+ const pos = typeof aliasObjOrIdx === "number" ? aliasObjOrIdx : alias.targets.indexOf(aliasObjOrIdx);
280
+ if (pos !== -1) {
281
+ alias.targets.splice(pos, 1);
282
+ if (!alias.targets.length) {
283
+ this.#aliases.delete(sourceId);
284
+ await this.states.unsubscribe(sourceId);
285
+ }
286
+ }
287
+ }
288
+ }
289
+ // Annotate the CommonJS export names for ESM import in node:
290
+ 0 && (module.exports = {
291
+ AliasManager
292
+ });
293
+ //# sourceMappingURL=AliasManager.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/lib/adapter/managers/AliasManager.ts"],
4
+ "sourcesContent": ["import { tools } from '@iobroker/js-controller-common';\nimport deepClone from 'deep-clone';\nimport type { AliasDetails, AliasTargetEntry } from '../../_Types.js';\nimport type { ValidateIdOptions } from '@/lib/adapter/validator.js';\nimport type { AdapterContext } from '@/lib/adapter/context.js';\nimport { AdapterContextBase } from '@/lib/adapter/managers/AdapterContextBase.js';\nimport { ALIAS_STARTS_WITH, SYSTEM_ADMIN_USER } from '@/lib/adapter/constants.js';\n\n/** Validates a (possibly foreign) id; throws on invalid. Bound to the adapter's Validator. */\nexport type ValidateId = (id: string, isForeignId: boolean, options?: ValidateIdOptions | null) => void;\n\n/**\n * Owns the alias subscription cache and its bookkeeping: which real (source) states feed which\n * `alias.*` targets, the alias subscription patterns, and the single `alias.*` object subscription.\n * The source-state change fan-out ({@link resolveSourceChange}) is synchronous by contract so the\n * state-change handler cannot interleave a cache mutation mid-fan-out.\n */\nexport class AliasManager extends AdapterContextBase {\n readonly #aliases = new Map<string, AliasDetails>();\n readonly #aliasPatterns = new Set<string>();\n #aliasObjectsSubscribed = false;\n readonly #validateId: ValidateId;\n\n /**\n * @param ctx Shared adapter context providing live runtime state\n * @param validateId Bound id validator from the adapter's Validator instance\n */\n constructor(ctx: AdapterContext, validateId: ValidateId) {\n super(ctx);\n this.#validateId = validateId;\n }\n\n /**\n * Whether the given source (real) state id currently feeds any alias.\n *\n * @param id the real source state id\n */\n hasSource(id: string): boolean {\n return this.#aliases.has(id);\n }\n\n /** Number of tracked source states. */\n get size(): number {\n return this.#aliases.size;\n }\n\n /**\n * Whether the given subscription pattern is tracked.\n *\n * @param pattern the subscription pattern\n */\n hasPattern(pattern: string): boolean {\n return this.#aliasPatterns.has(pattern);\n }\n\n /**\n * Track a subscription pattern.\n *\n * @param pattern the subscription pattern\n */\n addPattern(pattern: string): void {\n this.#aliasPatterns.add(pattern);\n }\n\n /**\n * Stop tracking a subscription pattern.\n *\n * @param pattern the subscription pattern\n */\n deletePattern(pattern: string): void {\n this.#aliasPatterns.delete(pattern);\n }\n\n /**\n * Whether `id` falls into any tracked alias pattern (wildcards via pattern2RegEx).\n *\n * @param id the id to test against the tracked patterns\n */\n matchesAnyPattern(id: string): boolean {\n for (const aliasPattern of this.#aliasPatterns) {\n const testPattern =\n aliasPattern.slice(-1) === '*' ? new RegExp(tools.pattern2RegEx(aliasPattern)) : aliasPattern;\n if (\n (typeof testPattern === 'string' && aliasPattern === id) ||\n (testPattern instanceof RegExp && testPattern.test(id))\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Reacts to a change of an `alias.*` object: re-points, updates, or removes the target across the\n * tracked sources, and picks up a newly-appeared alias that falls into a tracked pattern.\n * Live-iterates the cache while awaiting add/remove \u2014 the loop lives here, with the map, to\n * preserve the original mutation-during-iteration semantics exactly.\n *\n * @param id the changed alias object id\n * @param obj the new object (null/undefined if deleted)\n */\n async handleAliasObjectChange(id: string, obj: ioBroker.Object | null | undefined): Promise<void> {\n let isNewAlias = true;\n for (const [sourceId, alias] of this.#aliases) {\n const targetAlias = alias.targets.find(entry => entry.id === id);\n if (targetAlias) {\n isNewAlias = false;\n if (obj?.common?.alias?.id) {\n const newSourceId =\n typeof obj.common.alias.id.read === 'string' ? obj.common.alias.id.read : obj.common.alias.id;\n if (newSourceId !== sourceId) {\n await this.removeAliasSubscribe(sourceId, targetAlias);\n try {\n await this.addAliasSubscribe(obj, targetAlias.pattern);\n } catch (e: any) {\n this.logger.error(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);\n }\n } else {\n targetAlias.min = obj.common.min;\n targetAlias.max = obj.common.max;\n targetAlias.type = obj.common.type;\n targetAlias.alias = deepClone(obj.common.alias);\n }\n } else {\n await this.removeAliasSubscribe(sourceId, targetAlias);\n }\n }\n }\n if (isNewAlias && obj && this.matchesAnyPattern(id)) {\n try {\n await this.addAliasSubscribe(obj, id);\n } catch (e: any) {\n this.logger.warn(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);\n }\n }\n }\n\n /**\n * Removes every target subscribed under the given pattern, live-iterating the cache so a removal\n * mutating the map mid-loop keeps the original semantics. Awaits each removal.\n *\n * @param pattern the subscription pattern being unsubscribed\n */\n async removeTargetsForPattern(pattern: string): Promise<void> {\n const promises = new Array<Promise<void>>();\n for (const [sourceId, alias] of this.#aliases) {\n for (let i = alias.targets.length - 1; i >= 0; i--) {\n if (alias.targets[i].pattern === pattern) {\n promises.push(this.removeAliasSubscribe(sourceId, i));\n }\n }\n }\n await Promise.all(promises);\n }\n\n /**\n * Synchronously computes the fan-out of a source (real) state change to its alias targets.\n * Returns one `{ targetId, state }` per unique target. MUST NOT await \u2014 the caller relies on the\n * cache not mutating between read and emit.\n *\n * @param sourceId the changed real state id\n * @param state the new state value (or null on deletion)\n */\n resolveSourceChange(\n sourceId: string,\n state: ioBroker.State | null | undefined,\n ): Array<{ targetId: string; state: ioBroker.State | null }> {\n const out = new Array<{ targetId: string; state: ioBroker.State | null }>();\n const alias = this.#aliases.get(sourceId);\n if (!alias) {\n return out;\n }\n const uniqueTargets = new Set<string>();\n for (const target of alias.targets) {\n const targetId = target.id;\n if (uniqueTargets.has(targetId)) {\n continue;\n }\n uniqueTargets.add(targetId);\n const aState = state\n ? tools.formatAliasValue({\n sourceCommon: alias.source,\n targetCommon: target,\n state: deepClone(state),\n logger: this.logger,\n logNamespace: this.namespaceLog,\n sourceId,\n targetId,\n })\n : null;\n if (aState || !state) {\n out.push({ targetId, state: aState });\n }\n }\n return out;\n }\n\n /** Subscribe the `alias.*` object range once (idempotent). */\n ensureAliasObjectSubscription(): void {\n if (!this.#aliasObjectsSubscribed) {\n this.#aliasObjectsSubscribed = true;\n this.objects.subscribe(`${ALIAS_STARTS_WITH}*`);\n }\n }\n\n /** Drop the `alias.*` object subscription when no aliases remain. */\n maybeDropAliasObjectSubscription(): void {\n if (!this.#aliases.size && this.#aliasObjectsSubscribed) {\n this.#aliasObjectsSubscribed = false;\n this.objects.unsubscribe(`${ALIAS_STARTS_WITH}*`);\n }\n }\n\n /**\n * Register an alias target for its source state, subscribing the source state (and reading its\n * metadata once). Preserves the create-before-await ordering and the post-await existence\n * re-check that guard a concurrent removal.\n *\n * @param aliasObj the `alias.*` object being subscribed\n * @param pattern the subscription pattern that pulled it in\n */\n async addAliasSubscribe(aliasObj: ioBroker.AnyObject, pattern: string): Promise<void> {\n if (aliasObj.type !== 'state') {\n return;\n }\n if (!aliasObj.common?.alias?.id) {\n this.logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);\n throw new Error(`Alias ${aliasObj._id} has no target`);\n }\n const sourceId = tools.isObject(aliasObj.common.alias.id)\n ? aliasObj.common.alias.id.read\n : aliasObj.common.alias.id;\n try {\n this.#validateId(sourceId, true, null);\n } catch (e: any) {\n throw new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`);\n }\n const targetEntry: AliasTargetEntry = {\n alias: deepClone(aliasObj.common.alias),\n id: aliasObj._id,\n pattern,\n type: aliasObj.common.type,\n max: aliasObj.common.max,\n min: aliasObj.common.min,\n unit: aliasObj.common.unit,\n };\n let aliasDetails: AliasDetails;\n if (!this.#aliases.has(sourceId)) {\n aliasDetails = { targets: [] };\n this.#aliases.set(sourceId, aliasDetails);\n } else {\n aliasDetails = this.#aliases.get(sourceId)!;\n }\n if (!aliasDetails.source) {\n await this.states.subscribe(sourceId);\n const sourceObj = await this.objects.getObject(sourceId, { user: SYSTEM_ADMIN_USER });\n if (sourceObj?.common && this.#aliases.has(sourceObj._id)) {\n aliasDetails.source = {\n min: sourceObj.common.min,\n max: sourceObj.common.max,\n type: sourceObj.common.type,\n unit: sourceObj.common.unit,\n };\n }\n }\n aliasDetails.targets.push(targetEntry);\n }\n\n /**\n * Remove one alias target from its source; when the source has no targets left, delete the entry\n * and unsubscribe the source state.\n *\n * @param sourceId the real source state id\n * @param aliasObjOrIdx the target entry or its index in the targets array\n */\n async removeAliasSubscribe(sourceId: string, aliasObjOrIdx: number | AliasTargetEntry): Promise<void> {\n if (!this.#aliases.has(sourceId)) {\n return;\n }\n const alias = this.#aliases.get(sourceId)!;\n const pos = typeof aliasObjOrIdx === 'number' ? aliasObjOrIdx : alias.targets.indexOf(aliasObjOrIdx);\n if (pos !== -1) {\n alias.targets.splice(pos, 1);\n if (!alias.targets.length) {\n this.#aliases.delete(sourceId);\n await this.states.unsubscribe(sourceId);\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["deepClone"]
7
+ }
@@ -0,0 +1,50 @@
1
+ import type { InternalGetCertificatesResult } from '../../_Types.js';
2
+ import type { AdapterContext } from '../../../lib/adapter/context.js';
3
+ import { AdapterContextBase } from '../../../lib/adapter/managers/AdapterContextBase.js';
4
+ /** ID of the object holding all configured certificates */
5
+ export declare const CERTIFICATES_OBJECT_ID = "system.certificates";
6
+ /** Fetches SSL certificates from `system.certificates`, resolving file-backed values to their contents. */
7
+ export declare class CertificateManager extends AdapterContextBase {
8
+ #private;
9
+ /**
10
+ * @param ctx Shared adapter context providing live runtime state
11
+ */
12
+ constructor(ctx: AdapterContext);
13
+ /**
14
+ * Tells whether a new version of the `system.certificates` object actually changes one of the
15
+ * certificates handed out by the last {@link getCertificates} call. Unrelated certificates being
16
+ * added, changed or removed are ignored, so that editing some other adapter's certificate does
17
+ * not restart this one.
18
+ *
19
+ * Compares the raw (unresolved) values: for a file-backed certificate that is the path, so
20
+ * repointing it to a different file counts as a change, while a change of the file content is
21
+ * left to the file watcher.
22
+ *
23
+ * @param obj the new `system.certificates` object, or null/undefined if it was deleted
24
+ */
25
+ hasRelevantChange(obj: ioBroker.OtherObject | null | undefined): boolean;
26
+ /**
27
+ * Forgets the certificates handed out by the last {@link getCertificates} call, so a subsequent
28
+ * change of `system.certificates` is no longer treated as relevant by {@link hasRelevantChange}.
29
+ * Used when the adapter stops watching its certificates.
30
+ */
31
+ stopWatching(): void;
32
+ /**
33
+ * Loads the named certificates from `system.certificates`. File-backed values (short strings that
34
+ * are existing paths) are read from disk and their paths collected in `certFilePaths` so the caller
35
+ * can watch them.
36
+ *
37
+ * @param names public/private/chained certificate names
38
+ * @param names.publicName Name of the public certificate
39
+ * @param names.privateName Name of the private key
40
+ * @param names.chainedName Name of the chained certificate
41
+ * @throws {Error} `ERROR_DB_CLOSED` when the objects database is not connected
42
+ * @throws {Error} `ERROR_NOT_FOUND` when the requested certificates are not configured
43
+ */
44
+ getCertificates(names: {
45
+ publicName?: string;
46
+ privateName?: string;
47
+ chainedName?: string;
48
+ }): Promise<InternalGetCertificatesResult>;
49
+ }
50
+ //# sourceMappingURL=CertificateManager.d.ts.map