diff --git a/packages/x-components/src/main.ts b/packages/x-components/src/main.ts index 14677833ce..86e81cc866 100644 --- a/packages/x-components/src/main.ts +++ b/packages/x-components/src/main.ts @@ -1,13 +1,51 @@ -import { platformAdapter } from '@empathyco/x-adapter-platform'; +import App from './App.vue'; +import { setupDevtools } from './plugins/devtools/devtools.plugin'; +import router from './router'; import { baseInstallXOptions, baseSnippetConfig } from './views/base-config'; -import Vue3 from './vue3.vue'; import { XInstaller } from './x-installer/x-installer/x-installer'; +import { FilterEntityFactory } from './x-modules/facets/entities/filter-entity.factory'; +import { SingleSelectModifier } from './x-modules/facets/entities/single-select.modifier'; +import { StickyModifier } from './x-modules/facets/entities/sticky.modifier'; +import './tailwind/index.css'; -window.initX = baseSnippetConfig; +// Vue.config.productionTip = false; +FilterEntityFactory.instance.registerModifierByFacetId('age_facet', SingleSelectModifier); +FilterEntityFactory.instance.registerModifierByFacetId( + 'brand_facet', + StickyModifier, + SingleSelectModifier +); +FilterEntityFactory.instance.registerModifierByFacetId('price', SingleSelectModifier); +FilterEntityFactory.instance.registerModifierByFilterModelName( + 'HierarchicalFilter', + SingleSelectModifier +); -new XInstaller({ +const installer = new XInstaller({ ...baseInstallXOptions, - adapter: platformAdapter, - app: Vue3, - domElement: '#app' -}).init(); + app: App, + vueOptions: { + router + }, + domElement: '#app', + onCreateApp: initDevtools +}); + +if (window.initX) { + installer.init(); +} else { + installer.init(baseSnippetConfig).then(({ app }) => { + app.use(router); + }); +} + +/** + * If an app is provided, initialise the devtools. + * + * @param app - The root Vue instance of the application. + */ +function initDevtools(app: any): void { + if (process.env.NODE_ENV !== 'production') { + setupDevtools(app); + } +} diff --git a/packages/x-components/src/plugins/x-plugin.ts b/packages/x-components/src/plugins/x-plugin.ts index df4fc1cb07..ef7b28f181 100644 --- a/packages/x-components/src/plugins/x-plugin.ts +++ b/packages/x-components/src/plugins/x-plugin.ts @@ -5,28 +5,11 @@ import { createStore, Module, Store } from 'vuex'; import { XComponentsAdapter } from '@empathyco/x-types'; import { EventPayload, SubjectPayload, XBus } from '@empathyco/x-bus'; import { Observable } from 'rxjs'; +import { cleanGettersProxyCache } from '../store/utils/getters-proxy.utils'; +import { RootXStoreModule } from '../store/x.module'; import { AnyXStoreModule, RootXStoreState } from '../store/store.types'; import { XEvent, XEventsTypes } from '../wiring/events.types'; import { AnyWire, WireMetadata } from '../wiring/wiring.types'; -import { deviceXStoreModule } from '../x-modules/device/store/module'; -import { empathizeXStoreModule } from '../x-modules/empathize/store/module'; -import { experienceControlsXStoreModule } from '../x-modules/experience-controls/store/module'; -import { extraParamsXStoreModule } from '../x-modules/extra-params/store/module'; -import { facetsXStoreModule } from '../x-modules/facets/store/module'; -import { historyQueriesXStoreModule } from '../x-modules/history-queries/store/module'; -import { identifierResultsXStoreModule } from '../x-modules/identifier-results/store/module'; -import { nextQueriesXStoreModule } from '../x-modules/next-queries/store/module'; -import { popularSearchesXStoreModule } from '../x-modules/popular-searches/store/module'; -import { queriesPreviewXStoreModule } from '../x-modules/queries-preview/store/module'; -import { querySuggestionsXStoreModule } from '../x-modules/query-suggestions/store/module'; -import { recommendationsXStoreModule } from '../x-modules/recommendations/store/module'; -import { relatedTagsXStoreModule } from '../x-modules/related-tags/store/module'; -import { scrollXStoreModule } from '../x-modules/scroll/store/module'; -import { searchBoxXStoreModule } from '../x-modules/search-box/store/module'; -import { searchXStoreModule } from '../x-modules/search/store/module'; -import { semanticQueriesXStoreModule } from '../x-modules/semantic-queries/store/module'; -import { taggingXStoreModule } from '../x-modules/tagging/store/module'; -import { urlXStoreModule } from '../x-modules/url/store/module'; import { AnyXModule, XModuleName } from '../x-modules/x-modules.types'; import { sendWiringToDevtools } from './devtools/wiring.devtools'; import { bus } from './x-bus'; @@ -198,6 +181,7 @@ export class XPlugin implements PluginObject { * @internal */ static resetInstance(): void { + cleanGettersProxyCache(); this.instance = undefined; } @@ -247,8 +231,8 @@ export class XPlugin implements PluginObject { */ protected registerXModule(xModule: AnyXModule): void { if (!this.installedXModules.has(xModule.name)) { - // const customizedXModule = this.customizeXModule(xModule); - // this.registerStoreModule(customizedXModule); + const customizedXModule = this.customizeXModule(xModule); + this.registerStoreModule(customizedXModule); this.registerStoreEmitters(xModule); this.registerWiring(xModule); // The wiring must be registered after the store emitters @@ -376,51 +360,15 @@ export class XPlugin implements PluginObject { this.store = this.options.store ?? createStore({ - strict: process.env.NODE_ENV !== 'production', - modules: { - x: { - namespaced: true, - state: () => ({ test: {} }), - mutations: { - increment(state: any) { - const t0 = performance.now(); - Array.from(Array(210).keys()).forEach(key => { - console.log(key); - state.test[key] = { a: key }; - }); - const t1 = performance.now(); - console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`); - } - }, - modules: { - device: { namespaced: true, ...deviceXStoreModule }, - empathize: { namespaced: true, ...empathizeXStoreModule }, - extraParams: { namespaced: true, ...extraParamsXStoreModule }, - facets: { namespaced: true, ...facetsXStoreModule }, - historyQueries: { namespaced: true, ...historyQueriesXStoreModule }, - identifierResults: { namespaced: true, ...identifierResultsXStoreModule }, - nextQueries: { namespaced: true, ...nextQueriesXStoreModule }, - popularSearches: { namespaced: true, ...popularSearchesXStoreModule }, - queriesPreview: { namespaced: true, ...queriesPreviewXStoreModule }, - querySuggestions: { namespaced: true, ...querySuggestionsXStoreModule }, - recommendations: { namespaced: true, ...recommendationsXStoreModule }, - relatedTags: { namespaced: true, ...relatedTagsXStoreModule }, - scroll: { namespaced: true, ...scrollXStoreModule }, - search: { namespaced: true, ...searchXStoreModule }, - searchBox: { namespaced: true, ...searchBoxXStoreModule }, - semanticQueries: { namespaced: true, ...semanticQueriesXStoreModule }, - tagging: { namespaced: true, ...taggingXStoreModule }, - url: { namespaced: true, ...urlXStoreModule }, - experienceControls: { namespaced: true, ...experienceControlsXStoreModule } - } - } - } as any + /* strict mode causes slow down app significantly with vuex4 and + registering modules dynamically */ + // strict: process.env.NODE_ENV !== 'production' }); // if (!this.options.store) { // this.vue.prototype.$store = this.store; // } this.vue.use(this.store); - // this.store.registerModule('x', RootXStoreModule); + this.store.registerModule('x', RootXStoreModule); } /** diff --git a/packages/x-components/src/store/x.module.ts b/packages/x-components/src/store/x.module.ts index bcdc10fd57..21125f56c5 100644 --- a/packages/x-components/src/store/x.module.ts +++ b/packages/x-components/src/store/x.module.ts @@ -16,39 +16,7 @@ export type XModuleState = { [Key in keyof RootXStoreState['x']]: null }; * * @internal */ -export const RootXStoreModule: Module = { - state: () => ({ - device: null, - empathize: null, - extraParams: null, - facets: null, - historyQueries: null, - identifierResults: null, - nextQueries: null, - popularSearches: null, - queriesPreview: null, - querySuggestions: null, - recommendations: null, - relatedTags: null, - scroll: null, - search: null, - searchBox: null, - semanticQueries: null, - tagging: null, - url: null, - experienceControls: null, - test: {} - }), - mutations: { - increment(state) { - const t0 = performance.now(); - Array.from(Array(210).keys()).forEach(key => { - console.log(key); - (state as any).test[key] = { a: key }; - }); - const t1 = performance.now(); - console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`); - } - }, - namespaced: true +export const RootXStoreModule: Module = { + namespaced: true, + state: () => ({}) }; diff --git a/packages/x-components/src/x-modules/facets/store/module.ts b/packages/x-components/src/x-modules/facets/store/module.ts index 6654ed5f32..79490bedd5 100644 --- a/packages/x-components/src/x-modules/facets/store/module.ts +++ b/packages/x-components/src/x-modules/facets/store/module.ts @@ -1,4 +1,5 @@ -import { Facet } from '@empathyco/x-types'; +import { Facet, Filter } from '@empathyco/x-types'; +import { Dictionary } from '@empathyco/x-utils'; import { mergeConfig, setConfig } from '../../../store/utils/config-store.utils'; import { setQuery } from '../../../store/utils/query.utils'; import { facets } from './getters/facets.getter'; @@ -36,19 +37,15 @@ export const facetsXStoreModule: FacetsXStoreModule = { state.filters[newFilter.id] = newFilter; }, setFilters(state, filters) { - console.log('filters.length', filters.length); - const t0 = performance.now(); - const a = filters.reduce((acc, current) => { - acc[current.id] = current; - return acc; - }, {} as Record); + // filters.forEach(filter => (state.filters[filter.id] = filter)); + // Much faster than assign every filter to the state state.filters = { ...state.filters, - ...a + ...filters.reduce( + (acc, filter) => ((acc[filter.id] = filter), acc), + {} as Dictionary + ) }; - // filters.forEach(filter => (state.filters[filter.id] = filter)); - const t1 = performance.now(); - console.log(`Loop of FILTERS with assignation took ${(t1 - t0) / 1000} seconds.`); }, setPreselectedFilters(state, filters) { state.preselectedFilters = filters; @@ -57,11 +54,7 @@ export const facetsXStoreModule: FacetsXStoreModule = { delete state.filters[id]; }, removeFilters(state, filters) { - const copy = { ...state.filters }; - filters.forEach(({ id }) => delete copy[id]); - - state.filters = copy; - // filters.forEach(({ id }) => delete state.filters[id]); + filters.forEach(({ id }) => delete state.filters[id]); }, setFacetGroup(state, { facetId, groupId }: FacetGroupEntry) { state.groups[facetId] = groupId; diff --git a/packages/x-components/src/x-modules/search/store/module.ts b/packages/x-components/src/x-modules/search/store/module.ts index d1db8fa327..1679d1f71d 100644 --- a/packages/x-components/src/x-modules/search/store/module.ts +++ b/packages/x-components/src/x-modules/search/store/module.ts @@ -33,8 +33,7 @@ export const searchXStoreModule: SearchXStoreModule = { }, status: 'initial', isNoResults: false, - fromNoResultsWithFilters: false, - test: {} + fromNoResultsWithFilters: false }), getters: { request, @@ -54,13 +53,6 @@ export const searchXStoreModule: SearchXStoreModule = { setQuery, setResults(state, results) { state.results = results; - const t0 = performance.now(); - Array.from(Array(210).keys()).forEach(key => { - console.log(key); - state.test[key] = { a: key }; - }); - const t1 = performance.now(); - console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`); }, setPartialResults(state, partialResults) { state.partialResults = partialResults; diff --git a/packages/x-components/vite.config.ts b/packages/x-components/vite.config.ts index 8323cffd76..e71b2c78c8 100644 --- a/packages/x-components/vite.config.ts +++ b/packages/x-components/vite.config.ts @@ -1,6 +1,7 @@ import { resolve } from 'path'; import vue from '@vitejs/plugin-vue'; import { defineConfig } from 'vite'; +import Inspector from 'vite-plugin-vue-inspector'; export const vueDocsPlugin = { name: 'vue-docs', @@ -10,7 +11,7 @@ export const vueDocsPlugin = { }; export default defineConfig({ - plugins: [vue(), vueDocsPlugin], + plugins: [vue(), vueDocsPlugin, Inspector()], resolve: { alias: { vue: resolve(__dirname, 'node_modules/vue')