@iobroker/db-objects-jsonl 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc

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 (25) hide show
  1. package/build/cjs/index.js +5 -3
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/cjs/lib/objects/objectsInMemJsonlDB.d.ts +38 -7
  4. package/build/cjs/lib/objects/objectsInMemJsonlDB.js +67 -31
  5. package/build/cjs/lib/objects/objectsInMemJsonlDB.js.map +3 -3
  6. package/build/cjs/lib/objects/objectsInMemServerClass.d.ts +41 -8
  7. package/build/cjs/lib/objects/objectsInMemServerClass.js +27 -2
  8. package/build/cjs/lib/objects/objectsInMemServerClass.js.map +3 -3
  9. package/build/cjs/lib/objects/objectsInMemServerRedis.d.ts +50 -30
  10. package/build/cjs/lib/objects/objectsInMemServerRedis.js +69 -34
  11. package/build/cjs/lib/objects/objectsInMemServerRedis.js.map +4 -4
  12. package/build/esm/lib/objects/objectsInMemJsonlDB.d.ts +38 -7
  13. package/build/esm/lib/objects/objectsInMemJsonlDB.d.ts.map +1 -1
  14. package/build/esm/lib/objects/objectsInMemJsonlDB.js +67 -36
  15. package/build/esm/lib/objects/objectsInMemJsonlDB.js.map +1 -1
  16. package/build/esm/lib/objects/objectsInMemServerClass.d.ts +41 -8
  17. package/build/esm/lib/objects/objectsInMemServerClass.d.ts.map +1 -1
  18. package/build/esm/lib/objects/objectsInMemServerClass.js +25 -1
  19. package/build/esm/lib/objects/objectsInMemServerClass.js.map +1 -1
  20. package/build/esm/lib/objects/objectsInMemServerRedis.d.ts +50 -30
  21. package/build/esm/lib/objects/objectsInMemServerRedis.d.ts.map +1 -1
  22. package/build/esm/lib/objects/objectsInMemServerRedis.js +87 -68
  23. package/build/esm/lib/objects/objectsInMemServerRedis.js.map +1 -1
  24. package/build/tsconfig.build.tsbuildinfo +1 -1
  25. package/package.json +9 -9
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,18 +17,19 @@ var __copyProps = (to, from, except, desc) => {
16
17
  return to;
17
18
  };
