@searchspring/snap-controller 0.39.2 → 0.40.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.map +1 -1
- package/dist/cjs/Autocomplete/AutocompleteController.js +5 -1
- package/dist/cjs/Recommendation/RecommendationController.d.ts +1 -1
- package/dist/cjs/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/cjs/Recommendation/RecommendationController.js +154 -129
- package/dist/cjs/Search/SearchController.d.ts.map +1 -1
- package/dist/cjs/Search/SearchController.js +78 -74
- package/dist/cjs/types.d.ts +2 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/Autocomplete/AutocompleteController.d.ts.map +1 -1
- package/dist/esm/Autocomplete/AutocompleteController.js +4 -0
- package/dist/esm/Recommendation/RecommendationController.d.ts +1 -1
- package/dist/esm/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/esm/Recommendation/RecommendationController.js +153 -128
- package/dist/esm/Search/SearchController.d.ts.map +1 -1
- package/dist/esm/Search/SearchController.js +44 -42
- package/dist/esm/types.d.ts +2 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +10 -10
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import deepmerge from 'deepmerge';
|
|
2
|
-
import { BeaconType, BeaconCategory } from '@searchspring/snap-tracker';
|
|
2
|
+
import { BeaconType, BeaconCategory, ProfilePlacement } from '@searchspring/snap-tracker';
|
|
3
|
+
import { ErrorType } from '@searchspring/snap-store-mobx';
|
|
3
4
|
import { AbstractController } from '../Abstract/AbstractController';
|
|
4
5
|
import { ControllerTypes } from '../types';
|
|
5
|
-
import { ErrorType } from '@searchspring/snap-store-mobx';
|
|
6
6
|
const defaultConfig = {
|
|
7
7
|
id: 'recommend',
|
|
8
8
|
tag: '',
|
|
@@ -20,13 +20,119 @@ export class RecommendationController extends AbstractController {
|
|
|
20
20
|
render: undefined,
|
|
21
21
|
product: {},
|
|
22
22
|
};
|
|
23
|
-
this.track = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
this.track = (() => {
|
|
24
|
+
const getSeed = () => {
|
|
25
|
+
let skus = [];
|
|
26
|
+
switch (this.store.profile.placement) {
|
|
27
|
+
case ProfilePlacement.PRODUCTPAGE:
|
|
28
|
+
if (this.config.globals.product) {
|
|
29
|
+
skus = [this.config.globals.product];
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
case ProfilePlacement.BASKETPAGE:
|
|
33
|
+
skus = this.tracker.cookies.cart.get(); // this is an array
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (skus.length) {
|
|
39
|
+
return skus.map((sku) => ({
|
|
40
|
+
sku,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
product: {
|
|
46
|
+
click: (e, result) => {
|
|
47
|
+
if (!this.store.profile.tag || !result || !this.events.click)
|
|
48
|
+
return;
|
|
49
|
+
const payload = {
|
|
50
|
+
type: BeaconType.PROFILE_PRODUCT_CLICK,
|
|
51
|
+
category: BeaconCategory.RECOMMENDATIONS,
|
|
52
|
+
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
53
|
+
event: {
|
|
54
|
+
context: {
|
|
55
|
+
action: 'navigate',
|
|
56
|
+
placement: this.store.profile.placement,
|
|
57
|
+
tag: this.store.profile.tag,
|
|
58
|
+
type: 'product-recommendation',
|
|
59
|
+
},
|
|
60
|
+
product: {
|
|
61
|
+
id: result.id,
|
|
62
|
+
mappings: {
|
|
63
|
+
core: result.mappings.core,
|
|
64
|
+
},
|
|
65
|
+
seed: getSeed(),
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
pid: this.events.click.id,
|
|
69
|
+
};
|
|
70
|
+
const event = this.tracker.track.event(payload);
|
|
71
|
+
this.eventManager.fire('track.product.click', { controller: this, event: e, result, trackEvent: event });
|
|
72
|
+
return event;
|
|
73
|
+
},
|
|
74
|
+
impression: (result) => {
|
|
75
|
+
if (!this.store.profile.tag || !result || !this.events.impression || (this.events.product && this.events.product[result.id]?.impression))
|
|
76
|
+
return;
|
|
77
|
+
const payload = {
|
|
78
|
+
type: BeaconType.PROFILE_PRODUCT_IMPRESSION,
|
|
79
|
+
category: BeaconCategory.RECOMMENDATIONS,
|
|
80
|
+
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
81
|
+
event: {
|
|
82
|
+
context: {
|
|
83
|
+
placement: this.store.profile.placement,
|
|
84
|
+
tag: this.store.profile.tag,
|
|
85
|
+
type: 'product-recommendation',
|
|
86
|
+
},
|
|
87
|
+
product: {
|
|
88
|
+
id: result.id,
|
|
89
|
+
mappings: {
|
|
90
|
+
core: result.mappings.core,
|
|
91
|
+
},
|
|
92
|
+
seed: getSeed(),
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
pid: this.events.impression.id,
|
|
96
|
+
};
|
|
97
|
+
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
98
|
+
const event = (this.events.product[result.id].impression = this.tracker.track.event(payload));
|
|
99
|
+
this.eventManager.fire('track.product.impression', { controller: this, result, trackEvent: event });
|
|
100
|
+
return event;
|
|
101
|
+
},
|
|
102
|
+
render: (result) => {
|
|
103
|
+
if (!this.store.profile.tag || !result || !this.events.render || this.events.product[result.id]?.render)
|
|
104
|
+
return;
|
|
105
|
+
const payload = {
|
|
106
|
+
type: BeaconType.PROFILE_PRODUCT_RENDER,
|
|
107
|
+
category: BeaconCategory.RECOMMENDATIONS,
|
|
108
|
+
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
109
|
+
event: {
|
|
110
|
+
context: {
|
|
111
|
+
placement: this.store.profile.placement,
|
|
112
|
+
tag: this.store.profile.tag,
|
|
113
|
+
type: 'product-recommendation',
|
|
114
|
+
},
|
|
115
|
+
product: {
|
|
116
|
+
id: result.id,
|
|
117
|
+
mappings: {
|
|
118
|
+
core: result.mappings.core,
|
|
119
|
+
},
|
|
120
|
+
seed: getSeed(),
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
pid: this.events.render.id,
|
|
124
|
+
};
|
|
125
|
+
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
126
|
+
const event = (this.events.product[result.id].render = this.tracker.track.event(payload));
|
|
127
|
+
this.eventManager.fire('track.product.render', { controller: this, result, trackEvent: event });
|
|
128
|
+
return event;
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
click: (e) => {
|
|
132
|
+
if (!this.store.profile.tag)
|
|
27
133
|
return;
|
|
28
|
-
const
|
|
29
|
-
type: BeaconType.
|
|
134
|
+
const event = this.tracker.track.event({
|
|
135
|
+
type: BeaconType.PROFILE_CLICK,
|
|
30
136
|
category: BeaconCategory.RECOMMENDATIONS,
|
|
31
137
|
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
32
138
|
event: {
|
|
@@ -36,25 +142,24 @@ export class RecommendationController extends AbstractController {
|
|
|
36
142
|
tag: this.store.profile.tag,
|
|
37
143
|
type: 'product-recommendation',
|
|
38
144
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
seed:
|
|
145
|
+
profile: {
|
|
146
|
+
tag: this.store.profile.tag,
|
|
147
|
+
placement: this.store.profile.placement,
|
|
148
|
+
threshold: this.store.profile.display.threshold,
|
|
149
|
+
templateId: this.store.profile.display.template.uuid,
|
|
150
|
+
seed: getSeed(),
|
|
45
151
|
},
|
|
46
152
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.eventManager.fire('track.product.click', { controller: this, event: e, result, trackEvent: event });
|
|
153
|
+
});
|
|
154
|
+
this.events.click = event;
|
|
155
|
+
this.eventManager.fire('track.click', { controller: this, event: e, trackEvent: event });
|
|
51
156
|
return event;
|
|
52
157
|
},
|
|
53
|
-
impression: (
|
|
54
|
-
if (!this.store.profile.tag ||
|
|
158
|
+
impression: () => {
|
|
159
|
+
if (!this.store.profile.tag || this.events.impression)
|
|
55
160
|
return;
|
|
56
|
-
const
|
|
57
|
-
type: BeaconType.
|
|
161
|
+
const event = this.tracker.track.event({
|
|
162
|
+
type: BeaconType.PROFILE_IMPRESSION,
|
|
58
163
|
category: BeaconCategory.RECOMMENDATIONS,
|
|
59
164
|
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
60
165
|
event: {
|
|
@@ -63,26 +168,24 @@ export class RecommendationController extends AbstractController {
|
|
|
63
168
|
tag: this.store.profile.tag,
|
|
64
169
|
type: 'product-recommendation',
|
|
65
170
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
seed:
|
|
171
|
+
profile: {
|
|
172
|
+
tag: this.store.profile.tag,
|
|
173
|
+
placement: this.store.profile.placement,
|
|
174
|
+
threshold: this.store.profile.display.threshold,
|
|
175
|
+
templateId: this.store.profile.display.template.uuid,
|
|
176
|
+
seed: getSeed(),
|
|
72
177
|
},
|
|
73
178
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
const event = (this.events.product[result.id].impression = this.tracker.track.event(payload));
|
|
78
|
-
this.eventManager.fire('track.product.impression', { controller: this, result, trackEvent: event });
|
|
179
|
+
});
|
|
180
|
+
this.events.impression = event;
|
|
181
|
+
this.eventManager.fire('track.impression', { controller: this, trackEvent: event });
|
|
79
182
|
return event;
|
|
80
183
|
},
|
|
81
|
-
render: (
|
|
82
|
-
if (!this.store.profile.tag ||
|
|
184
|
+
render: () => {
|
|
185
|
+
if (!this.store.profile.tag || this.events.render)
|
|
83
186
|
return;
|
|
84
|
-
const
|
|
85
|
-
type: BeaconType.
|
|
187
|
+
const event = this.tracker.track.event({
|
|
188
|
+
type: BeaconType.PROFILE_RENDER,
|
|
86
189
|
category: BeaconCategory.RECOMMENDATIONS,
|
|
87
190
|
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
88
191
|
event: {
|
|
@@ -91,101 +194,23 @@ export class RecommendationController extends AbstractController {
|
|
|
91
194
|
tag: this.store.profile.tag,
|
|
92
195
|
type: 'product-recommendation',
|
|
93
196
|
},
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
seed:
|
|
197
|
+
profile: {
|
|
198
|
+
tag: this.store.profile.tag,
|
|
199
|
+
placement: this.store.profile.placement,
|
|
200
|
+
threshold: this.store.profile.display.threshold,
|
|
201
|
+
templateId: this.store.profile.display.template.uuid,
|
|
202
|
+
seed: getSeed(),
|
|
100
203
|
},
|
|
101
204
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.eventManager.fire('track.
|
|
205
|
+
});
|
|
206
|
+
this.events.render = event;
|
|
207
|
+
// track results render
|
|
208
|
+
this.store.results.forEach((result) => this.track.product.render(result));
|
|
209
|
+
this.eventManager.fire('track.render', { controller: this, trackEvent: event });
|
|
107
210
|
return event;
|
|
108
211
|
},
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (!this.store.profile.tag)
|
|
112
|
-
return;
|
|
113
|
-
const event = this.tracker.track.event({
|
|
114
|
-
type: BeaconType.PROFILE_CLICK,
|
|
115
|
-
category: BeaconCategory.RECOMMENDATIONS,
|
|
116
|
-
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
117
|
-
event: {
|
|
118
|
-
context: {
|
|
119
|
-
action: 'navigate',
|
|
120
|
-
placement: this.store.profile.placement,
|
|
121
|
-
tag: this.store.profile.tag,
|
|
122
|
-
type: 'product-recommendation',
|
|
123
|
-
},
|
|
124
|
-
profile: {
|
|
125
|
-
tag: this.store.profile.tag,
|
|
126
|
-
placement: this.store.profile.placement,
|
|
127
|
-
threshold: this.store.profile.display.threshold,
|
|
128
|
-
templateId: this.store.profile.display.template.uuid,
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
this.events.click = event;
|
|
133
|
-
this.eventManager.fire('track.click', { controller: this, event: e, trackEvent: event });
|
|
134
|
-
return event;
|
|
135
|
-
},
|
|
136
|
-
impression: () => {
|
|
137
|
-
if (!this.store.profile.tag || this.events.impression)
|
|
138
|
-
return;
|
|
139
|
-
const event = this.tracker.track.event({
|
|
140
|
-
type: BeaconType.PROFILE_IMPRESSION,
|
|
141
|
-
category: BeaconCategory.RECOMMENDATIONS,
|
|
142
|
-
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
143
|
-
event: {
|
|
144
|
-
context: {
|
|
145
|
-
placement: this.store.profile.placement,
|
|
146
|
-
tag: this.store.profile.tag,
|
|
147
|
-
type: 'product-recommendation',
|
|
148
|
-
},
|
|
149
|
-
profile: {
|
|
150
|
-
tag: this.store.profile.tag,
|
|
151
|
-
placement: this.store.profile.placement,
|
|
152
|
-
threshold: this.store.profile.display.threshold,
|
|
153
|
-
templateId: this.store.profile.display.template.uuid,
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
this.events.impression = event;
|
|
158
|
-
this.eventManager.fire('track.impression', { controller: this, trackEvent: event });
|
|
159
|
-
return event;
|
|
160
|
-
},
|
|
161
|
-
render: () => {
|
|
162
|
-
if (!this.store.profile.tag || this.events.render)
|
|
163
|
-
return;
|
|
164
|
-
const event = this.tracker.track.event({
|
|
165
|
-
type: BeaconType.PROFILE_RENDER,
|
|
166
|
-
category: BeaconCategory.RECOMMENDATIONS,
|
|
167
|
-
context: this.config.globals.siteId ? { website: { trackingCode: this.config.globals.siteId } } : undefined,
|
|
168
|
-
event: {
|
|
169
|
-
context: {
|
|
170
|
-
placement: this.store.profile.placement,
|
|
171
|
-
tag: this.store.profile.tag,
|
|
172
|
-
type: 'product-recommendation',
|
|
173
|
-
},
|
|
174
|
-
profile: {
|
|
175
|
-
tag: this.store.profile.tag,
|
|
176
|
-
placement: this.store.profile.placement,
|
|
177
|
-
threshold: this.store.profile.display.threshold,
|
|
178
|
-
templateId: this.store.profile.display.template.uuid,
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
this.events.render = event;
|
|
183
|
-
// track results render
|
|
184
|
-
this.store.results.forEach((result) => this.track.product.render(result));
|
|
185
|
-
this.eventManager.fire('track.render', { controller: this, trackEvent: event });
|
|
186
|
-
return event;
|
|
187
|
-
},
|
|
188
|
-
};
|
|
212
|
+
};
|
|
213
|
+
})();
|
|
189
214
|
this.search = async () => {
|
|
190
215
|
if (!this.initialized) {
|
|
191
216
|
await this.init();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchController.d.ts","sourceRoot":"","sources":["../../../src/Search/SearchController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AAErF,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAkD,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7I,OAAO,KAAK,EAAE,kBAAkB,EAA2E,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchController.d.ts","sourceRoot":"","sources":["../../../src/Search/SearchController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AAErF,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAkD,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7I,OAAO,KAAK,EAAE,kBAAkB,EAA2E,MAAM,2BAA2B,CAAC;AAsB7I,aAAK,kBAAkB,GAAG;IACzB,OAAO,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,WAAW,GAAG,SAAS,CAAC;KAC/D,CAAC;CACF,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,kBAAkB;IAChD,IAAI,kBAA0B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IACvC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,eAAe,CAAwC;gBAG9D,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;IA6F3B,KAAK,EAAE,kBAAkB,CA+BvB;IAEF,IAAI,MAAM,IAAI,kBAAkB,CAgD/B;IAED,MAAM,QAAa,QAAQ,IAAI,CAAC,CAmO9B;CACF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAiBxF"}
|
|
@@ -4,6 +4,7 @@ import { StorageStore, StorageType, ErrorType } from '@searchspring/snap-store-m
|
|
|
4
4
|
import { getSearchParams } from '../utils/getParams';
|
|
5
5
|
import { ControllerTypes } from '../types';
|
|
6
6
|
const HEIGHT_CHECK_INTERVAL = 50;
|
|
7
|
+
const API_LIMIT = 500;
|
|
7
8
|
const defaultConfig = {
|
|
8
9
|
id: 'search',
|
|
9
10
|
globals: {},
|
|
@@ -57,6 +58,10 @@ export class SearchController extends AbstractController {
|
|
|
57
58
|
await this.init();
|
|
58
59
|
}
|
|
59
60
|
const params = this.params;
|
|
61
|
+
if (this.params.search?.query?.string && this.params.search?.query?.string.length) {
|
|
62
|
+
// save it to the history store
|
|
63
|
+
this.store.history.save(this.params.search.query.string);
|
|
64
|
+
}
|
|
60
65
|
try {
|
|
61
66
|
try {
|
|
62
67
|
await this.eventManager.fire('beforeSearch', {
|
|
@@ -85,65 +90,59 @@ export class SearchController extends AbstractController {
|
|
|
85
90
|
let response;
|
|
86
91
|
// infinite functionality
|
|
87
92
|
// if params.page > 1 and infinite setting exists we should append results
|
|
88
|
-
if (this.config.settings?.infinite && params.pagination?.page > 1) {
|
|
89
|
-
const preventBackfill = this.config.settings.infinite?.backfill && !this.store.results.length && params.pagination
|
|
90
|
-
const dontBackfill = !this.config.settings.infinite?.backfill && !this.store.results.length
|
|
91
|
-
//if the page is higher than the backfill setting redirect back to page 1
|
|
93
|
+
if (this.config.settings?.infinite && params.pagination?.page && params.pagination.page > 1) {
|
|
94
|
+
const preventBackfill = this.config.settings.infinite?.backfill && !this.store.results.length && params.pagination.page > this.config.settings.infinite.backfill;
|
|
95
|
+
const dontBackfill = !this.config.settings.infinite?.backfill && !this.store.results.length;
|
|
96
|
+
// if the page is higher than the backfill setting redirect back to page 1
|
|
92
97
|
if (preventBackfill || dontBackfill) {
|
|
93
98
|
this.storage.set('scrollMap', {});
|
|
94
99
|
this.urlManager.set('page', 1).go();
|
|
95
100
|
return;
|
|
96
101
|
}
|
|
97
|
-
// if no results fetch results...
|
|
98
|
-
let previousResults = this.previousResults;
|
|
99
102
|
const backfills = [];
|
|
100
103
|
let pageSize = params.pagination?.pageSize || this.store.pagination.pageSize || this.store.pagination.defaultPageSize;
|
|
101
|
-
if
|
|
102
|
-
|
|
104
|
+
// if no results fetch results...
|
|
105
|
+
if (this.config.settings?.infinite.backfill && !this.previousResults.length) {
|
|
103
106
|
if (!pageSize) {
|
|
104
|
-
//
|
|
107
|
+
// pageSize is unknown - need to fetch meta to know defaultPageSize before we can continue
|
|
105
108
|
const meta = await this.client.meta();
|
|
106
109
|
pageSize = meta.pagination?.defaultPageSize;
|
|
107
110
|
}
|
|
108
|
-
|
|
111
|
+
// restricting pageSize to the limit
|
|
112
|
+
pageSize = pageSize > API_LIMIT ? API_LIMIT : pageSize;
|
|
113
|
+
const pagesNeeded = params.pagination?.page && params.pagination?.page > this.config.settings?.infinite.backfill
|
|
109
114
|
? this.config.settings?.infinite.backfill
|
|
110
115
|
: params.pagination?.page;
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (totalResultsNeeded < apiLimit) {
|
|
116
|
-
const backfillParams = deepmerge({ ...params }, { pagination: { pageSize: totalResultsNeeded, page: 1 } });
|
|
116
|
+
// figure out how many pages of results to backfill and wait on all responses
|
|
117
|
+
const { size: backFillPageSize, pages: backFillPages } = backFillSize(pagesNeeded, pageSize);
|
|
118
|
+
for (let i = 1; i <= backFillPages; i++) {
|
|
119
|
+
const backfillParams = deepmerge({ ...params }, { pagination: { pageSize: backFillPageSize, page: i } });
|
|
117
120
|
backfills.push(this.client.search(backfillParams));
|
|
118
121
|
}
|
|
119
|
-
else {
|
|
120
|
-
//how many pages are needed?
|
|
121
|
-
let pagesNeeded = Math.ceil(totalResultsNeeded / apiLimit);
|
|
122
|
-
// we dont want to get the full apiLimit # of results on the last page, so lets find out how many are left.
|
|
123
|
-
let lastPageCount = apiLimit - (pagesNeeded * apiLimit - totalResultsNeeded);
|
|
124
|
-
for (let i = 1; i <= pagesNeeded; i++) {
|
|
125
|
-
const backfillParams = deepmerge({ ...params }, { pagination: { pageSize: i < pagesNeeded ? apiLimit : lastPageCount, page: i } });
|
|
126
|
-
backfills.push(this.client.search(backfillParams));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
122
|
}
|
|
130
|
-
//infinite backfill
|
|
131
|
-
// use the previous results and only make request for new result
|
|
123
|
+
// infinite backfill results
|
|
132
124
|
if (backfills && backfills.length) {
|
|
125
|
+
// array to hold all results from backfill responses
|
|
133
126
|
let backfillResults = [];
|
|
134
127
|
const backfillResponses = await Promise.all(backfills);
|
|
135
|
-
backfillResponses.map(([
|
|
128
|
+
backfillResponses.map(([metaBackfill, responseBackfill]) => {
|
|
136
129
|
if (!meta) {
|
|
137
|
-
meta =
|
|
130
|
+
meta = metaBackfill;
|
|
138
131
|
}
|
|
139
132
|
if (!response) {
|
|
140
|
-
response =
|
|
141
|
-
backfillResults = response.results;
|
|
133
|
+
response = responseBackfill;
|
|
142
134
|
}
|
|
143
|
-
|
|
144
|
-
|
|
135
|
+
// push results to array
|
|
136
|
+
if (responseBackfill.results) {
|
|
137
|
+
backfillResults.push(...responseBackfill.results);
|
|
145
138
|
}
|
|
146
139
|
});
|
|
140
|
+
// overwrite pagination params to expected state
|
|
141
|
+
response.pagination.pageSize = pageSize;
|
|
142
|
+
response.pagination.totalPages = Math.ceil(response.pagination.totalResults / response.pagination.pageSize);
|
|
143
|
+
response.pagination.page = params.pagination?.page;
|
|
144
|
+
// set the response results with results from backfill responses
|
|
145
|
+
response.results = backfillResults;
|
|
147
146
|
if (!response.meta) {
|
|
148
147
|
/**
|
|
149
148
|
* MockClient will overwrite the client search() method and use
|
|
@@ -152,12 +151,6 @@ export class SearchController extends AbstractController {
|
|
|
152
151
|
// @ts-ignore
|
|
153
152
|
response.meta = meta;
|
|
154
153
|
}
|
|
155
|
-
//we need to overwrite the pagination params so the ui doesnt get confused.
|
|
156
|
-
response.pagination.pageSize = pageSize;
|
|
157
|
-
response.pagination.totalPages = Math.ceil(response.pagination.totalResults / response.pagination.pageSize);
|
|
158
|
-
response.pagination.page = params.pagination?.page;
|
|
159
|
-
//set the response results after all backfill promises are resolved.
|
|
160
|
-
response.results = backfillResults;
|
|
161
154
|
}
|
|
162
155
|
else {
|
|
163
156
|
// infinite with no backfills.
|
|
@@ -172,7 +165,7 @@ export class SearchController extends AbstractController {
|
|
|
172
165
|
response.meta = meta;
|
|
173
166
|
}
|
|
174
167
|
//append new results to previous results
|
|
175
|
-
response.results = [...previousResults, ...(response.results || [])];
|
|
168
|
+
response.results = [...this.previousResults, ...(response.results || [])];
|
|
176
169
|
}
|
|
177
170
|
}
|
|
178
171
|
else {
|
|
@@ -293,10 +286,12 @@ export class SearchController extends AbstractController {
|
|
|
293
286
|
window.location.replace(redirectURL);
|
|
294
287
|
return false;
|
|
295
288
|
}
|
|
289
|
+
const nonBackgroundFilters = search?.request?.filters?.filter((filter) => !filter.background);
|
|
296
290
|
if (config?.settings?.redirects?.singleResult &&
|
|
297
291
|
search?.response?.search?.query &&
|
|
298
292
|
search?.response?.pagination?.totalResults === 1 &&
|
|
299
|
-
!
|
|
293
|
+
!nonBackgroundFilters?.length &&
|
|
294
|
+
!search.controller.previousResults.length) {
|
|
300
295
|
window.location.replace(search?.response.results[0].mappings.core.url);
|
|
301
296
|
return false;
|
|
302
297
|
}
|
|
@@ -392,3 +387,10 @@ export function getStorableRequestParams(request) {
|
|
|
392
387
|
},
|
|
393
388
|
};
|
|
394
389
|
}
|
|
390
|
+
function backFillSize(pages, pageSize) {
|
|
391
|
+
const totalResults = pages * pageSize;
|
|
392
|
+
let numPages = Math.ceil(totalResults / API_LIMIT);
|
|
393
|
+
while (totalResults % numPages)
|
|
394
|
+
numPages++;
|
|
395
|
+
return { size: totalResults / numPages, pages: numPages };
|
|
396
|
+
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { Tracker, ProductViewEvent } from '@searchspring/snap-tracker';
|
|
|
6
6
|
import type { Profiler } from '@searchspring/snap-profiler';
|
|
7
7
|
import type { UrlManager } from '@searchspring/snap-url-manager';
|
|
8
8
|
import type { Logger } from '@searchspring/snap-logger';
|
|
9
|
+
import type { SearchRequestModel } from '@searchspring/snapi-types';
|
|
9
10
|
export declare type PluginFunction = (cntrlr: AbstractController, ...args: any) => Promise<void> | void;
|
|
10
11
|
export declare type PluginGrouping = [func: PluginFunction, ...args: unknown[]];
|
|
11
12
|
export declare type BeforeSearchObj = {
|
|
@@ -15,6 +16,7 @@ export declare type BeforeSearchObj = {
|
|
|
15
16
|
export declare type AfterSearchObj = {
|
|
16
17
|
controller: AbstractController;
|
|
17
18
|
response: any;
|
|
19
|
+
request: SearchRequestModel;
|
|
18
20
|
};
|
|
19
21
|
export declare type AfterStoreObj = {
|
|
20
22
|
controller: AbstractController;
|
package/dist/esm/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAEjF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,KAAK,EACX,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,yBAAyB,EACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@searchspring/snap-controller",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Snap Controllers",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
"test:watch": "jest --watch"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@searchspring/snap-toolbox": "^0.
|
|
23
|
+
"@searchspring/snap-toolbox": "^0.40.0",
|
|
24
24
|
"deepmerge": "4.2.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@searchspring/snap-client": "^0.
|
|
28
|
-
"@searchspring/snap-event-manager": "^0.
|
|
29
|
-
"@searchspring/snap-logger": "^0.
|
|
30
|
-
"@searchspring/snap-profiler": "^0.
|
|
31
|
-
"@searchspring/snap-store-mobx": "^0.
|
|
32
|
-
"@searchspring/snap-tracker": "^0.
|
|
33
|
-
"@searchspring/snap-url-manager": "^0.
|
|
27
|
+
"@searchspring/snap-client": "^0.40.0",
|
|
28
|
+
"@searchspring/snap-event-manager": "^0.40.0",
|
|
29
|
+
"@searchspring/snap-logger": "^0.40.0",
|
|
30
|
+
"@searchspring/snap-profiler": "^0.40.0",
|
|
31
|
+
"@searchspring/snap-store-mobx": "^0.40.0",
|
|
32
|
+
"@searchspring/snap-tracker": "^0.40.0",
|
|
33
|
+
"@searchspring/snap-url-manager": "^0.40.0"
|
|
34
34
|
},
|
|
35
35
|
"sideEffects": false,
|
|
36
36
|
"files": [
|
|
37
37
|
"dist/**/*"
|
|
38
38
|
],
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "ab543649e56e547374715ad0f018db29d72a0d8e"
|
|
40
40
|
}
|