@loglayer/log-level-manager-one-way 1.0.0 → 1.0.1

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.
package/dist/index.cjs CHANGED
@@ -41,6 +41,22 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
41
41
  } };
42
42
  parentManager = null;
43
43
  childManagers = /* @__PURE__ */ new Set();
44
+ isDisposed = false;
45
+ /**
46
+ * Gets all alive child managers and removes dead references.
47
+ * This prevents memory leaks by cleaning up references to garbage collected children.
48
+ */
49
+ getAliveChildren() {
50
+ const aliveChildren = [];
51
+ const deadRefs = [];
52
+ for (const childRef of this.childManagers) {
53
+ const child = childRef.deref();
54
+ if (child) aliveChildren.push(child);
55
+ else deadRefs.push(childRef);
56
+ }
57
+ for (const deadRef of deadRefs) this.childManagers.delete(deadRef);
58
+ return aliveChildren;
59
+ }
44
60
  /**
45
61
  * Sets the minimum log level to be used by the logger. Only messages with
46
62
  * this level or higher severity will be logged.
@@ -48,13 +64,15 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
48
64
  * If this is a child, the change only applies to this instance.
49
65
  */
50
66
  setLevel(logLevel) {
67
+ if (this.isDisposed) return;
51
68
  const minLogValue = __loglayer_log_level_manager.LogLevelPriority[logLevel];
52
69
  for (const level of Object.values(__loglayer_log_level_manager.LogLevel)) {
53
70
  const levelKey = level;
54
71
  const levelValue = __loglayer_log_level_manager.LogLevelPriority[level];
55
72
  this.logLevelContainer.status[levelKey] = levelValue >= minLogValue;
56
73
  }
57
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.setLevel(logLevel);
74
+ const aliveChildren = this.getAliveChildren();
75
+ for (const child of aliveChildren) child.setLevel(logLevel);
58
76
  }
59
77
  /**
60
78
  * Enables a specific log level.
@@ -62,9 +80,11 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
62
80
  * If this is a child, the change only applies to this instance.
63
81
  */
64
82
  enableIndividualLevel(logLevel) {
83
+ if (this.isDisposed) return;
65
84
  const level = logLevel;
66
85
  if (level in this.logLevelContainer.status) this.logLevelContainer.status[level] = true;
67
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.enableIndividualLevel(logLevel);
86
+ const aliveChildren = this.getAliveChildren();
87
+ for (const child of aliveChildren) child.enableIndividualLevel(logLevel);
68
88
  }
69
89
  /**
70
90
  * Disables a specific log level.
@@ -72,14 +92,17 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
72
92
  * If this is a child, the change only applies to this instance.
73
93
  */
74
94
  disableIndividualLevel(logLevel) {
95
+ if (this.isDisposed) return;
75
96
  const level = logLevel;
76
97
  if (level in this.logLevelContainer.status) this.logLevelContainer.status[level] = false;
77
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.disableIndividualLevel(logLevel);
98
+ const aliveChildren = this.getAliveChildren();
99
+ for (const child of aliveChildren) child.disableIndividualLevel(logLevel);
78
100
  }
79
101
  /**
80
102
  * Checks if a specific log level is enabled
81
103
  */
82
104
  isLevelEnabled(logLevel) {
105
+ if (this.isDisposed) return false;
83
106
  const level = logLevel;
84
107
  return this.logLevelContainer.status[level];
85
108
  }
@@ -89,8 +112,10 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
89
112
  * If this is a child, the change only applies to this instance.
90
113
  */
91
114
  enableLogging() {
115
+ if (this.isDisposed) return;
92
116
  for (const level of Object.keys(this.logLevelContainer.status)) this.logLevelContainer.status[level] = true;
93
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.enableLogging();
117
+ const aliveChildren = this.getAliveChildren();
118
+ for (const child of aliveChildren) child.enableLogging();
94
119
  }
95
120
  /**
96
121
  * All logging inputs are dropped and stops sending logs to the logging library.
@@ -98,8 +123,10 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
98
123
  * If this is a child, the change only applies to this instance.
99
124
  */
