77 type Tag ,
88 type NewTag ,
99 type EntryTag ,
10+ type EntryWithTags ,
1011 entrySchema ,
1112 newEntrySchema ,
1213 tagSchema ,
@@ -19,6 +20,25 @@ export type { Entry, NewEntry, Tag, NewTag, EntryTag }
1920
2021export class DB {
2122 #db: DatabaseSync
23+ #subscribers = new Set <
24+ ( changes : { tags ?: number [ ] ; entries ?: number [ ] } ) => void
25+ > ( )
26+
27+ subscribe (
28+ subscriber : ( changes : { tags ?: number [ ] ; entries ?: number [ ] } ) => void ,
29+ ) {
30+ this . #subscribers. add ( subscriber )
31+ return ( ) => {
32+ this . #subscribers. delete ( subscriber )
33+ }
34+ }
35+
36+ #notifySubscribers( changes : { tags ?: number [ ] ; entries ?: number [ ] } ) {
37+ for ( const subscriber of this . #subscribers) {
38+ subscriber ( changes )
39+ }
40+ }
41+
2242 constructor ( db : DatabaseSync ) {
2343 this . #db = db
2444 }
@@ -60,6 +80,7 @@ export class DB {
6080 if ( ! createdEntry ) {
6181 throw new Error ( 'Failed to query created entry' )
6282 }
83+ this . #notifySubscribers( { entries : [ id ] } )
6384 return createdEntry
6485 }
6586
@@ -87,7 +108,7 @@ export class DB {
87108 const tags = z
88109 . array ( z . object ( { id : z . number ( ) , name : z . string ( ) } ) )
89110 . parse ( tagsResult )
90- return { ...entry , tags }
111+ return { ...entry , tags } as EntryWithTags
91112 }
92113
93114 // TODO: listEntries to actually filter by tagIds
@@ -109,25 +130,25 @@ export class DB {
109130 }
110131 const updates = Object . entries ( entry )
111132 . filter ( ( [ key , value ] ) => value !== undefined )
112- . map ( ( [ key ] , index ) => `${ key } = ?${ index + 2 } ` )
133+ . map ( ( [ key ] ) => `${ key } = ?` )
113134 . join ( ', ' )
114135 if ( ! updates ) {
115136 return existingEntry
116137 }
117- const stmt = this . #db. prepare ( sql `
118- UPDATE entries
119- SET ${ updates } , updated_at = CURRENT_TIMESTAMP
120- WHERE id = ?1
121- ` )
122138 const updateValues = [
123- id ,
124139 ...Object . entries ( entry )
125140 . filter ( ( [ , value ] ) => value !== undefined )
126141 . map ( ( [ , value ] ) => value ) ,
142+ id ,
127143 ]
128144 if ( updateValues . some ( ( v ) => v === undefined ) ) {
129145 throw new Error ( 'Undefined value in updateEntry parameters' )
130146 }
147+ const stmt = this . #db. prepare ( sql `
148+ UPDATE entries
149+ SET ${ updates } , updated_at = CURRENT_TIMESTAMP
150+ WHERE id = ?
151+ ` )
131152 const result = stmt . run ( ...updateValues )
132153 if ( ! result . changes ) {
133154 throw new Error ( 'Failed to update entry' )
@@ -136,6 +157,7 @@ export class DB {
136157 if ( ! updatedEntry ) {
137158 throw new Error ( 'Failed to query updated entry' )
138159 }
160+ this . #notifySubscribers( { entries : [ id ] } )
139161 return updatedEntry
140162 }
141163
@@ -149,6 +171,7 @@ export class DB {
149171 if ( ! result . changes ) {
150172 throw new Error ( 'Failed to delete entry' )
151173 }
174+ this . #notifySubscribers( { entries : [ id ] } )
152175 return true
153176 }
154177
@@ -171,6 +194,7 @@ export class DB {
171194 if ( ! createdTag ) {
172195 throw new Error ( 'Failed to query created tag' )
173196 }
197+ this . #notifySubscribers( { tags : [ id ] } )
174198 return createdTag
175199 }
176200
@@ -202,25 +226,25 @@ export class DB {
202226 }
203227 const updates = Object . entries ( tag )
204228 . filter ( ( [ , value ] ) => value !== undefined )
205- . map ( ( [ key ] , index ) => `${ key } = ?${ index + 2 } ` )
229+ . map ( ( [ key ] ) => `${ key } = ?` )
206230 . join ( ', ' )
207231 if ( ! updates ) {
208232 return existingTag
209233 }
210- const stmt = this . #db. prepare ( sql `
211- UPDATE tags
212- SET ${ updates } , updated_at = CURRENT_TIMESTAMP
213- WHERE id = ?1
214- ` )
215234 const updateValues = [
216- id ,
217235 ...Object . entries ( tag )
218236 . filter ( ( [ , value ] ) => value !== undefined )
219237 . map ( ( [ , value ] ) => value ) ,
238+ id ,
220239 ]
221240 if ( updateValues . some ( ( v ) => v === undefined ) ) {
222241 throw new Error ( 'Undefined value in updateTag parameters' )
223242 }
243+ const stmt = this . #db. prepare ( sql `
244+ UPDATE tags
245+ SET ${ updates } , updated_at = CURRENT_TIMESTAMP
246+ WHERE id = ?
247+ ` )
224248 const result = stmt . run ( ...updateValues )
225249 if ( ! result . changes ) {
226250 throw new Error ( 'Failed to update tag' )
@@ -229,6 +253,7 @@ export class DB {
229253 if ( ! updatedTag ) {
230254 throw new Error ( 'Failed to query updated tag' )
231255 }
256+ this . #notifySubscribers( { tags : [ id ] } )
232257 return updatedTag
233258 }
234259
@@ -242,6 +267,7 @@ export class DB {
242267 if ( ! result . changes ) {
243268 throw new Error ( 'Failed to delete tag' )
244269 }
270+ this . #notifySubscribers( { tags : [ id ] } )
245271 return true
246272 }
247273
@@ -271,6 +297,7 @@ export class DB {
271297 if ( ! created ) {
272298 throw new Error ( 'Failed to query created entry tag' )
273299 }
300+ this . #notifySubscribers( { entries : [ entryId ] , tags : [ tagId ] } )
274301 return created
275302 }
276303
0 commit comments