11import { Bus } from "@/bus"
22import { BusEvent } from "@/bus/bus-event"
3- import { Instance } from "@/project/instance "
3+ import { InstanceContext } from "@/effect/instances "
44import { ProjectID } from "@/project/schema"
55import { MessageID , SessionID } from "@/session/schema"
66import { PermissionTable } from "@/session/session.sql"
77import { Database , eq } from "@/storage/db"
8- import { InstanceState } from "@/util/instance-state"
98import { Log } from "@/util/log"
109import { Wildcard } from "@/util/wildcard"
1110import { Deferred , Effect , Layer , Schema , ServiceMap } from "effect"
@@ -104,11 +103,6 @@ interface PendingEntry {
104103 deferred : Deferred . Deferred < void , RejectedError | CorrectedError >
105104}
106105
107- type State = {
108- pending : Map < PermissionID , PendingEntry >
109- approved : Ruleset
110- }
111-
112106export const AskInput = Request . partial ( { id : true } ) . extend ( {
113107 ruleset : Ruleset ,
114108} )
@@ -133,36 +127,30 @@ export class PermissionService extends ServiceMap.Service<PermissionService, Per
133127 static readonly layer = Layer . effect (
134128 PermissionService ,
135129 Effect . gen ( function * ( ) {
136- const instanceState = yield * InstanceState . make < State > ( ( ) =>
137- Effect . sync ( ( ) => {
138- const row = Database . use ( ( db ) =>
139- db . select ( ) . from ( PermissionTable ) . where ( eq ( PermissionTable . project_id , Instance . project . id ) ) . get ( ) ,
140- )
141- return {
142- pending : new Map < PermissionID , PendingEntry > ( ) ,
143- approved : row ?. data ?? [ ] ,
144- }
145- } ) ,
130+ const { project } = yield * InstanceContext
131+ const row = Database . use ( ( db ) =>
132+ db . select ( ) . from ( PermissionTable ) . where ( eq ( PermissionTable . project_id , project . id ) ) . get ( ) ,
146133 )
134+ const pending = new Map < PermissionID , PendingEntry > ( )
135+ const approved : Ruleset = row ?. data ?? [ ]
147136
148137 const ask = Effect . fn ( "PermissionService.ask" ) ( function * ( input : z . infer < typeof AskInput > ) {
149- const state = yield * InstanceState . get ( instanceState )
150138 const { ruleset, ...request } = input
151- let pending = false
139+ let needsAsk = false
152140
153141 for ( const pattern of request . patterns ) {
154- const rule = evaluate ( request . permission , pattern , ruleset , state . approved )
142+ const rule = evaluate ( request . permission , pattern , ruleset , approved )
155143 log . info ( "evaluated" , { permission : request . permission , pattern, action : rule } )
156144 if ( rule . action === "deny" ) {
157145 return yield * new DeniedError ( {
158146 ruleset : ruleset . filter ( ( rule ) => Wildcard . match ( request . permission , rule . permission ) ) ,
159147 } )
160148 }
161149 if ( rule . action === "allow" ) continue
162- pending = true
150+ needsAsk = true
163151 }
164152
165- if ( ! pending ) return
153+ if ( ! needsAsk ) return
166154
167155 const id = request . id ?? PermissionID . ascending ( )
168156 const info : Request = {
@@ -172,22 +160,21 @@ export class PermissionService extends ServiceMap.Service<PermissionService, Per
172160 log . info ( "asking" , { id, permission : info . permission , patterns : info . patterns } )
173161
174162 const deferred = yield * Deferred . make < void , RejectedError | CorrectedError > ( )
175- state . pending . set ( id , { info, deferred } )
163+ pending . set ( id , { info, deferred } )
176164 void Bus . publish ( Event . Asked , info )
177165 return yield * Effect . ensuring (
178166 Deferred . await ( deferred ) ,
179167 Effect . sync ( ( ) => {
180- state . pending . delete ( id )
168+ pending . delete ( id )
181169 } ) ,
182170 )
183171 } )
184172
185173 const reply = Effect . fn ( "PermissionService.reply" ) ( function * ( input : z . infer < typeof ReplyInput > ) {
186- const state = yield * InstanceState . get ( instanceState )
187- const existing = state . pending . get ( input . requestID )
174+ const existing = pending . get ( input . requestID )
188175 if ( ! existing ) return
189176
190- state . pending . delete ( input . requestID )
177+ pending . delete ( input . requestID )
191178 void Bus . publish ( Event . Replied , {
192179 sessionID : existing . info . sessionID ,
193180 requestID : existing . info . id ,
@@ -200,9 +187,9 @@ export class PermissionService extends ServiceMap.Service<PermissionService, Per
200187 input . message ? new CorrectedError ( { feedback : input . message } ) : new RejectedError ( ) ,
201188 )
202189
203- for ( const [ id , item ] of state . pending . entries ( ) ) {
190+ for ( const [ id , item ] of pending . entries ( ) ) {
204191 if ( item . info . sessionID !== existing . info . sessionID ) continue
205- state . pending . delete ( id )
192+ pending . delete ( id )
206193 void Bus . publish ( Event . Replied , {
207194 sessionID : item . info . sessionID ,
208195 requestID : item . info . id ,
@@ -217,20 +204,20 @@ export class PermissionService extends ServiceMap.Service<PermissionService, Per
217204 if ( input . reply === "once" ) return
218205
219206 for ( const pattern of existing . info . always ) {
220- state . approved . push ( {
207+ approved . push ( {
221208 permission : existing . info . permission ,
222209 pattern,
223210 action : "allow" ,
224211 } )
225212 }
226213
227- for ( const [ id , item ] of state . pending . entries ( ) ) {
214+ for ( const [ id , item ] of pending . entries ( ) ) {
228215 if ( item . info . sessionID !== existing . info . sessionID ) continue
229216 const ok = item . info . patterns . every (
230- ( pattern ) => evaluate ( item . info . permission , pattern , state . approved ) . action === "allow" ,
217+ ( pattern ) => evaluate ( item . info . permission , pattern , approved ) . action === "allow" ,
231218 )
232219 if ( ! ok ) continue
233- state . pending . delete ( id )
220+ pending . delete ( id )
234221 void Bus . publish ( Event . Replied , {
235222 sessionID : item . info . sessionID ,
236223 requestID : item . info . id ,
@@ -246,8 +233,7 @@ export class PermissionService extends ServiceMap.Service<PermissionService, Per
246233 } )
247234
248235 const list = Effect . fn ( "PermissionService.list" ) ( function * ( ) {
249- const state = yield * InstanceState . get ( instanceState )
250- return Array . from ( state . pending . values ( ) , ( item ) => item . info )
236+ return Array . from ( pending . values ( ) , ( item ) => item . info )
251237 } )
252238
253239 return PermissionService . of ( { ask, reply, list } )
0 commit comments