diff --git a/.changeset/small-crabs-clean.md b/.changeset/small-crabs-clean.md new file mode 100644 index 0000000000..38415dfbae --- /dev/null +++ b/.changeset/small-crabs-clean.md @@ -0,0 +1,6 @@ +--- +"@medusajs/medusa": patch +"@medusajs/utils": patch +--- + +fix(medusa,utils): Searching indexing product subscriber diff --git a/packages/medusa/src/subscribers/product.js b/packages/medusa/src/subscribers/product.js deleted file mode 100644 index a04dde7e4c..0000000000 --- a/packages/medusa/src/subscribers/product.js +++ /dev/null @@ -1,121 +0,0 @@ -import ProductVariantService from "../services/product-variant" -import ProductService from "../services/product" -import { indexTypes } from "medusa-core-utils" -import { isSearchEngineInstalledResolutionKey } from "../loaders/plugins" - -const searchFields = [ - "id", - "title", - "subtitle", - "status", - "description", - "handle", - "is_giftcard", - "discountable", - "thumbnail", - "profile_id", - "collection_id", - "type_id", - "origin_country", - "created_at", - "updated_at", -] - -const searchRelations = [ - "variants", - "tags", - "type", - "collection", - "variants.prices", - "variants.options", - "options", -] - -class ProductSearchSubscriber { - constructor(container) { - this.eventBus_ = container.eventBusService - this.searchService_ = container.searchService - this.productService_ = container.productService - - /** - * Do not subscribe to any event in case no search engine have been installed. - * If some events need to be subscribed out of the search engine reason, they can be subscribed above this comment - */ - - try { - container[isSearchEngineInstalledResolutionKey] - } catch (e) { - return this - } - - this.eventBus_.subscribe( - ProductService.Events.CREATED, - this.handleProductCreation - ) - - this.eventBus_.subscribe( - ProductService.Events.UPDATED, - this.handleProductUpdate - ) - - this.eventBus_.subscribe( - ProductService.Events.DELETED, - this.handleProductDeletion - ) - - this.eventBus_.subscribe( - ProductVariantService.Events.CREATED, - this.handleProductVariantChange - ) - - this.eventBus_.subscribe( - ProductVariantService.Events.UPDATED, - this.handleProductVariantChange - ) - - this.eventBus_.subscribe( - ProductVariantService.Events.DELETED, - this.handleProductVariantChange - ) - } - - handleProductCreation = async (data) => { - const product = await this.retrieveProduct_(data.id) - await this.searchService_.addDocuments( - ProductService.IndexName, - [product], - indexTypes.products - ) - } - - retrieveProduct_ = async (product_id) => { - return await this.productService_.retrieve(product_id, { - select: searchFields, - relations: searchRelations, - }) - } - - handleProductUpdate = async (data) => { - const product = await this.retrieveProduct_(data.id) - await this.searchService_.addDocuments( - ProductService.IndexName, - [product], - indexTypes.products - ) - } - - handleProductDeletion = async (data) => { - await this.searchService_.deleteDocument(ProductService.IndexName, data.id) - } - - handleProductVariantChange = async (data) => { - const product = await this.retrieveProduct_(data.product_id) - await this.searchService_.addDocuments( - ProductService.IndexName, - [product], - indexTypes.products - ) - } -} - -export default ProductSearchSubscriber diff --git a/packages/medusa/src/subscribers/product.ts b/packages/medusa/src/subscribers/product.ts new file mode 100644 index 0000000000..124697088f --- /dev/null +++ b/packages/medusa/src/subscribers/product.ts @@ -0,0 +1,87 @@ +import { IEventBusService, ISearchService } from "@medusajs/types" +import { defaultSearchIndexingProductRelations } from "@medusajs/utils" +import { indexTypes } from "medusa-core-utils" +import { isSearchEngineInstalledResolutionKey } from "../loaders/plugins" +import ProductService from "../services/product" +import ProductVariantService from "../services/product-variant" + +type InjectedDependencies = { + eventBusService: IEventBusService + searchService: ISearchService + productService: ProductService +} + +class ProductSearchSubscriber { + private readonly eventBusService_: IEventBusService + private readonly searchService_: ISearchService + private readonly productService_: ProductService + + constructor(container: InjectedDependencies) { + this.eventBusService_ = container.eventBusService + this.searchService_ = container.searchService + this.productService_ = container.productService + + /** + * Do not subscribe to any event in case no search engine have been installed. + * If some events need to be subscribed out of the search engine reason, they can be subscribed above this comment + */ + + try { + container[isSearchEngineInstalledResolutionKey] + } catch (e) { + return this + } + + this.eventBusService_ + .subscribe(ProductService.Events.CREATED, this.handleProductCreation) + .subscribe(ProductService.Events.UPDATED, this.handleProductUpdate) + .subscribe(ProductService.Events.DELETED, this.handleProductDeletion) + .subscribe( + ProductVariantService.Events.CREATED, + this.handleProductVariantChange + ) + .subscribe( + ProductVariantService.Events.UPDATED, + this.handleProductVariantChange + ) + .subscribe( + ProductVariantService.Events.DELETED, + this.handleProductVariantChange + ) + } + + handleProductCreation = async (data) => { + const product = await this.productService_.retrieve(data.id, { + relations: defaultSearchIndexingProductRelations, + }) + await this.searchService_.addDocuments( + ProductService.IndexName, + [product], + indexTypes.products + ) + } + + handleProductUpdate = async (data) => { + const product = await this.productService_.retrieve(data.id) + await this.searchService_.addDocuments( + ProductService.IndexName, + [product], + indexTypes.products + ) + } + + handleProductDeletion = async (data) => { + await this.searchService_.deleteDocument(ProductService.IndexName, data.id) + } + + handleProductVariantChange = async (data) => { + const product = await this.productService_.retrieve(data.product_id) + await this.searchService_.addDocuments( + ProductService.IndexName, + [product], + indexTypes.products + ) + } +} + +export default ProductSearchSubscriber diff --git a/packages/medusa/src/subscribers/search-indexing.ts b/packages/medusa/src/subscribers/search-indexing.ts index 13c51809b2..4376c08137 100644 --- a/packages/medusa/src/subscribers/search-indexing.ts +++ b/packages/medusa/src/subscribers/search-indexing.ts @@ -1,4 +1,5 @@ import { IEventBusService, ISearchService } from "@medusajs/types" +import { defaultSearchIndexingProductRelations } from "@medusajs/utils" import { indexTypes } from "medusa-core-utils" import ProductCategoryFeatureFlag from "../loaders/feature-flags/product-categories" import { SEARCH_INDEX_EVENT } from "../loaders/search-index" @@ -59,17 +60,7 @@ class SearchIndexingSubscriber { lastSeenId: string, take: number ): Promise { - const relations = [ - "variants", - "tags", - "type", - "collection", - "variants.prices", - "images", - "variants.options", - "options", - ] - + const relations = [...defaultSearchIndexingProductRelations] if ( this.featureFlagRouter_.isFeatureEnabled(ProductCategoryFeatureFlag.key) ) { diff --git a/packages/utils/src/search/index.ts b/packages/utils/src/search/index.ts index 0a54fde098..26c4d64a6d 100644 --- a/packages/utils/src/search/index.ts +++ b/packages/utils/src/search/index.ts @@ -1,3 +1,4 @@ export * from "./abstract-service" export * from "./is-search-service" +export * from "./search-relations" diff --git a/packages/utils/src/search/search-relations.ts b/packages/utils/src/search/search-relations.ts new file mode 100644 index 0000000000..00c5b32dfb --- /dev/null +++ b/packages/utils/src/search/search-relations.ts @@ -0,0 +1,10 @@ +export const defaultSearchIndexingProductRelations = [ + "variants", + "tags", + "type", + "collection", + "variants.prices", + "images", + "variants.options", + "options", +]