@@ -11,6 +11,7 @@ import type {
11
11
HistoryEntry ,
12
12
IdempotentListener ,
13
13
IdGenerator ,
14
+ IdUpsertInput ,
14
15
IndexDataEntry ,
15
16
KvId ,
16
17
KvKey ,
@@ -22,6 +23,7 @@ import type {
22
23
ParseInputType ,
23
24
PossibleCollectionOptions ,
24
25
PrimaryIndexKeys ,
26
+ PrimaryIndexUpsertInput ,
25
27
QueueHandlers ,
26
28
QueueListenerOptions ,
27
29
QueueMessageHandler ,
@@ -33,6 +35,8 @@ import type {
33
35
UpdateData ,
34
36
UpdateManyOptions ,
35
37
UpdateOptions ,
38
+ UpsertInput ,
39
+ UpsertOptions ,
36
40
WatchOptions ,
37
41
} from "./types.ts"
38
42
import {
@@ -830,6 +834,57 @@ export class Collection<
830
834
)
831
835
}
832
836
837
+ async upsert <
838
+ const TIndex extends PrimaryIndexKeys < TOutput , TOptions > ,
839
+ > (
840
+ input : UpsertInput < TInput , TOutput , TIndex > ,
841
+ options ?: UpsertOptions ,
842
+ ) {
843
+ // Check if is id or primary index upsert
844
+ if ( ( input as any ) . index !== undefined ) {
845
+ const inp = input as PrimaryIndexUpsertInput < TInput , TOutput , TIndex >
846
+
847
+ // First attempt update
848
+ const updateCr = await this . updateByPrimaryIndex (
849
+ ...inp . index ,
850
+ inp . update ,
851
+ options ,
852
+ )
853
+
854
+ if ( updateCr . ok ) {
855
+ return updateCr
856
+ }
857
+
858
+ // If id is present, set new entry with given id
859
+ if ( inp . id ) {
860
+ return await this . set ( inp . id , inp . set , {
861
+ ...options ,
862
+ overwrite : false ,
863
+ } )
864
+ }
865
+
866
+ // If no id, set new entry with generated id
867
+ return await this . add ( inp . set , {
868
+ ...options ,
869
+ overwrite : false ,
870
+ } )
871
+ } else {
872
+ // First attempt update
873
+ const id = ( input as IdUpsertInput < TInput , TOutput > ) . id
874
+ const updateCr = await this . update ( id , input . update , options )
875
+
876
+ if ( updateCr . ok ) {
877
+ return updateCr
878
+ }
879
+
880
+ // Set new entry with given id
881
+ return await this . set ( id , input . set , {
882
+ ...options ,
883
+ overwrite : false ,
884
+ } )
885
+ }
886
+ }
887
+
833
888
/**
834
889
* Update the value of multiple existing documents in the collection.
835
890
*
0 commit comments