@medyll/idae-db 0.106.0 → 0.108.0

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/README.md CHANGED
@@ -10,6 +10,14 @@ To install the library, run:
10
10
  npm install idae-db
11
11
  ```
12
12
 
13
+ ## Scripts
14
+
15
+ ```bash
16
+ npm run test # Run all tests
17
+ npm run test:coverage # Run tests with coverage (v8)
18
+ npm run test:mongodb # Run only the MongoDB adapter suite (in-memory mongo)
19
+ ```
20
+
13
21
  ## Usage
14
22
 
15
23
  ### Initialization
@@ -45,8 +45,10 @@ export class IdaeDBModel {
45
45
  await idaeAuto.db(increment_name);
46
46
  const incrementCollection = idaeAuto.collection(this._autoIncrementDbCollection);
47
47
  // await incrementCollection.createIndex({ _id: 1 }, { unique: true });
48
- await incrementCollection.updateWhere({ query: { _id: new ObjectId(this.fieldId) } }, { $inc: { value: 1 } }, { upsert: true });
49
- const next = await incrementCollection.findOne({ query: { _id: new ObjectId(this.fieldId) } });
48
+ // Use a stable string key per collection+field to track increments
49
+ const key = `${this._collectionName}:${this._fieldId}`;
50
+ await incrementCollection.updateWhere({ query: { _id: key } }, { $inc: { value: 1 } }, { upsert: true });
51
+ const next = await incrementCollection.findOne({ query: { _id: key } });
50
52
  return next?.value;
51
53
  }
52
54
  }
@@ -45,6 +45,7 @@ export declare class IdaeDbConnection {
45
45
  get dbName(): string;
46
46
  get connected(): boolean;
47
47
  get idaeDb(): IdaeDb;
48
+ get uri(): string;
48
49
  /**
49
50
  * Gets the full database name with scope.
50
51
  * @returns The full database name.
@@ -101,6 +101,9 @@ export class IdaeDbConnection {
101
101
  get idaeDb() {
102
102
  return this._idaeDb;
103
103
  }
104
+ get uri() {
105
+ return this.#uri;
106
+ }
104
107
  /**
105
108
  * Gets the full database name with scope.
106
109
  * @returns The full database name.
@@ -28,19 +28,33 @@ export function withEmitter() {
28
28
  descriptor.value = function (...args) {
29
29
  // Emit the pre-execution event
30
30
  this.emit(`pre:${String(propertyKey)}`, ...args);
31
- let result;
32
31
  try {
33
32
  // Execute the original method
34
- result = originalMethod.apply(this, args);
33
+ const executionResult = originalMethod.apply(this, args);
34
+ // If the method returns a Promise, handle async resolution/rejection
35
+ if (executionResult &&
36
+ (typeof executionResult.then === 'function' ||
37
+ executionResult instanceof Promise)) {
38
+ const promise = executionResult
39
+ .then((resolved) => {
40
+ this.emit(`post:${String(propertyKey)}`, resolved, ...args);
41
+ return resolved;
42
+ })
43
+ .catch((error) => {
44
+ this.emit(`error:${String(propertyKey)}`, error);
45
+ throw error;
46
+ });
47
+ return promise;
48
+ }
49
+ // Synchronous result
50
+ this.emit(`post:${String(propertyKey)}`, executionResult, ...args);
51
+ return executionResult;
35
52
  }
36
53
  catch (error) {
37
54
  // Emit the error event if an exception occurs
38
55
  this.emit(`error:${String(propertyKey)}`, error);
39
56
  throw error;
40
57
  }
41
- // Emit the post-execution event
42
- this.emit(`post:${String(propertyKey)}`, result, ...args);
43
- return result;
44
58
  };
45
59
  };
46
60
  }
@@ -53,8 +53,9 @@ export class MongoDBAdapter {
53
53
  }
54
54
  async create(data) {
55
55
  const id = await this.model.getNextIncrement();
56
- const result = await this.model.collection.findOneAndUpdate({ [this.fieldId]: id }, { $set: { ...data, [this.fieldId]: id } }, { upsert: true, returnDocument: 'after' });
57
- return result?.value;
56
+ await this.model.collection.updateOne({ [this.fieldId]: id }, { $set: { ...data, [this.fieldId]: id } }, { upsert: true });
57
+ const result = await this.model.collection.findOne({ [this.fieldId]: id });
58
+ return result;
58
59
  }
59
60
  async update(id, updateData, options) {
60
61
  return this.model.collection.updateMany({ [this.fieldId]: id }, { $set: { ...updateData } }, options);
package/dist/idaeDb.js CHANGED
@@ -47,6 +47,23 @@ export class IdaeDb {
47
47
  if (!IdaeDb.#instances.has(instanceKey)) {
48
48
  IdaeDb.#instances.set(instanceKey, new IdaeDb(uri, options));
49
49
  }
50
+ else if (options) {
51
+ // Merge only missing options into existing instance (do not override already set values)
52
+ const existing = IdaeDb.#instances.get(instanceKey);
53
+ const merged = { ...options };
54
+ // Apply keys where current value is undefined
55
+ for (const key of Object.keys(merged)) {
56
+ // @ts-expect-error index access on private field within class scope
57
+ if (existing.#options[key] === undefined && merged[key] !== undefined) {
58
+ // @ts-expect-error index access on private field within class scope
59
+ existing.#options[key] = merged[key];
60
+ }
61
+ }
62
+ // If dbEvents were provided, register them
63
+ if (merged.dbEvents) {
64
+ existing.registerEvents(merged.dbEvents);
65
+ }
66
+ }
50
67
  return IdaeDb.#instances.get(instanceKey);
51
68
  }
52
69
  /**
@@ -113,6 +130,7 @@ export class IdaeDb {
113
130
  if (this.#connection) {
114
131
  await this.#connection.close();
115
132
  this.#connections.delete(this.connectionKey);
133
+ this.#connection = undefined;
116
134
  }
117
135
  }
118
136
  /**
@@ -124,6 +142,7 @@ export class IdaeDb {
124
142
  await connection.close();
125
143
  }
126
144
  this.#connections.clear();
145
+ this.#connection = undefined;
127
146
  }
128
147
  /**
129
148
  * Gets the adapter class for the current database type.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medyll/idae-db",
3
- "version": "0.106.0",
3
+ "version": "0.108.0",
4
4
  "description": "@medyll/idae-db is a flexible and powerful library for interacting with various databases, with a particular focus on MongoDB support. It offers robust connection management, an intuitive API, and simplified CRUD operations.",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -11,6 +11,9 @@
11
11
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12
12
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
13
13
  "test": "vitest",
14
+ "test:coverage": "vitest run --coverage",
15
+ "test:mongodb": "vitest run tests/mongodb.test.ts",
16
+ "test:watch": "vitest --watch",
14
17
  "lint": "prettier --check . && eslint .",
15
18
  "format": "prettier --write .",
16
19
  "package:pre": "node scripts/package-pre.js"
@@ -36,10 +39,12 @@
36
39
  "@sveltejs/package": "^2.3.11",
37
40
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
38
41
  "@types/eslint": "^9.6.1",
42
+ "@vitest/coverage-v8": "^3.1.1",
39
43
  "eslint": "^9.25.0",
40
44
  "eslint-config-prettier": "^10.1.2",
41
45
  "eslint-plugin-svelte": "^3.5.1",
42
46
  "globals": "^16.0.0",
47
+ "mongodb-memory-server": "^10.1.4",
43
48
  "prettier": "^3.5.3",
44
49
  "prettier-plugin-svelte": "^3.3.3",
45
50
  "publint": "^0.3.12",
@@ -57,4 +62,4 @@
57
62
  "dependencies": {
58
63
  "chromadb": "^2.2.1"
59
64
  }
60
- }
65
+ }