/**
* JS lib to handle products search with E-Com Plus stores.
* {@link https://github.com/ecomclub/search-engine GitHub}
*
* @module @ecomplus/search-engine
* @author E-Com Club <[email protected]>
* @return {@link EcomSearch}
* @see EcomSearch
*
* @example
* // ES import default
* import EcomSearch from '@ecomplus/search-engine'
*
* @example
* // With CommonJS
* const EcomSearch = require('@ecomplus/search-engine')
*
* @example
* <!-- Global `EcomSearch` from CDN on browser -->
* <script src="https://cdn.jsdelivr.net/npm/@ecomplus/search-engine/dist/ecom-search.var.min.js"></script>
*
* @example
* <!-- Bundle from CDN with `ecomUtils`, `ecomClient`, `_.cloneDeep` and `_.merge` -->
* <script src="https://cdn.jsdelivr.net/npm/@ecomplus/search-engine/dist/ecom-search.bundle.min.js"></script>
*/
import { $ecomConfig } from '@ecomplus/utils'
import fetch from './methods/fetch'
import reset from './methods/reset'
import setSearchTerm from './methods/set-search-term'
import setPageNumber from './methods/set-page-number'
import setPageSize from './methods/set-page-size'
import setSortOrder from './methods/set-sort-order'
import mergeFilter from './methods/merge-filter'
import removeFilter from './methods/remove-filter'
import setSpec from './methods/set-spec'
import setCategoryNames from './methods/set-category-names'
import setCategoryIds from './methods/set-category-ids'
import setBrandNames from './methods/set-brand-names'
import setBrandIds from './methods/set-brand-ids'
import setSkus from './methods/set-skus'
import setProductIds from './methods/set-product-ids'
import setPriceRange from './methods/set-price-range'
import getItems from './methods/get-items'
import getTotalCount from './methods/get-total-count'
import getTermSuggestions from './methods/get-term-suggestions'
import getBrands from './methods/get-brands'
import getCategories from './methods/get-categories'
import getPriceRange from './methods/get-price-range'
import getSpecs from './methods/get-specs'
const _key = 'ecomSeachHistory'
const _storage = typeof window === 'object' && window.localStorage
export default function (storeId, storageKey = _key, localStorage = _storage) {
const self = this
/**
* Respective Store ID number.
* @name EcomSearch#storeId
* @type {number}
*/
this.storeId = storeId || $ecomConfig.get('store_id')
/**
* Item key to handle persistent [search history]{@link EcomSearch#history} data
* with [localStorage]{@link EcomSearch#localStorage}.
* @name EcomSearch#storageKey
* @type {string|null}
*/
this.storageKey = storageKey
/**
* [Storage interface]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage}.
* @name EcomSearch#localStorage
* @type {object}
*/
this.localStorage = localStorage
/**
* Search terms history.
* @name EcomSearch#history
* @type {array<string>}
*/
this.history = []
/**
* Current
* [Query DSL]{@link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html}
* for [Search API]{@link https://developers.e-com.plus/docs/api/#/search/items/items}
* request body.
* <br>
* You can edit this object to manually set Query DSL properties,
* or you can use instance methods listed below.
* @name EcomSearch#dsl
* @type {object}
*/
this.dsl = {}
/**
* Last search result object obtained with the
* [fetch method]{@link EcomSearch#fetch}.
* @name EcomSearch#result
* @type {result|undefined}
*/
this.result = undefined
// instance methods
this.fetch = (isSimpleSearch, axiosConfig) => fetch(self, isSimpleSearch, axiosConfig)
this.reset = () => reset(self)
this.setSearchTerm = term => setSearchTerm(self, term)
this.setPageNumber = page => setPageNumber(self, page)
this.setPageSize = limit => setPageSize(self, limit)
this.setSortOrder = enumOrder => setSortOrder(self, enumOrder)
this.mergeFilter = (filter, occur) => mergeFilter(self, filter, occur)
this.removeFilter = (field, occur) => removeFilter(self, field, occur)
this.setSpec = (gridId, textOptions) => setSpec(self, gridId, textOptions)
this.setCategoryNames = categoryNames => setCategoryNames(self, categoryNames)
this.setCategoryIds = categoryIds => setCategoryIds(self, categoryIds)
this.setBrandNames = brandNames => setBrandNames(self, brandNames)
this.setBrandIds = brandIds => setBrandIds(self, brandIds)
this.setSkus = skus => setSkus(self, skus)
this.setProductIds = productIds => setProductIds(self, productIds)
this.setPriceRange = (minPrice, maxPrice) => setPriceRange(self, minPrice, maxPrice)
this.getItems = result => getItems(self, result)
this.getTotalCount = result => getTotalCount(self, result)
this.getTermSuggestions = result => getTermSuggestions(self, result)
this.getBrands = result => getBrands(self, result)
this.getCategories = result => getCategories(self, result)
this.getPriceRange = result => getPriceRange(self, result)
this.getSpecs = result => getSpecs(self, result)
// preset query object
reset(self)
if (localStorage && storageKey) {
// try to preset search history from storage
const history = localStorage.getItem(storageKey)
if (typeof history === 'string') {
self.history = history.split('||')
}
}
}
/**
* Construct a new search engine instance object.
* @class EcomSearch
* @param {number} [storeId=$ecomConfig.get('store_id')] - Preset Store ID number
* @param {string|null} [storageKey='ecomSeachHistory'] - Item key to persist search history data
* @param {object} [localStorage=window.localStorage] -
* [Local Storage interface]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage}
*
* @example
const search = new EcomSearch()
*
* @example
// Defining Store ID other than the configured on `$ecomConfig`
const storeId = 2000
const search = new EcomSearch(storeId)
*/