@@ -13,7 +13,7 @@ export interface BotCode {
1313
1414export type BotCodes = Record < string , BotCode > ;
1515
16- let STORE : BotCodes = { } ;
16+ let ACTIVE_BOT_STORE : BotCodes = { } ;
1717
1818const botEventEmitter = new EventEmitter ( ) ;
1919
@@ -23,11 +23,36 @@ type SubmitBotCodeArgs = {
2323 userId : number ;
2424} ;
2525
26+ function formatBotCodeFilename ( { username, id, userId } : { username : string ; id : string ; userId : number } ) {
27+ return `${ BOT_CODE_DIR } /${ username } -${ id } -${ userId } .js` ;
28+ }
29+
30+ function extractBotMetadataFromFilename ( filename : string ) {
31+ const username = filename . split ( "-" ) [ 0 ] ;
32+ const id = filename . split ( "-" ) [ 1 ] ;
33+ const userId = filename . split ( "-" ) [ 2 ] ?. replace ( ".js" , "" ) ;
34+ if ( ! id || ! username || ! userId ) {
35+ throw new Error ( `Invalid bot code file: ${ filename } ` ) ;
36+ }
37+ return { id, username, userId : Number ( userId ) } ;
38+ }
39+
40+ async function getFirstUserBotMetadata ( userId : number ) {
41+ const userBotFiles = await fs . readdir ( BOT_CODE_DIR ) ;
42+ for ( const file of userBotFiles ) {
43+ const { username, id, userId : fileUserId } = extractBotMetadataFromFilename ( file ) ;
44+ if ( fileUserId === userId ) {
45+ return { id, username, userId : fileUserId } ;
46+ }
47+ }
48+ }
49+
2650export async function submitBotCode ( { code, username, userId } : SubmitBotCodeArgs ) {
27- // ensure each user has only one bot
28- const id = Object . values ( STORE ) . find ( botCode => botCode . username === username ) ?. id || Math . random ( ) . toString ( 36 ) . substring ( 5 ) ;
51+ const existingBotMetadata = await getFirstUserBotMetadata ( userId ) ;
52+ // Ensure that every user has only one bot
53+ const id = existingBotMetadata ?. id || Math . random ( ) . toString ( 36 ) . substring ( 5 ) ;
2954 const botCode = { id, code, username, userId } ;
30- STORE [ id ] = botCode ;
55+ ACTIVE_BOT_STORE [ id ] = botCode ;
3156 await saveBot ( botCode ) ;
3257
3358 // Submitting code makes the user active
@@ -36,15 +61,15 @@ export async function submitBotCode({ code, username, userId }: SubmitBotCodeArg
3661 data : { inactive : false } ,
3762 } ) ;
3863
39- botEventEmitter . emit ( "update" , STORE ) ;
64+ botEventEmitter . emit ( "update" , ACTIVE_BOT_STORE ) ;
4065}
4166
4267export function clearBots ( ) {
43- STORE = { } ;
68+ ACTIVE_BOT_STORE = { } ;
4469}
4570
4671export function getBots ( ) {
47- return { ...STORE } ;
72+ return { ...ACTIVE_BOT_STORE } ;
4873}
4974
5075export function subscribeToBotsUpdate ( onUpdate : ( bots : BotCodes ) => void ) : ( ) => void {
@@ -75,34 +100,36 @@ async function loadBots() {
75100 const inactiveUserIds = new Set ( inactiveUsers . map ( user => user . id ) ) ;
76101
77102 for ( const file of files ) {
78- const code = await fs . readFile ( `${ BOT_CODE_DIR } /${ file } ` , "utf8" ) ;
79- const username = file . split ( "-" ) [ 0 ] ;
80- const id = file . split ( "-" ) [ 1 ] ;
81- const userId = file . split ( "-" ) [ 2 ] ?. replace ( ".js" , "" ) ;
82- if ( ! id || ! code || ! username || ! userId ) {
103+ const { username, id, userId } = extractBotMetadataFromFilename ( file ) ;
104+ if ( ! id || ! username || ! userId ) {
83105 throw new Error ( `Invalid bot code file: ${ file } ` ) ;
84106 }
85107
86- if ( inactiveUserIds . has ( + userId ) ) {
108+ if ( inactiveUserIds . has ( userId ) ) {
87109 continue ;
88110 }
89111
90- STORE [ id ] = { id, code, username, userId : + userId } ;
112+ const code = await fs . readFile ( `${ BOT_CODE_DIR } /${ file } ` , "utf8" ) ;
113+ if ( ! code ) {
114+ throw new Error ( `Failed to read bot code file: ${ file } ` ) ;
115+ }
116+
117+ ACTIVE_BOT_STORE [ id ] = { id, code, username, userId } ;
91118 }
92119
93- botEventEmitter . emit ( "update" , STORE ) ;
120+ botEventEmitter . emit ( "update" , ACTIVE_BOT_STORE ) ;
94121}
95122
96123async function saveBot ( { id, code, username, userId } : BotCode ) {
97124 if ( ! await fsExists ( BOT_CODE_DIR ) ) {
98125 await fs . mkdir ( BOT_CODE_DIR ) ;
99126 }
100- const botCodeFile = ` ${ BOT_CODE_DIR } / ${ username } - ${ id } - ${ userId } .js` ;
127+ const botCodeFile = formatBotCodeFilename ( { username, id , userId } ) ;
101128
102129 await fs . writeFile ( botCodeFile , code ) ;
103130}
104131
105132loadBots ( )
106133 . then ( ( ) => {
107- console . log ( `Loaded ${ Object . keys ( STORE ) . length } bots` ) ;
134+ console . log ( `Loaded ${ Object . keys ( ACTIVE_BOT_STORE ) . length } bots` ) ;
108135 } ) ;
0 commit comments