diff --git a/src/engines/main.ts b/src/engines/main.ts index 0481ff1..c611ba3 100644 --- a/src/engines/main.ts +++ b/src/engines/main.ts @@ -44,6 +44,4 @@ export abstract class MagnifyEngine { async get(builder: Builder): Promise { return this.map(builder, await this.search(builder)) } - - abstract get client(): any } diff --git a/src/magnify_manager.ts b/src/magnify_manager.ts index afc3394..8f2a84d 100644 --- a/src/magnify_manager.ts +++ b/src/magnify_manager.ts @@ -1,9 +1,8 @@ import { RuntimeException } from '@adonisjs/core/exceptions' import { ManagerEngineFactory } from './types.js' -import { MagnifyEngine } from './engines/main.js' export class MagnifyManager> { - #cachedEngines: Partial> = {} + #cachedEngines: Map> = new Map() constructor(public config: { default?: keyof KnownEngines; engines: KnownEngines }) {} @@ -11,24 +10,28 @@ export class MagnifyManager(engine?: EngineName): MagnifyEngine { - const engineToUse = engine || this.config.default + engine( + engine?: EngineName + ): ReturnType { + 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 + this.#cachedEngines.set(engineToUse, newEngine) + return newEngine } } diff --git a/src/mixins/searchable.ts b/src/mixins/searchable.ts index 71633b0..8be6e48 100644 --- a/src/mixins/searchable.ts +++ b/src/mixins/searchable.ts @@ -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' diff --git a/tests/fixtures/fake_engine.ts b/tests/fixtures/fake_engine.ts index 299de8e..1e59662 100644 --- a/tests/fixtures/fake_engine.ts +++ b/tests/fixtures/fake_engine.ts @@ -20,7 +20,4 @@ export class FakeEngine extends MagnifyEngine { flush(): Promise { throw new Error('Method not implemented.') } - get client(): any { - throw new Error('Method not implemented.') - } } diff --git a/tests/units/magnify_manager.spec.ts b/tests/units/magnify_manager.spec.ts index aa2a989..b46d480 100644 --- a/tests/units/magnify_manager.spec.ts +++ b/tests/units/magnify_manager.spec.ts @@ -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 }) => { @@ -34,16 +35,16 @@ test.group('Magnify manager', () => { .parameter(0) .toEqualTypeOf<'meilisearch' | 'typesense' | 'algolia' | undefined>() - expectTypeOf(manager.engine('meilisearch')).toEqualTypeOf() - expectTypeOf(manager.engine('algolia')).toEqualTypeOf() - expectTypeOf(manager.engine('typesense')).toEqualTypeOf() + expectTypeOf(manager.engine('meilisearch')).toEqualTypeOf() + expectTypeOf(manager.engine('algolia')).toEqualTypeOf() + expectTypeOf(manager.engine('typesense')).toEqualTypeOf() 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: { @@ -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() + expectTypeOf(manager.engine('algolia').client).toEqualTypeOf() + expectTypeOf(manager.engine('typesense').client).toEqualTypeOf() }) })