100
125
  disableLogging() {
126
+ if (this.isDisposed) return;
101
127
  for (const level of Object.keys(this.logLevelContainer.status)) this.logLevelContainer.status[level] = false;
102
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.disableLogging();
128
+ const aliveChildren = this.getAliveChildren();
129
+ for (const child of aliveChildren) child.disableLogging();
103
130
  }
104
131
  /**
105
132
  * Links the child log level manager to the parent.
@@ -107,12 +134,13 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
107
134
  * Parent changes will propagate to children, but child changes won't affect the parent.
108
135
  */
109
136
  onChildLoggerCreated({ parentLogLevelManager, childLogLevelManager }) {
137
+ if (this.isDisposed) return;
110
138
  if (childLogLevelManager instanceof OneWayLogLevelManager && parentLogLevelManager instanceof OneWayLogLevelManager) {
111
139
  const child = childLogLevelManager;
112
140
  const parent = parentLogLevelManager;
113
141
  child.logLevelContainer.status = { ...parent.logLevelContainer.status };
114
- child.parentManager = parent;
115
- parent.childManagers.add(child);
142
+ child.parentManager = new WeakRef(parent);
143
+ parent.childManagers.add(new WeakRef(child));
116
144
  }
117
145
  }
118
146
  /**
@@ -120,10 +148,21 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
120
148
  * The clone is independent and not linked to the original.
121
149
  */
122
150
  clone() {
151
+ if (this.isDisposed) return new OneWayLogLevelManager();
123
152
  const clone = new OneWayLogLevelManager();
124
153
  clone.logLevelContainer.status = { ...this.logLevelContainer.status };
125
154
  return clone;
126
155
  }
156
+ /**
157
+ * Implements the Disposable interface for cleanup.
158
+ * Clears all parent and child references to prevent memory leaks.
159
+ */
160
+ [Symbol.dispose]() {
161
+ if (this.isDisposed) return;
162
+ this.parentManager = null;
163
+ this.childManagers.clear();
164
+ this.isDisposed = true;
165
+ }
127
166
  };
128
167
 
129
168
  //#endregion
package/dist/index.d.cts CHANGED
@@ -7,10 +7,16 @@ import { ILogLevelManager, LogLevelType, OnChildLogLevelManagerCreatedParams } f
7
7
  * Parent changes affect children, but child changes do not affect parents.
8
8
  * Changes only apply to a parent and their children (not separate instances).
9
9
  */
10
- declare class OneWayLogLevelManager implements ILogLevelManager {
10
+ declare class OneWayLogLevelManager implements ILogLevelManager, Disposable {
11
11
  private logLevelContainer;
12
12
  private parentManager;
13
13
  private childManagers;
14
+ private isDisposed;
15
+ /**
16
+ * Gets all alive child managers and removes dead references.
17
+ * This prevents memory leaks by cleaning up references to garbage collected children.
18
+ */
19
+ private getAliveChildren;
14
20
  /**
15
21
  * Sets the minimum log level to be used by the logger. Only messages with
16
22
  * this level or higher severity will be logged.
@@ -60,6 +66,11 @@ declare class OneWayLogLevelManager implements ILogLevelManager {
60
66
  * The clone is independent and not linked to the original.
61
67
  */
62
68
  clone(): ILogLevelManager;
69
+ /**
70
+ * Implements the Disposable interface for cleanup.
71
+ * Clears all parent and child references to prevent memory leaks.
72
+ */
73
+ [Symbol.dispose](): void;
63
74
  }
64
75
  //#endregion
65
76
  export { OneWayLogLevelManager };
package/dist/index.d.ts CHANGED
@@ -7,10 +7,16 @@ import { ILogLevelManager, LogLevelType, OnChildLogLevelManagerCreatedParams } f
7
7
  * Parent changes affect children, but child changes do not affect parents.
8
8
  * Changes only apply to a parent and their children (not separate instances).
9
9
  */
10
- declare class OneWayLogLevelManager implements ILogLevelManager {
10
+ declare class OneWayLogLevelManager implements ILogLevelManager, Disposable {
11
11
  private logLevelContainer;
12
12
  private parentManager;
13
13
  private childManagers;
14
+ private isDisposed;
15
+ /**
16
+ * Gets all alive child managers and removes dead references.
17
+ * This prevents memory leaks by cleaning up references to garbage collected children.
18
+ */
19
+ private getAliveChildren;
14
20
  /**
15
21
  * Sets the minimum log level to be used by the logger. Only messages with
16
22
  * this level or higher severity will be logged.
@@ -60,6 +66,11 @@ declare class OneWayLogLevelManager implements ILogLevelManager {
60
66
  * The clone is independent and not linked to the original.
61
67
  */
62
68
  clone(): ILogLevelManager;
69
+ /**
70
+ * Implements the Disposable interface for cleanup.
71
+ * Clears all parent and child references to prevent memory leaks.
72
+ */
73
+ [Symbol.dispose](): void;
63
74
  }
64
75
  //#endregion
65
76
  export { OneWayLogLevelManager };
package/dist/index.js CHANGED
@@ -17,6 +17,22 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
17
17
  } };
