blackcat.js-database 1.0.4 → 1.0.5

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
@@ -349,10 +349,20 @@ import { Database, MongoDriver } from "blackcat.js-database";
349
349
 
350
350
  const database = new Database({
351
351
  driver: new MongoDriver({
352
- mongourl: "mongodb://localhost:27017",
353
- databaseName: "mydb",
354
- collectionName: "store"
355
- })
352
+ mongourl: "mongourl",
353
+ databaseName: "BlackCat-Club",
354
+ collectionName: "database-test",
355
+ onLoad: ({ db, collection, databaseName }) => {
356
+ console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
357
+ console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
358
+ // Ví dụ advanced:
359
+ // db.command({ ping: 1 })
360
+ },
361
+ onError: ({ error, databaseName }) => {
362
+ console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
363
+ console.error(error);
364
+ }
365
+ }),
356
366
  });
357
367
  ```
358
368
  ---
package/dist/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { MongoClient, Db, Collection } from 'mongodb';
2
+
1
3
  /**
2
4
  * Interface định nghĩa contract cho các storage driver
3
5
  * được sử dụng bởi class `Database`.
@@ -369,7 +371,7 @@ type FirstObjectKey<TKey extends ObjectPath<string, any>> = TKey extends `${infe
369
371
  * // "user.profile"
370
372
  * // "user.profile.name"
371
373
  */
372
- type ObjectPath<T, TKey extends keyof T = keyof T> = IsAny<T> extends true ? string : T extends string | number | boolean | symbol ? string : T extends Array<any> ? TKey & string : TKey extends string ? T[TKey] extends Array<any> ? TKey : T[TKey] extends Record<string, any> ? `${TKey}` | `${TKey}.${ObjectPath<T[TKey]>}` : TKey : never;
374
+ type ObjectPath<T, TKey extends keyof T = keyof T> = IsAny<T> extends true ? string : T extends string | number | boolean | symbol ? string : T extends Array<any> ? TKey & string : TKey extends string ? NonNullable<T[TKey]> extends Array<any> ? TKey : NonNullable<T[TKey]> extends Record<string, any> ? `${TKey}` | `${TKey}.${ObjectPath<NonNullable<T[TKey]>>}` : TKey : never;
373
375
  /**
374
376
  * Trích xuất kiểu dữ liệu của giá trị tại một object path.
375
377
  * @hidden
@@ -1310,6 +1312,53 @@ declare class SQLiteDriver implements DatabaseDriver {
1310
1312
  delete(): Promise<boolean>;
1311
1313
  }
1312
1314
 
1315
+ /**
1316
+ * Context được truyền vào callback `onLoad` của MongoDriver.
1317
+ * @hidden
1318
+ */
1319
+ interface MongoDriverOnLoadContext {
1320
+ /**
1321
+ * Instance MongoClient đã kết nối.
1322
+ */
1323
+ client: MongoClient;
1324
+ /**
1325
+ * Database hiện tại.
1326
+ */
1327
+ db: Db;
1328
+ /**
1329
+ * Collection đang được sử dụng.
1330
+ */
1331
+ collection: Collection<DatabaseDocument>;
1332
+ /**
1333
+ * Tên database.
1334
+ */
1335
+ databaseName: string;
1336
+ /**
1337
+ * Tên collection.
1338
+ */
1339
+ collectionName: string;
1340
+ }
1341
+ /**
1342
+ * Context được truyền vào callback `onError` của MongoDriver.
1343
+ * @hidden
1344
+ */
1345
+ interface MongoDriverOnErrorContext {
1346
+ /**
1347
+ * Lỗi phát sinh.
1348
+ *
1349
+ * Có thể là bất kỳ kiểu nào (`unknown`),
1350
+ * nên cần type guard hoặc cast khi xử lý.
1351
+ */
1352
+ error: unknown;
1353
+ /**
1354
+ * Tên database tại thời điểm xảy ra lỗi.
1355
+ */
1356
+ databaseName: string;
1357
+ /**
1358
+ * Tên collection tại thời điểm xảy ra lỗi.
1359
+ */
1360
+ collectionName: string;
1361
+ }
1313
1362
  /**
1314
1363
  * Cấu hình cho MongoDriver.
1315
1364
  */
@@ -1332,6 +1381,21 @@ interface MongoDriverOptions {
1332
1381
  * @default "json_store"
1333
1382
  */
1334
1383
  collectionName?: string;
1384
+ /**
1385
+ * Callback khi kết nối thành công.
1386
+ */
1387
+ onLoad?: (ctx: MongoDriverOnLoadContext) => any;
1388
+ /**
1389
+ * Callback khi xảy ra lỗi.
1390
+ */
1391
+ onError?: (ctx: MongoDriverOnErrorContext) => any;
1392
+ }
1393
+ /**
1394
+ * Schema document dùng để lưu trữ database trong MongoDB.
1395
+ */
1396
+ interface DatabaseDocument<V = any> {
1397
+ _id: string;
1398
+ data: V;
1335
1399
  }
1336
1400
  /**
1337
1401
  * Driver lưu trữ dữ liệu bằng MongoDB.
@@ -1354,11 +1418,21 @@ interface MongoDriverOptions {
1354
1418
  *
1355
1419
  * @example
1356
1420
  * ```ts
1421
+ * import { Database, MongoDriver } from "blackcat.js-database";
1422
+ *
1357
1423
  * const database = new Database({
1358
1424
  * driver: new MongoDriver({
1359
1425
  * mongourl: "mongodb://localhost:27017",
1360
1426
  * databaseName: "mydb",
1361
- * collectionName: "store"
1427
+ * collectionName: "store",
1428
+ * onLoad: ({ db, collection, databaseName }) => {
1429
+ * console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
1430
+ * console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
1431
+ * },
1432
+ * onError: ({ error, databaseName }) => {
1433
+ * console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
1434
+ * console.error(error);
1435
+ * }
1362
1436
  * })
1363
1437
  * });
1364
1438
  * ```
@@ -1384,6 +1458,18 @@ declare class MongoDriver implements DatabaseDriver {
1384
1458
  * Tên collection MongoDB.
1385
1459
  */
1386
1460
  private collectionName;
1461
+ /**
1462
+ * Callback khi kết nối thành công.
1463
+ */
1464
+ onLoad?: (ctx: MongoDriverOnLoadContext) => any;
1465
+ /**
1466
+ * Callback khi xảy ra lỗi.
1467
+ */
1468
+ onError?: (ctx: MongoDriverOnErrorContext) => any;
1469
+ /**
1470
+ * Trạng thái đã gọi onLoad chưa (tránh spam)
1471
+ */
1472
+ private isLoaded;
1387
1473
  /**
1388
1474
  * Khởi tạo MongoDriver.
1389
1475
  *
@@ -1391,11 +1477,21 @@ declare class MongoDriver implements DatabaseDriver {
1391
1477
  *
1392
1478
  * @example
1393
1479
  * ```ts
1480
+ * import { Database, MongoDriver } from "blackcat.js-database";
1481
+ *
1394
1482
  * const database = new Database({
1395
1483
  * driver: new MongoDriver({
1396
1484
  * mongourl: "mongodb://localhost:27017",
1397
1485
  * databaseName: "mydb",
1398
- * collectionName: "store"
1486
+ * collectionName: "store",
1487
+ * onLoad: ({ db, collection, databaseName }) => {
1488
+ * console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
1489
+ * console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
1490
+ * },
1491
+ * onError: ({ error, databaseName }) => {
1492
+ * console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
1493
+ * console.error(error);
1494
+ * }
1399
1495
  * })
1400
1496
  * });
1401
1497
  */
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { MongoClient, Db, Collection } from 'mongodb';
2
+
1
3
  /**
2
4
  * Interface định nghĩa contract cho các storage driver
3
5
  * được sử dụng bởi class `Database`.
@@ -369,7 +371,7 @@ type FirstObjectKey<TKey extends ObjectPath<string, any>> = TKey extends `${infe
369
371
  * // "user.profile"
370
372
  * // "user.profile.name"
371
373
  */
372
- type ObjectPath<T, TKey extends keyof T = keyof T> = IsAny<T> extends true ? string : T extends string | number | boolean | symbol ? string : T extends Array<any> ? TKey & string : TKey extends string ? T[TKey] extends Array<any> ? TKey : T[TKey] extends Record<string, any> ? `${TKey}` | `${TKey}.${ObjectPath<T[TKey]>}` : TKey : never;
374
+ type ObjectPath<T, TKey extends keyof T = keyof T> = IsAny<T> extends true ? string : T extends string | number | boolean | symbol ? string : T extends Array<any> ? TKey & string : TKey extends string ? NonNullable<T[TKey]> extends Array<any> ? TKey : NonNullable<T[TKey]> extends Record<string, any> ? `${TKey}` | `${TKey}.${ObjectPath<NonNullable<T[TKey]>>}` : TKey : never;
373
375
  /**
374
376
  * Trích xuất kiểu dữ liệu của giá trị tại một object path.
375
377
  * @hidden
@@ -1310,6 +1312,53 @@ declare class SQLiteDriver implements DatabaseDriver {
1310
1312
  delete(): Promise<boolean>;
1311
1313
  }
1312
1314
 
1315
+ /**
1316
+ * Context được truyền vào callback `onLoad` của MongoDriver.
1317
+ * @hidden
1318
+ */
1319
+ interface MongoDriverOnLoadContext {
1320
+ /**
1321
+ * Instance MongoClient đã kết nối.
1322
+ */
1323
+ client: MongoClient;
1324
+ /**
1325
+ * Database hiện tại.
1326
+ */
1327
+ db: Db;
1328
+ /**
1329
+ * Collection đang được sử dụng.
1330
+ */
1331
+ collection: Collection<DatabaseDocument>;
1332
+ /**
1333
+ * Tên database.
1334
+ */
1335
+ databaseName: string;
1336
+ /**
1337
+ * Tên collection.
1338
+ */
1339
+ collectionName: string;
1340
+ }
1341
+ /**
1342
+ * Context được truyền vào callback `onError` của MongoDriver.
1343
+ * @hidden
1344
+ */
1345
+ interface MongoDriverOnErrorContext {
1346
+ /**
1347
+ * Lỗi phát sinh.
1348
+ *
1349
+ * Có thể là bất kỳ kiểu nào (`unknown`),
1350
+ * nên cần type guard hoặc cast khi xử lý.
1351
+ */
1352
+ error: unknown;
1353
+ /**
1354
+ * Tên database tại thời điểm xảy ra lỗi.
1355
+ */
1356
+ databaseName: string;
1357
+ /**
1358
+ * Tên collection tại thời điểm xảy ra lỗi.
1359
+ */
1360
+ collectionName: string;
1361
+ }
1313
1362
  /**
1314
1363
  * Cấu hình cho MongoDriver.
1315
1364
  */
@@ -1332,6 +1381,21 @@ interface MongoDriverOptions {
1332
1381
  * @default "json_store"
1333
1382
  */
1334
1383
  collectionName?: string;
1384
+ /**
1385
+ * Callback khi kết nối thành công.
1386
+ */
1387
+ onLoad?: (ctx: MongoDriverOnLoadContext) => any;
1388
+ /**
1389
+ * Callback khi xảy ra lỗi.
1390
+ */
1391
+ onError?: (ctx: MongoDriverOnErrorContext) => any;
1392
+ }
1393
+ /**
1394
+ * Schema document dùng để lưu trữ database trong MongoDB.
1395
+ */
1396
+ interface DatabaseDocument<V = any> {
1397
+ _id: string;
1398
+ data: V;
1335
1399
  }
1336
1400
  /**
1337
1401
  * Driver lưu trữ dữ liệu bằng MongoDB.
@@ -1354,11 +1418,21 @@ interface MongoDriverOptions {
1354
1418
  *
1355
1419
  * @example
1356
1420
  * ```ts
1421
+ * import { Database, MongoDriver } from "blackcat.js-database";
1422
+ *
1357
1423
  * const database = new Database({
1358
1424
  * driver: new MongoDriver({
1359
1425
  * mongourl: "mongodb://localhost:27017",
1360
1426
  * databaseName: "mydb",
1361
- * collectionName: "store"
1427
+ * collectionName: "store",
1428
+ * onLoad: ({ db, collection, databaseName }) => {
1429
+ * console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
1430
+ * console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
1431
+ * },
1432
+ * onError: ({ error, databaseName }) => {
1433
+ * console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
1434
+ * console.error(error);
1435
+ * }
1362
1436
  * })
1363
1437
  * });
1364
1438
  * ```
@@ -1384,6 +1458,18 @@ declare class MongoDriver implements DatabaseDriver {
1384
1458
  * Tên collection MongoDB.
1385
1459
  */
1386
1460
  private collectionName;
1461
+ /**
1462
+ * Callback khi kết nối thành công.
1463
+ */
1464
+ onLoad?: (ctx: MongoDriverOnLoadContext) => any;
1465
+ /**
1466
+ * Callback khi xảy ra lỗi.
1467
+ */
1468
+ onError?: (ctx: MongoDriverOnErrorContext) => any;
1469
+ /**
1470
+ * Trạng thái đã gọi onLoad chưa (tránh spam)
1471
+ */
1472
+ private isLoaded;
1387
1473
  /**
1388
1474
  * Khởi tạo MongoDriver.
1389
1475
  *
@@ -1391,11 +1477,21 @@ declare class MongoDriver implements DatabaseDriver {
1391
1477
  *
1392
1478
  * @example
1393
1479
  * ```ts
1480
+ * import { Database, MongoDriver } from "blackcat.js-database";
1481
+ *
1394
1482
  * const database = new Database({
1395
1483
  * driver: new MongoDriver({
1396
1484
  * mongourl: "mongodb://localhost:27017",
1397
1485
  * databaseName: "mydb",
1398
- * collectionName: "store"
1486
+ * collectionName: "store",
1487
+ * onLoad: ({ db, collection, databaseName }) => {
1488
+ * console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
1489
+ * console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
1490
+ * },
1491
+ * onError: ({ error, databaseName }) => {
1492
+ * console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
1493
+ * console.error(error);
1494
+ * }
1399
1495
  * })
1400
1496
  * });
1401
1497
  */
package/dist/index.js CHANGED
@@ -42,12 +42,16 @@ __export(index_exports, {
42
42
  module.exports = __toCommonJS(index_exports);
43
43
 
44
44
  // src/utils/isObject.function.ts
45
- var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item == "object", "isObject");
45
+ var isObject = /* @__PURE__ */ __name((item) => !Array.isArray(item) && item !== null && typeof item === "object", "isObject");
46
46
 
47
47
  // src/utils/typeOf.function.ts
48
48
  var typeOf = /* @__PURE__ */ __name((input) => {
49
- if (input == null || typeof input === "number" && Number.isNaN(input)) return String(input);
50
- if (typeof input === "function" && input.prototype) return `${input.name} class instance`;
49
+ if (input == null || typeof input === "number" && Number.isNaN(input)) {
50
+ return String(input);
51
+ }
52
+ if (typeof input === "function" && input.prototype) {
53
+ return `${input.name} class instance`;
54
+ }
51
55
  return input?.constructor?.name ?? typeof input;
52
56
  }, "typeOf");
53
57
 
@@ -56,20 +60,12 @@ var isNumber = /* @__PURE__ */ __name((input) => !isNaN(input) && input !== "" &
56
60
 
57
61
  // src/utils/BlackCatError.ts
58
62
  var errors = {
59
- DEVICE_IS_OFFLINE: "Your device appears to be offline so it's impossible to proceed with connection to your online MongoDB cluster. Please connect your device to the internet or switch to the local MongoDB database and try again.",
60
- CONNECTION_NOT_ESTABLISHED: "Failed to connect to MongoDB. Please double-check the specified connection URI and make sure that you're performing the database connection using the `QuickMongoClient.connect()` method.",
61
- CONNECTION_URI_NOT_SPECIFIED: "The MongoDB connection URI must be specified.",
62
- INVALID_CONNECTION_URI: "The specified MongoDB connection URI is invalid.",
63
- UNKNOWN_ERROR: "Unknown error.",
64
- REQUIRED_PARAMETER_MISSING: "'{1}' parameter is required but is missing.",
65
- REQUIRED_CONSTRUCTOR_PARAMETER_MISSING: "'{1}' parameter in constructor '{2}' is required but is missing.",
66
- INVALID_CONSTRUCTOR_PARAMETER_TYPE: "'{1}' parameter in constructor '{2}' must be a type of {3}. Received type: {4}.",
67
- INVALID_TYPE: "'{1}' must be a type of {2}. Received type: {3}.",
68
- ONE_OR_MORE_ARRAY_TYPES_INVALID: "All specified elements from array in '{1}' parameter must be a type of {2}. Received array of types: {3}.",
69
- INVALID_TARGET: "The target in database must be a type of {1}. Received target type: {2}.",
70
- INVALID_KEY: "{1}",
71
- INVALID_PARAMETER: "{1} {2}",
72
- DATABASE_CONNECTION_FAILED: "{1}"
63
+ UNKNOWN_ERROR: "L\u1ED7i kh\xF4ng x\xE1c \u0111\u1ECBnh.",
64
+ REQUIRED_PARAMETER_MISSING: "Tham s\u1ED1 '{1}' l\xE0 b\u1EAFt bu\u1ED9c nh\u01B0ng ch\u01B0a \u0111\u01B0\u1EE3c cung c\u1EA5p.",
65
+ INVALID_TYPE: "'{1}' ph\u1EA3i c\xF3 ki\u1EC3u {2}. Ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c: {3}.",
66
+ ONE_OR_MORE_ARRAY_TYPES_INVALID: "T\u1EA5t c\u1EA3 ph\u1EA7n t\u1EED trong m\u1EA3ng c\u1EE7a tham s\u1ED1 '{1}' ph\u1EA3i c\xF3 ki\u1EC3u {2}. C\xE1c ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c trong m\u1EA3ng: {3}.",
67
+ INVALID_TARGET: "\u0110\u1ED1i t\u01B0\u1EE3ng target trong database ph\u1EA3i c\xF3 ki\u1EC3u {1}. Ki\u1EC3u nh\u1EADn \u0111\u01B0\u1EE3c: {2}.",
68
+ INVALID_KEY: "{1}"
73
69
  };
74
70
  var createTypesArray = /* @__PURE__ */ __name((...elements) => `[${elements.map((element) => typeOf(element))}]`, "createTypesArray");
75
71
  var _BlackCatError = class _BlackCatError extends Error {
@@ -95,46 +91,107 @@ var BlackCatError = _BlackCatError;
95
91
  // src/utils/TypedObject.ts
96
92
  var _TypedObject = class _TypedObject {
97
93
  /**
98
- * Returns the names of the enumerable string properties and methods of an object.
94
+ * Lấy danh sách key của object với type chính xác.
95
+ *
96
+ * @typeParam TObject - Kiểu object đầu vào
99
97
  *
100
- * Type parameters:
98
+ * @param obj - Object cần lấy key
99
+ * @returns Mảng các key của object (`ExtractObjectKeys<TObject>[]`)
101
100
  *
102
- * - `TObject` (`Record<string, any>`) - The object to get the object keys types from.
101
+ * @remarks
102
+ * Khác với `Object.keys`:
103
+ * - `Object.keys(obj)` → `string[]`
104
+ * - `TypedObject.keys(obj)` → union key chính xác
103
105
  *
104
- * @param {TObject} obj Object to get the keys from.
106
+ * ---
105
107
  *
106
- * @returns {Array<ExtractObjectKeys<TObject>>}
107
- * Array of names of the enumerable string properties and methods of the specified object.
108
+ * ### Lưu ý:
109
+ * - Nếu `obj` `null` hoặc `undefined`, sẽ fallback thành `{}` trả về `[]`
110
+ *
111
+ * ---
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const obj = { a: 1, b: 2 };
116
+ *
117
+ * const keys = TypedObject.keys(obj);
118
+ * // ("a" | "b")[]
119
+ * ```
120
+ *
121
+ * @see Object.keys
108
122
  */
109
123
  static keys(obj) {
110
124
  return Object.keys(obj || {});
111
125
  }
112
126
  /**
113
- * Returns an array of values of the enumerable properties of an object.
127
+ * Lấy danh sách value của object với type chính xác.
128
+ *
129
+ * @typeParam TObject - Kiểu object đầu vào
114
130
  *
115
- * Type parameters:
131
+ * @param obj - Object cần lấy value
132
+ * @returns Mảng các value của object (`ExtractObjectValues<TObject>[]`)
116
133
  *
117
- * - `TObject` (`Record<string, any>`) - The object to get the object values types from.
134
+ * @remarks
135
+ * Khác với `Object.values`:
136
+ * - `Object.values(obj)` → `any[]`
137
+ * - `TypedObject.values(obj)` → union value chính xác
118
138
  *
119
- * @param {TObject} obj Object to get the values from.
139
+ * ---
120
140
  *
121
- * @returns {Array<ExtractObjectValues<TObject>>}
122
- * Array of values of the enumerable properties of the specified object.
141
+ * ### Lưu ý:
142
+ * - Nếu `obj` `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
143
+ *
144
+ * ---
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const obj = { a: 1, b: 2 };
149
+ *
150
+ * const values = TypedObject.values(obj);
151
+ * // number[]
152
+ * ```
153
+ *
154
+ * @see Object.values
123
155
  */
124
156
  static values(obj) {
125
157
  return Object.values(obj || {});
126
158
  }
127
159
  /**
128
- * Returns an array of entries (key-value pairs) of the enumerable properties of an object.
160
+ * Lấy danh sách entry (key-value) của object với type chính xác.
161
+ *
162
+ * @typeParam TObject - Kiểu object đầu vào
163
+ *
164
+ * @param obj - Object cần lấy entries
165
+ * @returns Mảng các cặp `[key, value]` (`ExtractObjectEntries<TObject>[]`)
166
+ *
167
+ * @remarks
168
+ * Khác với `Object.entries`:
169
+ * - `Object.entries(obj)` → `[string, any][]`
170
+ * - `TypedObject.entries(obj)` → typed tuple chính xác
129
171
  *
130
- * Type parameters:
172
+ * ---
131
173
  *
132
- * - `TObject` (`Record<string, any>`) - The object to get the object entries types (key-value pairs types) from.
174
+ * ### Lưu ý:
175
+ * - Nếu `obj` là `null` hoặc `undefined`, sẽ fallback thành `{}` → trả về `[]`
133
176
  *
134
- * @param {TObject} obj Object to get the entries from.
177
+ * ---
135
178
  *
136
- * @returns {ExtractObjectEntries<TObject>[]}
137
- * Array of entries (key-value pairs) of the enumerable properties of the specified object.
179
+ * @example
180
+ * ```ts
181
+ * const obj = { a: 1, b: 2 };
182
+ *
183
+ * const entries = TypedObject.entries(obj);
184
+ * // ["a" | "b", number][]
185
+ * ```
186
+ *
187
+ * @example
188
+ * ```ts
189
+ * for (const [key, value] of TypedObject.entries(obj)) {
190
+ * // key & value được infer đúng type
191
+ * }
192
+ * ```
193
+ *
194
+ * @see Object.entries
138
195
  */
139
196
  static entries(obj) {
140
197
  return Object.entries(obj || {});
@@ -143,9 +200,6 @@ var _TypedObject = class _TypedObject {
143
200
  __name(_TypedObject, "TypedObject");
144
201
  var TypedObject = _TypedObject;
145
202
 
146
- // src/utils/Emitter.ts
147
- var import_node_events = require("events");
148
-
149
203
  // src/Database.ts
150
204
  var _Database = class _Database {
151
205
  /**
@@ -1222,11 +1276,21 @@ var _MongoDriver = class _MongoDriver {
1222
1276
  *
1223
1277
  * @example
1224
1278
  * ```ts
1279
+ * import { Database, MongoDriver } from "blackcat.js-database";
1280
+ *
1225
1281
  * const database = new Database({
1226
1282
  * driver: new MongoDriver({
1227
1283
  * mongourl: "mongodb://localhost:27017",
1228
1284
  * databaseName: "mydb",
1229
- * collectionName: "store"
1285
+ * collectionName: "store",
1286
+ * onLoad: ({ db, collection, databaseName }) => {
1287
+ * console.log(`✅ Đã kết nối với cơ sở dữ liệu: ${databaseName}`);
1288
+ * console.log(`📦 Bộ sưu tập: ${collection.collectionName}`);
1289
+ * },
1290
+ * onError: ({ error, databaseName }) => {
1291
+ * console.error(`❌ Không thể kết nối với cơ sở dữ liệu: ${databaseName}`);
1292
+ * console.error(error);
1293
+ * }
1230
1294
  * })
1231
1295
  * });
1232
1296
  */
@@ -1251,6 +1315,18 @@ var _MongoDriver = class _MongoDriver {
1251
1315
  * Tên collection MongoDB.
1252
1316
  */
1253
1317
  __publicField(this, "collectionName");
1318
+ /**
1319
+ * Callback khi kết nối thành công.
1320
+ */
1321
+ __publicField(this, "onLoad");
1322
+ /**
1323
+ * Callback khi xảy ra lỗi.
1324
+ */
1325
+ __publicField(this, "onError");
1326
+ /**
1327
+ * Trạng thái đã gọi onLoad chưa (tránh spam)
1328
+ */
1329
+ __publicField(this, "isLoaded", false);
1254
1330
  const {
1255
1331
  mongourl = "mongodb://localhost:27017",
1256
1332
  databaseName = "database",
@@ -1259,21 +1335,42 @@ var _MongoDriver = class _MongoDriver {
1259
1335
  this.client = new import_mongodb.MongoClient(mongourl);
1260
1336
  this.databaseName = databaseName;
1261
1337
  this.collectionName = collectionName;
1338
+ this.onLoad = options.onLoad;
1339
+ this.onError = options.onError;
1262
1340
  }
1263
1341
  /**
1264
1342
  * Thiết lập kết nối MongoDB nếu chưa kết nối.
1265
1343
  */
1266
1344
  async connect() {
1267
1345
  if (!this.db) {
1268
- await this.client.connect();
1269
- this.db = this.client.db(this.databaseName);
1270
- this.collection = this.db.collection(this.collectionName);
1271
- const doc = await this.collection.findOne({ _id: "database" });
1272
- if (!doc) {
1273
- await this.collection.insertOne({
1274
- _id: "database",
1275
- data: {}
1346
+ try {
1347
+ await this.client.connect();
1348
+ this.db = this.client.db(this.databaseName);
1349
+ this.collection = this.db.collection(this.collectionName);
1350
+ const doc = await this.collection.findOne({ _id: "database" });
1351
+ if (!doc) {
1352
+ await this.collection.insertOne({
1353
+ _id: "database",
1354
+ data: {}
1355
+ });
1356
+ }
1357
+ if (!this.isLoaded) {
1358
+ this.isLoaded = true;
1359
+ this.onLoad?.({
1360
+ client: this.client,
1361
+ db: this.db,
1362
+ collection: this.collection,
1363
+ databaseName: this.databaseName,
1364
+ collectionName: this.collectionName
1365
+ });
1366
+ }
1367
+ } catch (error) {
1368
+ this.onError?.({
1369
+ error,
1370
+ databaseName: this.databaseName,
1371
+ collectionName: this.collectionName
1276
1372
  });
1373
+ throw error;
1277
1374
  }
1278
1375
  }
1279
1376
  }