@searchspring/snap-preact 0.28.0 → 0.30.1

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.
Files changed (46) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts +6 -5
  3. package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  4. package/dist/cjs/Instantiators/RecommendationInstantiator.js +19 -5
  5. package/dist/cjs/Snap.d.ts +67 -13
  6. package/dist/cjs/Snap.d.ts.map +1 -1
  7. package/dist/cjs/Snap.js +220 -79
  8. package/dist/cjs/create/createAutocompleteController.d.ts +1 -1
  9. package/dist/cjs/create/createAutocompleteController.d.ts.map +1 -1
  10. package/dist/cjs/create/createAutocompleteController.js +6 -1
  11. package/dist/cjs/create/createFinderController.d.ts +1 -1
  12. package/dist/cjs/create/createFinderController.d.ts.map +1 -1
  13. package/dist/cjs/create/createFinderController.js +6 -1
  14. package/dist/cjs/create/createRecommendationController.d.ts +1 -1
  15. package/dist/cjs/create/createRecommendationController.d.ts.map +1 -1
  16. package/dist/cjs/create/createRecommendationController.js +6 -1
  17. package/dist/cjs/create/createSearchController.d.ts +1 -1
  18. package/dist/cjs/create/createSearchController.d.ts.map +1 -1
  19. package/dist/cjs/create/createSearchController.js +6 -1
  20. package/dist/cjs/getBundleDetails/getBundleDetails.d.ts.map +1 -1
  21. package/dist/cjs/getBundleDetails/getBundleDetails.js +3 -2
  22. package/dist/cjs/types.d.ts +11 -5
  23. package/dist/cjs/types.d.ts.map +1 -1
  24. package/dist/esm/Instantiators/RecommendationInstantiator.d.ts +6 -5
  25. package/dist/esm/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  26. package/dist/esm/Instantiators/RecommendationInstantiator.js +21 -6
  27. package/dist/esm/Snap.d.ts +67 -13
  28. package/dist/esm/Snap.d.ts.map +1 -1
  29. package/dist/esm/Snap.js +184 -61
  30. package/dist/esm/create/createAutocompleteController.d.ts +1 -1
  31. package/dist/esm/create/createAutocompleteController.d.ts.map +1 -1
  32. package/dist/esm/create/createAutocompleteController.js +6 -1
  33. package/dist/esm/create/createFinderController.d.ts +1 -1
  34. package/dist/esm/create/createFinderController.d.ts.map +1 -1
  35. package/dist/esm/create/createFinderController.js +6 -1
  36. package/dist/esm/create/createRecommendationController.d.ts +1 -1
  37. package/dist/esm/create/createRecommendationController.d.ts.map +1 -1
  38. package/dist/esm/create/createRecommendationController.js +6 -1
  39. package/dist/esm/create/createSearchController.d.ts +1 -1
  40. package/dist/esm/create/createSearchController.d.ts.map +1 -1
  41. package/dist/esm/create/createSearchController.js +6 -1
  42. package/dist/esm/getBundleDetails/getBundleDetails.d.ts.map +1 -1
  43. package/dist/esm/getBundleDetails/getBundleDetails.js +3 -2
  44. package/dist/esm/types.d.ts +11 -5
  45. package/dist/esm/types.d.ts.map +1 -1
  46. package/package.json +13 -13
package/dist/cjs/Snap.js CHANGED
@@ -73,7 +73,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
73
73
  return (mod && mod.__esModule) ? mod : { "default": mod };
74
74
  };
75
75
  Object.defineProperty(exports, "__esModule", { value: true });
76
- exports.Snap = exports.SS_DEV_COOKIE = exports.BRANCH_COOKIE = void 0;
76
+ exports.Snap = exports.DEV_COOKIE = exports.BRANCH_COOKIE = void 0;
77
77
  var jsx_runtime_1 = require("preact/jsx-runtime");
78
78
  var deepmerge_1 = __importDefault(require("deepmerge"));
79
79
  var is_plain_object_1 = require("is-plain-object");
@@ -82,16 +82,20 @@ var snap_client_1 = require("@searchspring/snap-client");
82
82
  var snap_logger_1 = require("@searchspring/snap-logger");
83
83
  var snap_tracker_1 = require("@searchspring/snap-tracker");
84
84
  var snap_toolbox_1 = require("@searchspring/snap-toolbox");
85
- var snap_toolbox_2 = require("@searchspring/snap-toolbox");
86
85
  var snap_controller_1 = require("@searchspring/snap-controller");
87
86
  var createSearchController_1 = __importDefault(require("./create/createSearchController"));
88
87
  exports.BRANCH_COOKIE = 'ssBranch';