18
18
  parentManager = null;
19
19
  childManagers = /* @__PURE__ */ new Set();
20
+ isDisposed = false;
21
+ /**
22
+ * Gets all alive child managers and removes dead references.
23
+ * This prevents memory leaks by cleaning up references to garbage collected children.
24
+ */
25
+ getAliveChildren() {
26
+ const aliveChildren = [];
27
+ const deadRefs = [];
28
+ for (const childRef of this.childManagers) {
29
+ const child = childRef.deref();
30
+ if (child) aliveChildren.push(child);
31
+ else deadRefs.push(childRef);
32
+ }
33
+ for (const deadRef of deadRefs) this.childManagers.delete(deadRef);
34
+ return aliveChildren;
35
+ }
20
36
  /**
21
37
  * Sets the minimum log level to be used by the logger. Only messages with
22
38
  * this level or higher severity will be logged.
@@ -24,13 +40,15 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
24
40
  * If this is a child, the change only applies to this instance.
25
41
  */
26
42
  setLevel(logLevel) {
43
+ if (this.isDisposed) return;
27
44
  const minLogValue = LogLevelPriority[logLevel];
28
45
  for (const level of Object.values(LogLevel)) {
29
46
  const levelKey = level;
30
47
  const levelValue = LogLevelPriority[level];
31
48
  this.logLevelContainer.status[levelKey] = levelValue >= minLogValue;
32
49
  }
33
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.setLevel(logLevel);
50
+ const aliveChildren = this.getAliveChildren();
51
+ for (const child of aliveChildren) child.setLevel(logLevel);
34
52
  }
35
53
  /**
36
54
  * Enables a specific log level.
@@ -38,9 +56,11 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
38
56
  * If this is a child, the change only applies to this instance.
39
57
  */
40
58
  enableIndividualLevel(logLevel) {
59
+ if (this.isDisposed) return;
41
60
  const level = logLevel;
42
61
  if (level in this.logLevelContainer.status) this.logLevelContainer.status[level] = true;
43
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.enableIndividualLevel(logLevel);
62
+ const aliveChildren = this.getAliveChildren();
63
+ for (const child of aliveChildren) child.enableIndividualLevel(logLevel);
44
64
  }
45
65
  /**
46
66
  * Disables a specific log level.
@@ -48,14 +68,17 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
48
68
  * If this is a child, the change only applies to this instance.
49
69
  */
50
70
  disableIndividualLevel(logLevel) {
71
+ if (this.isDisposed) return;
51
72
  const level = logLevel;
52
73
  if (level in this.logLevelContainer.status) this.logLevelContainer.status[level] = false;
53
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.disableIndividualLevel(logLevel);
74
+ const aliveChildren = this.getAliveChildren();
75
+ for (const child of aliveChildren) child.disableIndividualLevel(logLevel);
54
76
  }
