@searchspring/snap-preact 0.27.8 → 0.30.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/README.md +2 -1
- package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts +6 -5
- package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
- package/dist/cjs/Instantiators/RecommendationInstantiator.js +19 -5
- package/dist/cjs/Snap.d.ts +67 -13
- package/dist/cjs/Snap.d.ts.map +1 -1
- package/dist/cjs/Snap.js +223 -81
- package/dist/cjs/create/createAutocompleteController.d.ts +1 -1
- package/dist/cjs/create/createAutocompleteController.d.ts.map +1 -1
- package/dist/cjs/create/createAutocompleteController.js +6 -1
- package/dist/cjs/create/createFinderController.d.ts +1 -1
- package/dist/cjs/create/createFinderController.d.ts.map +1 -1
- package/dist/cjs/create/createFinderController.js +6 -1
- package/dist/cjs/create/createRecommendationController.d.ts +1 -1
- package/dist/cjs/create/createRecommendationController.d.ts.map +1 -1
- package/dist/cjs/create/createRecommendationController.js +6 -1
- package/dist/cjs/create/createSearchController.d.ts +1 -1
- package/dist/cjs/create/createSearchController.d.ts.map +1 -1
- package/dist/cjs/create/createSearchController.js +6 -1
- package/dist/cjs/getBundleDetails/getBundleDetails.d.ts.map +1 -1
- package/dist/cjs/getBundleDetails/getBundleDetails.js +3 -2
- package/dist/cjs/types.d.ts +11 -5
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/Instantiators/RecommendationInstantiator.d.ts +6 -5
- package/dist/esm/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
- package/dist/esm/Instantiators/RecommendationInstantiator.js +21 -6
- package/dist/esm/Snap.d.ts +67 -13
- package/dist/esm/Snap.d.ts.map +1 -1
- package/dist/esm/Snap.js +185 -61
- package/dist/esm/create/createAutocompleteController.d.ts +1 -1
- package/dist/esm/create/createAutocompleteController.d.ts.map +1 -1
- package/dist/esm/create/createAutocompleteController.js +6 -1
- package/dist/esm/create/createFinderController.d.ts +1 -1
- package/dist/esm/create/createFinderController.d.ts.map +1 -1
- package/dist/esm/create/createFinderController.js +6 -1
- package/dist/esm/create/createRecommendationController.d.ts +1 -1
- package/dist/esm/create/createRecommendationController.d.ts.map +1 -1
- package/dist/esm/create/createRecommendationController.js +6 -1
- package/dist/esm/create/createSearchController.d.ts +1 -1
- package/dist/esm/create/createSearchController.d.ts.map +1 -1
- package/dist/esm/create/createSearchController.js +6 -1
- package/dist/esm/getBundleDetails/getBundleDetails.d.ts.map +1 -1
- package/dist/esm/getBundleDetails/getBundleDetails.js +3 -2
- package/dist/esm/types.d.ts +11 -5
- package/dist/esm/types.d.ts.map +1 -1
- package/package.json +13 -13
package/dist/esm/Snap.js
CHANGED
|
@@ -3,14 +3,14 @@ import deepmerge from 'deepmerge';
|
|
|
3
3
|
import { isPlainObject } from 'is-plain-object';
|
|
4
4
|
import { render } from 'preact';
|
|
5
5
|
import { Client } from '@searchspring/snap-client';
|
|
6
|
-
import { Logger
|
|
6
|
+
import { Logger } from '@searchspring/snap-logger';
|
|
7
7
|
import { Tracker } from '@searchspring/snap-tracker';
|
|
8
|
-
import { version, DomTargeter, url, cookies, featureFlags } from '@searchspring/snap-toolbox';
|
|
9
|
-
import { getContext } from '@searchspring/snap-toolbox';
|
|
8
|
+
import { AppMode, version, getContext, DomTargeter, url, cookies, featureFlags } from '@searchspring/snap-toolbox';
|
|
10
9
|
import { ControllerTypes } from '@searchspring/snap-controller';
|
|
11
10
|
import { default as createSearchController } from './create/createSearchController';
|
|
12
11
|
export const BRANCH_COOKIE = 'ssBranch';
|
|
13
|
-
export const
|
|
12
|
+
export const DEV_COOKIE = 'ssDev';
|
|
13
|
+
const SESSION_ATTRIBUTION = 'ssAttribution';
|
|
14
14
|
const COMPONENT_ERROR = `Uncaught Error - Invalid value passed as the component.
|
|
15
15
|
This usually happens when you pass a JSX Element, and not a function that returns the component, in the snap config.
|
|
16
16
|
|
|
@@ -47,6 +47,10 @@ This usually happens when you pass a JSX Element, and not a function that return
|
|
|
47
47
|
The error above happened in the following targeter in the Snap Config`;
|
|
48
48
|
export class Snap {
|
|
49
49
|
constructor(config, services) {
|
|
50
|
+
this.mode = AppMode.production;
|
|
51
|
+
this._instantiatorPromises = {};
|
|
52
|
+
this._controllerPromises = {};
|
|
53
|
+
this.controllers = {};
|
|
50
54
|
this.getInstantiator = (id) => {
|
|
51
55
|
return this._instantiatorPromises[id] || Promise.reject(`getInstantiator could not find instantiator with id: ${id}`);
|
|
52
56
|
};
|
|
@@ -58,12 +62,22 @@ export class Snap {
|
|
|
58
62
|
controllerIds.forEach((id) => getControllerPromises.push(this.getController(id)));
|
|
59
63
|
return Promise.all(getControllerPromises);
|
|
60
64
|
};
|
|
65
|
+
// exposed method used for creating controllers dynamically - calls _createController()
|
|
61
66
|
this.createController = async (type, config, services, urlConfig, context, callback) => {
|
|
67
|
+
if (typeof this._controllerPromises[config.id] != 'undefined') {
|
|
68
|
+
throw new Error(`Controller with id '${config.id}' is already defined`);
|
|
69
|
+
}
|
|
70
|
+
this._controllerPromises[config.id] = new Promise((resolve) => this._createController(type, config, services, urlConfig, context, async (cntrlr) => {
|
|
71
|
+
if (typeof callback == 'function')
|
|
72
|
+
await callback(cntrlr);
|
|
73
|
+
resolve(cntrlr);
|
|
74
|
+
}));
|
|
75
|
+
return this._controllerPromises[config.id];
|
|
76
|
+
};
|
|
77
|
+
// internal use method that creates controllers without verifying if id is in use first
|
|
78
|
+
this._createController = async (type, config, services, urlConfig, context, callback) => {
|
|
62
79
|
let importPromise;
|
|
63
80
|
switch (type) {
|
|
64
|
-
case ControllerTypes.search:
|
|
65
|
-
importPromise = import('./create/createSearchController');
|
|
66
|
-
break;
|
|
67
81
|
case ControllerTypes.autocomplete:
|
|
68
82
|
importPromise = import('./create/createAutocompleteController');
|
|
69
83
|
break;
|
|
@@ -73,10 +87,17 @@ export class Snap {
|
|
|
73
87
|
case ControllerTypes.recommendation:
|
|
74
88
|
importPromise = import('./create/createRecommendationController');
|
|
75
89
|
break;
|
|
90
|
+
case ControllerTypes.search:
|
|
91
|
+
default:
|
|
92
|
+
importPromise = import('./create/createSearchController');
|
|
93
|
+
break;
|
|
76
94
|
}
|
|
95
|
+
// @ts-ignore - we know the config is correct, but complicated typing
|
|
77
96
|
const creationFunc = (await importPromise).default;
|
|
78
97
|
if (!this.controllers[config.id]) {
|
|
79
|
-
|
|
98
|
+
window.searchspring.controller = window.searchspring.controller || {};
|
|
99
|
+
window.searchspring.controller[config.id] = this.controllers[config.id] = creationFunc({
|
|
100
|
+
mode: this.mode,
|
|
80
101
|
url: deepmerge(this.config.url || {}, urlConfig || {}),
|
|
81
102
|
controller: config,
|
|
82
103
|
context: deepmerge(this.context || {}, context || {}),
|
|
@@ -95,15 +116,42 @@ export class Snap {
|
|
|
95
116
|
}
|
|
96
117
|
return this.controllers[config.id];
|
|
97
118
|
};
|
|
119
|
+
this.handlers = {
|
|
120
|
+
error: (event) => {
|
|
121
|
+
try {
|
|
122
|
+
const { filename } = event;
|
|
123
|
+
if (filename.includes('snapui.searchspring.io') && this.tracker.track.error) {
|
|
124
|
+
const { colno, lineno, error: { stack }, message, timeStamp, } = event;
|
|
125
|
+
const userAgent = navigator.userAgent;
|
|
126
|
+
const href = window.location.href;
|
|
127
|
+
const beaconPayload = {
|
|
128
|
+
userAgent,
|
|
129
|
+
href,
|
|
130
|
+
filename,
|
|
131
|
+
stack,
|
|
132
|
+
message,
|
|
133
|
+
colno,
|
|
134
|
+
lineno,
|
|
135
|
+
timeStamp,
|
|
136
|
+
};
|
|
137
|
+
this.tracker.track.error(beaconPayload);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
// prevent error metrics from breaking the app
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
window.removeEventListener('error', this.handlers.error);
|
|
146
|
+
window.addEventListener('error', this.handlers.error);
|
|
98
147
|
this.config = config;
|
|
99
|
-
this.logger = services?.logger || new Logger('Snap Preact ');
|
|
100
148
|
let globalContext = {};
|
|
101
149
|
try {
|
|
102
150
|
// get global context
|
|
103
151
|
globalContext = getContext(['shopper', 'config', 'merchandising']);
|
|
104
152
|
}
|
|
105
153
|
catch (err) {
|
|
106
|
-
|
|
154
|
+
console.error('Snap failed to find global context');
|
|
107
155
|
}
|
|
108
156
|
// merge configs - but only merge plain objects
|
|
109
157
|
this.config = deepmerge(this.config || {}, globalContext.config || {}, {
|
|
@@ -115,8 +163,9 @@ export class Snap {
|
|
|
115
163
|
if ((!services?.client || !services?.tracker) && !this.config?.client?.globals?.siteId) {
|
|
116
164
|
throw new Error(`Snap: config provided must contain a valid config.client.globals.siteId value`);
|
|
117
165
|
}
|
|
118
|
-
|
|
119
|
-
|
|
166
|
+
// segmented merchandising context -> client globals
|
|
167
|
+
if (this.config.client?.globals && this.context.merchandising?.segments) {
|
|
168
|
+
if (this.config.client.globals?.merchandising) {
|
|
120
169
|
this.config.client.globals.merchandising.segments = deepmerge(this.config.client.globals.merchandising.segments, this.context.merchandising.segments);
|
|
121
170
|
}
|
|
122
171
|
else {
|
|
@@ -125,33 +174,73 @@ export class Snap {
|
|
|
125
174
|
};
|
|
126
175
|
}
|
|
127
176
|
}
|
|
128
|
-
this.client = services?.client || new Client(this.config.client.globals, this.config.client.config);
|
|
129
|
-
this.tracker = services?.tracker || new Tracker(this.config.client.globals);
|
|
130
|
-
this._controllerPromises = {};
|
|
131
|
-
this._instantiatorPromises = {};
|
|
132
|
-
this.controllers = {};
|
|
133
|
-
// TODO environment switch using URL?
|
|
134
|
-
this.logger.setMode(process.env.NODE_ENV);
|
|
135
|
-
// log version
|
|
136
|
-
this.logger.imageText({
|
|
137
|
-
url: 'https://snapui.searchspring.io/favicon.svg',
|
|
138
|
-
text: `[${version}]`,
|
|
139
|
-
style: `color: ${this.logger.colors.indigo}; font-weight: bold;`,
|
|
140
|
-
});
|
|
141
177
|
try {
|
|
142
178
|
const urlParams = url(window.location.href);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
179
|
+
const branchOverride = urlParams?.params?.query?.branch || cookies.get(BRANCH_COOKIE);
|
|
180
|
+
/* app mode priority:
|
|
181
|
+
1. node env
|
|
182
|
+
2. config
|
|
183
|
+
3. override via query param / cookie
|
|
184
|
+
*/
|
|
185
|
+
// node env
|
|
186
|
+
if (process.env.NODE_ENV && Object.values(AppMode).includes(process.env.NODE_ENV)) {
|
|
187
|
+
this.mode = process.env.NODE_ENV;
|
|
188
|
+
}
|
|
189
|
+
// config
|
|
190
|
+
if (this.config.mode && Object.values(AppMode).includes(this.config.mode)) {
|
|
191
|
+
this.mode = this.config.mode;
|
|
192
|
+
}
|
|
193
|
+
// query param / cookiev override
|
|
194
|
+
if ((urlParams?.params?.query && 'dev' in urlParams.params.query) || !!cookies.get(DEV_COOKIE)) {
|
|
195
|
+
if (urlParams?.params.query?.dev == 'false' || urlParams?.params.query?.dev == '0') {
|
|
196
|
+
cookies.unset(DEV_COOKIE);
|
|
197
|
+
this.mode = AppMode.production;
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
cookies.set(DEV_COOKIE, '1', 'Lax', 0);
|
|
201
|
+
this.mode = AppMode.development;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// client mode uses client config over snap config
|
|
205
|
+
if (this.config.client) {
|
|
206
|
+
this.config.client.config = this.config.client.config || {};
|
|
207
|
+
this.config.client.config.mode = this.config.client.config.mode || this.mode;
|
|
208
|
+
}
|
|
209
|
+
this.client = services?.client || new Client(this.config.client.globals, this.config.client.config);
|
|
210
|
+
this.tracker = services?.tracker || new Tracker(this.config.client.globals, { framework: 'preact' });
|
|
211
|
+
this.logger = services?.logger || new Logger({ prefix: 'Snap Preact ', mode: this.mode });
|
|
212
|
+
// check for tracking attribution in URL ?ss_attribution=type:id
|
|
213
|
+
const sessionAttribution = window.sessionStorage?.getItem(SESSION_ATTRIBUTION);
|
|
214
|
+
if (urlParams?.params?.query?.ss_attribution) {
|
|
215
|
+
const attribution = urlParams.params.query.ss_attribution.split(':');
|
|
216
|
+
const [type, id] = attribution;
|
|
217
|
+
if (type && id) {
|
|
218
|
+
this.tracker.updateContext('attribution', { type, id });
|
|
219
|
+
}
|
|
220
|
+
// save to session storage
|
|
221
|
+
window.sessionStorage?.setItem(SESSION_ATTRIBUTION, urlParams.params.query.ss_attribution);
|
|
222
|
+
}
|
|
223
|
+
else if (sessionAttribution) {
|
|
224
|
+
const [type, id] = sessionAttribution.split(':');
|
|
225
|
+
if (type && id) {
|
|
226
|
+
this.tracker.updateContext('attribution', { type, id });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// log version
|
|
230
|
+
this.logger.imageText({
|
|
231
|
+
url: 'https://snapui.searchspring.io/favicon.svg',
|
|
232
|
+
text: `[${version}]`,
|
|
233
|
+
style: `color: ${this.logger.colors.indigo}; font-weight: bold;`,
|
|
234
|
+
});
|
|
235
|
+
if (branchOverride && !document.querySelector(`script[${BRANCH_COOKIE}]`)) {
|
|
236
|
+
this.logger.warn(`...loading build... '${branchOverride}'`);
|
|
237
|
+
// set a cookie with branch
|
|
146
238
|
if (featureFlags.cookies) {
|
|
147
|
-
cookies.set(BRANCH_COOKIE,
|
|
148
|
-
cookies.set(SS_DEV_COOKIE, '1', 'Lax', 0);
|
|
239
|
+
cookies.set(BRANCH_COOKIE, branchOverride, 'Lax', 3600000); // 1 hour
|
|
149
240
|
}
|
|
150
241
|
else {
|
|
151
242
|
this.logger.warn('Cookies are not supported/enabled by this browser, branch overrides will not persist!');
|
|
152
243
|
}
|
|
153
|
-
this.logger.setMode(LogMode.DEVELOPMENT);
|
|
154
|
-
this.logger.warn(`...loading build... '${branchParam}'`);
|
|
155
244
|
// get the path and siteId from the current bundle script in case its not the same as the client config
|
|
156
245
|
let path = `https://snapui.searchspring.io/${this.config.client.globals.siteId}/`;
|
|
157
246
|
const script = document.querySelector('script[src*="//snapui.searchspring.io"]');
|
|
@@ -163,10 +252,9 @@ export class Snap {
|
|
|
163
252
|
}
|
|
164
253
|
// append script with new branch in path
|
|
165
254
|
const branchScript = document.createElement('script');
|
|
166
|
-
const src = `${path}${
|
|
255
|
+
const src = `${path}${branchOverride}/bundle.js`;
|
|
167
256
|
branchScript.src = src;
|
|
168
|
-
branchScript.setAttribute(BRANCH_COOKIE,
|
|
169
|
-
document.head.appendChild(branchScript);
|
|
257
|
+
branchScript.setAttribute(BRANCH_COOKIE, branchOverride);
|
|
170
258
|
new DomTargeter([
|
|
171
259
|
{
|
|
172
260
|
selector: 'body',
|
|
@@ -180,32 +268,43 @@ export class Snap {
|
|
|
180
268
|
},
|
|
181
269
|
},
|
|
182
270
|
], async (target, elem) => {
|
|
183
|
-
|
|
271
|
+
const props = {};
|
|
184
272
|
try {
|
|
185
273
|
const getBundleDetails = (await import('./getBundleDetails/getBundleDetails')).getBundleDetails;
|
|
186
|
-
|
|
274
|
+
props.details = await getBundleDetails(src);
|
|
187
275
|
}
|
|
188
276
|
catch (err) {
|
|
189
|
-
error = err;
|
|
277
|
+
props.error = err;
|
|
190
278
|
}
|
|
191
279
|
const BranchOverride = (await import('./components/BranchOverride')).BranchOverride;
|
|
192
|
-
render(_jsx(BranchOverride, {
|
|
280
|
+
render(_jsx(BranchOverride, { ...props, name: branchOverride, onRemoveClick: () => {
|
|
193
281
|
cookies.unset(BRANCH_COOKIE);
|
|
194
282
|
const urlState = url(window.location.href);
|
|
195
|
-
delete urlState
|
|
196
|
-
|
|
283
|
+
delete urlState?.params.query['branch'];
|
|
284
|
+
const newUrl = urlState?.url();
|
|
285
|
+
if (newUrl && newUrl != window.location.href) {
|
|
286
|
+
window.location.href = newUrl;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
window.location.reload();
|
|
290
|
+
}
|
|
197
291
|
} }), elem);
|
|
292
|
+
// reset the global searchspring object
|
|
293
|
+
delete window.searchspring;
|
|
294
|
+
document.head.appendChild(branchScript);
|
|
198
295
|
});
|
|
199
296
|
// prevent further instantiation of config
|
|
200
297
|
return;
|
|
201
298
|
}
|
|
202
299
|
}
|
|
203
|
-
catch (e) {
|
|
204
|
-
|
|
205
|
-
window.searchspring.context = this.context;
|
|
206
|
-
if (this.client)
|
|
207
|
-
window.searchspring.client = this.client;
|
|
300
|
+
catch (e) {
|
|
301
|
+
this.logger.error(e);
|
|
208
302
|
}
|
|
303
|
+
// bind to window global
|
|
304
|
+
window.searchspring = window.searchspring || {};
|
|
305
|
+
window.searchspring.context = this.context;
|
|
306
|
+
if (this.client)
|
|
307
|
+
window.searchspring.client = this.client;
|
|
209
308
|
// autotrack shopper id from the context
|
|
210
309
|
if (this.context?.shopper?.id) {
|
|
211
310
|
this.tracker.track.shopper.login({
|
|
@@ -216,7 +315,7 @@ export class Snap {
|
|
|
216
315
|
if (this.context?.shopper?.cart) {
|
|
217
316
|
const cart = this.context.shopper.cart;
|
|
218
317
|
if (Array.isArray(cart)) {
|
|
219
|
-
const cartItems = cart.filter((item) => item?.sku || item?.childSku).map((item) => (item?.sku || item?.childSku).trim());
|
|
318
|
+
const cartItems = cart.filter((item) => item?.sku || item?.childSku).map((item) => (item?.sku || item?.childSku || '').trim());
|
|
220
319
|
this.tracker.cookies.cart.set(cartItems);
|
|
221
320
|
}
|
|
222
321
|
}
|
|
@@ -225,7 +324,12 @@ export class Snap {
|
|
|
225
324
|
case 'search': {
|
|
226
325
|
this.config.controllers[type].forEach((controller, index) => {
|
|
227
326
|
try {
|
|
327
|
+
if (typeof this._controllerPromises[controller.config.id] != 'undefined') {
|
|
328
|
+
this.logger.error(`Controller with id '${controller.config.id}' is already defined`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
228
331
|
const cntrlr = createSearchController({
|
|
332
|
+
mode: this.mode,
|
|
229
333
|
url: deepmerge(this.config.url || {}, controller.url || {}),
|
|
230
334
|
controller: controller.config,
|
|
231
335
|
context: deepmerge(this.context || {}, controller.context || {}),
|
|
@@ -238,7 +342,8 @@ export class Snap {
|
|
|
238
342
|
logger: controller.services?.logger,
|
|
239
343
|
tracker: controller.services?.tracker || this.tracker,
|
|
240
344
|
});
|
|
241
|
-
|
|
345
|
+
window.searchspring.controller = window.searchspring.controller || {};
|
|
346
|
+
window.searchspring.controller[cntrlr.config.id] = this.controllers[cntrlr.config.id] = cntrlr;
|
|
242
347
|
this._controllerPromises[cntrlr.config.id] = new Promise((resolve) => resolve(cntrlr));
|
|
243
348
|
let searched = false;
|
|
244
349
|
const runSearch = () => {
|
|
@@ -272,7 +377,7 @@ export class Snap {
|
|
|
272
377
|
runSearch();
|
|
273
378
|
}
|
|
274
379
|
cntrlr.createTargeter({ controller: cntrlr, ...target }, async (target, elem, originalElem) => {
|
|
275
|
-
if (target.skeleton) {
|
|
380
|
+
if (target && target.skeleton && elem) {
|
|
276
381
|
const Skeleton = await target.skeleton();
|
|
277
382
|
setTimeout(() => {
|
|
278
383
|
render(_jsx(Skeleton, {}), elem);
|
|
@@ -290,6 +395,10 @@ export class Snap {
|
|
|
290
395
|
}
|
|
291
396
|
case 'autocomplete': {
|
|
292
397
|
this.config.controllers[type].forEach((controller, index) => {
|
|
398
|
+
if (typeof this._controllerPromises[controller.config.id] != 'undefined') {
|
|
399
|
+
this.logger.error(`Controller with id '${controller.config.id}' is already defined`);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
293
402
|
this._controllerPromises[controller.config.id] = new Promise((resolve) => {
|
|
294
403
|
try {
|
|
295
404
|
let bound = false;
|
|
@@ -315,8 +424,9 @@ export class Snap {
|
|
|
315
424
|
}
|
|
316
425
|
};
|
|
317
426
|
if (!controller?.targeters || controller?.targeters.length === 0) {
|
|
318
|
-
this.
|
|
319
|
-
|
|
427
|
+
this._createController(ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
428
|
+
if (cntrlr)
|
|
429
|
+
resolve(cntrlr);
|
|
320
430
|
});
|
|
321
431
|
}
|
|
322
432
|
controller?.targeters?.forEach((target, target_index) => {
|
|
@@ -342,8 +452,9 @@ export class Snap {
|
|
|
342
452
|
...target,
|
|
343
453
|
},
|
|
344
454
|
], async (target, elem, originalElem) => {
|
|
345
|
-
const cntrlr = await this.
|
|
346
|
-
|
|
455
|
+
const cntrlr = await this._createController(ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
456
|
+
if (cntrlr)
|
|
457
|
+
resolve(cntrlr);
|
|
347
458
|
});
|
|
348
459
|
runBind();
|
|
349
460
|
targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
|
|
@@ -360,6 +471,10 @@ export class Snap {
|
|
|
360
471
|
}
|
|
361
472
|
case 'finder': {
|
|
362
473
|
this.config.controllers[type].forEach((controller, index) => {
|
|
474
|
+
if (typeof this._controllerPromises[controller.config.id] != 'undefined') {
|
|
475
|
+
this.logger.error(`Controller with id '${controller.config.id}' is already defined`);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
363
478
|
this._controllerPromises[controller.config.id] = new Promise((resolve) => {
|
|
364
479
|
try {
|
|
365
480
|
let searched = false;
|
|
@@ -383,8 +498,9 @@ export class Snap {
|
|
|
383
498
|
}
|
|
384
499
|
};
|
|
385
500
|
if (!controller?.targeters || controller?.targeters.length === 0) {
|
|
386
|
-
this.
|
|
387
|
-
|
|
501
|
+
this._createController(ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
502
|
+
if (cntrlr)
|
|
503
|
+
resolve(cntrlr);
|
|
388
504
|
});
|
|
389
505
|
}
|
|
390
506
|
controller?.targeters?.forEach((target, target_index) => {
|
|
@@ -395,8 +511,9 @@ export class Snap {
|
|
|
395
511
|
throw new Error(`Targets at index ${target_index} missing component value (Component).`);
|
|
396
512
|
}
|
|
397
513
|
const targeter = new DomTargeter([{ ...target }], async (target, elem, originalElem) => {
|
|
398
|
-
const cntrlr = await this.
|
|
399
|
-
|
|
514
|
+
const cntrlr = await this._createController(ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
515
|
+
if (cntrlr)
|
|
516
|
+
resolve(cntrlr);
|
|
400
517
|
});
|
|
401
518
|
runSearch();
|
|
402
519
|
targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
|
|
@@ -413,6 +530,10 @@ export class Snap {
|
|
|
413
530
|
}
|
|
414
531
|
case 'recommendation': {
|
|
415
532
|
this.config.controllers[type].forEach((controller, index) => {
|
|
533
|
+
if (typeof this._controllerPromises[controller.config.id] != 'undefined') {
|
|
534
|
+
this.logger.error(`Controller with id '${controller.config.id}' is already defined`);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
416
537
|
this._controllerPromises[controller.config.id] = new Promise((resolve) => {
|
|
417
538
|
try {
|
|
418
539
|
let searched = false;
|
|
@@ -436,8 +557,9 @@ export class Snap {
|
|
|
436
557
|
}
|
|
437
558
|
};
|
|
438
559
|
if (!controller?.targeters || controller?.targeters.length === 0) {
|
|
439
|
-
this.
|
|
440
|
-
|
|
560
|
+
this._createController(ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
561
|
+
if (cntrlr)
|
|
562
|
+
resolve(cntrlr);
|
|
441
563
|
});
|
|
442
564
|
}
|
|
443
565
|
controller?.targeters?.forEach((target, target_index) => {
|
|
@@ -448,8 +570,9 @@ export class Snap {
|
|
|
448
570
|
throw new Error(`Targets at index ${target_index} missing component value (Component).`);
|
|
449
571
|
}
|
|
450
572
|
const targeter = new DomTargeter([{ ...target }], async (target, elem, originalElem) => {
|
|
451
|
-
const cntrlr = await this.
|
|
452
|
-
|
|
573
|
+
const cntrlr = await this._createController(ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
|
|
574
|
+
if (cntrlr)
|
|
575
|
+
resolve(cntrlr);
|
|
453
576
|
});
|
|
454
577
|
runSearch();
|
|
455
578
|
targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
|
|
@@ -469,6 +592,7 @@ export class Snap {
|
|
|
469
592
|
if (this.config?.instantiators?.recommendation) {
|
|
470
593
|
try {
|
|
471
594
|
this._instantiatorPromises.recommendation = import('./Instantiators/RecommendationInstantiator').then(({ RecommendationInstantiator }) => {
|
|
595
|
+
this.config.instantiators.recommendation.mode = this.config.instantiators.recommendation.mode || this.mode;
|
|
472
596
|
return new RecommendationInstantiator(this.config.instantiators.recommendation, {
|
|
473
597
|
client: this.client,
|
|
474
598
|
tracker: this.tracker,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutocompleteController } from '@searchspring/snap-controller';
|
|
2
2
|
import type { SnapControllerServices, SnapAutocompleteControllerConfig } from '../types';
|
|
3
|
-
declare const _default: (config: SnapAutocompleteControllerConfig, services?: SnapControllerServices) => AutocompleteController;
|
|
3
|
+
declare const _default: (config: SnapAutocompleteControllerConfig, services?: SnapControllerServices | undefined) => AutocompleteController;
|
|
4
4
|
export default _default;
|
|
5
5
|
//# sourceMappingURL=createAutocompleteController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAutocompleteController.d.ts","sourceRoot":"","sources":["../../../src/create/createAutocompleteController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AASvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,gCAAgC,EAAE,MAAM,UAAU,CAAC;iCAIjE,gCAAgC,
|
|
1
|
+
{"version":3,"file":"createAutocompleteController.d.ts","sourceRoot":"","sources":["../../../src/create/createAutocompleteController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AASvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,gCAAgC,EAAE,MAAM,UAAU,CAAC;iCAIjE,gCAAgC,oDAAsC,sBAAsB;AAApH,wBAwBE"}
|
|
@@ -10,13 +10,18 @@ import { Tracker } from '@searchspring/snap-tracker';
|
|
|
10
10
|
configureMobx({ useProxies: 'never' });
|
|
11
11
|
export default (config, services) => {
|
|
12
12
|
const urlManager = (services?.urlManager || new UrlManager(new UrlTranslator(config.url), reactLinker)).detach();
|
|
13
|
+
// set client mode
|
|
14
|
+
if (config.mode && config.client) {
|
|
15
|
+
config.client.config = config.client.config || {};
|
|
16
|
+
config.client.config.mode = config.mode;
|
|
17
|
+
}
|
|
13
18
|
const cntrlr = new AutocompleteController(config.controller, {
|
|
14
19
|
client: services?.client || new Client(config.client.globals, config.client.config),
|
|
15
20
|
store: services?.store || new AutocompleteStore(config.controller, { urlManager }),
|
|
16
21
|
urlManager,
|
|
17
22
|
eventManager: services?.eventManager || new EventManager(),
|
|
18
23
|
profiler: services?.profiler || new Profiler(),
|
|
19
|
-
logger: services?.logger || new Logger(),
|
|
24
|
+
logger: services?.logger || new Logger({ mode: config.mode }),
|
|
20
25
|
tracker: services?.tracker || new Tracker(config.client.globals),
|
|
21
26
|
}, config.context);
|
|
22
27
|
return cntrlr;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FinderController } from '@searchspring/snap-controller';
|
|
2
2
|
import type { SnapControllerServices, SnapFinderControllerConfig } from '../types';
|
|
3
|
-
declare const _default: (config: SnapFinderControllerConfig, services?: SnapControllerServices) => FinderController;
|
|
3
|
+
declare const _default: (config: SnapFinderControllerConfig, services?: SnapControllerServices | undefined) => FinderController;
|
|
4
4
|
export default _default;
|
|
5
5
|
//# sourceMappingURL=createFinderController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFinderController.d.ts","sourceRoot":"","sources":["../../../src/create/createFinderController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AASjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;iCAI3D,0BAA0B,
|
|
1
|
+
{"version":3,"file":"createFinderController.d.ts","sourceRoot":"","sources":["../../../src/create/createFinderController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AASjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;iCAI3D,0BAA0B,oDAAsC,gBAAgB;AAAxG,wBAwBE"}
|
|
@@ -10,13 +10,18 @@ import { Tracker } from '@searchspring/snap-tracker';
|
|
|
10
10
|
configureMobx({ useProxies: 'never' });
|
|
11
11
|
export default (config, services) => {
|
|
12
12
|
const urlManager = (services?.urlManager || new UrlManager(new UrlTranslator(config.url), reactLinker)).detach(true);
|
|
13
|
+
// set client mode
|
|
14
|
+
if (config.mode && config.client) {
|
|
15
|
+
config.client.config = config.client.config || {};
|
|
16
|
+
config.client.config.mode = config.mode;
|
|
17
|
+
}
|
|
13
18
|
const cntrlr = new FinderController(config.controller, {
|
|
14
19
|
client: services?.client || new Client(config.client.globals, config.client.config),
|
|
15
20
|
store: services?.store || new FinderStore(config.controller, { urlManager }),
|
|
16
21
|
urlManager,
|
|
17
22
|
eventManager: services?.eventManager || new EventManager(),
|
|
18
23
|
profiler: services?.profiler || new Profiler(),
|
|
19
|
-
logger: services?.logger || new Logger(),
|
|
24
|
+
logger: services?.logger || new Logger({ mode: config.mode }),
|
|
20
25
|
tracker: services?.tracker || new Tracker(config.client.globals),
|
|
21
26
|
}, config.context);
|
|
22
27
|
return cntrlr;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RecommendationController } from '@searchspring/snap-controller';
|
|
2
2
|
import type { SnapControllerServices, SnapRecommendationControllerConfig } from '../types';
|
|
3
|
-
declare const _default: (config: SnapRecommendationControllerConfig, services?: SnapControllerServices) => RecommendationController;
|
|
3
|
+
declare const _default: (config: SnapRecommendationControllerConfig, services?: SnapControllerServices | undefined) => RecommendationController;
|
|
4
4
|
export default _default;
|
|
5
5
|
//# sourceMappingURL=createRecommendationController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRecommendationController.d.ts","sourceRoot":"","sources":["../../../src/create/createRecommendationController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AASzE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,UAAU,CAAC;iCAInE,kCAAkC,
|
|
1
|
+
{"version":3,"file":"createRecommendationController.d.ts","sourceRoot":"","sources":["../../../src/create/createRecommendationController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AASzE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,UAAU,CAAC;iCAInE,kCAAkC,oDAAsC,wBAAwB;AAAxH,wBAwBE"}
|
|
@@ -10,13 +10,18 @@ import { Tracker } from '@searchspring/snap-tracker';
|
|
|
10
10
|
configureMobx({ useProxies: 'never' });
|
|
11
11
|
export default (config, services) => {
|
|
12
12
|
const urlManager = (services?.urlManager || new UrlManager(new UrlTranslator(config.url), reactLinker)).detach(true);
|
|
13
|
+
// set client mode
|
|
14
|
+
if (config.mode && config.client) {
|
|
15
|
+
config.client.config = config.client.config || {};
|
|
16
|
+
config.client.config.mode = config.mode;
|
|
17
|
+
}
|
|
13
18
|
const cntrlr = new RecommendationController(config.controller, {
|
|
14
19
|
client: services?.client || new Client(config.client.globals, config.client.config),
|
|
15
20
|
store: services?.store || new RecommendationStore(config.controller, { urlManager }),
|
|
16
21
|
urlManager,
|
|
17
22
|
eventManager: services?.eventManager || new EventManager(),
|
|
18
23
|
profiler: services?.profiler || new Profiler(),
|
|
19
|
-
logger: services?.logger || new Logger(),
|
|
24
|
+
logger: services?.logger || new Logger({ mode: config.mode }),
|
|
20
25
|
tracker: services?.tracker || new Tracker(config.client.globals),
|
|
21
26
|
}, config.context);
|
|
22
27
|
return cntrlr;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SearchController } from '@searchspring/snap-controller';
|
|
2
2
|
import type { SnapControllerServices, SnapSearchControllerConfig } from '../types';
|
|
3
|
-
declare const _default: (config: SnapSearchControllerConfig, services?: SnapControllerServices) => SearchController;
|
|
3
|
+
declare const _default: (config: SnapSearchControllerConfig, services?: SnapControllerServices | undefined) => SearchController;
|
|
4
4
|
export default _default;
|
|
5
5
|
//# sourceMappingURL=createSearchController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSearchController.d.ts","sourceRoot":"","sources":["../../../src/create/createSearchController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAQjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;iCAI3D,0BAA0B,
|
|
1
|
+
{"version":3,"file":"createSearchController.d.ts","sourceRoot":"","sources":["../../../src/create/createSearchController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAQjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;iCAI3D,0BAA0B,oDAAsC,gBAAgB;AAAxG,wBAwBE"}
|
|
@@ -10,13 +10,18 @@ import { Tracker } from '@searchspring/snap-tracker';
|
|
|
10
10
|
configureMobx({ useProxies: 'never' });
|
|
11
11
|
export default (config, services) => {
|
|
12
12
|
const urlManager = services?.urlManager || new UrlManager(new UrlTranslator(config.url), reactLinker);
|
|
13
|
+
// set client mode
|
|
14
|
+
if (config.mode && config.client) {
|
|
15
|
+
config.client.config = config.client.config || {};
|
|
16
|
+
config.client.config.mode = config.mode;
|
|
17
|
+
}
|
|
13
18
|
const cntrlr = new SearchController(config.controller, {
|
|
14
19
|
client: services?.client || new Client(config.client.globals, config.client.config),
|
|
15
20
|
store: services?.store || new SearchStore(config.controller, { urlManager }),
|
|
16
21
|
urlManager,
|
|
17
22
|
eventManager: services?.eventManager || new EventManager(),
|
|
18
23
|
profiler: services?.profiler || new Profiler(),
|
|
19
|
-
logger: services?.logger || new Logger(),
|
|
24
|
+
logger: services?.logger || new Logger({ mode: config.mode }),
|
|
20
25
|
tracker: services?.tracker || new Tracker(config.client.globals),
|
|
21
26
|
}, config.context);
|
|
22
27
|
return cntrlr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getBundleDetails.d.ts","sourceRoot":"","sources":["../../../src/getBundleDetails/getBundleDetails.ts"],"names":[],"mappings":"AAAA,aAAK,aAAa,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAe,MAAM,KAAG,QAAQ,aAAa,
|
|
1
|
+
{"version":3,"file":"getBundleDetails.d.ts","sourceRoot":"","sources":["../../../src/getBundleDetails/getBundleDetails.ts"],"names":[],"mappings":"AAAA,aAAK,aAAa,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAe,MAAM,KAAG,QAAQ,aAAa,CAyBzE,CAAC"}
|
|
@@ -5,10 +5,11 @@ export const getBundleDetails = async (url) => {
|
|
|
5
5
|
request.onreadystatechange = () => {
|
|
6
6
|
if (request.readyState === request.DONE) {
|
|
7
7
|
const status = request.status;
|
|
8
|
-
|
|
8
|
+
const lastModified = request.getResponseHeader('Last-Modified');
|
|
9
|
+
if ((lastModified && status === 0) || (status >= 200 && status < 400)) {
|
|
9
10
|
resolve({
|
|
10
11
|
url,
|
|
11
|
-
lastModified:
|
|
12
|
+
lastModified: lastModified.split(',')[1].trim(),
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
15
|
else {
|