@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.
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 +223 -81
  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 +185 -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"]');
@@ -220,11 +323,10 @@ var Snap = /** @class */ (function () {
220
323
  }
221
324
  }
222
325
  // append script with new branch in path
223
- var branchScript = document.createElement('script');
224
- var src_1 = "".concat(path).concat(branchParam_1, "/bundle.js");
225
- branchScript.src = src_1;
226
- branchScript.setAttribute(exports.BRANCH_COOKIE, branchParam_1);
227
- document.head.appendChild(branchScript);
326
+ var branchScript_1 = document.createElement('script');
327
+ var src_1 = "".concat(path).concat(branchOverride_1, "/bundle.js");
328
+ branchScript_1.src = src_1;
329
+ branchScript_1.setAttribute(exports.BRANCH_COOKIE, branchOverride_1);
228
330
  new snap_toolbox_1.DomTargeter([
229
331
  {
230
332
  selector: 'body',
@@ -238,31 +340,44 @@ var Snap = /** @class */ (function () {
238
340
  },
239
341
  },
240
342
  ], function (target, elem) { return __awaiter(_this, void 0, void 0, function () {
241
- var bundleDetails, error, getBundleDetails, err_1, BranchOverride;
242
- return __generator(this, function (_a) {
243
- switch (_a.label) {
343
+ var props, getBundleDetails, _a, err_1, BranchOverride;
344
+ return __generator(this, function (_b) {
345
+ switch (_b.label) {
244
346
  case 0:
245
- _a.trys.push([0, 3, , 4]);
246
- return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./getBundleDetails/getBundleDetails')); })];
347
+ props = {};
348
+ _b.label = 1;
247
349
  case 1:
248
- getBundleDetails = (_a.sent()).getBundleDetails;
249
- 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')); })];
250
352
  case 2:
251
- bundleDetails = _a.sent();
252
- return [3 /*break*/, 4];
353
+ getBundleDetails = (_b.sent()).getBundleDetails;
354
+ _a = props;
355
+ return [4 /*yield*/, getBundleDetails(src_1)];
253
356
  case 3:
254
- err_1 = _a.sent();
255
- error = err_1;
256
- return [3 /*break*/, 4];
257
- case 4: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('./components/BranchOverride')); })];
258
- case 5:
259
- BranchOverride = (_a.sent()).BranchOverride;
260
- (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 () {
261
367
  snap_toolbox_1.cookies.unset(exports.BRANCH_COOKIE);
262
368
  var urlState = (0, snap_toolbox_1.url)(window.location.href);
263
- delete urlState.params.query['branch'];
264
- window.location.href = urlState.url();
265
- } }), elem);
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;
380
+ document.head.appendChild(branchScript_1);
266
381
  return [2 /*return*/];
267
382
  }
268
383
  });
@@ -271,33 +386,40 @@ var Snap = /** @class */ (function () {
271
386
  return;
272
387
  }
273
388
  }
274
- catch (e) { }
275
- if (window.searchspring) {
276
- window.searchspring.context = this.context;
277
- if (this.client)
278
- window.searchspring.client = this.client;
389
+ catch (e) {
390
+ this.logger.error(e);
279
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;
280
397
  // autotrack shopper id from the context
281
- 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) {
282
399
  this.tracker.track.shopper.login({
283
400
  id: this.context.shopper.id,
284
401
  });
285
402
  }
286
403
  // auto populate cart cookie from the context
287
- 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) {
288
405
  var cart = this.context.shopper.cart;
289
406
  if (Array.isArray(cart)) {
290
- 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(); });
291
408
  this.tracker.cookies.cart.set(cartItems);
292
409
  }
293
410
  }