55
77
  /**
56
78
  * Checks if a specific log level is enabled
57
79
  */
58
80
  isLevelEnabled(logLevel) {
81
+ if (this.isDisposed) return false;
59
82
  const level = logLevel;
60
83
  return this.logLevelContainer.status[level];
61
84
  }
@@ -65,8 +88,10 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
65
88
  * If this is a child, the change only applies to this instance.
66
89
  */
67
90
  enableLogging() {
91
+ if (this.isDisposed) return;
68
92
  for (const level of Object.keys(this.logLevelContainer.status)) this.logLevelContainer.status[level] = true;
69
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.enableLogging();
93
+ const aliveChildren = this.getAliveChildren();
94
+ for (const child of aliveChildren) child.enableLogging();
70
95
  }
71
96
  /**
72
97
  * All logging inputs are dropped and stops sending logs to the logging library.
@@ -74,8 +99,10 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
74
99
  * If this is a child, the change only applies to this instance.
75
100
  */
76
101
  disableLogging() {
102
+ if (this.isDisposed) return;
77
103
  for (const level of Object.keys(this.logLevelContainer.status)) this.logLevelContainer.status[level] = false;
78
- if (this.childManagers.size > 0) for (const child of this.childManagers) child.disableLogging();
104
+ const aliveChildren = this.getAliveChildren();
105
+ for (const child of aliveChildren) child.disableLogging();
79
106
  }
80
107
  /**
81
108
  * Links the child log level manager to the parent.
@@ -83,12 +110,13 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
83
110
  * Parent changes will propagate to children, but child changes won't affect the parent.
84
111
  */
85
112
  onChildLoggerCreated({ parentLogLevelManager, childLogLevelManager }) {
113
+ if (this.isDisposed) return;
86
114
  if (childLogLevelManager instanceof OneWayLogLevelManager && parentLogLevelManager instanceof OneWayLogLevelManager) {
87
115
  const child = childLogLevelManager;
88
116
  const parent = parentLogLevelManager;
89
117
  child.logLevelContainer.status = { ...parent.logLevelContainer.status };
90
- child.parentManager = parent;
91
- parent.childManagers.add(child);
118
+ child.parentManager = new WeakRef(parent);
119
+ parent.childManagers.add(new WeakRef(child));
92
120
  }
93
121
  }
94
122
  /**
@@ -96,10 +124,21 @@ var OneWayLogLevelManager = class OneWayLogLevelManager {
96
124
  * The clone is independent and not linked to the original.
97
125
  */
98
126
  clone() {
127
+ if (this.isDisposed) return new OneWayLogLevelManager();
99
128
  const clone = new OneWayLogLevelManager();
100
129
  clone.logLevelContainer.status = { ...this.logLevelContainer.status };
101
130
  return clone;
102
131
  }
132
+ /**
133
+ * Implements the Disposable interface for cleanup.
134
+ * Clears all parent and child references to prevent memory leaks.
135
+ */
136
+ [Symbol.dispose]() {
137
+ if (this.isDisposed) return;
138
+ this.parentManager = null;
139
+ this.childManagers.clear();
140
+ this.isDisposed = true;
141
+ }
103
142
  };
104
143
 
105
144
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loglayer/log-level-manager-one-way",
3
3
  "description": "Log level manager for loglayer that keeps log levels synchronized between parent and children (parent changes affect children, but child changes don't affect parents).",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -32,7 +32,7 @@
32
32
  "log level manager"
33
33
  ],
34
34
  "dependencies": {
35
- "@loglayer/log-level-manager": "1.0.0"
35
+ "@loglayer/log-level-manager": "1.0.1"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "24.10.1",
@@ -40,7 +40,7 @@
40
40
  "typescript": "5.9.3",
41
41
  "vitest": "4.0.9",
42
42
  "@internal/tsconfig": "2.1.0",
43
- "loglayer": "8.0.0"
43
+ "loglayer": "8.0.2"
44
44
  },
45
45
  "bugs": "https://github.com/loglayer/loglayer/issues",
46
46
  "engines": {