Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/2918 #3156

Merged
merged 35 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e1f15ff
Bugfix for the inconsistient prices naming strategy (#2918) + `final_…
pkarw Jun 25, 2019
df99258
Fix for inconsitient price naming #2918
pkarw Jun 25, 2019
f6cbad5
eslint fixes
pkarw Jun 25, 2019
70eb2a4
Update CHANGELOG.md
pkarw Jun 25, 2019
f6102be
Upgrade notes updated
pkarw Jun 25, 2019
7639c56
Vue.prototype.$bus references replaced with `EventBus` - #3050
pkarw Jun 25, 2019
65b964f
Fix for the rest of Vue.prototype calls #3050
pkarw Jun 25, 2019
dc001dc
Merge branch 'develop' into bugfix/2918
pkarw Jun 28, 2019
e318fa6
Tests to green
pkarw Jul 1, 2019
d86f39c
Merge branch 'bugfix/2918' of https://github.com/DivanteLtd/vue-store…
pkarw Jul 1, 2019
e3bc3e0
Backward compatibility for syncProductPrice + further naming conventi…
pkarw Jul 1, 2019
dc32132
eslint fixes
pkarw Jul 1, 2019
2063aad
Additional price names fixed
pkarw Jul 1, 2019
1434ad8
Update cartCacheHandler.spec.ts
pkarw Jul 1, 2019
f768c67
Merge branch 'develop' into bugfix/2918
pkarw Jul 1, 2019
58f3ef7
Code sample removed from the docs
pkarw Jul 1, 2019
706a68b
Fix - final_price does include tax
pkarw Jul 1, 2019
60727db
Fix - final_price does include tax
pkarw Jul 1, 2019
5476733
Unit tests to green
pkarw Jul 1, 2019
483cc4e
Update cartCacheHandler.spec.ts
pkarw Jul 1, 2019
5664fd8
eslint fix
pkarw Jul 2, 2019
2d95ed3
Fix for finding the cheapest product variant (if no specific configur…
pkarw Jul 2, 2019
dd15b73
FIx for configuring the products in the Search bar by default
pkarw Jul 2, 2019
9ddc043
Final price fields added to systemFields
pkarw Jul 2, 2019
ae793cb
Two missing conditions reverted
pkarw Jul 2, 2019
3d1d81c
priceInclTax -> price_incl_tax
pkarw Jul 3, 2019
fc73829
CR fixes
pkarw Jul 10, 2019
f116d9f
Conflicts resolved
pkarw Jul 10, 2019
b5587ae
StorageMap
pkarw Jul 10, 2019
85a17a5
Merge branch 'develop' into bugfix/2918
pkarw Jul 10, 2019
5ef452b
Merge branch 'bugfix/2918' of https://github.com/DivanteLtd/vue-store…
pkarw Jul 10, 2019
bdaa00a
Unit test fix
pkarw Jul 10, 2019
4dda559
Update index.ts
pkarw Jul 10, 2019
13c6bb6
Conflicts resolved
pkarw Jul 10, 2019
9b6368c
Update task.ts
pkarw Jul 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- Fixed product link in wishlist and microcart - @michasik (#2987)
- Fixed naming strategy for product prices - `special_priceInclTax` -> `special_price_incl_tax`, `priceInclTax` -> `price_incl_tax`, `priceTax` -> `price_tax`; old names have been kept as @deprecated - @pkarw (#2918)
- The `final_price` field is now being used for setting the `special_price` or `price` of the product (depending on the
value); `final_price` might been used along with `special_price` with Magento for the products with activated catalog pricing rules - @pkarw (#3099)
- Resolve problem with getting CMS block from cache - @qiqqq (#2499)
- Make image proxy url work with relative base url - @cewald (#3158)
- Fixed memory leak with enabled dynamicConfigReload - @dimasch (#3075)
Expand Down
18 changes: 10 additions & 8 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@
},
"productList": {
"sort": "updated_at:desc",
"includeFields": [ "type_id", "sku", "product_links", "tax_class_id", "special_price", "special_to_date", "special_from_date", "name", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "url_path", "url_key", "status", "tier_prices", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax" ],
"includeFields": [ "type_id", "sku", "product_links", "tax_class_id", "special_price", "special_to_date", "special_from_date", "name", "price", "price_incl_tax", "original_price_incl_tax", "original_price", "special_price_incl_tax", "id", "image", "sale", "new", "url_path", "url_key", "status", "tier_prices", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.price_incl_tax", "configurable_children.special_price_incl_tax", "configurable_children.original_price", "configurable_children.original_price_incl_tax" ],
"excludeFields": [ "description", "configurable_options", "sgn", "*.sgn", "msrp_display_actual_price_type", "*.msrp_display_actual_price_type", "required_options" ]
},
"productListWithChildren": {
"includeFields": [ "type_id", "sku", "name", "tax_class_id", "special_price", "special_to_date", "special_from_date", "price", "priceInclTax", "originalPriceInclTax", "originalPrice", "specialPriceInclTax", "id", "image", "sale", "new", "configurable_children.image", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.priceInclTax", "configurable_children.specialPriceInclTax", "configurable_children.originalPrice", "configurable_children.originalPriceInclTax", "configurable_children.color", "configurable_children.size", "configurable_children.id", "configurable_children.tier_prices", "product_links", "url_path", "url_key", "status", "tier_prices"],
"includeFields": [ "type_id", "sku", "name", "tax_class_id", "special_price", "special_to_date", "special_from_date", "price", "price_incl_tax", "original_price_incl_tax", "original_price", "special_price_incl_tax", "id", "image", "sale", "new", "configurable_children.image", "configurable_children.sku", "configurable_children.price", "configurable_children.special_price", "configurable_children.price_incl_tax", "configurable_children.special_price_incl_tax", "configurable_children.original_price", "configurable_children.original_price_incl_tax", "configurable_children.color", "configurable_children.size", "configurable_children.id", "configurable_children.tier_prices", "product_links", "url_path", "url_key", "status", "tier_prices"],
"excludeFields": [ "description", "sgn", "*.sgn", "msrp_display_actual_price_type", "*.msrp_display_actual_price_type", "required_options"]
},
"review": {
Expand All @@ -181,6 +181,8 @@
"size_options",
"regular_price",
"final_price",
"final_price_incl_tax",
"final_price_tax",
"price",
"color_options",
"id",
Expand All @@ -206,10 +208,10 @@
"max_regular_price",
"category",
"status",
"priceTax",
"priceInclTax",
"specialPriceTax",
"specialPriceInclTax",
"price_tax",
"price_incl_tax",
"special_price_tax",
"special_price_incl_tax",
"_score",
"slug",
"errors",
Expand All @@ -218,8 +220,8 @@
"special_from_date",
"news_from_date",
"custom_design_from",
"originalPrice",
"originalPriceInclTax",
"original_price",
"original_price_incl_tax",
"parentSku",
"options",
"product_option",
Expand Down
3 changes: 2 additions & 1 deletion core/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Vue from 'vue'
import { isServer } from '@vue-storefront/core/helpers'

// Plugins
import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import i18n from '@vue-storefront/i18n'
import VueRouter from 'vue-router'
import VueLazyload from 'vue-lazyload'
Expand Down Expand Up @@ -115,7 +116,7 @@ const createApp = async (ssrContext, config, storeCode = null): Promise<{app: Vu
registerExtensions(extensions, app, router, store, config, ssrContext)
registerTheme(globalConfig.theme, app, router, store, globalConfig, ssrContext)

Vue.prototype.$bus.$emit('application-after-init', app)
EventBus.$emit('application-after-init', app)

return { app, router, store }
}
Expand Down
2 changes: 1 addition & 1 deletion core/compatibility/plugins/event-bus/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ if (!EventBus.$dataFilters) {

const EventBusPlugin = {
install (Vue) {
if (!Vue.prototype.$bus) {
if (!Vue.prototype.$bus) { /** Vue.prototype.$bus is now @deprecated please do use `EventBus` instead */
Object.defineProperties(Vue.prototype, {
$bus: {
get: function () {
Expand Down
10 changes: 5 additions & 5 deletions core/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import Vue from 'vue'
import config from 'config'
import { sha3_224 } from 'js-sha3'

export const processURLAddress = (url: string = '') => {
if (url.startsWith('/')) return `${config.api.url}${url}`
return url
}

/**
* Create slugify -> "create-slugify" permalink of text
* @param {String} text
Expand Down Expand Up @@ -172,11 +177,6 @@ export const onlineHelper = Vue.observable({
!isServer && window.addEventListener('online', () => { onlineHelper.isOnline = true })
!isServer && window.addEventListener('offline', () => { onlineHelper.isOnline = false })

export const processURLAddress = (url: string = '') => {
if (url.startsWith('/')) return `${config.api.url}${url}`
return url
}

/*
* serial executes Promises sequentially.
* @param {funcs} An array of funcs that return promises.
Expand Down
19 changes: 16 additions & 3 deletions core/helpers/initCacheStorage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as localForage from 'localforage'
import UniversalStorage from '@vue-storefront/core/store/lib/storage'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'
import { currentStoreView } from '@vue-storefront/core/lib/multistore'
import config from 'config'

/** Inits cache storage for given module. By default via local storage */
export function initCacheStorage (key, localised = true) {
function _prepareCachestorage (key, localised = true) {
const storeView = currentStoreView()
const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''
const dbNamePrefix = storeView && storeView.storeCode ? storeView.storeCode + '-' : ''
const cacheDriver = config.localForage && config.localForage.defaultDrivers[key]
? config.localForage.defaultDrivers[key]
: 'LOCALSTORAGE'
Expand All @@ -17,3 +17,16 @@ export function initCacheStorage (key, localised = true) {
driver: localForage[cacheDriver]
}))
}

/** Inits cache storage for given module. By default via local storage */
export function initCacheStorage (key, localised = true, registerStorgeManager = true) {
if (registerStorgeManager) {
if (!StorageManager.exists(key)) {
return StorageManager.set(key, _prepareCachestorage(key, localised))
} else {
return StorageManager.get(key)
}
} else {
return _prepareCachestorage(key, localised)
}
}
9 changes: 3 additions & 6 deletions core/lib/multistore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import merge from 'lodash-es/merge'
import { RouterManager } from '@vue-storefront/core/lib/router-manager'
import VueRouter, { RouteConfig, RawLocation } from 'vue-router'
import config from 'config'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'

export interface LocalizedRoute {
path?: string,
Expand Down Expand Up @@ -98,13 +99,9 @@ export function prepareStoreView (storeCode: string): StoreView {
if (storeViewHasChanged) {
rootStore.state.storeView = storeView
}

if (storeViewHasChanged || Vue.prototype.$db.currentStoreCode !== storeCode) {
if (typeof Vue.prototype.$db === 'undefined') {
Vue.prototype.$db = {}
}
if (storeViewHasChanged || StorageManager.currentStoreCode !== storeCode) {
initializeSyncTaskStorage()
Vue.prototype.$db.currentStoreCode = storeView.storeCode
StorageManager.currentStoreCode = storeView.storeCode
}

return storeView
Expand Down
3 changes: 2 additions & 1 deletion core/lib/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SearchResponse } from '@vue-storefront/core/types/search/SearchResponse
import { Logger } from '@vue-storefront/core/lib/logger'
import config from 'config'
import { isServer } from '@vue-storefront/core/helpers'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'

// TODO - use one from helpers instead
export function isOnline (): boolean {
Expand Down Expand Up @@ -52,7 +53,7 @@ export const quickSearchByQuery = async ({ query = {}, start = 0, size = 50, ent
Request.groupId = rootStore.state.user.groupId
}

const cache = Vue.prototype.$db.elasticCacheCollection // switch to appcache?
const cache = StorageManager.get('elasticCacheCollection') // switch to appcache?
let servedFromCache = false
const cacheKey = sha3_224(JSON.stringify(Request))
const benchmarkTime = new Date()
Expand Down
8 changes: 5 additions & 3 deletions core/lib/sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import { execute as taskExecute, _prepareTask } from './task'
import { isServer } from '@vue-storefront/core/helpers'
import config from 'config'
import Task from '@vue-storefront/core/lib/sync/types/Task'
import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'

/** Syncs given task. If user is offline requiest will be sent to the server after restored connection */
async function queue (task) {
const tasksCollection = Vue.prototype.$db.syncTaskCollection
const tasksCollection = StorageManager.get('syncTaskCollection')
task = _prepareTask(task)
Logger.info('Sync task queued ' + task.url, 'sync', { task })()
return new Promise((resolve, reject) => {
tasksCollection.setItem(task.task_id.toString(), task, (err, resp) => {
if (err) Logger.error(err, 'sync')()
Vue.prototype.$bus.$emit('sync/PROCESS_QUEUE', { config: config }) // process checkout queue
EventBus.$emit('sync/PROCESS_QUEUE', { config: config }) // process checkout queue
resolve(task)
}, config.syncTasks.disablePersistentTaskQueue).catch((reason) => {
Logger.error(reason, 'sync')() // it doesn't work on SSR
Expand Down Expand Up @@ -48,7 +50,7 @@ async function execute (task): Promise<Task> { // not offline task

/** Clear sync tasks that were not transmitted yet */
function clearNotTransmited () {
const syncTaskCollection = Vue.prototype.$db.syncTaskCollection
const syncTaskCollection = StorageManager.get('syncTaskCollection')
syncTaskCollection.iterate((task, id, iterationNumber) => {
if (!task.transmited) {
syncTaskCollection.removeItem(id)
Expand Down
20 changes: 11 additions & 9 deletions core/lib/sync/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import fetch from 'isomorphic-fetch'
import * as localForage from 'localforage'
import rootStore from '@vue-storefront/core/store'
import { adjustMultistoreApiUrl, currentStoreView } from '@vue-storefront/core/lib/multistore'
import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import Task from '@vue-storefront/core/lib/sync/types/Task'
import { Logger } from '@vue-storefront/core/lib/logger'
import { TaskQueue } from '@vue-storefront/core/lib/sync'
import * as entities from '@vue-storefront/core/store/lib/entities'
import UniversalStorage from '@vue-storefront/core/store/lib/storage'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'
import { processURLAddress } from '@vue-storefront/core/helpers'
import { serial } from '@vue-storefront/core/helpers'
import config from 'config'
Expand Down Expand Up @@ -89,7 +91,7 @@ function _internalExecute (resolve, reject, task: Task, currentToken, currentCar
rootStore.state.userTokenInvalidateLock = -1
rootStore.dispatch('user/logout', { silent: true })
TaskQueue.clearNotTransmited()
Vue.prototype.$bus.$emit('modal-show', 'modal-signup')
EventBus.$emit('modal-show', 'modal-signup')
rootStore.dispatch('notification/spawnNotification', {
type: 'error',
message: i18n.t('Internal Application error while refreshing the tokens. Please clear the storage and refresh page.'),
Expand All @@ -107,14 +109,14 @@ function _internalExecute (resolve, reject, task: Task, currentToken, currentCar
} else {
rootStore.state.userTokenInvalidateLock = -1
rootStore.dispatch('user/logout', { silent: true })
Vue.prototype.$bus.$emit('modal-show', 'modal-signup')
EventBus.$emit('modal-show', 'modal-signup')
TaskQueue.clearNotTransmited()
Logger.error('Error refreshing user token' + resp.result, 'sync')()
}
}).catch((excp) => {
rootStore.state.userTokenInvalidateLock = -1
rootStore.dispatch('user/logout', { silent: true })
Vue.prototype.$bus.$emit('modal-show', 'modal-signup')
EventBus.$emit('modal-show', 'modal-signup')
TaskQueue.clearNotTransmited()
Logger.error('Error refreshing user token' + excp, 'sync')()
})
Expand All @@ -124,7 +126,7 @@ function _internalExecute (resolve, reject, task: Task, currentToken, currentCar
} else {
Logger.info('Invalidation process is disabled (autoRefreshTokens is set to false)', 'sync')()
rootStore.dispatch('user/logout', { silent: true })
Vue.prototype.$bus.$emit('modal-show', 'modal-signup')
EventBus.$emit('modal-show', 'modal-signup')
}
}

Expand All @@ -151,7 +153,7 @@ function _internalExecute (resolve, reject, task: Task, currentToken, currentCar
if (task.callback_event.startsWith('store:')) {
rootStore.dispatch(task.callback_event.split(':')[1], task)
} else {
Vue.prototype.$bus.$emit(task.callback_event, task)
EventBus.$emit(task.callback_event, task)
}
}
if (!rootStore.state.userTokenInvalidateLock) { // in case we're revalidaing the token - user must wait for it
Expand Down Expand Up @@ -180,19 +182,19 @@ export function initializeSyncTaskStorage () {
const storeView = currentStoreView()
const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''

Vue.prototype.$db.syncTaskCollection = new UniversalStorage(localForage.createInstance({
StorageManager.set('syncTaskCollection', new UniversalStorage(localForage.createInstance({
name: dbNamePrefix + 'shop',
storeName: 'syncTasks',
driver: localForage[config.localForage.defaultDrivers['syncTasks']]
}))
})))
}

export function registerSyncTaskProcessor () {
const mutex = {}
Vue.prototype.$bus.$on('sync/PROCESS_QUEUE', async data => {
EventBus.$on('sync/PROCESS_QUEUE', async data => {
if (onlineHelper.isOnline) {
// event.data.config - configuration, endpoints etc
const syncTaskCollection = Vue.prototype.$db.syncTaskCollection
const syncTaskCollection = StorageManager.get('syncTaskCollection')
const currentUserToken = rootStore.getters['user/getUserToken']
const currentCartToken = rootStore.getters['cart/getCartToken']

Expand Down
1 change: 1 addition & 0 deletions core/lib/test/unit/multistore.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { storeCodeFromRoute } from '../../multistore'
import config from 'config'
jest.mock('@vue-storefront/core/app', () => ({ createApp: jest.fn() }))
jest.mock('../../../store', () => ({}))
jest.mock('@vue-storefront/i18n', () => ({loadLanguageAsync: jest.fn()}))
jest.mock('../../sync/task', () => ({initializeSyncTaskStorage: jest.fn()}))
Expand Down
18 changes: 12 additions & 6 deletions core/modules/cart/components/AddToCart.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Product from '@vue-storefront/core/modules/catalog/types/Product'
import { Logger } from '@vue-storefront/core/lib/logger';

export const AddToCart = {
name: 'AddToCart',
Expand All @@ -20,13 +21,18 @@ export const AddToCart = {
methods: {
async addToCart (product: Product) {
this.isAddingToCart = true
const diffLog = await this.$store.dispatch('cart/addItem', { productToAdd: product })
if (diffLog.clientNotifications && diffLog.clientNotifications.length > 0) {
diffLog.clientNotifications.forEach(notificationData => {
this.$store.dispatch('notification/spawnNotification', notificationData, { root: true })
})
try {
const diffLog = await this.$store.dispatch('cart/addItem', { productToAdd: product })
if (diffLog.clientNotifications && diffLog.clientNotifications.length > 0) {
diffLog.clientNotifications.forEach(notificationData => {
this.$store.dispatch('notification/spawnNotification', notificationData, { root: true })
})
}
} catch (e) {
Logger.error(e, 'cart')()
} finally {
this.isAddingToCart = false
}
this.isAddingToCart = false
}
}
}
8 changes: 5 additions & 3 deletions core/modules/cart/helpers/cartCacheHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as types from '../store/mutation-types';

import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'

export function cartCacheHandlerFactory (Vue) {
return (mutation, state) => {
const type = mutation.type;
Expand All @@ -11,19 +13,19 @@ export function cartCacheHandlerFactory (Vue) {
type.endsWith(types.CART_UPD_ITEM) ||
type.endsWith(types.CART_UPD_ITEM_PROPS)
) {
return Vue.prototype.$db.cartsCollection.setItem('current-cart', state.cart.cartItems).catch((reason) => {
return StorageManager.get('cartsCollection').setItem('current-cart', state.cart.cartItems).catch((reason) => {
console.error(reason) // it doesn't work on SSR
}) // populate cache
} else if (
type.endsWith(types.CART_LOAD_CART_SERVER_TOKEN)
) {
return Vue.prototype.$db.cartsCollection.setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => {
return StorageManager.get('cartsCollection').setItem('current-cart-token', state.cart.cartServerToken).catch((reason) => {
console.error(reason)
})
} else if (
type.endsWith(types.CART_SET_ITEMS_HASH)
) {
return Vue.prototype.$db.cartsCollection.setItem('current-cart-hash', state.cart.cartItemsHash).catch((reason) => {
return StorageManager.get('cartsCollection').setItem('current-cart-hash', state.cart.cartItemsHash).catch((reason) => {
console.error(reason)
})
}
Expand Down
5 changes: 3 additions & 2 deletions core/modules/cart/hooks/beforeRegistration.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import * as localForage from 'localforage'
import UniversalStorage from '@vue-storefront/core/store/lib/storage'
import { currentStoreView } from '@vue-storefront/core/lib/multistore'
import { StorageManager } from '@vue-storefront/core/store/lib/storage-manager'

export function beforeRegistration ({ Vue, config, store, isServer }) {
const storeView = currentStoreView()
const dbNamePrefix = storeView.storeCode ? storeView.storeCode + '-' : ''

Vue.prototype.$db.cartsCollection = new UniversalStorage(localForage.createInstance({
StorageManager.set('cartsCollection', new UniversalStorage(localForage.createInstance({
name: (config.storeViews.commonCache ? '' : dbNamePrefix) + 'shop',
storeName: 'carts',
driver: localForage[config.localForage.defaultDrivers['carts']]
}))
})))
}
Loading