diff --git a/apps/backend/src/features/search/index.spec.ts b/apps/backend/src/features/search/index.spec.ts index ce177039..50d0a15a 100644 --- a/apps/backend/src/features/search/index.spec.ts +++ b/apps/backend/src/features/search/index.spec.ts @@ -19,7 +19,7 @@ describe( 'Search', () => { it( 'should return no results given an unreasonable query', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'pppppppppppppppp' } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'pppppppppppppppp' } ) const results = await client.waitForEvent( 'search:results' ) expect( results ).toHaveLength( 0 ) @@ -28,7 +28,7 @@ describe( 'Search', () => { it( 'should return first letter results', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'hhhg' } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'hhhg' } ) const results = await client.waitForEvent( 'search:results' ) expect( results.length ).toBeGreaterThan( 0 ) @@ -37,7 +37,7 @@ describe( 'Search', () => { it( 'should return full word results', async () => { const { client } = setup() - await client.sendEvent( 'search:full-word', { query: 'hir gun gwvY' } ) + await client.sendEvent( 'search:query', { type: 'full-word', query: 'hir gun gwvY' } ) const results = await client.waitForEvent( 'search:results' ) expect( results.length ).toBeGreaterThan( 0 ) @@ -46,7 +46,7 @@ describe( 'Search', () => { it( 'should not return extra fields determined by options', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'hggmssp' } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'hggmssp' } ) const results = await client.waitForEvent( 'search:results' ) expect( results[ 0 ].shabad ).toBeUndefined() @@ -58,7 +58,7 @@ describe( 'Search', () => { it( 'should return citations with results', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'hggmssp', options: { citations: true } } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'hggmssp', options: { citations: true } } ) const results = await client.waitForEvent( 'search:results' ) expect( results[ 0 ].shabad!.section ).toBeDefined() @@ -67,7 +67,7 @@ describe( 'Search', () => { it( 'should return translations with results', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'hggmssp', options: { translations: true } } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'hggmssp', options: { translations: true } } ) const results = await client.waitForEvent( 'search:results' ) expect( results[ 0 ].translations ).toBeDefined() @@ -76,7 +76,7 @@ describe( 'Search', () => { it( 'should return transliterations with results', async () => { const { client } = setup() - await client.sendEvent( 'search:first-letter', { query: 'hggmssp', options: { transliterations: true } } ) + await client.sendEvent( 'search:query', { type: 'first-letter', query: 'hggmssp', options: { transliterations: true } } ) const results = await client.waitForEvent( 'search:results' ) expect( results[ 0 ].transliterations ).toBeDefined() diff --git a/apps/backend/src/features/search/index.ts b/apps/backend/src/features/search/index.ts index ef5313ad..a5ff34ba 100644 --- a/apps/backend/src/features/search/index.ts +++ b/apps/backend/src/features/search/index.ts @@ -1,20 +1,31 @@ +import { SearchQuery } from '@presenter/contract' + import { firstLetterSearch, fullWordSearch } from '~/services/database' import { SocketServer } from '~/services/websocket-server' -const searchHandlers = [ - [ 'first-letter', firstLetterSearch ], - [ 'full-word', fullWordSearch ], -] as const +const searchHandlers = { + 'first-letter': firstLetterSearch, + 'full-word': fullWordSearch, +} satisfies Record< + //! This typing is a little silly + SearchQuery['type'], + ( params: Parameters[0] ) => ReturnType +> type SearchModuleOptions = { socketServer: SocketServer, } const createSearchModule = ( { socketServer }: SearchModuleOptions ) => { - searchHandlers.forEach( ( [ name, searchFn ] ) => socketServer.on( - `search:${name}`, - ( { query, options }, { json } ) => void searchFn( query, options ).then( ( results ) => json( 'search:results', results ) ) - ) ) + socketServer.on( + 'search:query', + ( { type, query, options }, { json } ) => { + const searchFn = searchHandlers[ type ] + if ( !searchFn ) return + + void searchFn( query, options ).then( ( results ) => json( 'search:results', results ) ) + } + ) } export default createSearchModule diff --git a/packages/contract/src/index.ts b/packages/contract/src/index.ts index 161b4a30..cf7fdc69 100644 --- a/packages/contract/src/index.ts +++ b/packages/contract/src/index.ts @@ -1,4 +1,5 @@ export * from './about' export * from './data' +export * from './search' export * from './settings' export * from './websocket' diff --git a/packages/contract/src/search.ts b/packages/contract/src/search.ts index f69eaba8..ae194bba 100644 --- a/packages/contract/src/search.ts +++ b/packages/contract/src/search.ts @@ -1,4 +1,5 @@ export type SearchQuery = { + type: 'first-letter' | 'full-word', query: string, options?: { translations?: boolean, diff --git a/packages/contract/src/websocket.ts b/packages/contract/src/websocket.ts index 179d167b..872cfcd9 100644 --- a/packages/contract/src/websocket.ts +++ b/packages/contract/src/websocket.ts @@ -22,8 +22,7 @@ export const serverEvents = [ 'content:tracker:autojump', 'history:clear', 'settings:all', - 'search:first-letter', - 'search:full-word', + 'search:query', 'action:open-overlay-folder', 'action:open-logs-folder', 'action:open-external-url', @@ -37,8 +36,7 @@ export type ServerEventParameters = DefineParameters, - 'search:full-word': SearchQuery, - 'search:first-letter': SearchQuery, + 'search:query': SearchQuery, 'action:open-external-url': string, }>