89
- exports.SS_DEV_COOKIE = 'ssDev';
88
+ exports.DEV_COOKIE = 'ssDev';
89
+ var SESSION_ATTRIBUTION = 'ssAttribution';
90
90
  var COMPONENT_ERROR = "Uncaught Error - Invalid value passed as the component.\nThis usually happens when you pass a JSX Element, and not a function that returns the component, in the snap config. \n\t\t\n\t\tinstead of - \n\n\ttargeters: [\n\t\t{\n\t\t\tselector: '#searchspring-content',\n\t\t\thideTarget: true,\n\t\t\tcomponent: <Content/>,\n\t\t},\n\t]\n\n\t\tor - \n\n\ttargeters: [\n\t\t{\n\t\t\tselector: '#searchspring-content',\n\t\t\thideTarget: true,\n\t\t\tcomponent: Content,\n\t\t},\n\t]\n\n\t\tplease try - \n\n\ttargeters: [\n\t\t{\n\t\t\tselector: '#searchspring-content',\n\t\t\thideTarget: true,\n\t\t\tcomponent: () => Content\n\t\t},\n\t]\n\nThe error above happened in the following targeter in the Snap Config";
91
91
  var Snap = /** @class */ (function () {
92
92
  function Snap(config, services) {
93
93
  var _this = this;
94
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
94
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
95
+ this.mode = snap_toolbox_1.AppMode.production;
96
+ this._instantiatorPromises = {};
97
+ this._controllerPromises = {};
98
+ this.controllers = {};
95
99
  this.getInstantiator = function (id) {
96
100
  return _this._instantiatorPromises[id] || Promise.reject("getInstantiator could not find instantiator with id: ".concat(id));
97
101
  };
@@ -107,15 +111,40 @@ var Snap = /** @class */ (function () {
107
111
  controllerIds.forEach(function (id) { return getControllerPromises.push(_this.getController(id)); });
108
112
  return Promise.all(getControllerPromises);
109
113
  };
114
+ // exposed method used for creating controllers dynamically - calls _createController()
110
115
  this.createController = function (type, config, services, urlConfig, context, callback) { return __awaiter(_this, void 0, void 0, function () {
116
+ var _this = this;
117
+ return __generator(this, function (_a) {
118
+ if (typeof this._controllerPromises[config.id] != 'undefined') {
119
+ throw new Error("Controller with id '".concat(config.id, "' is already defined"));
120
+ }
121
+ this._controllerPromises[config.id] = new Promise(function (resolve) {
122
+ return _this._createController(type, config, services, urlConfig, context, function (cntrlr) { return __awaiter(_this, void 0, void 0, function () {
123
+ return __generator(this, function (_a) {
124
+ switch (_a.label) {
125
+ case 0:
126
+ if (!(typeof callback == 'function')) return [3 /*break*/, 2];
127
+ return [4 /*yield*/, callback(cntrlr)];
128
+ case 1:
129
+ _a.sent();
130
+ _a.label = 2;
131
+ case 2:
132
+ resolve(cntrlr);
133
+ return [2 /*return*/];
134
+ }
135
+ });
136
+ }); });
137
+ });
138
+ return [2 /*return*/, this._controllerPromises[config.id]];
139
+ });
140
+ }); };
141
+ // internal use method that creates controllers without verifying if id is in use first
142
+ this._createController = function (type, config, services, urlConfig, context, callback) { return __awaiter(_this, void 0, void 0, function () {
111
143
  var importPromise, creationFunc;
112
144
  return __generator(this, function (_a) {
113
145
  switch (_a.label) {
114
146
  case 0:
115
147
  switch (type) {
116
- case snap_controller_1.ControllerTypes.search:
117
- importPromise = Promise.resolve().then(function () { return __importStar(require('./create/createSearchController')); });
118
- break;
119
148
  case snap_controller_1.ControllerTypes.autocomplete:
120
149
  importPromise = Promise.resolve().then(function () { return __importStar(require('./create/createAutocompleteController')); });
121
150
  break;
@@ -125,12 +154,18 @@ var Snap = /** @class */ (function () {
125
154
  case snap_controller_1.ControllerTypes.recommendation:
126
155
  importPromise = Promise.resolve().then(function () { return __importStar(require('./create/createRecommendationController')); });
127
156
  break;
157
+ case snap_controller_1.ControllerTypes.search:
158
+ default:
159
+ importPromise = Promise.resolve().then(function () { return __importStar(require('./create/createSearchController')); });
160
+ break;
128
161
  }
129
162
  return [4 /*yield*/, importPromise];
130
163
  case 1:
131
164
  creationFunc = (_a.sent()).default;
132
165
  if (!this.controllers[config.id]) {
133
- this.controllers[config.id] = creationFunc({
166
+ window.searchspring.controller = window.searchspring.controller || {};
167
+ window.searchspring.controller[config.id] = this.controllers[config.id] = creationFunc({
168
+ mode: this.mode,
134
169
  url: (0, deepmerge_1.default)(this.config.url || {}, urlConfig || {}),
135
170
  controller: config,
136
171
  context: (0, deepmerge_1.default)(this.context || {}, context || {}),
@@ -153,15 +188,42 @@ var Snap = /** @class */ (function () {
153
188
  }
154
189
  });
155
190
  }); };
191
+ this.handlers = {
192
+ error: function (event) {
193
+ try {
194
+ var filename = event.filename;
195
+ if (filename.includes('snapui.searchspring.io') && _this.tracker.track.error) {
196
+ var colno = event.colno, lineno = event.lineno, stack = event.error.stack, message = event.message, timeStamp = event.timeStamp;
197
+ var userAgent = navigator.userAgent;
198
+ var href = window.location.href;
199
+ var beaconPayload = {
200
+ userAgent: userAgent,
201
+ href: href,
202
+ filename: filename,
203
+ stack: stack,
204
+ message: message,
205
+ colno: colno,
206
+ lineno: lineno,
207
+ timeStamp: timeStamp,
208
+ };
209
+ _this.tracker.track.error(beaconPayload);
210
+ }
211
+ }
212
+ catch (e) {
213
+ // prevent error metrics from breaking the app
214
+ }
215
+ },
216
+ };
217
+ window.removeEventListener('error', this.handlers.error);
218
+ window.addEventListener('error', this.handlers.error);
156
219
  this.config = config;
157
- this.logger = (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger('Snap Preact ');
158
220
  var globalContext = {};
159
221
  try {
160
222
  // get global context
161
- globalContext = (0, snap_toolbox_2.getContext)(['shopper', 'config', 'merchandising']);
223
+ globalContext = (0, snap_toolbox_1.getContext)(['shopper', 'config', 'merchandising']);
162
224
  }
163
225
  catch (err) {
164
- this.logger.error('failed to find global context');
226
+ console.error('Snap failed to find global context');
165
227
  }
166
228
  // merge configs - but only merge plain objects
167
229
  this.config = (0, deepmerge_1.default)(this.config || {}, globalContext.config || {}, {
@@ -173,8 +235,9 @@ var Snap = /** @class */ (function () {
173
235
  if ((!(services === null || services === void 0 ? void 0 : services.client) || !(services === null || services === void 0 ? void 0 : services.tracker)) && !((_c = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.client) === null || _b === void 0 ? void 0 : _b.globals) === null || _c === void 0 ? void 0 : _c.siteId)) {
174
236
  throw new Error("Snap: config provided must contain a valid config.client.globals.siteId value");
175
237
  }
176
- if ((_d = this.context.merchandising) === null || _d === void 0 ? void 0 : _d.segments) {
177
- if (this.config.client.globals.merchandising) {
238
+ // segmented merchandising context -> client globals
239
+ if (((_d = this.config.client) === null || _d === void 0 ? void 0 : _d.globals) && ((_e = this.context.merchandising) === null || _e === void 0 ? void 0 : _e.segments)) {
240
+ if ((_f = this.config.client.globals) === null || _f === void 0 ? void 0 : _f.merchandising) {
178
241
  this.config.client.globals.merchandising.segments = (0, deepmerge_1.default)(this.config.client.globals.merchandising.segments, this.context.merchandising.segments);
179
242
  }
180
243
  else {
@@ -183,33 +246,73 @@ var Snap = /** @class */ (function () {
183
246
  };
184
247
  }
185
248
  }
186
- this.client = (services === null || services === void 0 ? void 0 : services.client) || new snap_client_1.Client(this.config.client.globals, this.config.client.config);
187
- this.tracker = (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(this.config.client.globals);
188
- this._controllerPromises = {};
189
- this._instantiatorPromises = {};
190
- this.controllers = {};
191
- // TODO environment switch using URL?
192
- this.logger.setMode(process.env.NODE_ENV);
193
- // log version
194
- this.logger.imageText({
195
- url: 'https://snapui.searchspring.io/favicon.svg',
196
- text: "[".concat(snap_toolbox_1.version, "]"),
197
- style: "color: ".concat(this.logger.colors.indigo, "; font-weight: bold;"),
198
- });
199
249
  try {
200
250
  var urlParams = (0, snap_toolbox_1.url)(window.location.href);
201
- var branchParam_1 = ((_f = (_e = urlParams.params) === null || _e === void 0 ? void 0 : _e.query) === null || _f === void 0 ? void 0 : _f.branch) || snap_toolbox_1.cookies.get(exports.BRANCH_COOKIE);
202
- if (branchParam_1 && !document.querySelector("script[".concat(exports.BRANCH_COOKIE, "]"))) {
203
- // set a cookie or localstorage with branch
251
+ var branchOverride_1 = ((_h = (_g = urlParams === null || urlParams === void 0 ? void 0 : urlParams.params) === null || _g === void 0 ? void 0 : _g.query) === null || _h === void 0 ? void 0 : _h.branch) || snap_toolbox_1.cookies.get(exports.BRANCH_COOKIE);
252
+ /* app mode priority:
253
+ 1. node env
254
+ 2. config
255
+ 3. override via query param / cookie
256
+ */
257
+ // node env
258
+ if (process.env.NODE_ENV && Object.values(snap_toolbox_1.AppMode).includes(process.env.NODE_ENV)) {
259
+ this.mode = process.env.NODE_ENV;
260
+ }
261
+ // config
262
+ if (this.config.mode && Object.values(snap_toolbox_1.AppMode).includes(this.config.mode)) {
263
+ this.mode = this.config.mode;
264
+ }
265
+ // query param / cookiev override
266
+ if ((((_j = urlParams === null || urlParams === void 0 ? void 0 : urlParams.params) === null || _j === void 0 ? void 0 : _j.query) && 'dev' in urlParams.params.query) || !!snap_toolbox_1.cookies.get(exports.DEV_COOKIE)) {
267
+ if (((_k = urlParams === null || urlParams === void 0 ? void 0 : urlParams.params.query) === null || _k === void 0 ? void 0 : _k.dev) == 'false' || ((_l = urlParams === null || urlParams === void 0 ? void 0 : urlParams.params.query) === null || _l === void 0 ? void 0 : _l.dev) == '0') {
268
+ snap_toolbox_1.cookies.unset(exports.DEV_COOKIE);
269
+ this.mode = snap_toolbox_1.AppMode.production;
270
+ }
271
+ else {
272
+ snap_toolbox_1.cookies.set(exports.DEV_COOKIE, '1', 'Lax', 0);
273
+ this.mode = snap_toolbox_1.AppMode.development;
274
+ }
275
+ }
276
+ // client mode uses client config over snap config
277
+ if (this.config.client) {
278
+ this.config.client.config = this.config.client.config || {};
279
+ this.config.client.config.mode = this.config.client.config.mode || this.mode;
280
+ }
281
+ this.client = (services === null || services === void 0 ? void 0 : services.client) || new snap_client_1.Client(this.config.client.globals, this.config.client.config);
282
+ this.tracker = (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(this.config.client.globals, { framework: 'preact' });
283
+ this.logger = (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger({ prefix: 'Snap Preact ', mode: this.mode });
284
+ // check for tracking attribution in URL ?ss_attribution=type:id
285
+ var sessionAttribution = (_m = window.sessionStorage) === null || _m === void 0 ? void 0 : _m.getItem(SESSION_ATTRIBUTION);
286
+ if ((_p = (_o = urlParams === null || urlParams === void 0 ? void 0 : urlParams.params) === null || _o === void 0 ? void 0 : _o.query) === null || _p === void 0 ? void 0 : _p.ss_attribution) {
287
+ var attribution = urlParams.params.query.ss_attribution.split(':');
288
+ var type = attribution[0], id = attribution[1];
289
+ if (type && id) {
290
+ this.tracker.updateContext('attribution', { type: type, id: id });
291
+ }
292
+ // save to session storage
293
+ (_q = window.sessionStorage) === null || _q === void 0 ? void 0 : _q.setItem(SESSION_ATTRIBUTION, urlParams.params.query.ss_attribution);
294
+ }
295
+ else if (sessionAttribution) {
296
+ var _y = sessionAttribution.split(':'), type = _y[0], id = _y[1];
297
+ if (type && id) {
298
+ this.tracker.updateContext('attribution', { type: type, id: id });
299
+ }
300
+ }
301
+ // log version
302
+ this.logger.imageText({
303
+ url: 'https://snapui.searchspring.io/favicon.svg',
304
+ text: "[".concat(snap_toolbox_1.version, "]"),
305
+ style: "color: ".concat(this.logger.colors.indigo, "; font-weight: bold;"),
306
+ });
307
+ if (branchOverride_1 && !document.querySelector("script[".concat(exports.BRANCH_COOKIE, "]"))) {
308
+ this.logger.warn("...loading build... '".concat(branchOverride_1, "'"));
309
+ // set a cookie with branch
204
310
  if (snap_toolbox_1.featureFlags.cookies) {
205
- snap_toolbox_1.cookies.set(exports.BRANCH_COOKIE, branchParam_1, 'Lax', 3600000); // 1 hour
206
- snap_toolbox_1.cookies.set(exports.SS_DEV_COOKIE, '1', 'Lax', 0);
311
+ snap_toolbox_1.cookies.set(exports.BRANCH_COOKIE, branchOverride_1, 'Lax', 3600000); // 1 hour
207
312
  }
208
313
  else {
209
314
  this.logger.warn('Cookies are not supported/enabled by this browser, branch overrides will not persist!');
210
315
  }
211
- this.logger.setMode(snap_logger_1.LogMode.DEVELOPMENT);
212
- this.logger.warn("...loading build... '".concat(branchParam_1, "'"));
213
316
  // get the path and siteId from the current bundle script in case its not the same as the client config
214
317
  var path = "https://snapui.searchspring.io/".concat(this.config.client.globals.siteId, "/");
215
318
  var script = document.querySelector('script[src*="//snapui.searchspring.io"]');
@@ -221,9 +324,9 @@ var Snap = /** @class */ (function () {
221
324
  }
222
325
  // append script with new branch in path
223
326
  var branchScript_1 = document.createElement('script');
224
- var src_1 = "".concat(path).concat(branchParam_1, "/bundle.js");
327
+ var src_1 = "".concat(path).concat(branchOverride_1, "/bundle.js");
225
328
  branchScript_1.src = src_1;
226
- branchScript_1.setAttribute(exports.BRANCH_COOKIE, branchParam_1);
329
+ branchScript_1.setAttribute(exports.BRANCH_COOKIE, branchOverride_1);
227
330
  new snap_toolbox_1.DomTargeter([
228
331
  {
229
332
  selector: 'body',
@@ -237,32 +340,43 @@ var Snap = /** @class */ (function () {
237
340
  },
238
341
  },
239
342
  ], function (target, elem) { return __awaiter(_this, void 0, void 0, function () {
240
- var bundleDetails, error, getBundleDetails, err_1, BranchOverride;
241
- return __generator(this, function (_a) {
242
- switch (_a.label) {
343
+ var props, getBundleDetails, _a, err_1, BranchOverride;
344
+ return __generator(this, function (_b) {
345
+ switch (_b.label) {
243
346
  case 0:
244
- _a.trys.push([0, 3, , 4]);
245
- return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./getBundleDetails/getBundleDetails')); })];
347
+ props = {};
348
+ _b.label = 1;
246
349
  case 1:
247
- getBundleDetails = (_a.sent()).getBundleDetails;
248
- return [4 /*yield*/, getBundleDetails(src_1)];
350
+ _b.trys.push([1, 4, , 5]);
351
+ return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./getBundleDetails/getBundleDetails')); })];
249
352
  case 2:
250
- bundleDetails = _a.sent();
251
- return [3 /*break*/, 4];
353
+ getBundleDetails = (_b.sent()).getBundleDetails;
354
+ _a = props;
355
+ return [4 /*yield*/, getBundleDetails(src_1)];
252
356
  case 3:
253
- err_1 = _a.sent();
254
- error = err_1;
255
- return [3 /*break*/, 4];
256
- case 4: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./components/BranchOverride')); })];
257
- case 5:
258
- BranchOverride = (_a.sent()).BranchOverride;
259
- (0, preact_1.render)((0, jsx_runtime_1.jsx)(BranchOverride, { name: branchParam_1, details: bundleDetails, error: error, onRemoveClick: function () {
357
+ _a.details = _b.sent();
358
+ return [3 /*break*/, 5];
359
+ case 4:
360
+ err_1 = _b.sent();
361
+ props.error = err_1;
362
+ return [3 /*break*/, 5];
363
+ case 5: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./components/BranchOverride')); })];
364
+ case 6:
365
+ BranchOverride = (_b.sent()).BranchOverride;
366
+ (0, preact_1.render)((0, jsx_runtime_1.jsx)(BranchOverride, __assign({}, props, { name: branchOverride_1, onRemoveClick: function () {
260
367
  snap_toolbox_1.cookies.unset(exports.BRANCH_COOKIE);
261
368
  var urlState = (0, snap_toolbox_1.url)(window.location.href);
262
- delete urlState.params.query['branch'];
263
- window.location.href = urlState.url();
264
- } }), elem);
265
- window.searchspring = undefined;
369
+ urlState === null || urlState === void 0 ? true : delete urlState.params.query['branch'];
370
+ var newUrl = urlState === null || urlState === void 0 ? void 0 : urlState.url();
371
+ if (newUrl && newUrl != window.location.href) {
372
+ window.location.href = newUrl;
373
+ }
374
+ else {
375
+ window.location.reload();
376
+ }
377
+ } })), elem);
378
+ // reset the global searchspring object
379
+ delete window.searchspring;
266
380
  document.head.appendChild(branchScript_1);
267
381
  return [2 /*return*/];
268
382
  }
@@ -272,33 +386,40 @@ var Snap = /** @class */ (function () {
272
386
  return;
273
387
  }
274
388
  }
275
- catch (e) { }
276
- if (window.searchspring) {
277
- window.searchspring.context = this.context;
278
- if (this.client)
279
- window.searchspring.client = this.client;
389
+ catch (e) {
390
+ this.logger.error(e);
280
391
  }
392
+ // bind to window global
393
+ window.searchspring = window.searchspring || {};
394
+ window.searchspring.context = this.context;
395
+ if (this.client)
396
+ window.searchspring.client = this.client;
281
397
  // autotrack shopper id from the context
282
- if ((_h = (_g = this.context) === null || _g === void 0 ? void 0 : _g.shopper) === null || _h === void 0 ? void 0 : _h.id) {
398
+ if ((_s = (_r = this.context) === null || _r === void 0 ? void 0 : _r.shopper) === null || _s === void 0 ? void 0 : _s.id) {
283
399
  this.tracker.track.shopper.login({
284
400
  id: this.context.shopper.id,
285
401
  });
286
402
  }
287
403
  // auto populate cart cookie from the context
288
- if ((_k = (_j = this.context) === null || _j === void 0 ? void 0 : _j.shopper) === null || _k === void 0 ? void 0 : _k.cart) {
404
+ if ((_u = (_t = this.context) === null || _t === void 0 ? void 0 : _t.shopper) === null || _u === void 0 ? void 0 : _u.cart) {
289
405
  var cart = this.context.shopper.cart;
290
406
  if (Array.isArray(cart)) {
291
- var cartItems = cart.filter(function (item) { return (item === null || item === void 0 ? void 0 : item.sku) || (item === null || item === void 0 ? void 0 : item.childSku); }).map(function (item) { return ((item === null || item === void 0 ? void 0 : item.sku) || (item === null || item === void 0 ? void 0 : item.childSku)).trim(); });
407
+ var cartItems = cart.filter(function (item) { return (item === null || item === void 0 ? void 0 : item.sku) || (item === null || item === void 0 ? void 0 : item.childSku); }).map(function (item) { return ((item === null || item === void 0 ? void 0 : item.sku) || (item === null || item === void 0 ? void 0 : item.childSku) || '').trim(); });
292
408
  this.tracker.cookies.cart.set(cartItems);
293
409
  }
294
410
  }
295
- Object.keys(((_l = this.config) === null || _l === void 0 ? void 0 : _l.controllers) || {}).forEach(function (type) {
411
+ Object.keys(((_v = this.config) === null || _v === void 0 ? void 0 : _v.controllers) || {}).forEach(function (type) {
296
412
  switch (type) {
297
413
  case 'search': {
298
414
  _this.config.controllers[type].forEach(function (controller, index) {
299
415
  var _a, _b, _c, _d, _e, _f, _g, _h;
300
416
  try {
417
+ if (typeof _this._controllerPromises[controller.config.id] != 'undefined') {
418
+ _this.logger.error("Controller with id '".concat(controller.config.id, "' is already defined"));
419
+ return;
420
+ }
301
421
  var cntrlr_1 = (0, createSearchController_1.default)({
422
+ mode: _this.mode,
302
423
  url: (0, deepmerge_1.default)(_this.config.url || {}, controller.url || {}),
303
424
  controller: controller.config,
304
425
  context: (0, deepmerge_1.default)(_this.context || {}, controller.context || {}),
@@ -311,7 +432,8 @@ var Snap = /** @class */ (function () {
311
432
  logger: (_f = controller.services) === null || _f === void 0 ? void 0 : _f.logger,
312
433
  tracker: ((_g = controller.services) === null || _g === void 0 ? void 0 : _g.tracker) || _this.tracker,
313
434
  });
314
- _this.controllers[cntrlr_1.config.id] = cntrlr_1;
435
+ window.searchspring.controller = window.searchspring.controller || {};
436
+ window.searchspring.controller[cntrlr_1.config.id] = _this.controllers[cntrlr_1.config.id] = cntrlr_1;
315
437
  _this._controllerPromises[cntrlr_1.config.id] = new Promise(function (resolve) { return resolve(cntrlr_1); });
316
438
  var searched_1 = false;
317
439
  var runSearch_1 = function () {
@@ -369,7 +491,7 @@ var Snap = /** @class */ (function () {
369
491
  return __generator(this, function (_a) {
370
492
  switch (_a.label) {
371
493
  case 0:
372
- if (!target.skeleton) return [3 /*break*/, 2];
494
+ if (!(target && target.skeleton && elem)) return [3 /*break*/, 2];
373
495
  return [4 /*yield*/, target.skeleton()];
374
496
  case 1:
375
497
  Skeleton_1 = _a.sent();
@@ -393,6 +515,10 @@ var Snap = /** @class */ (function () {
393
515
  }
394
516
  case 'autocomplete': {
395
517
  _this.config.controllers[type].forEach(function (controller, index) {
518
+ if (typeof _this._controllerPromises[controller.config.id] != 'undefined') {
519
+ _this.logger.error("Controller with id '".concat(controller.config.id, "' is already defined"));
520
+ return;
521
+ }
396
522
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
397
523
  var _a;
398
524
  try {
@@ -439,8 +565,9 @@ var Snap = /** @class */ (function () {
439
565
  });
440
566
  }); };
441
567
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
442
- _this.createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
443
- resolve(cntrlr);
568
+ _this._createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
569
+ if (cntrlr)
570
+ resolve(cntrlr);
444
571
  });
445
572
  }
446
573
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -466,8 +593,9 @@ var Snap = /** @class */ (function () {
466
593
  var cntrlr;
467
594
  return __generator(this, function (_a) {
468
595
  switch (_a.label) {
469
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
470
- resolve(cntrlr);
596
+ case 0: return [4 /*yield*/, this._createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
597
+ if (cntrlr)
598
+ resolve(cntrlr);
471
599
  })];
472
600
  case 1:
473
601
  cntrlr = _a.sent();
@@ -489,6 +617,10 @@ var Snap = /** @class */ (function () {
489
617
  }
490
618
  case 'finder': {
491
619
  _this.config.controllers[type].forEach(function (controller, index) {
620
+ if (typeof _this._controllerPromises[controller.config.id] != 'undefined') {
621
+ _this.logger.error("Controller with id '".concat(controller.config.id, "' is already defined"));
622
+ return;
623
+ }
492
624
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
493
625
  var _a;
494
626
  try {
@@ -533,8 +665,9 @@ var Snap = /** @class */ (function () {
533
665
  });
534
666
  }); };
535
667
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
536
- _this.createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
537
- resolve(cntrlr);
668
+ _this._createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
669
+ if (cntrlr)
670
+ resolve(cntrlr);
538
671
  });
539
672
  }
540
673
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -548,8 +681,9 @@ var Snap = /** @class */ (function () {
548
681
  var cntrlr;
549
682
  return __generator(this, function (_a) {
550
683
  switch (_a.label) {
551
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
552
- resolve(cntrlr);
684
+ case 0: return [4 /*yield*/, this._createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
685
+ if (cntrlr)
686
+ resolve(cntrlr);
553
687
  })];
554
688
  case 1:
555
689
  cntrlr = _a.sent();
@@ -571,6 +705,10 @@ var Snap = /** @class */ (function () {
571
705
  }
572
706
  case 'recommendation': {
573
707
  _this.config.controllers[type].forEach(function (controller, index) {
708
+ if (typeof _this._controllerPromises[controller.config.id] != 'undefined') {
709
+ _this.logger.error("Controller with id '".concat(controller.config.id, "' is already defined"));
710
+ return;
711
+ }
574
712
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
575
713
  var _a;
576
714
  try {
@@ -615,8 +753,9 @@ var Snap = /** @class */ (function () {
615
753
  });
616
754
  }); };
617
755
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
618
- _this.createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
619
- resolve(cntrlr);
756
+ _this._createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
757
+ if (cntrlr)
758
+ resolve(cntrlr);
620
759
  });
621
760
  }
622
761
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -630,8 +769,9 @@ var Snap = /** @class */ (function () {
630
769
  var cntrlr;
631
770
  return __generator(this, function (_a) {
632
771
  switch (_a.label) {
633
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
634
- resolve(cntrlr);
772
+ case 0: return [4 /*yield*/, this._createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
773
+ if (cntrlr)
774
+ resolve(cntrlr);
635
775
  })];
636
776
  case 1:
637
777
  cntrlr = _a.sent();
@@ -653,10 +793,11 @@ var Snap = /** @class */ (function () {
653
793
  }
654
794
  }
655
795
  });
656
- if ((_o = (_m = this.config) === null || _m === void 0 ? void 0 : _m.instantiators) === null || _o === void 0 ? void 0 : _o.recommendation) {
796
+ if ((_x = (_w = this.config) === null || _w === void 0 ? void 0 : _w.instantiators) === null || _x === void 0 ? void 0 : _x.recommendation) {
657
797
  try {
658
798
  this._instantiatorPromises.recommendation = Promise.resolve().then(function () { return __importStar(require('./Instantiators/RecommendationInstantiator')); }).then(function (_a) {
659
799
  var RecommendationInstantiator = _a.RecommendationInstantiator;
800
+ _this.config.instantiators.recommendation.mode = _this.config.instantiators.recommendation.mode || _this.mode;
660
801
  return new RecommendationInstantiator(_this.config.instantiators.recommendation, {
661
802
  client: _this.client,
662
803
  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,aAAa,sBAAsB,KAAG,sBAAsB;AAApH,wBAkBE"}
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"}
@@ -12,13 +12,18 @@ var snap_tracker_1 = require("@searchspring/snap-tracker");
12
12
  (0, mobx_1.configure)({ useProxies: 'never' });
13
13
  exports.default = (function (config, services) {
14
14
  var urlManager = ((services === null || services === void 0 ? void 0 : services.urlManager) || new snap_url_manager_1.UrlManager(new snap_url_manager_1.UrlTranslator(config.url), snap_url_manager_1.reactLinker)).detach();
15
+ // set client mode
16
+ if (config.mode && config.client) {
17
+ config.client.config = config.client.config || {};
18
+ config.client.config.mode = config.mode;
19
+ }
15
20
  var cntrlr = new snap_controller_1.AutocompleteController(config.controller, {
16
21
  client: (services === null || services === void 0 ? void 0 : services.client) || new snap_client_1.Client(config.client.globals, config.client.config),
17
22
  store: (services === null || services === void 0 ? void 0 : services.store) || new snap_store_mobx_1.AutocompleteStore(config.controller, { urlManager: urlManager }),
18
23
  urlManager: urlManager,
19
24
  eventManager: (services === null || services === void 0 ? void 0 : services.eventManager) || new snap_event_manager_1.EventManager(),
20
25
  profiler: (services === null || services === void 0 ? void 0 : services.profiler) || new snap_profiler_1.Profiler(),
21
- logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger(),
26
+ logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger({ mode: config.mode }),
22
27
  tracker: (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(config.client.globals),
23
28
  }, config.context);
24
29
  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,aAAa,sBAAsB,KAAG,gBAAgB;AAAxG,wBAkBE"}
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"}
@@ -12,13 +12,18 @@ var snap_tracker_1 = require("@searchspring/snap-tracker");
12
12
  (0, mobx_1.configure)({ useProxies: 'never' });
13
13
  exports.default = (function (config, services) {
14
14
  var urlManager = ((services === null || services === void 0 ? void 0 : services.urlManager) || new snap_url_manager_1.UrlManager(new snap_url_manager_1.UrlTranslator(config.url), snap_url_manager_1.reactLinker)).detach(true);
15
+ // set client mode
16
+ if (config.mode && config.client) {
17
+ config.client.config = config.client.config || {};
18
+ config.client.config.mode = config.mode;
19
+ }
15
20
  var cntrlr = new snap_controller_1.FinderController(config.controller, {
16
21
  client: (services === null || services === void 0 ? void 0 : services.client) || new snap_client_1.Client(config.client.globals, config.client.config),
17
22
  store: (services === null || services === void 0 ? void 0 : services.store) || new snap_store_mobx_1.FinderStore(config.controller, { urlManager: urlManager }),
18
23
  urlManager: urlManager,
19
24
  eventManager: (services === null || services === void 0 ? void 0 : services.eventManager) || new snap_event_manager_1.EventManager(),
20
25
  profiler: (services === null || services === void 0 ? void 0 : services.profiler) || new snap_profiler_1.Profiler(),
21
- logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger(),
26
+ logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger({ mode: config.mode }),
22
27
  tracker: (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(config.client.globals),
23
28
  }, config.context);
24
29
  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,aAAa,sBAAsB,KAAG,wBAAwB;AAAxH,wBAiBE"}
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"}
@@ -12,13 +12,18 @@ var snap_tracker_1 = require("@searchspring/snap-tracker");
12
12
  (0, mobx_1.configure)({ useProxies: 'never' });
13
13
  exports.default = (function (config, services) {
14
14
  var urlManager = ((services === null || services === void 0 ? void 0 : services.urlManager) || new snap_url_manager_1.UrlManager(new snap_url_manager_1.UrlTranslator(config.url), snap_url_manager_1.reactLinker)).detach(true);
15
+ // set client mode
16
+ if (config.mode && config.client) {
17
+ config.client.config = config.client.config || {};
18
+ config.client.config.mode = config.mode;
19
+ }
15
20
  var cntrlr = new snap_controller_1.RecommendationController(config.controller, {
16
21
  client: (services === null || services === void 0 ? void 0 : services.client) || new snap_client_1.Client(config.client.globals, config.client.config),
17
22
  store: (services === null || services === void 0 ? void 0 : services.store) || new snap_store_mobx_1.RecommendationStore(config.controller, { urlManager: urlManager }),
18
23
  urlManager: urlManager,
19
24
  eventManager: (services === null || services === void 0 ? void 0 : services.eventManager) || new snap_event_manager_1.EventManager(),
20
25
  profiler: (services === null || services === void 0 ? void 0 : services.profiler) || new snap_profiler_1.Profiler(),
21
- logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger(),
26
+ logger: (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger({ mode: config.mode }),
22
27
  tracker: (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(config.client.globals),
23
28
  }, config.context);
24
29
  return cntrlr;