18
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var esm_exports = {};
20
- __export(esm_exports, {
20
+ var index_exports = {};
21
+ __export(index_exports, {
21
22
  Client: () => import_db_objects_redis.Client,
22
23
  Server: () => import_objectsInMemServerClass.ObjectsInMemoryServerClass,
23
24
  getDefaultPort: () => getDefaultPort
24
25
  });
25
- module.exports = __toCommonJS(esm_exports);
26
+ module.exports = __toCommonJS(index_exports);
26
27
  var import_db_objects_redis = require("@iobroker/db-objects-redis");
27
28
  var import_objectsInMemServerClass = require("./lib/objects/objectsInMemServerClass.js");
28
29
  function getDefaultPort() {
29
30
  return 9001;
30
31
  }
32
+ __name(getDefaultPort, "getDefaultPort");
31
33
  // Annotate the CommonJS export names for ESM import in node:
32
34
  0 && (module.exports = {
33
35
  Client,
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
4
  "sourcesContent": ["export { Client } from '@iobroker/db-objects-redis';\nexport { ObjectsInMemoryServerClass as Server } from './lib/objects/objectsInMemServerClass.js';\n\n/**\n * Get the default port of the objects db\n */\nexport function getDefaultPort(): number {\n return 9001;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;AAAA,8BAAuB;AACvB,qCAAqD;AAK/C,SAAU,iBAAc;AAC1B,SAAO;AACX;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AAAA,8BAAuB;AACvB,qCAAqD;AAK/C,SAAU,iBAAc;AAC1B,SAAO;AACX;AAFgB;",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,33 @@
1
1
  /**
2
- * This class inherits InMemoryFileDB class and adds all relevant logic for objects
2
+ * Object DB in memory - Server
3
+ *
4
+ * Copyright 2013-2026 bluefox <dogafox@gmail.com>
5
+ *
6
+ * MIT License
7
+ *
8
+ */
9
+ import { ObjectsInMemoryFileDB } from '@iobroker/db-objects-file';
10
+ import type { FileDbSettings } from '@iobroker/db-base';
11
+ /**
12
+ * This class inherits InMemoryFileDB class and adds all relevant logic for objects,
3
13
  * including the available methods for use by js-controller directly
4
14
  */
5
- export class ObjectsInMemoryJsonlDB extends ObjectsInMemoryFileDB {
6
- constructor(settings: any);
7
- _db: JsonlDB<unknown>;
8
- _backupInterval: NodeJS.Timeout | undefined;
15
+ export declare class ObjectsInMemoryJsonlDB<THandler extends {
16
+ _subscribe?: Record<string, {
17
+ pattern: string;
18
+ regex: RegExp;
19
+ }[]>;
20
+ }> extends ObjectsInMemoryFileDB<THandler> {
21
+ private readonly _db;
22
+ private _backupInterval;
23
+ /**
24
+ * @param settings Settings for the objects database
25
+ */
26
+ constructor(settings: FileDbSettings<ioBroker.AnyObject | ioBroker.DesignObject>);
27
+ /**
28
+ * Open the JSONL database, migrating from the legacy file DB if necessary
29
+ */
30
+ open(): Promise<void>;
9
31
  /**
10
32
  * Checks if an existing file DB should be migrated to JSONL
11
33
  *
@@ -13,8 +35,17 @@ export class ObjectsInMemoryJsonlDB extends ObjectsInMemoryFileDB {
13
35
  * If this returns true, the jsonl DB was opened and doesn't need to be opened again.
14
36
  */
15
37
  _maybeMigrateFileDB(): Promise<boolean>;
38
+ /**
39
+ * Persist the state. Nothing to do here as the JSONL DB saves behind the scenes.
40
+ */
41
+ saveState(): Promise<void>;
42
+ /**
43
+ * Regularly called to store a compressed backup of the DB
44
+ */
16
45
  saveBackup(): Promise<void>;
46
+ /**
47
+ * Stop the backup interval, close the DB and clean up
48
+ */
49
+ destroy(): Promise<void>;
17
50
  }
18
- import { ObjectsInMemoryFileDB } from '@iobroker/db-objects-file';
19
- import { JsonlDB } from '@alcalzone/jsonl-db';
20
51
  //# sourceMappingURL=objectsInMemJsonlDB.d.ts.map
@@ -5,6 +5,7 @@ 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 });
8
9
  var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -31,11 +32,11 @@ __export(objectsInMemJsonlDB_exports, {
31
32
  ObjectsInMemoryJsonlDB: () => ObjectsInMemoryJsonlDB
32
33
  });
33
34
  module.exports = __toCommonJS(objectsInMemJsonlDB_exports);
34
- var import_db_objects_file = require("@iobroker/db-objects-file");
35
- var import_jsonl_db = require("@alcalzone/jsonl-db");
36
35
  var import_node_path = __toESM(require("node:path"), 1);
37
36
  var import_node_fs = __toESM(require("node:fs"), 1);
38
37
  var import_node_os = __toESM(require("node:os"), 1);
38
+ var import_db_objects_file = require("@iobroker/db-objects-file");
39
+ var import_jsonl_db = require("@alcalzone/jsonl-db");
39
40
  var import_js_controller_common_db = require("@iobroker/js-controller-common-db");
40
41
  function normalizeJsonlOptions(conf = {}) {
41
42
  const ret = {
@@ -61,8 +62,11 @@ function normalizeJsonlOptions(conf = {}) {
61
62
  staleMs: 2e3
62
63
  }
63
64
  };
64
- if (import_js_controller_common_db.tools.isObject(conf.autoCompress)) {
65
+ if (conf.autoCompress && typeof conf.autoCompress === "object") {
65
66
  const ac = conf.autoCompress;
67
+ if (!ret.autoCompress) {
68
+ throw new Error("Unexpected autoCompress");
69
+ }
66
70
  if (typeof ac.sizeFactor === "number" && ac.sizeFactor >= 2 && ac.sizeFactor <= 100) {
67
71
  ret.autoCompress.sizeFactor = ac.sizeFactor;
68
72
  }
@@ -70,8 +74,11 @@ function normalizeJsonlOptions(conf = {}) {
70
74
  ret.autoCompress.sizeFactorMinimumSize = ac.sizeFactorMinimumSize;
71
75
  }
72
76
  }
73
- if (import_js_controller_common_db.tools.isObject(conf.throttleFS)) {
77
+ if (conf.throttleFS && typeof conf.throttleFS === "object") {
74
78
  const thr = conf.throttleFS;
79
+ if (!ret.throttleFS) {
80
+ throw new Error("Unexpected throttle fs");
81
+ }
75
82
  if (typeof thr.intervalMs === "number" && thr.intervalMs >= 1e3 && thr.intervalMs <= 36e5) {
76
83
  ret.throttleFS.intervalMs = thr.intervalMs;
77
84
  }
@@ -81,51 +88,63 @@ function normalizeJsonlOptions(conf = {}) {
81
88
  }
82
89
  return ret;
83
90
  }
91
+ __name(normalizeJsonlOptions, "normalizeJsonlOptions");
84
92
  class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileDB {
93
+ static {
94
+ __name(this, "ObjectsInMemoryJsonlDB");
95
+ }
96
+ _db;
97
+ _backupInterval;
98
+ /**
99
+ * @param settings Settings for the objects database
100
+ */
85
101
  constructor(settings) {
86
- settings = settings || {};
87
102
  settings.fileDB = {
88
103
  fileName: "objects.json",
89
104
  backupDirName: "backup-objects"
90
105
  };
91
106
  const jsonlOptions = normalizeJsonlOptions(settings.connection.jsonlOptions);
107
+ const jsonlFileName = "objects.jsonl";
92
108
  settings.jsonlDB = {
93
- fileName: "objects.jsonl"
109
+ fileName: jsonlFileName
94
110
  };
95
111
  super(settings);
96
- this._db = new import_jsonl_db.JsonlDB(import_node_path.default.join(this.dataDir, settings.jsonlDB.fileName), jsonlOptions);
112
+ this._db = new import_jsonl_db.JsonlDB(import_node_path.default.join(this.dataDir, jsonlFileName), jsonlOptions);
97
113
  }
114
+ /**
115
+ * Open the JSONL database, migrating from the legacy file DB if necessary
116
+ */
98
117
  async open() {
99
118
  if (!await this._maybeMigrateFileDB()) {
100
119
  await this._db.open();
101
120
  }
102
121
  this.dataset = new Proxy(this._db, {
103
122
  /**
104
- * @param target
105
- * @param prop
123
+ * @param target The proxied JsonlDB instance
124
+ * @param prop The property key being read
106
125
  */
107
126
  get(target, prop) {
108
127
  return target.get(prop);
109
128
  },
110
129
  /**
111
- * @param target
112
- * @param prop
130
+ * @param target The proxied JsonlDB instance
131
+ * @param prop The property key being checked
113
132
  */
114
133
  has(target, prop) {
115
134
  return target.has(prop);
116
135
  },
117
136
  /**
118
- * @param target
119
- * @param prop
120
- * @param value
137
+ * @param target The proxied JsonlDB instance
138
+ * @param prop The property key being written
139
+ * @param value The value to store
121
140
  */
122
141
  set(target, prop, value) {
123
142
  target.set(prop, value);
124
143
  return true;
125
144
  },
126
145
  /**
127
- * @param target
128
- * @param prop
146
+ * @param target The proxied JsonlDB instance
147
+ * @param prop The property key being deleted
129
148
  */
130
149
  deleteProperty(target, prop) {
131
150
  return target.delete(prop);
@@ -134,8 +153,8 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
134
153
  return [...target.keys()];
135
154
  },
136
155
  /**
137
- * @param target
138
- * @param prop
156
+ * @param target The proxied JsonlDB instance
157
+ * @param prop The property key to describe
139
158
  */
140
159
  getOwnPropertyDescriptor(target, prop) {
141
160
  if (!target.has(prop)) {
@@ -149,9 +168,9 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
149
168
  };
150
169
  }
151
170
  });
152
- if (this.settings.backup && this.settings.backup.period && !this.settings.backup.disabled) {
171
+ if (this.settings.backup?.period && !this.settings.backup.disabled) {
153
172
  this._backupInterval = setInterval(() => {
154
- this.saveBackup();
173
+ this.saveBackup().catch((e) => this.log.error(`${this.namespace} Cannot save backup: ${e.message}`));
155
174
  }, this.settings.backup.period);
156
175
  }
157
176
  }
@@ -162,30 +181,35 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
162
181
  * If this returns true, the jsonl DB was opened and doesn't need to be opened again.
163
182
  */
164
183
  async _maybeMigrateFileDB() {
165
- const jsonlFileName = import_node_path.default.join(this.dataDir, this.settings.jsonlDB.fileName);
166
- const jsonFileName = import_node_path.default.join(this.dataDir, this.settings.fileDB.fileName);
167
- const bakFileName = import_node_path.default.join(this.dataDir, `${this.settings.fileDB.fileName}.bak`);
184
+ const jsonlName = this.settings.jsonlDB?.fileName;
185
+ const jsonName = this.settings.fileDB?.fileName;
186
+ if (!jsonlName || !jsonName) {
187
+ return false;
188
+ }
189
+ const jsonlFileName = import_node_path.default.join(this.dataDir, jsonlName);
190
+ const jsonFileName = import_node_path.default.join(this.dataDir, jsonName);
191
+ const bakFileName = import_node_path.default.join(this.dataDir, `${jsonName}.bak`);
168
192
  let jsonlTimeStamp = 0;
169
193
  let jsonTimeStamp = 0;
170
194
  let bakTimeStamp = 0;
171
195
  try {
172
196
  const stat = import_node_fs.default.statSync(jsonlFileName);
173
197
  if (stat.isFile()) {
174
- jsonlTimeStamp = stat.mtime;
198
+ jsonlTimeStamp = stat.mtimeMs;
175
199
  }
176
200
  } catch {
177
201
  }
178
202
  try {
179
203
  const stat = import_node_fs.default.statSync(jsonFileName);
180
204
  if (stat.isFile()) {
181
- jsonTimeStamp = stat.mtime;
205
+ jsonTimeStamp = stat.mtimeMs;
182
206
  }
183
207
  } catch {
184
208
  }
185
209
  try {
186
210
  const stat = import_node_fs.default.statSync(bakFileName);
187
211
  if (stat.isFile()) {
188
- bakTimeStamp = stat.mtime;
212
+ bakTimeStamp = stat.mtimeMs;
189
213
  }
190
214
  } catch {
191
215
  }
@@ -199,7 +223,7 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
199
223
  }
200
224
  await this._db.open();
201
225
  this._db.clear();
202
- await this._db.importJson(importFilename);
226
+ this._db.importJSON(JSON.parse(import_node_fs.default.readFileSync(importFilename, "utf8")));
203
227
  if (import_node_fs.default.existsSync(jsonFileName)) {
204
228
  try {
205
229
  import_node_fs.default.renameSync(jsonFileName, `${jsonFileName}.migrated`);
@@ -214,13 +238,22 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
214
238
  }
215
239
  return true;
216
240
  }
241
+ /**
242
+ * Persist the state. Nothing to do here as the JSONL DB saves behind the scenes.
243
+ */
217
244
  async saveState() {
218
245
  }
219
- // Is regularly called and stores a compressed backup of the DB
246
+ /**
247
+ * Regularly called to store a compressed backup of the DB
248
+ */
220
249
  async saveBackup() {
250
+ const jsonlFileName = this.settings.jsonlDB?.fileName;
251
+ if (!jsonlFileName) {
252
+ return;
253
+ }
221
254
  const now = Date.now();
222
- const tmpBackupFileName = import_node_path.default.join(import_node_os.default.tmpdir(), `${this.getTimeStr(now)}_${this.settings.jsonlDB.fileName}`);
223
- const backupFileName = import_node_path.default.join(this.backupDir, `${this.getTimeStr(now)}_${this.settings.jsonlDB.fileName}.gz`);
255
+ const tmpBackupFileName = import_node_path.default.join(import_node_os.default.tmpdir(), `${this.getTimeStr(now)}_${jsonlFileName}`);
256
+ const backupFileName = import_node_path.default.join(this.backupDir, `${this.getTimeStr(now)}_${jsonlFileName}.gz`);
224
257
  if (!this._db.isOpen) {
225
258
  this.log.warn(`${this.namespace} Cannot save backup ${backupFileName}: DB is closed`);
226
259
  return;
@@ -231,11 +264,14 @@ class ObjectsInMemoryJsonlDB extends import_db_objects_file.ObjectsInMemoryFileD
231
264
  }
232
265
  await this._db.dump(tmpBackupFileName);
233
266
  await import_js_controller_common_db.tools.compressFileGZip(tmpBackupFileName, backupFileName, { deleteInput: true });
234
- this.deleteOldBackupFiles(this.settings.jsonlDB.fileName);
267
+ this.deleteOldBackupFiles(jsonlFileName);
235
268
  } catch (e) {
236
269
  this.log.error(`${this.namespace} Cannot save backup ${backupFileName}: ${e.message}`);
237
270
  }
238
271
  }
272
+ /**
273
+ * Stop the backup interval, close the DB and clean up
274
+ */
239
275
  async destroy() {
240
276
  await super.destroy();
241
277
  if (this._backupInterval) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/lib/objects/objectsInMemJsonlDB.js"],
4
- "sourcesContent": ["/**\n * Object DB in memory - Server\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport { ObjectsInMemoryFileDB } from '@iobroker/db-objects-file';\nimport { JsonlDB } from '@alcalzone/jsonl-db';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport { tools } from '@iobroker/js-controller-common-db';\n\n/**\n * Normalizes options for the JsonlDB\n *\n * @param conf The jsonlOptions options from iobroker.json\n * @returns\n */\nfunction normalizeJsonlOptions(conf = {}) {\n const ret = {\n autoCompress: {\n // Compress when the number of uncompressed entries has grown a lot\n sizeFactor: 2,\n sizeFactorMinimumSize: 25000,\n // Compress at least daily to avoid a huge file when DBs have few objects\n // but big objects are updated regularly (e.g. the repositories)\n intervalMs: 1000 * 60 * 60 * 23,\n },\n ignoreReadErrors: true,\n throttleFS: {\n intervalMs: 60000,\n maxBufferedCommands: 1000,\n },\n lockfile: {\n // 5 retries starting at 250ms add up to just above 2s,\n // so the DB has 3 more seconds to load all data if it wants to stay within the 5s connectionTimeout\n retries: 5,\n retryMinTimeoutMs: 250,\n // This makes sure the DB stays locked for maximum 2s even if the process crashes\n staleMs: 2000,\n },\n };\n\n // Be really careful what we allow here. Incorrect settings may cause problems in production.\n if (tools.isObject(conf.autoCompress)) {\n const ac = conf.autoCompress;\n // Letting the DB grow more than 100x is risky\n if (typeof ac.sizeFactor === 'number' && ac.sizeFactor >= 2 && ac.sizeFactor <= 100) {\n ret.autoCompress.sizeFactor = ac.sizeFactor;\n }\n // Also we should definitely compress once the DB has reached 100k lines or it might grow too big\n if (\n typeof ac.sizeFactorMinimumSize === 'number' &&\n ac.sizeFactorMinimumSize >= 0 &&\n ac.sizeFactorMinimumSize <= 100000\n ) {\n ret.autoCompress.sizeFactorMinimumSize = ac.sizeFactorMinimumSize;\n }\n }\n if (tools.isObject(conf.throttleFS)) {\n const thr = conf.throttleFS;\n // Don't write more often than every second and write at least once every hour\n if (typeof thr.intervalMs === 'number' && thr.intervalMs >= 1000 && thr.intervalMs <= 3600000) {\n ret.throttleFS.intervalMs = thr.intervalMs;\n }\n // Don't keep too much in memory - 100k changes are more than enough\n if (\n typeof thr.maxBufferedCommands === 'number' &&\n thr.maxBufferedCommands >= 0 &&\n thr.maxBufferedCommands <= 100000\n ) {\n ret.throttleFS.maxBufferedCommands = thr.maxBufferedCommands;\n }\n }\n\n return ret;\n}\n\n/**\n * This class inherits InMemoryFileDB class and adds all relevant logic for objects\n * including the available methods for use by js-controller directly\n */\nexport class ObjectsInMemoryJsonlDB extends ObjectsInMemoryFileDB {\n constructor(settings) {\n settings = settings || {};\n settings.fileDB = {\n fileName: 'objects.json',\n backupDirName: 'backup-objects',\n };\n\n const jsonlOptions = normalizeJsonlOptions(settings.connection.jsonlOptions);\n settings.jsonlDB = {\n fileName: 'objects.jsonl',\n };\n super(settings);\n\n this._db = new JsonlDB(path.join(this.dataDir, settings.jsonlDB.fileName), jsonlOptions);\n }\n\n async open() {\n if (!(await this._maybeMigrateFileDB())) {\n await this._db.open();\n }\n\n // Create an object-like wrapper around the internal Map\n this.dataset = new Proxy(this._db, {\n /**\n * @param target\n * @param prop\n */\n get(target, prop) {\n return target.get(prop);\n },\n /**\n * @param target\n * @param prop\n */\n has(target, prop) {\n return target.has(prop);\n },\n /**\n * @param target\n * @param prop\n * @param value\n */\n set(target, prop, value) {\n target.set(prop, value);\n return true;\n },\n /**\n * @param target\n * @param prop\n */\n deleteProperty(target, prop) {\n return target.delete(prop);\n },\n ownKeys(target) {\n return [...target.keys()];\n },\n /**\n * @param target\n * @param prop\n */\n getOwnPropertyDescriptor(target, prop) {\n if (!target.has(prop)) {\n return undefined;\n }\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.get(prop),\n };\n },\n });\n\n if (this.settings.backup && this.settings.backup.period && !this.settings.backup.disabled) {\n this._backupInterval = setInterval(() => {\n this.saveBackup();\n }, this.settings.backup.period);\n }\n }\n\n /**\n * Checks if an existing file DB should be migrated to JSONL\n *\n * @returns true if the file DB was migrated. false if not.\n * If this returns true, the jsonl DB was opened and doesn't need to be opened again.\n */\n async _maybeMigrateFileDB() {\n const jsonlFileName = path.join(this.dataDir, this.settings.jsonlDB.fileName);\n const jsonFileName = path.join(this.dataDir, this.settings.fileDB.fileName);\n const bakFileName = path.join(this.dataDir, `${this.settings.fileDB.fileName}.bak`);\n\n // Check the timestamps of each file, defaulting to 0 if they don't exist\n let jsonlTimeStamp = 0;\n let jsonTimeStamp = 0;\n let bakTimeStamp = 0;\n try {\n const stat = fs.statSync(jsonlFileName);\n if (stat.isFile()) {\n jsonlTimeStamp = stat.mtime;\n }\n } catch {\n // ignore\n }\n try {\n const stat = fs.statSync(jsonFileName);\n if (stat.isFile()) {\n jsonTimeStamp = stat.mtime;\n }\n } catch {\n // ignore\n }\n try {\n const stat = fs.statSync(bakFileName);\n if (stat.isFile()) {\n bakTimeStamp = stat.mtime;\n }\n } catch {\n // ignore\n }\n\n // Figure out which file needs to be imported\n let importFilename;\n if (jsonTimeStamp > 0 && jsonTimeStamp >= bakTimeStamp && jsonTimeStamp >= jsonlTimeStamp) {\n importFilename = jsonFileName;\n } else if (bakTimeStamp > 0 && bakTimeStamp >= jsonTimeStamp && bakTimeStamp >= jsonlTimeStamp) {\n importFilename = bakFileName;\n } else {\n // None of the File DB files are newer than the JSONL file\n // There is nothing to restore, we're done\n return false;\n }\n\n await this._db.open();\n this._db.clear();\n await this._db.importJson(importFilename);\n\n // And rename the existing files to avoid redoing the work next time\n if (fs.existsSync(jsonFileName)) {\n try {\n fs.renameSync(jsonFileName, `${jsonFileName}.migrated`);\n } catch {\n // ignore\n }\n }\n if (fs.existsSync(bakFileName)) {\n try {\n fs.renameSync(bakFileName, `${bakFileName}.migrated`);\n } catch {\n // ignore\n }\n }\n\n // Signal to the caller that the DB is already open\n return true;\n }\n\n async saveState() {\n // Nothing to do, the DB saves behind the scenes\n }\n\n // Is regularly called and stores a compressed backup of the DB\n async saveBackup() {\n const now = Date.now();\n const tmpBackupFileName = path.join(os.tmpdir(), `${this.getTimeStr(now)}_${this.settings.jsonlDB.fileName}`);\n const backupFileName = path.join(\n this.backupDir,\n `${this.getTimeStr(now)}_${this.settings.jsonlDB.fileName}.gz`,\n );\n\n if (!this._db.isOpen) {\n this.log.warn(`${this.namespace} Cannot save backup ${backupFileName}: DB is closed`);\n return;\n }\n\n try {\n if (fs.existsSync(backupFileName)) {\n return;\n }\n\n // Create a DB dump\n await this._db.dump(tmpBackupFileName);\n // and zip it\n await tools.compressFileGZip(tmpBackupFileName, backupFileName, { deleteInput: true });\n // figure out if older files need to be deleted\n this.deleteOldBackupFiles(this.settings.jsonlDB.fileName);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot save backup ${backupFileName}: ${e.message}`);\n }\n }\n\n async destroy() {\n await super.destroy();\n\n if (this._backupInterval) {\n clearInterval(this._backupInterval);\n }\n if (this._db) {\n await this._db.close();\n }\n }\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../../../src/lib/objects/objectsInMemJsonlDB.ts"],
4
+ "sourcesContent": ["/**\n * Object DB in memory - Server\n *\n * Copyright 2013-2026 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n/// <reference types=\"@iobroker/types-dev\" />\n\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport os from 'node:os';\n\nimport { ObjectsInMemoryFileDB } from '@iobroker/db-objects-file';\nimport type { FileDbSettings } from '@iobroker/db-base';\nimport { JsonlDB, type JsonlDBOptions } from '@alcalzone/jsonl-db';\nimport { tools } from '@iobroker/js-controller-common-db';\n\n/**\n * Normalizes options for the JsonlDB\n *\n * @param conf The jsonlOptions options from iobroker.json\n * @returns the normalized and validated JsonlDB options\n */\nfunction normalizeJsonlOptions(\n conf: Partial<JsonlDBOptions<ioBroker.AnyObject | ioBroker.DesignObject>> = {},\n): JsonlDBOptions<ioBroker.AnyObject | ioBroker.DesignObject> {\n const ret: JsonlDBOptions<ioBroker.AnyObject | ioBroker.DesignObject> = {\n autoCompress: {\n // Compress when the number of uncompressed entries has grown a lot\n sizeFactor: 2,\n sizeFactorMinimumSize: 25000,\n // Compress at least daily to avoid a huge file when DBs have few objects\n // but big objects are updated regularly (e.g. the repositories)\n intervalMs: 1000 * 60 * 60 * 23,\n },\n ignoreReadErrors: true,\n throttleFS: {\n intervalMs: 60000,\n maxBufferedCommands: 1000,\n },\n lockfile: {\n // 5 retries starting at 250ms add up to just above 2s,\n // so the DB has 3 more seconds to load all data if it wants to stay within the 5s connectionTimeout\n retries: 5,\n retryMinTimeoutMs: 250,\n // This makes sure the DB stays locked for maximum 2s even if the process crashes\n staleMs: 2000,\n },\n };\n\n // Be really careful what we allow here. Incorrect settings may cause problems in production.\n if (conf.autoCompress && typeof conf.autoCompress === 'object') {\n const ac = conf.autoCompress;\n if (!ret.autoCompress) {\n throw new Error('Unexpected autoCompress');\n } // Letting the DB grow more than 100x is risky\n if (typeof ac.sizeFactor === 'number' && ac.sizeFactor >= 2 && ac.sizeFactor <= 100) {\n ret.autoCompress.sizeFactor = ac.sizeFactor;\n }\n // Also we should definitely compress once the DB has reached 100k lines, or it might grow too big\n if (\n typeof ac.sizeFactorMinimumSize === 'number' &&\n ac.sizeFactorMinimumSize >= 0 &&\n ac.sizeFactorMinimumSize <= 100000\n ) {\n ret.autoCompress.sizeFactorMinimumSize = ac.sizeFactorMinimumSize;\n }\n }\n if (conf.throttleFS && typeof conf.throttleFS === 'object') {\n const thr = conf.throttleFS;\n if (!ret.throttleFS) {\n throw new Error('Unexpected throttle fs');\n }\n // Don't write more often than every second and write at least once every hour\n if (typeof thr.intervalMs === 'number' && thr.intervalMs >= 1000 && thr.intervalMs <= 3600000) {\n ret.throttleFS.intervalMs = thr.intervalMs;\n }\n // Don't keep too much in memory - 100k changes are more than enough\n if (\n typeof thr.maxBufferedCommands === 'number' &&\n thr.maxBufferedCommands >= 0 &&\n thr.maxBufferedCommands <= 100000\n ) {\n ret.throttleFS.maxBufferedCommands = thr.maxBufferedCommands;\n }\n }\n\n return ret;\n}\n\n/**\n * This class inherits InMemoryFileDB class and adds all relevant logic for objects,\n * including the available methods for use by js-controller directly\n */\nexport class ObjectsInMemoryJsonlDB<\n THandler extends {\n _subscribe?: Record<\n string,\n {\n pattern: string;\n regex: RegExp;\n }[]\n >;\n },\n> extends ObjectsInMemoryFileDB<THandler> {\n private readonly _db: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>;\n private _backupInterval: NodeJS.Timeout | undefined;\n\n /**\n * @param settings Settings for the objects database\n */\n constructor(settings: FileDbSettings<ioBroker.AnyObject | ioBroker.DesignObject>) {\n settings.fileDB = {\n fileName: 'objects.json',\n backupDirName: 'backup-objects',\n };\n\n const jsonlOptions = normalizeJsonlOptions(settings.connection.jsonlOptions);\n const jsonlFileName = 'objects.jsonl';\n settings.jsonlDB = {\n fileName: jsonlFileName,\n };\n super(settings);\n\n this._db = new JsonlDB(path.join(this.dataDir, jsonlFileName), jsonlOptions);\n }\n\n /**\n * Open the JSONL database, migrating from the legacy file DB if necessary\n */\n async open(): Promise<void> {\n if (!(await this._maybeMigrateFileDB())) {\n await this._db.open();\n }\n\n // Create an object-like wrapper around the internal Map\n this.dataset = new Proxy(this._db, {\n /**\n * @param target The proxied JsonlDB instance\n * @param prop The property key being read\n */\n get(target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>, prop: string) {\n return target.get(prop);\n },\n /**\n * @param target The proxied JsonlDB instance\n * @param prop The property key being checked\n */\n has(target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>, prop: string) {\n return target.has(prop);\n },\n /**\n * @param target The proxied JsonlDB instance\n * @param prop The property key being written\n * @param value The value to store\n */\n set(\n target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>,\n prop: string,\n value: ioBroker.AnyObject | ioBroker.DesignObject,\n ) {\n target.set(prop, value);\n return true;\n },\n /**\n * @param target The proxied JsonlDB instance\n * @param prop The property key being deleted\n */\n deleteProperty(target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>, prop: string) {\n return target.delete(prop);\n },\n ownKeys(target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>) {\n return [...target.keys()];\n },\n /**\n * @param target The proxied JsonlDB instance\n * @param prop The property key to describe\n */\n getOwnPropertyDescriptor(target: JsonlDB<ioBroker.AnyObject | ioBroker.DesignObject>, prop: string) {\n if (!target.has(prop)) {\n return undefined;\n }\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: target.get(prop),\n };\n },\n }) as unknown as Record<string, ioBroker.AnyObject | ioBroker.DesignObject>;\n\n if (this.settings.backup?.period && !this.settings.backup.disabled) {\n this._backupInterval = setInterval(() => {\n this.saveBackup().catch(e => this.log.error(`${this.namespace} Cannot save backup: ${e.message}`));\n }, this.settings.backup.period);\n }\n }\n\n /**\n * Checks if an existing file DB should be migrated to JSONL\n *\n * @returns true if the file DB was migrated. false if not.\n * If this returns true, the jsonl DB was opened and doesn't need to be opened again.\n */\n async _maybeMigrateFileDB(): Promise<boolean> {\n const jsonlName = this.settings.jsonlDB?.fileName;\n const jsonName = this.settings.fileDB?.fileName;\n if (!jsonlName || !jsonName) {\n return false;\n }\n const jsonlFileName = path.join(this.dataDir, jsonlName);\n const jsonFileName = path.join(this.dataDir, jsonName);\n const bakFileName = path.join(this.dataDir, `${jsonName}.bak`);\n\n // Check the timestamps of each file, defaulting to 0 if they don't exist\n let jsonlTimeStamp = 0;\n let jsonTimeStamp = 0;\n let bakTimeStamp = 0;\n try {\n const stat = fs.statSync(jsonlFileName);\n if (stat.isFile()) {\n jsonlTimeStamp = stat.mtimeMs;\n }\n } catch {\n // ignore\n }\n try {\n const stat = fs.statSync(jsonFileName);\n if (stat.isFile()) {\n jsonTimeStamp = stat.mtimeMs;\n }\n } catch {\n // ignore\n }\n try {\n const stat = fs.statSync(bakFileName);\n if (stat.isFile()) {\n bakTimeStamp = stat.mtimeMs;\n }\n } catch {\n // ignore\n }\n\n // Figure out which file needs to be imported\n let importFilename: string;\n if (jsonTimeStamp > 0 && jsonTimeStamp >= bakTimeStamp && jsonTimeStamp >= jsonlTimeStamp) {\n importFilename = jsonFileName;\n } else if (bakTimeStamp > 0 && bakTimeStamp >= jsonTimeStamp && bakTimeStamp >= jsonlTimeStamp) {\n importFilename = bakFileName;\n } else {\n // None of the File DB files are newer than the JSONL file\n // There is nothing to restore, we're done\n return false;\n }\n\n await this._db.open();\n this._db.clear();\n this._db.importJSON(JSON.parse(fs.readFileSync(importFilename, 'utf8')));\n\n // And rename the existing files to avoid redoing the work next time\n if (fs.existsSync(jsonFileName)) {\n try {\n fs.renameSync(jsonFileName, `${jsonFileName}.migrated`);\n } catch {\n // ignore\n }\n }\n if (fs.existsSync(bakFileName)) {\n try {\n fs.renameSync(bakFileName, `${bakFileName}.migrated`);\n } catch {\n // ignore\n }\n }\n\n // Signal to the caller that the DB is already open\n return true;\n }\n\n /**\n * Persist the state. Nothing to do here as the JSONL DB saves behind the scenes.\n */\n async saveState(): Promise<void> {\n // Nothing to do, the DB saves behind the scenes\n }\n\n /**\n * Regularly called to store a compressed backup of the DB\n */\n async saveBackup(): Promise<void> {\n const jsonlFileName = this.settings.jsonlDB?.fileName;\n if (!jsonlFileName) {\n return;\n }\n const now = Date.now();\n const tmpBackupFileName = path.join(os.tmpdir(), `${this.getTimeStr(now)}_${jsonlFileName}`);\n const backupFileName = path.join(this.backupDir, `${this.getTimeStr(now)}_${jsonlFileName}.gz`);\n\n if (!this._db.isOpen) {\n this.log.warn(`${this.namespace} Cannot save backup ${backupFileName}: DB is closed`);\n return;\n }\n\n try {\n if (fs.existsSync(backupFileName)) {\n return;\n }\n\n // Create a DB dump\n await this._db.dump(tmpBackupFileName);\n // and zip it\n await tools.compressFileGZip(tmpBackupFileName, backupFileName, { deleteInput: true });\n // figure out if older files need to be deleted\n this.deleteOldBackupFiles(jsonlFileName);\n } catch (e) {\n this.log.error(`${this.namespace} Cannot save backup ${backupFileName}: ${e.message}`);\n }\n }\n\n /**\n * Stop the backup interval, close the DB and clean up\n */\n async destroy(): Promise<void> {\n await super.destroy();\n\n if (this._backupInterval) {\n clearInterval(this._backupInterval);\n }\n if (this._db) {\n await this._db.close();\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fs", "os"]
7
7
  }
@@ -1,12 +1,45 @@
1
- export class ObjectsInMemoryServerClass extends ObjectsInRedisClient {
2
- constructor(settings: any);
3
- objectsServer: ObjectsInMemoryServer;
4
- syncFileDirectory(limitId: any): {
1
+ /**
2
+ * States DB in memory - Server with Redis protocol
3
+ *
4
+ * Copyright 2013-2026 bluefox <dogafox@gmail.com>
5
+ *
6
+ * MIT License
7
+ *
8
+ */
9
+ import { Client as ObjectsInRedisClient, type ObjectsSettings } from '@iobroker/db-objects-redis';
10
+ import { type DbStatus } from '@iobroker/db-base';
11
+ /**
12
+ * Objects database client that also starts an in-memory server speaking the Redis protocol
13
+ */
14
+ export declare class ObjectsInMemoryServerClass extends ObjectsInRedisClient {
15
+ private readonly objectsServer;
16
+ /**
17
+ * @param settings Settings for the objects client and the in-memory server
18
+ */
19
+ constructor(settings: ObjectsSettings);
20
+ /**
21
+ * Destroy the client first and the in-memory server afterwards
22
+ */
23
+ destroy(): Promise<void>;
24
+ /**
25
+ * Get the status as reported by the in-memory server
26
+ */
27
+ getStatus(): DbStatus;
28
+ /**
29
+ * Synchronize the file directory of the in-memory server
30
+ *
31
+ * @param limitId Optional object ID to limit the synchronization to
32
+ */
33
+ syncFileDirectory(limitId?: string): {
5
34
  numberSuccess: number;
6
- notifications: any[];
35
+ notifications: string[];
7
36
  };
8
- dirExists(id: any, name: any): boolean;
37
+ /**
38
+ * Check whether a directory exists in the in-memory server's file storage
39
+ *
40
+ * @param id The object ID owning the files
41
+ * @param name The directory path to check
42
+ */
43
+ dirExists(id: string, name: string): boolean;
9
44
  }
10
- import { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';
11
- import { ObjectsInMemoryServer } from './objectsInMemServerRedis.js';
12
45
  //# sourceMappingURL=objectsInMemServerClass.d.ts.map
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -24,6 +25,13 @@ module.exports = __toCommonJS(objectsInMemServerClass_exports);
24
25
  var import_db_objects_redis = require("@iobroker/db-objects-redis");
25
26
  var import_objectsInMemServerRedis = require("./objectsInMemServerRedis.js");
26
27
  class ObjectsInMemoryServerClass extends import_db_objects_redis.Client {
28
+ static {
29
+ __name(this, "ObjectsInMemoryServerClass");
30
+ }
31
+ objectsServer;
32
+ /**
33
+ * @param settings Settings for the objects client and the in-memory server
34
+ */
27
35
  constructor(settings) {
28
36
  settings.autoConnect = false;
29
37
  super(settings);
@@ -32,22 +40,39 @@ class ObjectsInMemoryServerClass extends import_db_objects_redis.Client {
32
40
  connection: settings.connection,
33
41
  logger: settings.logger,
34
42
  hostname: settings.hostname,
35
- connected: () => {
43
+ connected: /* @__PURE__ */ __name(() => {
36
44
  this.connectDb();
37
- }
45
+ }, "connected")
38
46
  };
39
47
  this.objectsServer = new import_objectsInMemServerRedis.ObjectsInMemoryServer(serverSettings);
40
48
  }
49
+ /**
50
+ * Destroy the client first and the in-memory server afterwards
51
+ */
41
52
  async destroy() {
42
53
  await super.destroy();
43
54
  await this.objectsServer.destroy();
44
55
  }
56
+ /**
57
+ * Get the status as reported by the in-memory server
58
+ */
45
59
  getStatus() {
46
60
  return this.objectsServer.getStatus();
47
61
  }
62
+ /**
63
+ * Synchronize the file directory of the in-memory server
64
+ *
65
+ * @param limitId Optional object ID to limit the synchronization to
66
+ */
48
67
  syncFileDirectory(limitId) {
49
68
  return this.objectsServer.syncFileDirectory(limitId);
50
69
  }
70
+ /**
71
+ * Check whether a directory exists in the in-memory server's file storage
72
+ *
73
+ * @param id The object ID owning the files
74
+ * @param name The directory path to check
75
+ */
51
76
  dirExists(id, name) {
52
77
  return this.objectsServer.dirExists(id, name);
53
78
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../../src/lib/objects/objectsInMemServerClass.js"],
4
- "sourcesContent": ["/**\n * States DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport { Client as ObjectsInRedisClient } from '@iobroker/db-objects-redis';\nimport { ObjectsInMemoryServer } from './objectsInMemServerRedis.js';\n\nexport class ObjectsInMemoryServerClass extends ObjectsInRedisClient {\n constructor(settings) {\n settings.autoConnect = false; // delay Client connection to when we need it\n super(settings);\n\n const serverSettings = {\n namespace: settings.namespace ? `${settings.namespace}-Server` : 'Server',\n connection: settings.connection,\n logger: settings.logger,\n hostname: settings.hostname,\n connected: () => {\n this.connectDb(); // now that server is connected also connect client\n },\n };\n this.objectsServer = new ObjectsInMemoryServer(serverSettings);\n }\n\n async destroy() {\n await super.destroy(); // destroy client first\n await this.objectsServer.destroy(); // server afterwards too\n }\n\n getStatus() {\n return this.objectsServer.getStatus(); // return Status as Server\n }\n\n syncFileDirectory(limitId) {\n return this.objectsServer.syncFileDirectory(limitId);\n }\n\n dirExists(id, name) {\n return this.objectsServer.dirExists(id, name);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AASA,8BAA+C;AAC/C,qCAAsC;AAEhC,MAAO,mCAAmC,wBAAAA,OAAoB;EAChE,YAAY,UAAQ;AAChB,aAAS,cAAc;AACvB,UAAM,QAAQ;AAEd,UAAM,iBAAiB;MACnB,WAAW,SAAS,YAAY,GAAG,SAAS,SAAS,YAAY;MACjE,YAAY,SAAS;MACrB,QAAQ,SAAS;MACjB,UAAU,SAAS;MACnB,WAAW,MAAK;AACZ,aAAK,UAAS;MAClB;;AAEJ,SAAK,gBAAgB,IAAI,qDAAsB,cAAc;EACjE;EAEA,MAAM,UAAO;AACT,UAAM,MAAM,QAAO;AACnB,UAAM,KAAK,cAAc,QAAO;EACpC;EAEA,YAAS;AACL,WAAO,KAAK,cAAc,UAAS;EACvC;EAEA,kBAAkB,SAAO;AACrB,WAAO,KAAK,cAAc,kBAAkB,OAAO;EACvD;EAEA,UAAU,IAAI,MAAI;AACd,WAAO,KAAK,cAAc,UAAU,IAAI,IAAI;EAChD;;",
3
+ "sources": ["../../../../src/lib/objects/objectsInMemServerClass.ts"],
4
+ "sourcesContent": ["/**\n * States DB in memory - Server with Redis protocol\n *\n * Copyright 2013-2026 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport { Client as ObjectsInRedisClient, type ObjectsSettings } from '@iobroker/db-objects-redis';\nimport { ObjectsInMemoryServer } from './objectsInMemServerRedis.js';\nimport { type DbStatus } from '@iobroker/db-base';\n\n/**\n * Objects database client that also starts an in-memory server speaking the Redis protocol\n */\nexport class ObjectsInMemoryServerClass extends ObjectsInRedisClient {\n private readonly objectsServer: ObjectsInMemoryServer;\n\n /**\n * @param settings Settings for the objects client and the in-memory server\n */\n constructor(settings: ObjectsSettings) {\n settings.autoConnect = false; // delay Client connection to when we need it\n super(settings);\n\n const serverSettings = {\n namespace: settings.namespace ? `${settings.namespace}-Server` : 'Server',\n connection: settings.connection,\n logger: settings.logger,\n hostname: settings.hostname,\n connected: () => {\n this.connectDb(); // now that server is connected also connect client\n },\n };\n this.objectsServer = new ObjectsInMemoryServer(serverSettings);\n }\n\n /**\n * Destroy the client first and the in-memory server afterwards\n */\n async destroy(): Promise<void> {\n await super.destroy(); // destroy client first\n await this.objectsServer.destroy(); // server afterwards too\n }\n\n /**\n * Get the status as reported by the in-memory server\n */\n getStatus(): DbStatus {\n return this.objectsServer.getStatus(); // return Status as Server\n }\n\n /**\n * Synchronize the file directory of the in-memory server\n *\n * @param limitId Optional object ID to limit the synchronization to\n */\n syncFileDirectory(limitId?: string): { numberSuccess: number; notifications: string[] } {\n return this.objectsServer.syncFileDirectory(limitId);\n }\n\n /**\n * Check whether a directory exists in the in-memory server's file storage\n *\n * @param id The object ID owning the files\n * @param name The directory path to check\n */\n dirExists(id: string, name: string): boolean {\n return this.objectsServer.dirExists(id, name);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;AASA,8BAAqE;AACrE,qCAAsC;AAMhC,MAAO,mCAAmC,wBAAAA,OAAoB;EAhBpE,OAgBoE;;;EAC/C;;;;EAKjB,YAAY,UAAyB;AACjC,aAAS,cAAc;AACvB,UAAM,QAAQ;AAEd,UAAM,iBAAiB;MACnB,WAAW,SAAS,YAAY,GAAG,SAAS,SAAS,YAAY;MACjE,YAAY,SAAS;MACrB,QAAQ,SAAS;MACjB,UAAU,SAAS;MACnB,WAAW,6BAAK;AACZ,aAAK,UAAS;MAClB,GAFW;;AAIf,SAAK,gBAAgB,IAAI,qDAAsB,cAAc;EACjE;;;;EAKA,MAAM,UAAO;AACT,UAAM,MAAM,QAAO;AACnB,UAAM,KAAK,cAAc,QAAO;EACpC;;;;EAKA,YAAS;AACL,WAAO,KAAK,cAAc,UAAS;EACvC;;;;;;EAOA,kBAAkB,SAAgB;AAC9B,WAAO,KAAK,cAAc,kBAAkB,OAAO;EACvD;;;;;;;EAQA,UAAU,IAAY,MAAY;AAC9B,WAAO,KAAK,cAAc,UAAU,IAAI,IAAI;EAChD;;",
6
6
  "names": ["ObjectsInRedisClient"]
7
7
  }