Skip to content
This repository has been archived by the owner on Nov 9, 2024. It is now read-only.

Commit

Permalink
Improve typing of MagnifyManager
Browse files Browse the repository at this point in the history
  • Loading branch information
simoneNEMO committed Oct 2, 2024
1 parent e200886 commit a218b49
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 30 deletions.
2 changes: 0 additions & 2 deletions src/engines/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,4 @@ export abstract class MagnifyEngine {
async get(builder: Builder): Promise<any[]> {
return this.map(builder, await this.search(builder))
}

abstract get client(): any
}
35 changes: 19 additions & 16 deletions src/magnify_manager.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
import { RuntimeException } from '@adonisjs/core/exceptions'
import { ManagerEngineFactory } from './types.js'
import { MagnifyEngine } from './engines/main.js'

export class MagnifyManager<KnownEngines extends Record<string, ManagerEngineFactory>> {
#cachedEngines: Partial<Record<keyof KnownEngines, MagnifyEngine>> = {}
#cachedEngines: Map<keyof KnownEngines, ReturnType<KnownEngines[keyof KnownEngines]>> = new Map()

constructor(public config: { default?: keyof KnownEngines; engines: KnownEngines }) {}

/**
* Use one of the registered engines.
*
* ```ts
* manager.use() // returns default engine
* manager.use('meilisearch')
* manager.engine() // returns default engine
* manager.engine('meilisearch')
* ```
*/
engine<EngineName extends keyof KnownEngines>(engine?: EngineName): MagnifyEngine {
const engineToUse = engine || this.config.default
engine<EngineName extends keyof KnownEngines>(
engine?: EngineName
): ReturnType<KnownEngines[EngineName]> {
const engineToUse = (engine || this.config.default) as keyof KnownEngines
if (!engineToUse) throw new RuntimeException('No search engine selected')

if (!engineToUse) {
throw new RuntimeException(
'Cannot create engine instance. No default engine is defined in the config.'
)
/**
* Check if the search engine was already instantiated
*/
if (this.#cachedEngines.has(engineToUse)) {
return this.#cachedEngines.get(engineToUse)!
}

const cachedEngine = this.#cachedEngines[engineToUse]
if (cachedEngine) {
return cachedEngine
}

return this.config.engines[engineToUse]()
/**
* Otherwise create a new instance and cache it
*/
const newEngine = this.config.engines[engineToUse]() as ReturnType<KnownEngines[EngineName]>
this.#cachedEngines.set(engineToUse, newEngine)
return newEngine
}
}
2 changes: 1 addition & 1 deletion src/mixins/searchable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NormalizeConstructor } from '@adonisjs/core/types/helpers'
import { BaseModel } from '@adonisjs/lucid/orm'
import { ModelObject } from '@adonisjs/lucid/types/model'
import { Builder } from '../builder.js'
import magnify from '../../services/magnify.js'
import magnify from '../../services/main.js'
import { MagnifyEngine } from '../engines/main.js'
import { SearchableModel } from '../types.js'

Expand Down
23 changes: 12 additions & 11 deletions tests/units/magnify_manager.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Algoliasearch } from 'algoliasearch'
import { MeiliSearch } from 'meilisearch'
import { test } from '@japa/runner'
import { MagnifyManager } from '../../src/magnify_manager.js'
import { Client } from 'typesense'

import { MeilisearchEngine } from '../../src/engines/meilisearch.js'
import { MagnifyEngine } from '../../src/engines/main.js'
import { TypesenseEngine } from '../../src/engines/typesense.js'
import { MagnifyManager } from '../../src/magnify_manager.js'
import { AlgoliaEngine } from '../../src/engines/algolia.js'
import { MeiliSearch } from 'meilisearch'
import { Client } from 'typesense'

test.group('Magnify manager', () => {
test('create engine instance from the manager', ({ assert, expectTypeOf }) => {
Expand Down Expand Up @@ -34,16 +35,16 @@ test.group('Magnify manager', () => {
.parameter(0)
.toEqualTypeOf<'meilisearch' | 'typesense' | 'algolia' | undefined>()

expectTypeOf(manager.engine('meilisearch')).toEqualTypeOf<MagnifyEngine>()
expectTypeOf(manager.engine('algolia')).toEqualTypeOf<MagnifyEngine>()
expectTypeOf(manager.engine('typesense')).toEqualTypeOf<MagnifyEngine>()
expectTypeOf(manager.engine('meilisearch')).toEqualTypeOf<MeilisearchEngine>()
expectTypeOf(manager.engine('algolia')).toEqualTypeOf<AlgoliaEngine>()
expectTypeOf(manager.engine('typesense')).toEqualTypeOf<TypesenseEngine>()

assert.instanceOf(manager.engine('meilisearch'), MeilisearchEngine)
assert.instanceOf(manager.engine('algolia'), AlgoliaEngine)
assert.instanceOf(manager.engine('typesense'), TypesenseEngine)
})

test('get the client from an engine', ({ assert }) => {
test('get the client from an engine', ({ expectTypeOf }) => {
const manager = new MagnifyManager({
default: 'meilisearch',
engines: {
Expand All @@ -65,8 +66,8 @@ test.group('Magnify manager', () => {
},
})

assert.instanceOf(manager.engine('meilisearch').client, MeiliSearch)
// assert.instanceOf(manager.engine('algolia').client, Algoliasearch) // algolia exports a type and not a class
assert.instanceOf(manager.engine('typesense').client, Client)
expectTypeOf(manager.engine('meilisearch').client).toEqualTypeOf<MeiliSearch>()
expectTypeOf(manager.engine('algolia').client).toEqualTypeOf<Algoliasearch>()
expectTypeOf(manager.engine('typesense').client).toEqualTypeOf<Client>()
})
})

0 comments on commit a218b49

Please sign in to comment.