@iobroker/db-base 7.2.3-alpha.8-20260709-8d8c9c5ed → 7.2.3

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.
@@ -1,4 +1,4 @@
1
- export { InMemoryFileDB, type ConnectionOptions, type DbStatus, type DbOptions, type FileDbSettings, type MetaObject, } from './lib/inMemFileDB.js';
1
+ export { InMemoryFileDB } from './lib/inMemFileDB.js';
2
2
  export { RedisHandler } from './lib/redisHandler.js';
3
3
  export { tools } from '@iobroker/js-controller-common-db';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -16,13 +16,13 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var index_exports = {};
20
- __export(index_exports, {
19
+ var esm_exports = {};
20
+ __export(esm_exports, {
21
21
  InMemoryFileDB: () => import_inMemFileDB.InMemoryFileDB,
22
22
  RedisHandler: () => import_redisHandler.RedisHandler,
23
23
  tools: () => import_js_controller_common_db.tools
24
24
  });
25
- module.exports = __toCommonJS(index_exports);
25
+ module.exports = __toCommonJS(esm_exports);
26
26
  var import_inMemFileDB = require("./lib/inMemFileDB.js");
27
27
  var import_redisHandler = require("./lib/redisHandler.js");
28
28
  var import_js_controller_common_db = require("@iobroker/js-controller-common-db");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export {\n InMemoryFileDB,\n type ConnectionOptions,\n type DbStatus,\n type DbOptions,\n type FileDbSettings,\n type MetaObject,\n} from './lib/inMemFileDB.js';\nexport { RedisHandler } from './lib/redisHandler.js';\nexport { tools } from '@iobroker/js-controller-common-db';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;AAAA,yBAOO;AACP,0BAA6B;AAC7B,qCAAsB;",
4
+ "sourcesContent": ["export { InMemoryFileDB } from './lib/inMemFileDB.js';\nexport { RedisHandler } from './lib/redisHandler.js';\nexport { tools } from '@iobroker/js-controller-common-db';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;AAAA,yBAA+B;AAC/B,0BAA6B;AAC7B,qCAAsB;",
6
6
  "names": []
7
7
  }
@@ -1,120 +1,66 @@
1
1
  /**
2
2
  * States DB in memory - Server
3
3
  *
4
- * Copyright 2013-2026 bluefox <dogafox@gmail.com>
4
+ * Copyright 2013-2024 bluefox <dogafox@gmail.com>
5
5
  *
6
6
  * MIT License
7
7
  *
8
8
  */
9
9
  import type { InternalLogger } from '@iobroker/js-controller-common-db/tools';
10
- interface BackupOptions {
11
- /** deactivates backup if true */
12
- disabled: boolean;
13
- /** minimum number of files */
14
- files: number;
15
- hours: number;
16
- /** minutes */
17
- period: number;
18
- path: string;
19
- }
20
- export type MetaObject = Record<string, string>;
21
- export type FileSize = number;
22
- /** Options describing how to connect to the database server */
23
10
  export interface ConnectionOptions {
24
- /** Password for authentication, if required */
25
11
  pass?: string;
26
- /** Name of the sentinel master to connect to */
27
12
  sentinelName?: string;
28
13
  /** array on sentinel */
29
14
  host: string | string[];
30
15
  /** array on sentinel */
31
16
  port: number | number[];
32
- /** Additional connection options passed to the database driver */
33
- options: ioBroker.ObjectsDatabaseOptions['options'];
34
- /** Options forwarded to the JSONL database backend */
35
- jsonlOptions?: ioBroker.ObjectsDatabaseOptions['jsonlOptions'];
36
- /** Redis key prefix used by the in-memory server */
37
- redisNamespace?: string;
38
- /** Enable more verbose connection logging */
17
+ options: Record<string, any>;
39
18
  enhancedLogging?: boolean;
40
- /** Disable the in-memory file cache and always read files from disk */
41
- noFileCache?: boolean;
42
- /** Whether the connection should be secured via TLS */
43
- secure?: boolean;
44
- /** Backup configuration */
45
19
  backup?: BackupOptions;
46
20
  /** relative path to the data dir */
47
21
  dataDir?: string;
48
- /** Interval in milliseconds in which the in-memory states are persisted to disk */
49
- writeFileInterval?: number;
50
22
  }
51
- type ChangeFunction<TObject> = (id: string, obj: TObject) => void;
52
- /** Status information about the database */
23
+ type ChangeFunction = (id: string, state: any) => void;
53
24
  export interface DbStatus {
54
- /** Type of the database backend (e.g. file, jsonl, redis) */
55
- type: 'file' | 'redis' | 'jsonl';
56
- /** Whether this process runs the database server */
25
+ type: string;
57
26
  server: boolean;
58
27
  }
59
- /** Options describing where the database stores its files */
28
+ interface BackupOptions {
29
+ /** deactivates backup if true */
30
+ disabled: boolean;
31
+ /** minimum number of files */
32
+ files: number;
33
+ hours: number;
34
+ /** minutes */
35
+ period: number;
36
+ path: string;
37
+ }
60
38
  export interface DbOptions {
61
- /** Name of the directory used for backups */
62
39
  backupDirName: string;
63
- /** Name of the database file */
64
40
  fileName: string;
65
41
  }
66
- /** Settings accepted by the in-memory database classes and their subclasses */
67
- export interface FileDbSettings<TObject> {
68
- /** File DB storage options (filled in by the subclass constructor before `super()`) */
69
- fileDB?: DbOptions;
70
- /** JSONL DB storage options (only set by the JSONL backend; only the file name is used) */
71
- jsonlDB?: Pick<DbOptions, 'fileName'>;
72
- /** Backup options (derived from `connection.backup` by the base constructor) */
73
- backup?: BackupOptions;
74
- /** Callback invoked when a value in the database changes */
75
- change?: ChangeFunction<TObject>;
76
- /** Callback invoked once the database server is ready */
77
- connected: (nameOfServer?: string) => void;
78
- /** Logger instance (or logger configuration) used for all database logging */
79
- logger?: InternalLogger;
80
- /** Options describing how to connect to the database server */
42
+ interface FileDbSettings {
43
+ fileDB: DbOptions;
44
+ jsonlDB: DbOptions;
45
+ backup: BackupOptions;
46
+ change?: ChangeFunction;
47
+ connected: (nameOfServer: string) => void;
48
+ logger: InternalLogger;
81
49
  connection: ConnectionOptions;
82
50
  /** unused */
83
51
  auth?: null;
84
- /** Whether the server connection should be secured via TLS */
85
- secure?: boolean;
86
- /** Port the in-memory server listens on */
87
- port?: number;
88
- /** Host the in-memory server binds to */
89
- host?: string;
52
+ secure: boolean;
53
+ /** as required by createServer TODO: if createServer is typed, add type */
54
+ certificates: any;
55
+ port: number;
56
+ host: string;
90
57
  /** logging namespace */
91
58
  namespace?: string;
92
- /** Host name used as a fallback for the logging namespace */
93
- hostname?: string;
94
- /** Default ACL applied to newly created objects */
95
- defaultNewAcl?: {
96
- object: number;
97
- state: number;
98
- file: number;
99
- owner: ioBroker.ObjectIDs.User;
100
- ownerGroup: ioBroker.ObjectIDs.Group;
101
- };
102
- /** Redis key prefix used by the in-memory server (defaults to "io") */
103
- redisNamespace?: string;
104
- /** Namespace used for the message box */
105
- namespaceMsg?: string;
106
- /** Namespace used for log messages */
107
- namespaceLog?: string;
108
- /** Namespace used for sessions */
109
- namespaceSession?: string;
110
- /** Namespace used for meta information */
111
- metaNamespace?: string;
112
- /** Redis key prefix used for object meta information (defaults to "meta") */
113
- namespaceMeta?: string;
114
59
  }
115
60
  interface Subscription {
116
61
  pattern: string;
117
62
  regex: RegExp;
63
+ options: any;
118
64
  }
119
65
  interface SubscriptionClient {
120
66
  _subscribe?: Record<string, Subscription[]>;
@@ -123,25 +69,19 @@ interface SubscriptionClient {
123
69
  * The parent of the class structure, which provides basic JSON storage
124
70
  * and general subscription and publish functionality
125
71
  */
126
- export declare class InMemoryFileDB<TObject, THandler extends SubscriptionClient = SubscriptionClient> {
127
- protected settings: FileDbSettings<TObject>;
128
- protected change: ChangeFunction<TObject> | undefined;
129
- protected dataset: Record<string, TObject | MetaObject>;
130
- protected namespace: string;
72
+ export declare class InMemoryFileDB {
73
+ private settings;
74
+ private readonly change;
75
+ protected dataset: Record<string, any>;
76
+ private readonly namespace;
131
77
  private lastSave;
132
- protected stateTimer: NodeJS.Timeout | null;
78
+ private stateTimer;
133
79
  private callbackSubscriptionClient;
134
- protected readonly dataDir: string;
80
+ private readonly dataDir;
135
81
  private readonly datasetName;
136
- protected log: InternalLogger;
137
- protected readonly backupDir: string;
138
- /**
139
- * @param settings Settings for the database, the connection and backups
140
- */
141
- constructor(settings: FileDbSettings<TObject>);
142
- /**
143
- * Open the database by loading the dataset from disk
144
- */
82
+ private log;
83
+ private readonly backupDir;
84
+ constructor(settings: FileDbSettings);
145
85
  open(): Promise<void>;
146
86
  /**
147
87
  * Loads a dataset file
@@ -149,55 +89,20 @@ export declare class InMemoryFileDB<TObject, THandler extends SubscriptionClient
149
89
  * @param datasetName Filename of the file to load
150
90
  * @returns obj read data, normally as object
151
91
  */
152
- loadDatasetFile(datasetName: string): Promise<Record<string, TObject>>;
92
+ loadDatasetFile(datasetName: string): Promise<Record<string, any>>;
153
93
  /**
154
94
  * Loads the dataset including pot. Fallback handling
155
95
  *
156
96
  * @param datasetName Filename of the file to load
157
97
  * @returns obj dataset read as object
158
98
  */
159
- loadDataset(datasetName: string): Promise<Record<string, TObject>>;
160
- /**
161
- * Normalize the backup settings and create the backup directory
162
- */
99
+ loadDataset(datasetName: string): Promise<Record<string, any>>;
163
100
  initBackupDir(): void;
164
- /**
165
- * Subscribe a client to changes matching the given pattern
166
- *
167
- * @param client The client to register the subscription for
168
- * @param type The subscription type (e.g. objects or states)
169
- * @param pattern One or more patterns to subscribe to
170
- */
171
- handleSubscribe(client: SubscriptionClient, type: string, pattern: string | string[]): void;
172
- /**
173
- * Remove a client's subscription for the given pattern
174
- *
175
- * @param client The client whose subscription should be removed
176
- * @param type The subscription type (e.g. objects or states)
177
- * @param pattern One or more patterns to unsubscribe from
178
- * @param cb Called once the subscription has been removed
179
- */
101
+ handleSubscribe(client: SubscriptionClient, type: string, pattern: string | string[], cb?: () => void): void;
102
+ handleSubscribe(client: SubscriptionClient, type: string, pattern: string | string[], options: any, cb?: () => void): void;
180
103
  handleUnsubscribe(client: SubscriptionClient, type: string, pattern: string | string[], cb?: () => void): void | Promise<void>;
181
- /**
182
- * Publish a change to a single client. Must be implemented by a subclass that handles client communication.
183
- *
184
- * @param _client The client to publish to
185
- * @param _type The change type (e.g. objects or states)
186
- * @param _id The ID of the changed object or state
187
- * @param _obj The new value of the object or state
188
- */
189
- publishToClients(_client: SubscriptionClient, _type: string, _id: string, _obj: TObject | string | null | FileSize | MetaObject): number;
190
- /**
191
- * Delete outdated backup files according to the configured retention settings
192
- *
193
- * @param baseFilename Base file name of the backups that should be pruned
194
- */
104
+ publishToClients(_client: SubscriptionClient, _type: string, _id: string, _obj: any): number;
195
105
  deleteOldBackupFiles(baseFilename: string): void;
196
- /**
197
- * Format a timestamp into a "YYYY-MM-DD_HH-MM-SS" string used for backup file names
198
- *
199
- * @param date Timestamp in milliseconds
200
- */
201
106
  getTimeStr(date: number): string;
202
107
  /**
203
108
  * Handle saving the dataset incl. backups
@@ -215,25 +120,9 @@ export declare class InMemoryFileDB<TObject, THandler extends SubscriptionClient
215
120
  * @param jsonString JSON string of the complete dataset to also be stored into a compressed backup file
216
121
  */
217
122
  saveBackup(jsonString: string): void;
218
- /**
219
- * Get the current status of the database
220
- */
221
123
  getStatus(): DbStatus;
222
- /**
223
- * Get the currently connected clients. Subclasses override this to return the real clients.
224
- */
225
- getClients(): Record<string, THandler>;
226
- /**
227
- * Publish a change to all connected clients and local subscribers
228
- *
229
- * @param type The change type (e.g. objects or states)
230
- * @param id The ID of the changed object or state
231
- * @param obj The new value of the object or state
232
- */
233
- publishAll(type: string, id: string, obj: TObject | string | null | FileSize | MetaObject): number;
234
- /**
235
- * Destructor of the class. Called when shutting down to persist state and clear timers.
236
- */
124
+ getClients(): Record<string, any>;
125
+ publishAll(type: string, id: string, obj: any): number;
237
126
  destroy(): Promise<void>;
238
127
  }
239
128
  export {};
@@ -5,7 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
8
  var __export = (target, all) => {
10
9
  for (var name in all)
11
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -37,27 +36,24 @@ var import_node_path = __toESM(require("node:path"), 1);
37
36
  var import_js_controller_common_db = require("@iobroker/js-controller-common-db");
38
37
  var import_node_zlib = require("node:zlib");
39
38
  class InMemoryFileDB {
40
- static {
41
- __name(this, "InMemoryFileDB");
42
- }
43
39
  settings;
44
40
  change;
45
- dataset = {};
41
+ dataset;
46
42
  namespace;
47
- lastSave = null;
48
- stateTimer = null;
49
- callbackSubscriptionClient = {};
43
+ lastSave;
44
+ stateTimer;
45
+ callbackSubscriptionClient;
50
46
  dataDir;
51
47
  datasetName;
52
48
  log;
53
49
  backupDir;
54
- /**
55
- * @param settings Settings for the database, the connection and backups
56
- */
57
50
  constructor(settings) {
58
- this.settings = settings;
51
+ this.settings = settings || {};
59
52
  this.change = this.settings.change;
53
+ this.dataset = {};
60
54
  this.namespace = this.settings.namespace || "";
55
+ this.lastSave = null;
56
+ this.callbackSubscriptionClient = {};
61
57
  this.settings.backup = this.settings.connection.backup || {
62
58
  disabled: false,
63
59
  // deactivates
@@ -70,36 +66,29 @@ class InMemoryFileDB {
70
66
  path: ""
71
67
  // use default path
72
68
  };
73
- const backup = this.settings.backup;
74
69
  this.dataDir = this.settings.connection.dataDir || import_js_controller_common_db.tools.getDefaultDataDir();
75
70
  if (!import_node_path.default.isAbsolute(this.dataDir)) {
76
71
  this.dataDir = import_node_path.default.normalize(import_node_path.default.join(import_js_controller_common_db.tools.getControllerDir(), this.dataDir));
77
72
  }
78
73
  this.dataDir = this.dataDir.replace(/\\/g, "/");
79
- const fileDbOptions = this.settings.fileDB;
80
- if (!fileDbOptions) {
81
- throw new Error(`${this.namespace} No fileDB storage options were provided`);
82
- }
83
- const fileName = this.settings.jsonlDB ? this.settings.jsonlDB.fileName : fileDbOptions.fileName;
74
+ const fileName = this.settings.jsonlDB ? this.settings.jsonlDB.fileName : this.settings.fileDB.fileName;
84
75
  this.datasetName = import_node_path.default.join(this.dataDir, fileName);
85
76
  const parts = import_node_path.default.dirname(this.datasetName);
86
77
  import_fs_extra.default.ensureDirSync(parts);
87
- this.backupDir = backup.path || import_node_path.default.join(this.dataDir, fileDbOptions.backupDirName);
78
+ this.stateTimer = null;
79
+ this.backupDir = this.settings.backup.path || import_node_path.default.join(this.dataDir, this.settings.fileDB.backupDirName);
88
80
  this.log = import_js_controller_common_db.tools.getLogger(this.settings.logger);
89
- if (!backup.disabled) {
81
+ if (!this.settings.backup.disabled) {
90
82
  try {
91
83
  this.initBackupDir();
92
84
  } catch (e) {
93
85
  this.log.error(`Database backups are disabled, because backup directory could not be initialized: ${e.message}`);
94
86
  this.log.error("This leads to an increased risk of data loss, please check that the configured backup directory is available and restart the controller");
95
- backup.disabled = true;
87
+ this.settings.backup.disabled = true;
96
88
  }
97
89
  }
98
90
  this.log.debug(`${this.namespace} Data File: ${this.datasetName}`);
99
91
  }
100
- /**
101
- * Open the database by loading the dataset from disk
102
- */
103
92
  async open() {
104
93
  this.dataset = await this.loadDataset(this.datasetName);
105
94
  }
@@ -162,75 +151,58 @@ class InMemoryFileDB {
162
151
  }
163
152
  return ret;
164
153
  }
165
- /**
166
- * Normalize the backup settings and create the backup directory
167
- */
168
154
  initBackupDir() {
169
- import_fs_extra.default.ensureDirSync(this.backupDir);
170
- const backup = this.settings.backup;
171
- if (!backup) {
172
- return;
173
- }
174
- backup.period = backup.period === void 0 ? 120 : parseInt(String(backup.period));
175
- if (isNaN(backup.period)) {
176
- backup.period = 120;
155
+ this.settings.backup.period = this.settings.backup.period === void 0 ? 120 : parseInt(String(this.settings.backup.period));
156
+ if (isNaN(this.settings.backup.period)) {
157
+ this.settings.backup.period = 120;
177
158
  }
178
159
  const maxTimeoutMinutes = Math.floor((2 ** 31 - 1) / 6e4);
179
- if (backup.period > maxTimeoutMinutes) {
180
- this.log.warn(`${this.namespace} Configured backup period ${backup.period} is larger than the supported maximum of ${maxTimeoutMinutes} minutes. Defaulting to 120 minutes.`);
181
- backup.period = 120;
160
+ if (this.settings.backup.period > maxTimeoutMinutes) {
161
+ this.log.warn(`${this.namespace} Configured backup period ${this.settings.backup.period} is larger than the supported maximum of ${maxTimeoutMinutes} minutes. Defaulting to 120 minutes.`);
162
+ this.settings.backup.period = 120;
182
163
  }
183
- backup.period *= 6e4;
184
- backup.files = backup.files === void 0 ? 24 : parseInt(String(backup.files));
185
- if (isNaN(backup.files)) {
186
- backup.files = 24;
164
+ this.settings.backup.period *= 6e4;
165
+ this.settings.backup.files = this.settings.backup.files === void 0 ? 24 : parseInt(String(this.settings.backup.files));
166
+ if (isNaN(this.settings.backup.files)) {
167
+ this.settings.backup.files = 24;
187
168
  }
188
- backup.hours = backup.hours === void 0 ? 48 : parseInt(String(backup.hours));
189
- if (isNaN(backup.hours)) {
190
- backup.hours = 48;
169
+ this.settings.backup.hours = this.settings.backup.hours === void 0 ? 48 : parseInt(String(this.settings.backup.hours));
170
+ if (isNaN(this.settings.backup.hours)) {
171
+ this.settings.backup.hours = 48;
191
172
  }
173
+ import_fs_extra.default.ensureDirSync(this.backupDir);
192
174
  }
193
- /**
194
- * Subscribe a client to changes matching the given pattern
195
- *
196
- * @param client The client to register the subscription for
197
- * @param type The subscription type (e.g. objects or states)
198
- * @param pattern One or more patterns to subscribe to
199
- */
200
- handleSubscribe(client, type, pattern) {
201
- client._subscribe ||= {};
202
- client._subscribe[type] ||= [];
175
+ handleSubscribe(client, type, pattern, options, cb) {
176
+ if (typeof options === "function") {
177
+ cb = options;
178
+ options = void 0;
179
+ }
180
+ client._subscribe = client._subscribe || {};
181
+ client._subscribe[type] = client._subscribe[type] || [];
203
182
  const s = client._subscribe[type];
204
183
  if (pattern instanceof Array) {
205
184
  pattern.forEach((pattern2) => {
206
185
  if (s.find((sub) => sub.pattern === pattern2)) {
207
186
  return;
208
187
  }
209
- s.push({ pattern: pattern2, regex: new RegExp(import_js_controller_common_db.tools.pattern2RegEx(pattern2)) });
188
+ s.push({ pattern: pattern2, regex: new RegExp(import_js_controller_common_db.tools.pattern2RegEx(pattern2)), options });
210
189
  });
211
190
  } else {
212
191
  if (!s.find((sub) => sub.pattern === pattern)) {
213
- s.push({ pattern, regex: new RegExp(import_js_controller_common_db.tools.pattern2RegEx(pattern)) });
192
+ s.push({ pattern, regex: new RegExp(import_js_controller_common_db.tools.pattern2RegEx(pattern)), options });
214
193
  }
215
194
  }
195
+ typeof cb === "function" && cb();
216
196
  }
217
- /**
218
- * Remove a client's subscription for the given pattern
219
- *
220
- * @param client The client whose subscription should be removed
221
- * @param type The subscription type (e.g. objects or states)
222
- * @param pattern One or more patterns to unsubscribe from
223
- * @param cb Called once the subscription has been removed
224
- */
225
197
  handleUnsubscribe(client, type, pattern, cb) {
226
198
  const s = client?._subscribe?.[type];
227
199
  if (s) {
228
- const removeEntry = /* @__PURE__ */ __name((p) => {
200
+ const removeEntry = (p) => {
229
201
  const index = s.findIndex((sub) => sub.pattern === p);
230
202
  if (index > -1) {
231
203
  s.splice(index, 1);
232
204
  }
233
- }, "removeEntry");
205
+ };
234
206
  if (pattern instanceof Array) {
235
207
  pattern.forEach((p) => {
236
208
  removeEntry(p);
@@ -241,28 +213,15 @@ class InMemoryFileDB {
241
213
  }
242
214
  return import_js_controller_common_db.tools.maybeCallback(cb);
243
215
  }
244
- /**
245
- * Publish a change to a single client. Must be implemented by a subclass that handles client communication.
246
- *
247
- * @param _client The client to publish to
248
- * @param _type The change type (e.g. objects or states)
249
- * @param _id The ID of the changed object or state
250
- * @param _obj The new value of the object or state
251
- */
252
216
  publishToClients(_client, _type, _id, _obj) {
253
217
  throw new Error("no communication handling implemented");
254
218
  }
255
- /**
256
- * Delete outdated backup files according to the configured retention settings
257
- *
258
- * @param baseFilename Base file name of the backups that should be pruned
259
- */
260
219
  deleteOldBackupFiles(baseFilename) {
261
220
  let files = import_fs_extra.default.readdirSync(this.backupDir);
262
221
  files.sort();
263
- const limit = Date.now() - (this.settings.backup?.hours ?? 48) * 36e5;
222
+ const limit = Date.now() - this.settings.backup.hours * 36e5;
264
223
  files = files.filter((f) => f.endsWith(`${baseFilename}.gz`));
265
- while (files.length > (this.settings.backup?.files ?? 24)) {
224
+ while (files.length > this.settings.backup.files) {
266
225
  const file = files.shift();
267
226
  if (!file) {
268
227
  continue;
@@ -277,11 +236,6 @@ class InMemoryFileDB {
277
236
  }
278
237
  }
279
238
  }
280
- /**
281
- * Format a timestamp into a "YYYY-MM-DD_HH-MM-SS" string used for backup file names
282
- *
283
- * @param date Timestamp in milliseconds
284
- */
285
239
  getTimeStr(date) {
286
240
  const dateObj = new Date(date);
287
241
  let text = `${dateObj.getFullYear().toString()}-`;
@@ -313,7 +267,7 @@ class InMemoryFileDB {
313
267
  async saveState() {
314
268
  try {
315
269
  const jsonString = await this.saveDataset();
316
- if (!this.settings.backup?.disabled && jsonString) {
270
+ if (!this.settings.backup.disabled && jsonString) {
317
271
  this.saveBackup(jsonString);
318
272
  }
319
273
  } finally {
@@ -378,10 +332,9 @@ class InMemoryFileDB {
378
332
  */
379
333
  saveBackup(jsonString) {
380
334
  const now = Date.now();
381
- const fileName = this.settings.fileDB?.fileName;
382
- if (fileName && this.settings.backup?.period && (!this.lastSave || now - this.lastSave > this.settings.backup.period)) {
335
+ if (this.settings.backup.period && (!this.lastSave || now - this.lastSave > this.settings.backup.period)) {
383
336
  this.lastSave = now;
384
- const backFileName = import_node_path.default.join(this.backupDir, `${this.getTimeStr(now)}_${fileName}.gz`);
337
+ const backFileName = import_node_path.default.join(this.backupDir, `${this.getTimeStr(now)}_${this.settings.fileDB.fileName}.gz`);
385
338
  try {
386
339
  if (!import_fs_extra.default.existsSync(backFileName)) {
387
340
  const output = import_fs_extra.default.createWriteStream(backFileName);
@@ -392,32 +345,19 @@ class InMemoryFileDB {
392
345
  compress.pipe(output);
393
346
  compress.write(jsonString);
394
347
  compress.end();
395
- this.deleteOldBackupFiles(fileName);
348
+ this.deleteOldBackupFiles(this.settings.fileDB.fileName);
396
349
  }
397
350
  } catch (e) {
398
351
  this.log.error(`${this.namespace} Cannot save backup ${backFileName}: ${e.message}`);
399
352
  }
400
353
  }
401
354
  }
402
- /**
403
- * Get the current status of the database
404
- */
405
355
  getStatus() {
406
356
  return { type: "file", server: true };
407
357
  }
408
- /**
409
- * Get the currently connected clients. Subclasses override this to return the real clients.
410
- */
411
358
  getClients() {
412
359
  return {};
413
360
  }
414
- /**
415
- * Publish a change to all connected clients and local subscribers
416
- *
417
- * @param type The change type (e.g. objects or states)
418
- * @param id The ID of the changed object or state
419
- * @param obj The new value of the object or state
420
- */
421
361
  publishAll(type, id, obj) {
422
362
  if (id === void 0) {
423
363
  this.log.error(`${this.namespace} Can not publish empty ID`);
@@ -440,9 +380,7 @@ class InMemoryFileDB {
440
380
  }
441
381
  return publishCount;
442
382
  }
443
- /**
444
- * Destructor of the class. Called when shutting down to persist state and clear timers.
445
- */
383
+ // Destructor of the class. Called by shutting down.
446
384
  async destroy() {
447
385
  if (this.stateTimer) {
448
386
  clearTimeout(this.stateTimer);