blackcat.js-database 1.0.5 → 1.0.7
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 +6 -1
- package/dist/{index.js → index.cjs} +465 -125
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +353 -50
- package/dist/index.d.ts +353 -50
- package/dist/index.mjs +464 -124
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/dist/index.js.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -82,6 +82,21 @@ interface DatabaseConfiguration {
|
|
|
82
82
|
* (ví dụ: memory, file, json, mongo, redis...).
|
|
83
83
|
*/
|
|
84
84
|
driver: DatabaseDriver;
|
|
85
|
+
/**
|
|
86
|
+
* Ký tự phân tách dùng để tách các phần của đường dẫn (key).
|
|
87
|
+
*
|
|
88
|
+
* @defaultValue "."
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* // "user.profile.name"
|
|
93
|
+
* delimiter: "."
|
|
94
|
+
*
|
|
95
|
+
* // "user/profile/name"
|
|
96
|
+
* delimiter: "/"
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
delimiter?: string;
|
|
85
100
|
/**
|
|
86
101
|
* Bật chế độ debug.
|
|
87
102
|
*
|
|
@@ -113,7 +128,32 @@ interface DatabaseConfiguration {
|
|
|
113
128
|
*/
|
|
114
129
|
type Maybe<T> = Exclude<T | null, undefined>;
|
|
115
130
|
/**
|
|
131
|
+
* Utility type dùng để trích xuất kiểu phần tử bên trong một mảng.
|
|
132
|
+
* @hidden
|
|
133
|
+
*
|
|
134
|
+
* Nếu `T` là một mảng (`U[]`) thì kiểu trả về sẽ là `U` (kiểu phần tử).
|
|
135
|
+
* Nếu `T` không phải là mảng thì kiểu trả về chính là `T`.
|
|
136
|
+
*
|
|
137
|
+
* Thường được sử dụng trong các generic type để làm việc
|
|
138
|
+
* với kiểu dữ liệu của phần tử trong mảng một cách an toàn.
|
|
139
|
+
*
|
|
140
|
+
* @typeParam T - Kiểu dữ liệu đầu vào, có thể là mảng hoặc bất kỳ kiểu nào.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* type A = ArrayElement<string[]>;
|
|
144
|
+
* // Kết quả: string
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* type B = ArrayElement<number[]>;
|
|
148
|
+
* // Kết quả: number
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* type C = ArrayElement<string>;
|
|
152
|
+
* // Kết quả: string
|
|
116
153
|
*
|
|
154
|
+
* @example
|
|
155
|
+
* type D = ArrayElement<(number | string)[]>;
|
|
156
|
+
* // Kết quả: number | string
|
|
117
157
|
*/
|
|
118
158
|
type ArrayElement<T> = T extends (infer U)[] ? U : T;
|
|
119
159
|
/**
|
|
@@ -310,26 +350,6 @@ type IsAny<T> = 0 extends (1 & T) ? true : false;
|
|
|
310
350
|
* const c: Status = "custom"; // vẫn hợp lệ
|
|
311
351
|
*/
|
|
312
352
|
type AutocompletableString<S extends string> = S | (string & {});
|
|
313
|
-
/**
|
|
314
|
-
* Trích xuất **key đầu tiên** từ một object path dạng chuỗi.
|
|
315
|
-
* @hidden
|
|
316
|
-
*
|
|
317
|
-
* Ví dụ với path `"member.user.id"` thì key đầu tiên sẽ là `"member"`.
|
|
318
|
-
*
|
|
319
|
-
* Type này thường được dùng để xác định **object cấp cao nhất**
|
|
320
|
-
* khi làm việc với các path dạng `dot notation`.
|
|
321
|
-
*
|
|
322
|
-
* @typeParam TKey - Object path cần trích xuất key đầu tiên.
|
|
323
|
-
*
|
|
324
|
-
* @example
|
|
325
|
-
* type A = FirstObjectKey<"user.profile.name">;
|
|
326
|
-
* // Kết quả: "user"
|
|
327
|
-
*
|
|
328
|
-
* @example
|
|
329
|
-
* type B = FirstObjectKey<"settings">;
|
|
330
|
-
* // Kết quả: "settings"
|
|
331
|
-
*/
|
|
332
|
-
type FirstObjectKey<TKey extends ObjectPath<string, any>> = TKey extends `${infer Key}.${infer _Rest}` ? Key : TKey extends string ? TKey : never;
|
|
333
353
|
/**
|
|
334
354
|
* Đại diện cho **đường dẫn (path)** tới một thuộc tính trong object,
|
|
335
355
|
* hỗ trợ truy cập các property lồng nhau bằng `dot notation`.
|
|
@@ -401,7 +421,7 @@ type ObjectPath<T, TKey extends keyof T = keyof T> = IsAny<T> extends true ? str
|
|
|
401
421
|
* type C = ObjectValue<User, "profile">;
|
|
402
422
|
* // Kết quả: { name: string; age: number }
|
|
403
423
|
*/
|
|
404
|
-
type ObjectValue<T, P extends ObjectPath<T> | AutocompletableString<ObjectPath<T>>> = T extends
|
|
424
|
+
type ObjectValue<T, P extends ObjectPath<T> | AutocompletableString<ObjectPath<T>>> = T extends string | number | boolean | bigint | symbol | null | undefined | Date | Function ? T : T extends (infer U)[] ? ObjectValue<U, P>[] : P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? ObjectValue<T[Key], Rest> : never : P extends keyof T ? T[P] : never;
|
|
405
425
|
|
|
406
426
|
/**
|
|
407
427
|
* Class Database cung cấp API thao tác dữ liệu dạng key-path
|
|
@@ -481,7 +501,7 @@ declare class Database<V = any> {
|
|
|
481
501
|
* console.log(data.users);
|
|
482
502
|
* ```
|
|
483
503
|
*/
|
|
484
|
-
all
|
|
504
|
+
all(): Promise<V>;
|
|
485
505
|
/**
|
|
486
506
|
* Lấy giá trị từ database theo key-path.
|
|
487
507
|
*
|
|
@@ -510,7 +530,7 @@ declare class Database<V = any> {
|
|
|
510
530
|
* const all = await db.get();
|
|
511
531
|
* ```
|
|
512
532
|
*/
|
|
513
|
-
get<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<Maybe<ObjectValue<V, P
|
|
533
|
+
get<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<Maybe<ObjectValue<V, P>>>;
|
|
514
534
|
/**
|
|
515
535
|
* Tìm và trả về một bản ghi đầu tiên khớp với điều kiện trong database.
|
|
516
536
|
*
|
|
@@ -547,7 +567,7 @@ declare class Database<V = any> {
|
|
|
547
567
|
* });
|
|
548
568
|
* ```
|
|
549
569
|
*/
|
|
550
|
-
findOne<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>, query?: Partial<ArrayElement<ObjectValue<V, P>>>): Promise<Maybe<ObjectValue<V, P
|
|
570
|
+
findOne<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>, query?: Partial<ArrayElement<ObjectValue<V, P>>>): Promise<Maybe<ObjectValue<V, P>>>;
|
|
551
571
|
/**
|
|
552
572
|
* Kiểm tra một key-path có tồn tại trong database hay không.
|
|
553
573
|
*
|
|
@@ -576,7 +596,7 @@ declare class Database<V = any> {
|
|
|
576
596
|
* @param {AutocompletableString<P>} key Đường dẫn dữ liệu cần gán giá trị.
|
|
577
597
|
* @param {ObjectValue<V, P>} value Giá trị mới.
|
|
578
598
|
*
|
|
579
|
-
* @returns {
|
|
599
|
+
* @returns {void} Giá trị vừa được set hoặc object root nếu value là object.
|
|
580
600
|
*
|
|
581
601
|
* @example
|
|
582
602
|
* ```ts
|
|
@@ -588,25 +608,66 @@ declare class Database<V = any> {
|
|
|
588
608
|
* await db.set("config.prefix", "!");
|
|
589
609
|
* ```
|
|
590
610
|
*/
|
|
591
|
-
set<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<
|
|
611
|
+
set<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<void>;
|
|
592
612
|
/**
|
|
593
|
-
*
|
|
613
|
+
* Đảm bảo một key tồn tại với giá trị mặc định.
|
|
614
|
+
* Nếu key đã tồn tại → giữ nguyên và trả về giá trị hiện tại.
|
|
615
|
+
* Nếu chưa tồn tại → set giá trị default và trả về default đó.
|
|
594
616
|
*
|
|
595
|
-
*
|
|
617
|
+
* Khác với `set()` — không bao giờ ghi đè dữ liệu đã có.
|
|
618
|
+
*
|
|
619
|
+
* @template P Key path trong database.
|
|
620
|
+
*
|
|
621
|
+
* @param key Đường dẫn cần đảm bảo tồn tại.
|
|
622
|
+
* @param defaultValue Giá trị mặc định nếu key chưa có.
|
|
623
|
+
*
|
|
624
|
+
* @returns Giá trị tại key sau khi ensure (current hoặc default).
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* // "config.maxRetries" chưa tồn tại → set về 3, trả về 3
|
|
628
|
+
* const retries = await db.ensure("config.maxRetries", 3);
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* // "config.maxRetries" đã là 10 → không đổi, trả về 10
|
|
632
|
+
* const retries = await db.ensure("config.maxRetries", 3);
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* // Dùng với object — đảm bảo cấu trúc user tồn tại
|
|
636
|
+
* const user = await db.ensure("users.123", {
|
|
637
|
+
* balance: 0,
|
|
638
|
+
* level: 1,
|
|
639
|
+
* joinedAt: Date.now(),
|
|
640
|
+
* });
|
|
641
|
+
*/
|
|
642
|
+
ensure<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, defaultValue: ObjectValue<V, P>): Promise<NonNullable<ObjectValue<V, P>>>;
|
|
643
|
+
/**
|
|
644
|
+
* Xóa dữ liệu khỏi database.
|
|
645
|
+
* Hỗ trợ truy cập dữ liệu lồng nhau bằng dot notation.
|
|
646
|
+
* Nếu key không tồn tại hoặc đường dẫn không hợp lệ, hàm sẽ trả về `false`.
|
|
596
647
|
*
|
|
597
648
|
* @typeParam P - Path của object.
|
|
598
649
|
*
|
|
599
|
-
* @param key - Đường dẫn
|
|
650
|
+
* @param key - Đường dẫn dữ liệu cần xóa.
|
|
600
651
|
*
|
|
601
652
|
* @returns
|
|
602
|
-
* - `true` nếu xóa thành công
|
|
603
|
-
* - `false` nếu key không tồn tại
|
|
653
|
+
* - `true` nếu xóa thành công.
|
|
654
|
+
* - `false` nếu key không tồn tại hoặc đường dẫn không hợp lệ.
|
|
604
655
|
*
|
|
605
656
|
* @throws BlackCatError
|
|
606
|
-
* - INVALID_TYPE nếu key không phải
|
|
657
|
+
* - INVALID_TYPE nếu `key` không phải là chuỗi.
|
|
607
658
|
*
|
|
608
659
|
* @example
|
|
660
|
+
* // Xóa một thuộc tính
|
|
609
661
|
* await db.delete("user.name");
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* // Xóa object lồng nhau
|
|
665
|
+
* await db.delete("users.0.profile");
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* // Key không tồn tại
|
|
669
|
+
* const deleted = await db.delete("user.address");
|
|
670
|
+
* console.log(deleted); // false
|
|
610
671
|
*/
|
|
611
672
|
delete<P extends AutocompletableString<ObjectPath<V>>>(key?: AutocompletableString<P>): Promise<boolean>;
|
|
612
673
|
/**
|
|
@@ -665,25 +726,57 @@ declare class Database<V = any> {
|
|
|
665
726
|
*/
|
|
666
727
|
deleteMany<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, query: Partial<ArrayElement<ObjectValue<V, P>>>): Promise<number>;
|
|
667
728
|
/**
|
|
668
|
-
* Cập nhật dữ liệu trong database theo đường dẫn key.
|
|
729
|
+
* Cập nhật dữ liệu trong database theo đường dẫn (`key`).
|
|
730
|
+
*
|
|
731
|
+
* ## Chức năng
|
|
732
|
+
* - Cập nhật giá trị tại một key hoặc nested key trong database.
|
|
733
|
+
* - Tự động tạo object trung gian nếu đường dẫn chưa tồn tại.
|
|
734
|
+
* - Hỗ trợ gộp dữ liệu (merge) đối với object và mảng nhằm hạn chế ghi đè dữ liệu đã có.
|
|
735
|
+
*
|
|
736
|
+
* ## Mô tả hoạt động
|
|
737
|
+
* Hàm sẽ đọc toàn bộ dữ liệu database, tìm đến vị trí tương ứng với `key`
|
|
738
|
+
* và cập nhật giá trị mới theo các quy tắc sau:
|
|
669
739
|
*
|
|
670
|
-
*
|
|
671
|
-
* Nếu
|
|
672
|
-
*
|
|
740
|
+
* - **Đối với Array**
|
|
741
|
+
* - Nếu cả giá trị hiện tại và giá trị mới đều là mảng thì sẽ **không ghi đè**.
|
|
742
|
+
* - Các phần tử mới sẽ được thêm vào cuối mảng.
|
|
743
|
+
* - Chỉ thêm những phần tử chưa tồn tại ví dụ dựa trên cặp thuộc tính:
|
|
744
|
+
* - `username`
|
|
745
|
+
* - `guild`
|
|
746
|
+
* - Điều này giúp tránh lưu trùng dữ liệu thành viên giữa nhiều lần cập nhật.
|
|
673
747
|
*
|
|
674
|
-
*
|
|
748
|
+
* - **Đối với Object**
|
|
749
|
+
* - Nếu cả hai đều là object sẽ thực hiện **shallow merge** (`...old, ...new`).
|
|
750
|
+
* - Các thuộc tính mới sẽ ghi đè thuộc tính cùng tên.
|
|
751
|
+
* - Những thuộc tính khác vẫn được giữ nguyên.
|
|
675
752
|
*
|
|
676
|
-
*
|
|
753
|
+
* - **Các kiểu dữ liệu khác**
|
|
754
|
+
* - Giá trị mới sẽ ghi đè hoàn toàn giá trị cũ.
|
|
677
755
|
*
|
|
678
|
-
*
|
|
679
|
-
* Hỗ trợ nested path dạng `"a.b.c"`.
|
|
756
|
+
* Sau khi cập nhật xong, toàn bộ database sẽ được ghi lại thông qua driver.
|
|
680
757
|
*
|
|
681
|
-
* @
|
|
758
|
+
* @template P
|
|
759
|
+
* Đường dẫn hợp lệ của object trong database.
|
|
760
|
+
*
|
|
761
|
+
* @param key
|
|
762
|
+
* Đường dẫn cần cập nhật.
|
|
763
|
+
*
|
|
764
|
+
* Hỗ trợ nested path:
|
|
765
|
+
* ```ts
|
|
766
|
+
* "guilds.123.settings.prefix"
|
|
767
|
+
* "users.456.profile.name"
|
|
768
|
+
* ```
|
|
769
|
+
*
|
|
770
|
+
* @param value
|
|
771
|
+
* Giá trị mới cần cập nhật.
|
|
682
772
|
*
|
|
683
773
|
* @returns
|
|
684
|
-
* Trả về giá trị cuối cùng sau khi
|
|
774
|
+
* Trả về giá trị cuối cùng sau khi được lưu vào database.
|
|
775
|
+
*
|
|
776
|
+
* ## Cách sử dụng
|
|
777
|
+
*
|
|
778
|
+
* ### Ví dụ 1 - Cập nhật object
|
|
685
779
|
*
|
|
686
|
-
* @example
|
|
687
780
|
* Database ban đầu:
|
|
688
781
|
* ```json
|
|
689
782
|
* {
|
|
@@ -695,10 +788,9 @@ declare class Database<V = any> {
|
|
|
695
788
|
* }
|
|
696
789
|
* ```
|
|
697
790
|
*
|
|
698
|
-
* Cập nhật:
|
|
699
791
|
* ```ts
|
|
700
792
|
* await db.update("123", {
|
|
701
|
-
*
|
|
793
|
+
* history: [1, 2, 3]
|
|
702
794
|
* });
|
|
703
795
|
* ```
|
|
704
796
|
*
|
|
@@ -708,16 +800,211 @@ declare class Database<V = any> {
|
|
|
708
800
|
* "123": {
|
|
709
801
|
* "guildID": "123",
|
|
710
802
|
* "guildName": "BlackCat",
|
|
711
|
-
* "history": [1,2,3]
|
|
803
|
+
* "history": [1, 2, 3]
|
|
804
|
+
* }
|
|
805
|
+
* }
|
|
806
|
+
* ```
|
|
807
|
+
*
|
|
808
|
+
* ---
|
|
809
|
+
*
|
|
810
|
+
* ### Ví dụ 2 - Cập nhật nested key
|
|
811
|
+
*
|
|
812
|
+
* ```ts
|
|
813
|
+
* await db.update("guilds.123.settings.prefix", "!");
|
|
814
|
+
* ```
|
|
815
|
+
*
|
|
816
|
+
* Nếu đường dẫn chưa tồn tại:
|
|
817
|
+
*
|
|
818
|
+
* ```json
|
|
819
|
+
* {}
|
|
820
|
+
* ```
|
|
821
|
+
*
|
|
822
|
+
* Sau khi cập nhật:
|
|
823
|
+
*
|
|
824
|
+
* ```json
|
|
825
|
+
* {
|
|
826
|
+
* "guilds": {
|
|
827
|
+
* "123": {
|
|
828
|
+
* "settings": {
|
|
829
|
+
* "prefix": "!"
|
|
830
|
+
* }
|
|
831
|
+
* }
|
|
712
832
|
* }
|
|
713
833
|
* }
|
|
714
834
|
* ```
|
|
715
835
|
*
|
|
836
|
+
* ---
|
|
837
|
+
*
|
|
838
|
+
* ### Ví dụ 3 - Merge object
|
|
839
|
+
*
|
|
840
|
+
* Giá trị hiện tại:
|
|
841
|
+
*
|
|
842
|
+
* ```json
|
|
843
|
+
* {
|
|
844
|
+
* "name": "BlackCat",
|
|
845
|
+
* "language": "vi",
|
|
846
|
+
* "prefix": "!"
|
|
847
|
+
* }
|
|
848
|
+
* ```
|
|
849
|
+
*
|
|
850
|
+
* ```ts
|
|
851
|
+
* await db.update("config", {
|
|
852
|
+
* prefix: "?",
|
|
853
|
+
* color: "#5865F2"
|
|
854
|
+
* });
|
|
855
|
+
* ```
|
|
856
|
+
*
|
|
857
|
+
* Kết quả:
|
|
858
|
+
*
|
|
859
|
+
* ```json
|
|
860
|
+
* {
|
|
861
|
+
* "name": "BlackCat",
|
|
862
|
+
* "language": "vi",
|
|
863
|
+
* "prefix": "?",
|
|
864
|
+
* "color": "#5865F2"
|
|
865
|
+
* }
|
|
866
|
+
* ```
|
|
867
|
+
*
|
|
868
|
+
* ---
|
|
869
|
+
*
|
|
870
|
+
* ### Ví dụ 4 - Merge mảng và loại bỏ phần tử trùng
|
|
871
|
+
*
|
|
872
|
+
* Giá trị hiện tại:
|
|
873
|
+
*
|
|
874
|
+
* ```json
|
|
875
|
+
* [
|
|
876
|
+
* {
|
|
877
|
+
* "username": "Alice",
|
|
878
|
+
* "guild": "123"
|
|
879
|
+
* }
|
|
880
|
+
* ]
|
|
881
|
+
* ```
|
|
882
|
+
*
|
|
883
|
+
* ```ts
|
|
884
|
+
* await db.update("history", [
|
|
885
|
+
* {
|
|
886
|
+
* username: "Alice",
|
|
887
|
+
* guild: "123"
|
|
888
|
+
* },
|
|
889
|
+
* {
|
|
890
|
+
* username: "Bob",
|
|
891
|
+
* guild: "123"
|
|
892
|
+
* }
|
|
893
|
+
* ]);
|
|
894
|
+
* ```
|
|
895
|
+
*
|
|
896
|
+
* Kết quả:
|
|
897
|
+
*
|
|
898
|
+
* ```json
|
|
899
|
+
* [
|
|
900
|
+
* {
|
|
901
|
+
* "username": "Alice",
|
|
902
|
+
* "guild": "123"
|
|
903
|
+
* },
|
|
904
|
+
* {
|
|
905
|
+
* "username": "Bob",
|
|
906
|
+
* "guild": "123"
|
|
907
|
+
* }
|
|
908
|
+
* ]
|
|
909
|
+
* ```
|
|
910
|
+
*
|
|
911
|
+
* Phần tử `"Alice"` sẽ không được thêm lần nữa vì đã tồn tại với cùng
|
|
912
|
+
* `username` và `guild`.
|
|
913
|
+
*
|
|
716
914
|
* @throws {BlackCatError}
|
|
717
|
-
* - `REQUIRED_PARAMETER_MISSING` nếu
|
|
718
|
-
* - `INVALID_TYPE` nếu key không phải string
|
|
915
|
+
* - `REQUIRED_PARAMETER_MISSING` nếu không truyền `key`.
|
|
916
|
+
* - `INVALID_TYPE` nếu `key` không phải kiểu `string`.
|
|
719
917
|
*/
|
|
720
|
-
update<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<If<IsObject<V>, ObjectValue<V,
|
|
918
|
+
update<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, value: ObjectValue<V, P>): Promise<If<IsObject<V>, ObjectValue<V, P>>>;
|
|
919
|
+
/**
|
|
920
|
+
* ## Đồng bộ dữ liệu với cơ sở dữ liệu
|
|
921
|
+
*
|
|
922
|
+
* ### Chức năng
|
|
923
|
+
* Đồng bộ dữ liệu tại một đường dẫn (`keys`) với giá trị mới (`value`).
|
|
924
|
+
*
|
|
925
|
+
* Hàm sẽ tự động:
|
|
926
|
+
* - Tạo mới dữ liệu nếu chưa tồn tại.
|
|
927
|
+
* - So sánh dữ liệu cũ và mới.
|
|
928
|
+
* - Chỉ cập nhật các trường thực sự thay đổi đối với Object.
|
|
929
|
+
* - Không thực hiện ghi nếu dữ liệu không thay đổi.
|
|
930
|
+
*
|
|
931
|
+
* Điều này giúp giảm số lần ghi xuống cơ sở dữ liệu và tối ưu hiệu năng.
|
|
932
|
+
*
|
|
933
|
+
* ---
|
|
934
|
+
*
|
|
935
|
+
* ### Cơ chế hoạt động
|
|
936
|
+
*
|
|
937
|
+
* 1. Lấy dữ liệu hiện tại bằng `get()`.
|
|
938
|
+
* 2. Nếu chưa tồn tại (`undefined` hoặc `null`)
|
|
939
|
+
* → gọi `set()` để tạo mới.
|
|
940
|
+
* 3. Nếu truyền hàm `compare` và hàm này trả về `true`
|
|
941
|
+
* → bỏ qua đồng bộ.
|
|
942
|
+
* 4. Nếu dữ liệu không phải Object (hoặc là Array)
|
|
943
|
+
* → so sánh bằng `Object.is()`, nếu khác thì gọi `update()`.
|
|
944
|
+
* 5. Nếu dữ liệu là Object
|
|
945
|
+
* → chỉ lấy các thuộc tính thay đổi và cập nhật đúng các trường đó.
|
|
946
|
+
* 6. Nếu không có trường nào thay đổi thì không ghi dữ liệu.
|
|
947
|
+
*
|
|
948
|
+
* ---
|
|
949
|
+
*
|
|
950
|
+
* ### Giá trị trả về
|
|
951
|
+
*
|
|
952
|
+
* - `undefined`
|
|
953
|
+
* - Khi tạo mới dữ liệu.
|
|
954
|
+
* - Khi không có thay đổi.
|
|
955
|
+
* - Khi dữ liệu nguyên thủy được cập nhật.
|
|
956
|
+
* - `Partial<ObjectValue<V, P>>`
|
|
957
|
+
* - Trả về object chỉ chứa các trường đã được cập nhật khi đồng bộ Object.
|
|
958
|
+
*
|
|
959
|
+
* ---
|
|
960
|
+
*
|
|
961
|
+
* ### Ví dụ
|
|
962
|
+
*
|
|
963
|
+
* ```ts
|
|
964
|
+
* // Tạo mới nếu chưa tồn tại
|
|
965
|
+
* await db.syncDatabase({
|
|
966
|
+
* keys: "users.1",
|
|
967
|
+
* value: {
|
|
968
|
+
* name: "BlackCat",
|
|
969
|
+
* age: 20
|
|
970
|
+
* }
|
|
971
|
+
* });
|
|
972
|
+
*
|
|
973
|
+
* // Chỉ cập nhật trường age
|
|
974
|
+
* await db.syncDatabase({
|
|
975
|
+
* keys: "users.1",
|
|
976
|
+
* value: {
|
|
977
|
+
* name: "BlackCat",
|
|
978
|
+
* age: 21
|
|
979
|
+
* }
|
|
980
|
+
* });
|
|
981
|
+
*
|
|
982
|
+
* // Sử dụng compare để bỏ qua đồng bộ
|
|
983
|
+
* await db.syncDatabase({
|
|
984
|
+
* keys: "users.1",
|
|
985
|
+
* value: newData,
|
|
986
|
+
* compare(oldData, newData) {
|
|
987
|
+
* return oldData.version >= newData.version;
|
|
988
|
+
* }
|
|
989
|
+
* });
|
|
990
|
+
* ```
|
|
991
|
+
*
|
|
992
|
+
* @template P Đường dẫn tới dữ liệu trong cơ sở dữ liệu.
|
|
993
|
+
*
|
|
994
|
+
* @param options Thông tin đồng bộ.
|
|
995
|
+
* @param options.keys Đường dẫn của dữ liệu cần đồng bộ.
|
|
996
|
+
* @param options.value Giá trị mới cần ghi.
|
|
997
|
+
* @param options.compare Hàm so sánh tùy chỉnh. Nếu trả về `true` thì sẽ không thực hiện đồng bộ.
|
|
998
|
+
*
|
|
999
|
+
* @returns
|
|
1000
|
+
* - `undefined` nếu không có thay đổi hoặc dữ liệu được tạo mới.
|
|
1001
|
+
* - `Partial<ObjectValue<V, P>>` chứa các trường đã thay đổi khi cập nhật Object.
|
|
1002
|
+
*/
|
|
1003
|
+
syncDatabase<P extends AutocompletableString<ObjectPath<V>>>({ keys, value, compare }: {
|
|
1004
|
+
keys: AutocompletableString<P>;
|
|
1005
|
+
value: ObjectValue<V, P>;
|
|
1006
|
+
compare?: (oldData: ObjectValue<V, P>, newData: ObjectValue<V, P>) => boolean;
|
|
1007
|
+
}): Promise<Partial<ObjectValue<V, P>> | undefined>;
|
|
721
1008
|
/**
|
|
722
1009
|
* Cộng thêm giá trị vào một key dạng number.
|
|
723
1010
|
*
|
|
@@ -754,6 +1041,22 @@ declare class Database<V = any> {
|
|
|
754
1041
|
* ```
|
|
755
1042
|
*/
|
|
756
1043
|
subtract<P extends AutocompletableString<ObjectPath<V>>>(key: AutocompletableString<P>, numberToSubtract: number): Promise<number>;
|
|
1044
|
+
/**
|
|
1045
|
+
* Thêm một hoặc nhiều phần tử vào đầu array.
|
|
1046
|
+
*
|
|
1047
|
+
* Chỉ thêm những phần tử chưa tồn tại trong array.
|
|
1048
|
+
*
|
|
1049
|
+
* @typeParam P - Path trỏ tới array.
|
|
1050
|
+
*
|
|
1051
|
+
* @param key - Đường dẫn array.
|
|
1052
|
+
* @param values - Một hoặc nhiều phần tử cần thêm.
|
|
1053
|
+
*
|
|
1054
|
+
* @returns Array sau khi thêm.
|
|
1055
|
+
*
|
|
1056
|
+
* @example
|
|
1057
|
+
* await db.unshift("users", newUser);
|
|
1058
|
+
*/
|
|
1059
|
+
unshift<P extends ObjectPath<V>>(key: AutocompletableString<P>, ...values: RestOrArray<ExtractFromArray<ObjectValue<V, P>>>): Promise<ExtractFromArray<ObjectValue<V, P>>[]>;
|
|
757
1060
|
/**
|
|
758
1061
|
* Thêm một hoặc nhiều phần tử vào cuối array tại key-path.
|
|
759
1062
|
*
|
|
@@ -1519,4 +1822,4 @@ declare class MongoDriver implements DatabaseDriver {
|
|
|
1519
1822
|
delete(): Promise<boolean>;
|
|
1520
1823
|
}
|
|
1521
1824
|
|
|
1522
|
-
export { Database, JSONDriver, MemoryDriver, MongoDriver, SQLiteDriver };
|
|
1825
|
+
export { Database, type DatabaseDriver, JSONDriver, MemoryDriver, MongoDriver, SQLiteDriver };
|