@@ -38,8 +38,9 @@ const ShareSchema = Schema.Struct({
3838export type Share = typeof ShareSchema . Type
3939
4040type State = {
41- queue : Map < string , { data : Map < string , Data > } >
41+ queue : Map < SessionID , Map < string , Data > >
4242 scope : Scope . Closeable
43+ shared : Map < SessionID , Share | null >
4344}
4445
4546type Data =
@@ -118,17 +119,20 @@ export const layer = Layer.effect(
118119 function sync ( sessionID : SessionID , data : Data [ ] ) : Effect . Effect < void > {
119120 return Effect . gen ( function * ( ) {
120121 if ( disabled ) return
122+ const share = yield * getCached ( sessionID )
123+ if ( ! share ) return
124+
121125 const s = yield * InstanceState . get ( state )
122126 const existing = s . queue . get ( sessionID )
123127 if ( existing ) {
124128 for ( const item of data ) {
125- existing . data . set ( key ( item ) , item )
129+ existing . set ( key ( item ) , item )
126130 }
127131 return
128132 }
129133
130134 const next = new Map ( data . map ( ( item ) => [ key ( item ) , item ] ) )
131- s . queue . set ( sessionID , { data : next } )
135+ s . queue . set ( sessionID , next )
132136 yield * flush ( sessionID ) . pipe (
133137 Effect . delay ( 1000 ) ,
134138 Effect . catchCause ( ( cause ) =>
@@ -143,13 +147,14 @@ export const layer = Layer.effect(
143147
144148 const state : InstanceState . InstanceState < State > = yield * InstanceState . make < State > (
145149 Effect . fn ( "ShareNext.state" ) ( function * ( _ctx ) {
146- const cache : State = { queue : new Map ( ) , scope : yield * Scope . make ( ) }
150+ const cache : State = { queue : new Map ( ) , scope : yield * Scope . make ( ) , shared : new Map ( ) }
147151
148152 yield * Effect . addFinalizer ( ( ) =>
149153 Scope . close ( cache . scope , Exit . void ) . pipe (
150154 Effect . andThen (
151155 Effect . sync ( ( ) => {
152156 cache . queue . clear ( )
157+ cache . shared . clear ( )
153158 } ) ,
154159 ) ,
155160 ) ,
@@ -227,6 +232,18 @@ export const layer = Layer.effect(
227232 return { id : row . id , secret : row . secret , url : row . url } satisfies Share
228233 } )
229234
235+ const getCached = Effect . fnUntraced ( function * ( sessionID : SessionID ) {
236+ const s = yield * InstanceState . get ( state )
237+ if ( s . shared . has ( sessionID ) ) {
238+ const cached = s . shared . get ( sessionID )
239+ return cached === null ? undefined : cached
240+ }
241+
242+ const share = yield * get ( sessionID )
243+ s . shared . set ( sessionID , share ?? null )
244+ return share
245+ } )
246+
230247 const flush = Effect . fn ( "ShareNext.flush" ) ( function * ( sessionID : SessionID ) {
231248 if ( disabled ) return
232249 const s = yield * InstanceState . get ( state )
@@ -235,13 +252,13 @@ export const layer = Layer.effect(
235252
236253 s . queue . delete ( sessionID )
237254
238- const share = yield * get ( sessionID )
255+ const share = yield * getCached ( sessionID )
239256 if ( ! share ) return
240257
241258 const req = yield * request ( )
242259 const res = yield * HttpClientRequest . post ( `${ req . baseUrl } ${ req . api . sync ( share . id ) } ` ) . pipe (
243260 HttpClientRequest . setHeaders ( req . headers ) ,
244- HttpClientRequest . bodyJson ( { secret : share . secret , data : Array . from ( queued . data . values ( ) ) } ) ,
261+ HttpClientRequest . bodyJson ( { secret : share . secret , data : Array . from ( queued . values ( ) ) } ) ,
245262 Effect . flatMap ( ( r ) => http . execute ( r ) ) ,
246263 )
247264
@@ -307,6 +324,7 @@ export const layer = Layer.effect(
307324 . run ( ) ,
308325 )
309326 const s = yield * InstanceState . get ( state )
327+ s . shared . set ( sessionID , result )
310328 yield * full ( sessionID ) . pipe (
311329 Effect . catchCause ( ( cause ) =>
312330 Effect . sync ( ( ) => {
@@ -321,8 +339,13 @@ export const layer = Layer.effect(
321339 const remove = Effect . fn ( "ShareNext.remove" ) ( function * ( sessionID : SessionID ) {
322340 if ( disabled ) return
323341 log . info ( "removing share" , { sessionID } )
324- const share = yield * get ( sessionID )
325- if ( ! share ) return
342+ const s = yield * InstanceState . get ( state )
343+ const share = yield * getCached ( sessionID )
344+ if ( ! share ) {
345+ s . shared . delete ( sessionID )
346+ s . queue . delete ( sessionID )
347+ return
348+ }
326349
327350 const req = yield * request ( )
328351 yield * HttpClientRequest . delete ( `${ req . baseUrl } ${ req . api . remove ( share . id ) } ` ) . pipe (
@@ -332,6 +355,8 @@ export const layer = Layer.effect(
332355 )
333356
334357 yield * db ( ( db ) => db . delete ( SessionShareTable ) . where ( eq ( SessionShareTable . session_id , sessionID ) ) . run ( ) )
358+ s . shared . delete ( sessionID )
359+ s . queue . delete ( sessionID )
335360 } )
336361
337362 return Service . of ( { init, url, request, create, remove } )
0 commit comments