294
- 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) {
295
412
  switch (type) {
296
413
  case 'search': {
297
414
  _this.config.controllers[type].forEach(function (controller, index) {
298
415
  var _a, _b, _c, _d, _e, _f, _g, _h;
299
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
+ }
300
421
  var cntrlr_1 = (0, createSearchController_1.default)({
422
+ mode: _this.mode,
301
423
  url: (0, deepmerge_1.default)(_this.config.url || {}, controller.url || {}),
302
424
  controller: controller.config,
303
425
  context: (0, deepmerge_1.default)(_this.context || {}, controller.context || {}),
@@ -310,7 +432,8 @@ var Snap = /** @class */ (function () {
310
432
  logger: (_f = controller.services) === null || _f === void 0 ? void 0 : _f.logger,
311
433
  tracker: ((_g = controller.services) === null || _g === void 0 ? void 0 : _g.tracker) || _this.tracker,
312
434
  });
313
- _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;
314
437
  _this._controllerPromises[cntrlr_1.config.id] = new Promise(function (resolve) { return resolve(cntrlr_1); });
315
438
  var searched_1 = false;
316
439
  var runSearch_1 = function () {
@@ -368,7 +491,7 @@ var Snap = /** @class */ (function () {
368
491
  return __generator(this, function (_a) {
369
492
  switch (_a.label) {
370
493
  case 0:
371
- if (!target.skeleton) return [3 /*break*/, 2];
494
+ if (!(target && target.skeleton && elem)) return [3 /*break*/, 2];
372
495
  return [4 /*yield*/, target.skeleton()];
373
496
  case 1:
374
497
  Skeleton_1 = _a.sent();
@@ -392,6 +515,10 @@ var Snap = /** @class */ (function () {
392
515
  }
393
516
  case 'autocomplete': {
394
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
+ }
395
522
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
396
523
  var _a;
397
524
  try {
@@ -438,8 +565,9 @@ var Snap = /** @class */ (function () {
438
565
  });
439
566
  }); };
440
567
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
441
- _this.createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
442
- 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);
443
571
  });
444
572
  }
445
573
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -465,8 +593,9 @@ var Snap = /** @class */ (function () {
465
593
  var cntrlr;
466
594
  return __generator(this, function (_a) {
467
595
  switch (_a.label) {
468
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
469
- 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);
470
599
  })];
471
600
  case 1:
472
601
  cntrlr = _a.sent();
@@ -488,6 +617,10 @@ var Snap = /** @class */ (function () {
488
617
  }
489
618
  case 'finder': {
490
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
+ }
491
624
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
492
625
  var _a;
493
626
  try {
@@ -532,8 +665,9 @@ var Snap = /** @class */ (function () {
532
665
  });
533
666
  }); };
534
667
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
535
- _this.createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
536
- 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);
537
671
  });
538
672
  }
539
673
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -547,8 +681,9 @@ var Snap = /** @class */ (function () {
547
681
  var cntrlr;
548
682
  return __generator(this, function (_a) {
549
683
  switch (_a.label) {
550
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
551
- 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);
552
687
  })];
553
688
  case 1:
554
689
  cntrlr = _a.sent();
@@ -570,6 +705,10 @@ var Snap = /** @class */ (function () {
570
705
  }
571
706
  case 'recommendation': {
572
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
+ }
573
712
  _this._controllerPromises[controller.config.id] = new Promise(function (resolve) {
574
713
  var _a;
575
714
  try {
@@ -614,8 +753,9 @@ var Snap = /** @class */ (function () {
614
753
  });
615
754
  }); };
616
755
  if (!(controller === null || controller === void 0 ? void 0 : controller.targeters) || (controller === null || controller === void 0 ? void 0 : controller.targeters.length) === 0) {
617
- _this.createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
618
- 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);
619
759
  });
620
760
  }
621
761
  (_a = controller === null || controller === void 0 ? void 0 : controller.targeters) === null || _a === void 0 ? void 0 : _a.forEach(function (target, target_index) {
@@ -629,8 +769,9 @@ var Snap = /** @class */ (function () {
629
769
  var cntrlr;
630
770
  return __generator(this, function (_a) {
631
771
  switch (_a.label) {
632
- case 0: return [4 /*yield*/, this.createController(snap_controller_1.ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, function (cntrlr) {
633
- 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);
634
775
  })];
635
776
  case 1:
636
777
  cntrlr = _a.sent();
@@ -652,10 +793,11 @@ var Snap = /** @class */ (function () {
652
793
  }
653
794
  }
654
795
  });
655
- 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) {
656
797
  try {
657
798
  this._instantiatorPromises.recommendation = Promise.resolve().then(function () { return __importStar(require('./Instantiators/RecommendationInstantiator')); }).then(function (_a) {
658
799
  var RecommendationInstantiator = _a.RecommendationInstantiator;
800
+ _this.config.instantiators.recommendation.mode = _this.config.instantiators.recommendation.mode || _this.mode;
659
801
  return new RecommendationInstantiator(_this.config.instantiators.recommendation, {
660
802
  client: _this.client,
661
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;