@searchspring/snap-controller 0.63.5 → 0.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Autocomplete/AutocompleteController.d.ts +15 -2
- package/dist/cjs/Autocomplete/AutocompleteController.d.ts.map +1 -1
- package/dist/cjs/Autocomplete/AutocompleteController.js +133 -7
- package/dist/cjs/Finder/FinderController.d.ts.map +1 -1
- package/dist/cjs/Finder/FinderController.js +1 -3
- package/dist/cjs/Recommendation/RecommendationController.d.ts +12 -16
- package/dist/cjs/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/cjs/Recommendation/RecommendationController.js +83 -320
- package/dist/cjs/Search/SearchController.d.ts +10 -3
- package/dist/cjs/Search/SearchController.d.ts.map +1 -1
- package/dist/cjs/Search/SearchController.js +221 -48
- package/dist/esm/Autocomplete/AutocompleteController.d.ts +15 -2
- package/dist/esm/Autocomplete/AutocompleteController.d.ts.map +1 -1
- package/dist/esm/Autocomplete/AutocompleteController.js +127 -7
- package/dist/esm/Finder/FinderController.d.ts.map +1 -1
- package/dist/esm/Finder/FinderController.js +1 -3
- package/dist/esm/Recommendation/RecommendationController.d.ts +12 -16
- package/dist/esm/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/esm/Recommendation/RecommendationController.js +79 -302
- package/dist/esm/Search/SearchController.d.ts +10 -3
- package/dist/esm/Search/SearchController.d.ts.map +1 -1
- package/dist/esm/Search/SearchController.js +178 -22
- package/package.json +10 -10
|
@@ -37,12 +37,62 @@ export class AutocompleteController extends AbstractController {
|
|
|
37
37
|
constructor(config, { client, store, urlManager, eventManager, profiler, logger, tracker }, context) {
|
|
38
38
|
super(config, { client, store, urlManager, eventManager, profiler, logger, tracker }, context);
|
|
39
39
|
this.type = ControllerTypes.autocomplete;
|
|
40
|
+
this.events = {
|
|
41
|
+
product: {},
|
|
42
|
+
};
|
|
40
43
|
this.track = {
|
|
41
|
-
// TODO: add in future when autocomplete supports result click tracking
|
|
42
44
|
product: {
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
+
clickThrough: (e, result) => {
|
|
46
|
+
if (this.events.product[result.id]?.clickThrough) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const data = getAutocompleteSchemaData({ params: this.params, store: this.store, results: [result] });
|
|
50
|
+
this.tracker.events.autocomplete.clickThrough({ data, siteId: this.config.globals?.siteId });
|
|
51
|
+
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
52
|
+
this.events.product[result.id].clickThrough = true;
|
|
53
|
+
this.eventManager.fire('track.product.clickThrough', { controller: this, event: e, products: [result], trackEvent: data });
|
|
54
|
+
},
|
|
55
|
+
click: (e, result) => {
|
|
56
|
+
if (result.type === 'banner') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// TODO: closest might be going too far - write own function to only go n levels up - additionally check that href includes result.url
|
|
60
|
+
const href = e.target?.getAttribute('href') || e.target?.closest('a')?.getAttribute('href');
|
|
61
|
+
if (href) {
|
|
62
|
+
this.track.product.clickThrough(e, result);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// TODO: in future, send as an interaction event
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
render: (result) => {
|
|
69
|
+
if (this.events.product[result.id]?.render)
|
|
70
|
+
return;
|
|
71
|
+
const data = getAutocompleteSchemaData({ params: this.params, store: this.store, results: [result] });
|
|
72
|
+
this.tracker.events.autocomplete.render({ data, siteId: this.config.globals?.siteId });
|
|
73
|
+
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
74
|
+
this.events.product[result.id].render = true;
|
|
75
|
+
this.eventManager.fire('track.product.render', { controller: this, products: [result], trackEvent: data });
|
|
76
|
+
},
|
|
77
|
+
impression: (result) => {
|
|
78
|
+
if (this.events.product[result.id]?.impression)
|
|
79
|
+
return;
|
|
80
|
+
const data = getAutocompleteSchemaData({ params: this.params, store: this.store, results: [result] });
|
|
81
|
+
this.tracker.events.autocomplete.impression({ data, siteId: this.config.globals?.siteId });
|
|
82
|
+
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
83
|
+
this.events.product[result.id].impression = true;
|
|
84
|
+
this.eventManager.fire('track.product.impression', { controller: this, products: [result], trackEvent: data });
|
|
45
85
|
},
|
|
86
|
+
addToCart: (result) => {
|
|
87
|
+
const data = getAutocompleteSchemaData({ params: this.params, store: this.store, results: [result] });
|
|
88
|
+
this.tracker.events.autocomplete.addToCart({ data, siteId: this.config.globals?.siteId });
|
|
89
|
+
this.eventManager.fire('track.product.addToCart', { controller: this, products: [result], trackEvent: data });
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
redirect: (redirectURL) => {
|
|
93
|
+
const data = getAutocompleteRedirectSchemaData({ redirectURL });
|
|
94
|
+
this.tracker.events.autocomplete.redirect({ data, siteId: this.config.globals?.siteId });
|
|
95
|
+
this.eventManager.fire('track.product.redirect', { controller: this, redirectURL, trackEvent: data });
|
|
46
96
|
},
|
|
47
97
|
};
|
|
48
98
|
this.handlers = {
|
|
@@ -257,6 +307,8 @@ export class AutocompleteController extends AbstractController {
|
|
|
257
307
|
if (!this.initialized) {
|
|
258
308
|
await this.init();
|
|
259
309
|
}
|
|
310
|
+
// reset events for new search
|
|
311
|
+
this.events = { product: {} };
|
|
260
312
|
// if urlManager has no query, there will be no need to get params and no query
|
|
261
313
|
if (!this.urlManager.state.query) {
|
|
262
314
|
return;
|
|
@@ -382,6 +434,10 @@ export class AutocompleteController extends AbstractController {
|
|
|
382
434
|
this.store.loading = false;
|
|
383
435
|
}
|
|
384
436
|
};
|
|
437
|
+
this.addToCart = async (product) => {
|
|
438
|
+
this.track.product.addToCart(product);
|
|
439
|
+
this.eventManager.fire('addToCart', { controller: this, products: [product] });
|
|
440
|
+
};
|
|
385
441
|
// deep merge config with defaults
|
|
386
442
|
this.config = deepmerge(defaultConfig, this.config);
|
|
387
443
|
this.store.setConfig(this.config);
|
|
@@ -409,6 +465,7 @@ export class AutocompleteController extends AbstractController {
|
|
|
409
465
|
await next();
|
|
410
466
|
const redirectURL = ac.controller.store.merchandising?.redirect;
|
|
411
467
|
if (redirectURL && this.config?.settings?.redirects?.merchandising) {
|
|
468
|
+
this.track.redirect(redirectURL);
|
|
412
469
|
window.location.href = redirectURL;
|
|
413
470
|
return false;
|
|
414
471
|
}
|
|
@@ -429,9 +486,7 @@ export class AutocompleteController extends AbstractController {
|
|
|
429
486
|
get params() {
|
|
430
487
|
const urlState = this.urlManager.state;
|
|
431
488
|
const params = deepmerge({ ...getSearchParams(urlState) }, this.config.globals);
|
|
432
|
-
const userId = this.tracker.
|
|
433
|
-
const sessionId = this.tracker.getContext().sessionId;
|
|
434
|
-
const pageLoadId = this.tracker.getContext().pageLoadId;
|
|
489
|
+
const { userId, sessionId, pageLoadId, shopperId } = this.tracker.getContext();
|
|
435
490
|
params.tracking = params.tracking || {};
|
|
436
491
|
params.tracking.domain = window.location.href;
|
|
437
492
|
if (userId) {
|
|
@@ -454,7 +509,6 @@ export class AutocompleteController extends AbstractController {
|
|
|
454
509
|
params.personalization = params.personalization || {};
|
|
455
510
|
params.personalization.lastViewed = lastViewedItems.join(',');
|
|
456
511
|
}
|
|
457
|
-
const shopperId = this.tracker.getShopperId();
|
|
458
512
|
if (shopperId) {
|
|
459
513
|
params.personalization = params.personalization || {};
|
|
460
514
|
params.personalization.shopper = shopperId;
|
|
@@ -633,3 +687,69 @@ function unbindFormParameters(form, fn) {
|
|
|
633
687
|
}
|
|
634
688
|
}
|
|
635
689
|
}
|
|
690
|
+
function getAutocompleteRedirectSchemaData({ redirectURL }) {
|
|
691
|
+
return {
|
|
692
|
+
redirect: redirectURL,
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
function getAutocompleteSchemaData({ params, store, results, }) {
|
|
696
|
+
const filters = params.filters?.reduce((acc, filter) => {
|
|
697
|
+
const key = filter.background ? 'bgfilter' : 'filter';
|
|
698
|
+
acc[key] = acc[key] || [];
|
|
699
|
+
const value = filter.type === 'range' &&
|
|
700
|
+
!isNaN(filter.value?.low) &&
|
|
701
|
+
!isNaN(filter.value?.low)
|
|
702
|
+
? [`low=${filter.value?.low}`, `high=${filter.value?.high}`]
|
|
703
|
+
: [`${filter.value}`];
|
|
704
|
+
const existing = acc[key].find((item) => item.field === filter.field);
|
|
705
|
+
if (existing && !existing.value.includes(value[0])) {
|
|
706
|
+
existing.value.push(...value);
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
acc[key].push({
|
|
710
|
+
field: filter.field,
|
|
711
|
+
value,
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
return acc;
|
|
715
|
+
}, {});
|
|
716
|
+
return {
|
|
717
|
+
q: params.search?.query?.string || '',
|
|
718
|
+
correctedQuery: params.search?.originalQuery || '',
|
|
719
|
+
...filters,
|
|
720
|
+
sort: [
|
|
721
|
+
{
|
|
722
|
+
field: store.sorting.current?.field,
|
|
723
|
+
dir: store.sorting.current?.direction,
|
|
724
|
+
},
|
|
725
|
+
],
|
|
726
|
+
pagination: {
|
|
727
|
+
totalResults: store.pagination.totalResults,
|
|
728
|
+
page: store.pagination.page,
|
|
729
|
+
resultsPerPage: store.pagination.pageSize,
|
|
730
|
+
},
|
|
731
|
+
merchandising: {
|
|
732
|
+
personalized: store.merchandising.personalized,
|
|
733
|
+
redirect: store.merchandising.redirect,
|
|
734
|
+
triggeredCampaigns: (store.merchandising.campaigns?.length &&
|
|
735
|
+
store.merchandising.campaigns?.map((campaign) => {
|
|
736
|
+
const experiement = store.merchandising.experiments.find((experiment) => experiment.campaignId === campaign.id);
|
|
737
|
+
return {
|
|
738
|
+
id: campaign.id,
|
|
739
|
+
experimentId: experiement?.experimentId,
|
|
740
|
+
variationId: experiement?.variationId,
|
|
741
|
+
};
|
|
742
|
+
})) ||
|
|
743
|
+
undefined,
|
|
744
|
+
},
|
|
745
|
+
results: results?.map((result) => {
|
|
746
|
+
const core = result.mappings.core;
|
|
747
|
+
return {
|
|
748
|
+
uid: core.uid || '',
|
|
749
|
+
// childUid: core.uid,
|
|
750
|
+
sku: core.sku,
|
|
751
|
+
// childSku: core.sku,
|
|
752
|
+
};
|
|
753
|
+
}) || [],
|
|
754
|
+
};
|
|
755
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FinderController.d.ts","sourceRoot":"","sources":["../../../src/Finder/FinderController.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,KAAK,EAAE,sBAAsB,EAAkB,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAiB7G,qBAAa,gBAAiB,SAAQ,kBAAkB;IAChD,IAAI,kBAA0B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;gBAGtC,MAAM,EAAE,sBAAsB,EAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAC1F,OAAO,CAAC,EAAE,gBAAgB;IA+B3B,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"FinderController.d.ts","sourceRoot":"","sources":["../../../src/Finder/FinderController.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,KAAK,EAAE,sBAAsB,EAAkB,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAiB7G,qBAAa,gBAAiB,SAAQ,kBAAkB;IAChD,IAAI,kBAA0B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;gBAGtC,MAAM,EAAE,sBAAsB,EAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAC1F,OAAO,CAAC,EAAE,gBAAgB;IA+B3B,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA6BhC;IAED,IAAI,QAAa,QAAQ,IAAI,CAAC,CAkB5B;IAEF,KAAK,QAAO,IAAI,CAId;IAEF,MAAM,QAAa,QAAQ,IAAI,CAAC,CAoI9B;CACF"}
|
|
@@ -194,9 +194,7 @@ export class FinderController extends AbstractController {
|
|
|
194
194
|
}
|
|
195
195
|
get params() {
|
|
196
196
|
const urlState = this.urlManager.state;
|
|
197
|
-
const userId = this.tracker.
|
|
198
|
-
const sessionId = this.tracker.getContext().sessionId;
|
|
199
|
-
const pageLoadId = this.tracker.getContext().pageLoadId;
|
|
197
|
+
const { userId, sessionId, pageLoadId } = this.tracker.getContext();
|
|
200
198
|
const tracking = {};
|
|
201
199
|
if (userId) {
|
|
202
200
|
tracking.userId = userId;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Product } from '@searchspring/snap-store-mobx';
|
|
2
|
-
import { BeaconEvent } from '@searchspring/snap-tracker';
|
|
3
2
|
import { AbstractController } from '../Abstract/AbstractController';
|
|
4
3
|
import { ControllerTypes } from '../types';
|
|
5
4
|
import type { RecommendationStore } from '@searchspring/snap-store-mobx';
|
|
@@ -7,28 +6,25 @@ import type { RecommendRequestModel } from '@searchspring/snap-client';
|
|
|
7
6
|
import type { RecommendationControllerConfig, ControllerServices, ContextVariables } from '../types';
|
|
8
7
|
type RecommendationTrackMethods = {
|
|
9
8
|
product: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
clickThrough: (e: MouseEvent, result: Product) => void;
|
|
10
|
+
click: (e: MouseEvent, result: Product) => void;
|
|
11
|
+
render: (result: Product) => void;
|
|
12
|
+
impression: (result: Product) => void;
|
|
13
|
+
addToCart: (result: Product) => void;
|
|
14
|
+
};
|
|
15
|
+
bundle: {
|
|
16
|
+
addToCart: (results: Product[]) => void;
|
|
15
17
|
};
|
|
16
|
-
click: (e: MouseEvent) => BeaconEvent | undefined;
|
|
17
|
-
addBundle: (e: MouseEvent, results: Product[]) => BeaconEvent | undefined;
|
|
18
|
-
impression: () => BeaconEvent | undefined;
|
|
19
|
-
render: (results?: Product[]) => BeaconEvent | undefined;
|
|
20
18
|
};
|
|
21
19
|
export declare class RecommendationController extends AbstractController {
|
|
22
20
|
type: ControllerTypes;
|
|
23
21
|
store: RecommendationStore;
|
|
24
22
|
config: RecommendationControllerConfig;
|
|
25
23
|
events: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
impression?: BeaconEvent;
|
|
31
|
-
render?: BeaconEvent;
|
|
24
|
+
product: Record<string, {
|
|
25
|
+
clickThrough?: boolean;
|
|
26
|
+
impression?: boolean;
|
|
27
|
+
render?: boolean;
|
|
32
28
|
}>;
|
|
33
29
|
};
|
|
34
30
|
constructor(config: RecommendationControllerConfig, { client, store, urlManager, eventManager, profiler, logger, tracker }: ControllerServices, context?: ContextVariables);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecommendationController.d.ts","sourceRoot":"","sources":["../../../src/Recommendation/RecommendationController.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RecommendationController.d.ts","sourceRoot":"","sources":["../../../src/Recommendation/RecommendationController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,8BAA8B,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAIrG,KAAK,0BAA0B,GAAG;IACjC,OAAO,EAAE;QACR,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;QACvD,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;QAChD,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;QAClC,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;QACtC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;KACrC,CAAC;IACF,MAAM,EAAE;QACP,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;KACxC,CAAC;CACF,CAAC;AAUF,qBAAa,wBAAyB,SAAQ,kBAAkB;IACxD,IAAI,kBAAkC;IACrC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,8BAA8B,CAAC;IAE/C,MAAM,EAAE;QACP,OAAO,EAAE,MAAM,CACd,MAAM,EACN;YACC,YAAY,CAAC,EAAE,OAAO,CAAC;YACvB,UAAU,CAAC,EAAE,OAAO,CAAC;YACrB,MAAM,CAAC,EAAE,OAAO,CAAC;SACjB,CACD,CAAC;KACF,CAEC;gBAGD,MAAM,EAAE,8BAA8B,EACtC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAC1F,OAAO,CAAC,EAAE,gBAAgB;IAwC3B,KAAK,EAAE,0BAA0B,CAyD/B;IAEF,IAAI,MAAM,IAAI,qBAAqB,CA4BlC;IAED,MAAM,QAAa,QAAQ,IAAI,CAAC,CA6H9B;CACF"}
|