@searchspring/snap-preact 0.59.0 → 0.60.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.
@@ -43,9 +43,15 @@ export declare class RecommendationInstantiator {
43
43
  config: RecommendationInstantiatorConfig;
44
44
  context: ContextVariables;
45
45
  targeter: DomTargeter;
46
- private uses;
47
- private plugins;
48
- private middleware;
46
+ uses: Attachments[];
47
+ plugins: {
48
+ func: (cntrlr: AbstractController, ...args: any) => Promise<void>;
49
+ args: unknown[];
50
+ }[];
51
+ middleware: {
52
+ event: string;
53
+ func: Middleware<unknown>[];
54
+ }[];
49
55
  constructor(config: RecommendationInstantiatorConfig, services?: RecommendationInstantiatorServices, context?: ContextVariables);
50
56
  plugin(func: (cntrlr: AbstractController, ...args: any) => Promise<void>, ...args: unknown[]): void;
51
57
  on(event: string, ...func: Middleware<unknown>[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAGnE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,IAAI,CAAC,EAAE,MAAM,OAAO,OAAO,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,aAAa,CAAC;KACzB,GAAG,WAAW,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,qBAAa,0BAA0B;IACtC,OAAO,CAAC,IAAI,CAAsB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,CAAC;KACxC,CAAM;IACA,MAAM,EAAE,gCAAgC,CAAC;IACzC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC;IAE7B,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAgG;IAC/G,OAAO,CAAC,UAAU,CAAwD;gBAE9D,MAAM,EAAE,gCAAgC,EAAE,QAAQ,CAAC,EAAE,kCAAkC,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAyQxH,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAInG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAIvD,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;CAG1C"}
1
+ {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
@@ -140,180 +140,64 @@ var RecommendationInstantiator = /** @class */ (function () {
140
140
  },
141
141
  },
142
142
  },
143
- ], function (target, injectedElem, elem) { return __awaiter(_this, void 0, void 0, function () {
144
- var tag, contextGlobals, elemContext, context, shopper, shopperId, product, products, seed, cart, options, cartContents, cartFuncContents, defaultGlobals, globals, controllerConfig, controller, createRecommendationController, profileVars, component, RecommendationsComponent, _a;
143
+ {
144
+ selector: 'script[type="searchspring/recommendations"]',
145
+ autoRetarget: true,
146
+ clickRetarget: true,
147
+ emptyTarget: false,
148
+ },
149
+ ], function (target, elem, originalElem) { return __awaiter(_this, void 0, void 0, function () {
150
+ var elemContext, scriptContextProfiles, scriptContextGlobals_1, requestGlobals_1, targetsArr_1, profile, products, product, seed, options, batched, shopper, shopperId, profileRequestGlobals;
145
151
  var _this = this;
146
- var _b, _c, _d, _e;
147
- return __generator(this, function (_f) {
148
- switch (_f.label) {
149
- case 0:
150
- tag = injectedElem === null || injectedElem === void 0 ? void 0 : injectedElem.getAttribute('searchspring-recommend');
151
- if (!tag) {
152
- this.logger.warn("'profile' attribute is missing from <script> tag, skipping this profile", elem);
153
- return [2 /*return*/];
154
- }
155
- contextGlobals = {};
156
- elemContext = (0, snap_toolbox_1.getContext)(['shopperId', 'shopper', 'product', 'products', 'seed', 'cart', 'options', 'profile', 'custom'], elem);
157
- context = (0, deepmerge_1.default)(this.context, elemContext);
158
- shopper = context.shopper, shopperId = context.shopperId, product = context.product, products = context.products, seed = context.seed, cart = context.cart, options = context.options;
159
- /*
160
- type instantiatorContext = {
161
- shopper?: {
162
- id: string;
163
- };
164
- shopperId?: string;
165
- product?: string;
166
- products?: string[];
167
- seed?: string;
168
- cart?: string[] | () => string[];
169
- options?: {
170
- siteId?: string;
171
- branch?: string;
172
- batched?: boolean;
173
- realtime?: boolean;
174
- categories?: string[];
175
- blockedItems?: string[];
176
- brands?: string[];
177
- limit?: number;
178
- }
179
- }
180
- */
181
- if (shopper || shopperId) {
182
- contextGlobals.shopper = (shopper === null || shopper === void 0 ? void 0 : shopper.id) || shopperId;
183
- }
184
- if (product || seed) {
185
- contextGlobals.product = product || seed;
186
- }
187
- if (products) {
188
- contextGlobals.products = products;
189
- }
190
- // options
191
- if (options === null || options === void 0 ? void 0 : options.branch) {
192
- contextGlobals.branch = options.branch;
193
- }
194
- if (options === null || options === void 0 ? void 0 : options.siteId) {
195
- contextGlobals.siteId = options.siteId;
152
+ var _a;
153
+ return __generator(this, function (_b) {
154
+ elemContext = (0, snap_toolbox_1.getContext)(['shopperId', 'shopper', 'product', 'products', 'seed', 'cart', 'options', 'profile', 'custom', 'profiles', 'globals'], (originalElem || elem));
155
+ if (elemContext.profiles && elemContext.profiles.length) {
156
+ scriptContextProfiles = elemContext.profiles;
157
+ scriptContextGlobals_1 = elemContext.globals;
158
+ requestGlobals_1 = {
159
+ blockedItems: scriptContextGlobals_1.blockedItems,
160
+ cart: scriptContextGlobals_1.cart && getArrayFunc(scriptContextGlobals_1.cart),
161
+ products: scriptContextGlobals_1.products,
162
+ shopper: (_a = scriptContextGlobals_1.shopper) === null || _a === void 0 ? void 0 : _a.id,
163
+ siteId: scriptContextGlobals_1.siteId,
164
+ batchId: Math.random(),
165
+ };
166
+ targetsArr_1 = [];
167
+ // build out the targets array for each profile
168
+ scriptContextProfiles.forEach(function (profile) {
169
+ if (profile.target) {
170
+ var targetObj = {
171
+ selector: profile.target,
172
+ autoRetarget: true,
173
+ clickRetarget: true,
174
+ profile: profile,
175
+ };
176
+ targetsArr_1.push(targetObj);
196
177
  }
197
- if (options === null || options === void 0 ? void 0 : options.categories) {
198
- contextGlobals.categories = options.categories;
199
- }
200
- if (options === null || options === void 0 ? void 0 : options.filters) {
201
- contextGlobals.filters = options.filters;
202
- }
203
- if (options === null || options === void 0 ? void 0 : options.brands) {
204
- contextGlobals.brands = options.brands;
205
- }
206
- if ((options === null || options === void 0 ? void 0 : options.limit) && Number.isInteger(Number(options === null || options === void 0 ? void 0 : options.limit))) {
207
- contextGlobals.limits = Number(options === null || options === void 0 ? void 0 : options.limit);
208
- }
209
- if ((options === null || options === void 0 ? void 0 : options.blockedItems) && Array.isArray(options.blockedItems)) {
210
- contextGlobals.blockedItems = options.blockedItems;
211
- }
212
- if (typeof cart === 'function') {
213
- try {
214
- cartFuncContents = cart();
215
- if (Array.isArray(cartFuncContents)) {
216
- cartContents = cartFuncContents;
178
+ });
179
+ new snap_toolbox_1.DomTargeter(targetsArr_1, function (target, elem, originalElem) { return __awaiter(_this, void 0, void 0, function () {
180
+ var profileRequestGlobals, profileContext;
181
+ var _a, _b;
182
+ return __generator(this, function (_c) {
183
+ if ((_a = target.profile) === null || _a === void 0 ? void 0 : _a.profile) {
184
+ profileRequestGlobals = __assign(__assign(__assign({}, requestGlobals_1), (_b = target.profile) === null || _b === void 0 ? void 0 : _b.options), { tag: target.profile.profile });
185
+ profileContext = (0, deepmerge_1.default)(this.context, { globals: scriptContextGlobals_1, profile: target.profile });
186
+ if (elemContext.custom) {
187
+ profileContext.custom = elemContext.custom;
217
188
  }
189
+ readyTheController(this, elem, profileContext, profileCount, originalElem, profileRequestGlobals);
218
190
  }
219
- catch (e) {
220
- this.logger.warn("Error getting cart contents from function", e);
221
- }
222
- }
223
- else if (Array.isArray(cart)) {
224
- cartContents = cart;
225
- }
226
- if (Array.isArray(cartContents)) {
227
- this.tracker.cookies.cart.set(cartContents);
228
- contextGlobals.cart = this.tracker.cookies.cart.get();
229
- }
230
- profileCount[tag] = profileCount[tag] + 1 || 1;
231
- defaultGlobals = {
232
- limits: 20,
233
- };
234
- globals = (0, deepmerge_1.default)((0, deepmerge_1.default)((0, deepmerge_1.default)(defaultGlobals, ((_b = this.config.client) === null || _b === void 0 ? void 0 : _b.globals) || {}), ((_c = this.config.config) === null || _c === void 0 ? void 0 : _c.globals) || {}), contextGlobals);
235
- controllerConfig = __assign(__assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1), tag: tag, batched: (_d = options === null || options === void 0 ? void 0 : options.batched) !== null && _d !== void 0 ? _d : true, realtime: Boolean(options === null || options === void 0 ? void 0 : options.realtime) }, this.config.config), { globals: globals });
236
- controller = Object.keys(this.controller)
237
- .map(function (id) { return _this.controller[id]; })
238
- .filter(function (controller) {
239
- return (JSON.stringify({
240
- batched: controller.config.batched,
241
- branch: controller.config.branch,
242
- globals: controller.config.globals,
243
- tag: controller.config.tag,
244
- realtime: controller.config.realtime,
245
- }) ==
246
- JSON.stringify({
247
- batched: controllerConfig.batched,
248
- branch: controllerConfig.branch,
249
- globals: controllerConfig.globals,
250
- tag: controllerConfig.tag,
251
- realtime: controllerConfig.realtime,
252
- }));
253
- })[0];
254
- if (!!controller) return [3 /*break*/, 2];
255
- return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('../create/createRecommendationController')); })];
256
- case 1:
257
- createRecommendationController = (_f.sent()).default;
258
- controller = createRecommendationController({
259
- url: this.config.url,
260
- controller: controllerConfig,
261
- context: context,
262
- mode: this.config.mode,
263
- }, { client: this.client, tracker: this.tracker });
264
- _f.label = 2;
265
- case 2:
266
- this.uses.forEach(function (attachements) { return controller.use(attachements); });
267
- this.plugins.forEach(function (plugin) { return controller.plugin.apply(controller, __spreadArray([plugin.func], plugin.args, false)); });
268
- this.middleware.forEach(function (middleware) { return controller.on.apply(controller, __spreadArray([middleware.event], middleware.func, false)); });
269
- if (!(!controller.store.loaded && !controller.store.loading)) return [3 /*break*/, 4];
270
- return [4 /*yield*/, controller.search()];
271
- case 3:
272
- _f.sent();
273
- _f.label = 4;
274
- case 4:
275
- controller.addTargeter(this.targeter);
276
- this.controller[controller.config.id] = controller;
277
- window.searchspring.controller = window.searchspring.controller || {};
278
- window.searchspring.controller[controller.config.id] = controller;
279
- profileVars = controller.store.profile.display.templateParameters;
280
- component = (_e = controller.store.profile.display.template) === null || _e === void 0 ? void 0 : _e.component;
281
- if (controller.store.error) {
282
- //something went wrong
283
- //err was already logged - nothing to do.
284
191
  return [2 /*return*/];
285
- }
286
- if (!controller.store.profile.display.template) {
287
- this.logger.error("profile '".concat(tag, "' found on the following element is missing a template!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
288
- return [2 /*return*/];
289
- }
290
- if (!profileVars) {
291
- this.logger.error("profile '".concat(tag, "' found on the following element is missing templateParameters!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
292
- return [2 /*return*/];
293
- }
294
- if (!component) {
295
- this.logger.error("profile '".concat(tag, "' found on the following element is missing a component!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
296
- return [2 /*return*/];
297
- }
298
- _a = this.config.components[component];
299
- if (!_a) return [3 /*break*/, 6];
300
- return [4 /*yield*/, this.config.components[component]()];
301
- case 5:
302
- _a = (_f.sent());
303
- _f.label = 6;
304
- case 6:
305
- RecommendationsComponent = _a;
306
- if (!RecommendationsComponent) {
307
- this.logger.error("profile '".concat(tag, "' found on the following element is expecting component mapping for '").concat(component, "' - verify instantiator config.\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
308
- return [2 /*return*/];
309
- }
310
- setTimeout(function () {
311
- if (injectedElem) {
312
- (0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), injectedElem);
313
- }
314
192
  });
315
- return [2 /*return*/];
193
+ }); });
194
+ }
195
+ else {
196
+ profile = elemContext.profile, products = elemContext.products, product = elemContext.product, seed = elemContext.seed, options = elemContext.options, batched = elemContext.batched, shopper = elemContext.shopper, shopperId = elemContext.shopperId;
197
+ profileRequestGlobals = __assign({ tag: profile, batched: batched !== null && batched !== void 0 ? batched : true, batchId: 1, products: products || (product && [product]) || (seed && [seed]), cart: elemContext.cart && getArrayFunc(elemContext.cart), shopper: (shopper === null || shopper === void 0 ? void 0 : shopper.id) || shopperId }, options);
198
+ readyTheController(this, elem, elemContext, profileCount, originalElem, profileRequestGlobals);
316
199
  }
200
+ return [2 /*return*/];
317
201
  });
318
202
  }); });
319
203
  }
@@ -337,3 +221,131 @@ var RecommendationInstantiator = /** @class */ (function () {
337
221
  return RecommendationInstantiator;
338
222
  }());
339
223
  exports.RecommendationInstantiator = RecommendationInstantiator;
224
+ function readyTheController(instance, injectedElem, context, profileCount, elem, controllerGlobals) {
225
+ var _a, _b, _c;
226
+ return __awaiter(this, void 0, void 0, function () {
227
+ var batched, batchId, realtime, cart, tag, defaultGlobals, globals, controllerConfig, controller, createRecommendationController, profileVars, component, RecommendationsComponent, _d;
228
+ return __generator(this, function (_e) {
229
+ switch (_e.label) {
230
+ case 0:
231
+ batched = controllerGlobals.batched, batchId = controllerGlobals.batchId, realtime = controllerGlobals.realtime, cart = controllerGlobals.cart, tag = controllerGlobals.tag;
232
+ if (!tag) {
233
+ // FEEDBACK: change message depending on script integration type (profile vs. legacy)
234
+ instance.logger.warn("'profile' is missing from <script> tag, skipping this profile", elem);
235
+ return [2 /*return*/];
236
+ }
237
+ if (Array.isArray(cart)) {
238
+ instance.tracker.cookies.cart.set(cart);
239
+ }
240
+ profileCount[tag] = profileCount[tag] + 1 || 1;
241
+ defaultGlobals = {
242
+ limit: 20,
243
+ };
244
+ globals = deepmerge_1.default.all([
245
+ defaultGlobals,
246
+ ((_a = instance.config.client) === null || _a === void 0 ? void 0 : _a.globals) || {},
247
+ ((_b = instance.config.config) === null || _b === void 0 ? void 0 : _b.globals) || {},
248
+ controllerGlobals,
249
+ ]);
250
+ controllerConfig = __assign(__assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1), tag: tag, batched: batched !== null && batched !== void 0 ? batched : true, realtime: Boolean(realtime), batchId: batchId }, instance.config.config), { globals: globals });
251
+ controller = Object.keys(instance.controller)
252
+ .map(function (id) { return instance.controller[id]; })
253
+ .filter(function (controller) {
254
+ return (JSON.stringify({
255
+ batched: controller.config.batched,
256
+ branch: controller.config.branch,
257
+ globals: controller.config.globals,
258
+ tag: controller.config.tag,
259
+ realtime: controller.config.realtime,
260
+ }) ==
261
+ JSON.stringify({
262
+ batched: controllerConfig.batched,
263
+ branch: controllerConfig.branch,
264
+ globals: controllerConfig.globals,
265
+ tag: controllerConfig.tag,
266
+ realtime: controllerConfig.realtime,
267
+ }));
268
+ })[0];
269
+ if (!!controller) return [3 /*break*/, 2];
270
+ return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('../create/createRecommendationController')); })];
271
+ case 1:
272
+ createRecommendationController = (_e.sent()).default;
273
+ controller = createRecommendationController({
274
+ url: instance.config.url,
275
+ controller: controllerConfig,
276
+ context: context,
277
+ mode: instance.config.mode,
278
+ }, { client: instance.client, tracker: instance.tracker });
279
+ instance.uses.forEach(function (attachements) { return controller.use(attachements); });
280
+ instance.plugins.forEach(function (plugin) { return controller.plugin.apply(controller, __spreadArray([plugin.func], plugin.args, false)); });
281
+ instance.middleware.forEach(function (middleware) { return controller.on.apply(controller, __spreadArray([middleware.event], middleware.func, false)); });
282
+ _e.label = 2;
283
+ case 2:
284
+ if (!(!controller.store.loaded && !controller.store.loading)) return [3 /*break*/, 4];
285
+ return [4 /*yield*/, controller.search()];
286
+ case 3:
287
+ _e.sent();
288
+ _e.label = 4;
289
+ case 4:
290
+ controller.addTargeter(instance.targeter);
291
+ instance.controller[controller.config.id] = controller;
292
+ window.searchspring.controller = window.searchspring.controller || {};
293
+ window.searchspring.controller[controller.config.id] = controller;
294
+ profileVars = controller.store.profile.display.templateParameters;
295
+ component = (_c = controller.store.profile.display.template) === null || _c === void 0 ? void 0 : _c.component;
296
+ if (controller.store.error) {
297
+ //something went wrong
298
+ //err was already logged - nothing to do.
299
+ return [2 /*return*/];
300
+ }
301
+ if (!controller.store.profile.display.template) {
302
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing a template!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
303
+ return [2 /*return*/];
304
+ }
305
+ if (!profileVars) {
306
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing templateParameters!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
307
+ return [2 /*return*/];
308
+ }
309
+ if (!component) {
310
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing a component!\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
311
+ return [2 /*return*/];
312
+ }
313
+ _d = instance.config.components[component];
314
+ if (!_d) return [3 /*break*/, 6];
315
+ return [4 /*yield*/, instance.config.components[component]()];
316
+ case 5:
317
+ _d = (_e.sent());
318
+ _e.label = 6;
319
+ case 6:
320
+ RecommendationsComponent = _d;
321
+ if (!RecommendationsComponent) {
322
+ instance.logger.error("profile '".concat(tag, "' found on the following element is expecting component mapping for '").concat(component, "' - verify instantiator config.\n").concat(elem === null || elem === void 0 ? void 0 : elem.outerHTML));
323
+ return [2 /*return*/];
324
+ }
325
+ setTimeout(function () {
326
+ if (injectedElem) {
327
+ (0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), injectedElem);
328
+ }
329
+ });
330
+ return [2 /*return*/];
331
+ }
332
+ });
333
+ });
334
+ }
335
+ function getArrayFunc(arrayOrFunc) {
336
+ if (typeof arrayOrFunc === 'function') {
337
+ try {
338
+ var funcContents = arrayOrFunc();
339
+ if (Array.isArray(funcContents)) {
340
+ return funcContents;
341
+ }
342
+ }
343
+ catch (e) {
344
+ // function didn't return an array
345
+ }
346
+ }
347
+ else if (Array.isArray(arrayOrFunc)) {
348
+ return arrayOrFunc;
349
+ }
350
+ return [];
351
+ }
@@ -43,9 +43,15 @@ export declare class RecommendationInstantiator {
43
43
  config: RecommendationInstantiatorConfig;
44
44
  context: ContextVariables;
45
45
  targeter: DomTargeter;
46
- private uses;
47
- private plugins;
48
- private middleware;
46
+ uses: Attachments[];
47
+ plugins: {
48
+ func: (cntrlr: AbstractController, ...args: any) => Promise<void>;
49
+ args: unknown[];
50
+ }[];
51
+ middleware: {
52
+ event: string;
53
+ func: Middleware<unknown>[];
54
+ }[];
49
55
  constructor(config: RecommendationInstantiatorConfig, services?: RecommendationInstantiatorServices, context?: ContextVariables);
50
56
  plugin(func: (cntrlr: AbstractController, ...args: any) => Promise<void>, ...args: unknown[]): void;
51
57
  on(event: string, ...func: Middleware<unknown>[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjI,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAGnE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,IAAI,CAAC,EAAE,MAAM,OAAO,OAAO,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,aAAa,CAAC;KACzB,GAAG,WAAW,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,qBAAa,0BAA0B;IACtC,OAAO,CAAC,IAAI,CAAsB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,CAAC;KACxC,CAAM;IACA,MAAM,EAAE,gCAAgC,CAAC;IACzC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC;IAE7B,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAgG;IAC/G,OAAO,CAAC,UAAU,CAAwD;gBAE9D,MAAM,EAAE,gCAAgC,EAAE,QAAQ,CAAC,EAAE,kCAAkC,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAyQxH,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAInG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAIvD,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;CAG1C"}
1
+ {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
@@ -53,171 +53,66 @@ export class RecommendationInstantiator {
53
53
  },
54
54
  },
55
55
  },
56
- ], async (target, injectedElem, elem) => {
57
- const tag = injectedElem?.getAttribute('searchspring-recommend');
58
- if (!tag) {
59
- this.logger.warn(`'profile' attribute is missing from <script> tag, skipping this profile`, elem);
60
- return;
61
- }
62
- const contextGlobals = {};
63
- const elemContext = getContext(['shopperId', 'shopper', 'product', 'products', 'seed', 'cart', 'options', 'profile', 'custom'], elem);
64
- const context = deepmerge(this.context, elemContext);
65
- const { shopper, shopperId, product, products, seed, cart, options } = context;
66
- /*
67
- type instantiatorContext = {
68
- shopper?: {
69
- id: string;
70
- };
71
- shopperId?: string;
72
- product?: string;
73
- products?: string[];
74
- seed?: string;
75
- cart?: string[] | () => string[];
76
- options?: {
77
- siteId?: string;
78
- branch?: string;
79
- batched?: boolean;
80
- realtime?: boolean;
81
- categories?: string[];
82
- blockedItems?: string[];
83
- brands?: string[];
84
- limit?: number;
56
+ {
57
+ selector: 'script[type="searchspring/recommendations"]',
58
+ autoRetarget: true,
59
+ clickRetarget: true,
60
+ emptyTarget: false,
61
+ },
62
+ ], async (target, elem, originalElem) => {
63
+ const elemContext = getContext(['shopperId', 'shopper', 'product', 'products', 'seed', 'cart', 'options', 'profile', 'custom', 'profiles', 'globals'], (originalElem || elem));
64
+ if (elemContext.profiles && elemContext.profiles.length) {
65
+ // using the new script integration structure
66
+ // type the new profile specific integration context variables
67
+ const scriptContextProfiles = elemContext.profiles;
68
+ const scriptContextGlobals = elemContext.globals;
69
+ // grab from globals
70
+ const requestGlobals = {
71
+ blockedItems: scriptContextGlobals.blockedItems,
72
+ cart: scriptContextGlobals.cart && getArrayFunc(scriptContextGlobals.cart),
73
+ products: scriptContextGlobals.products,
74
+ shopper: scriptContextGlobals.shopper?.id,
75
+ siteId: scriptContextGlobals.siteId,
76
+ batchId: Math.random(),
77
+ };
78
+ const targetsArr = [];
79
+ // build out the targets array for each profile
80
+ scriptContextProfiles.forEach((profile) => {
81
+ if (profile.target) {
82
+ const targetObj = {
83
+ selector: profile.target,
84
+ autoRetarget: true,
85
+ clickRetarget: true,
86
+ profile,
87
+ };
88
+ targetsArr.push(targetObj);
85
89
  }
86
- }
87
- */
88
- if (shopper || shopperId) {
89
- contextGlobals.shopper = shopper?.id || shopperId;
90
- }
91
- if (product || seed) {
92
- contextGlobals.product = product || seed;
93
- }
94
- if (products) {
95
- contextGlobals.products = products;
96
- }
97
- // options
98
- if (options?.branch) {
99
- contextGlobals.branch = options.branch;
100
- }
101
- if (options?.siteId) {
102
- contextGlobals.siteId = options.siteId;
103
- }
104
- if (options?.categories) {
105
- contextGlobals.categories = options.categories;
106
- }
107
- if (options?.filters) {
108
- contextGlobals.filters = options.filters;
109
- }
110
- if (options?.brands) {
111
- contextGlobals.brands = options.brands;
112
- }
113
- if (options?.limit && Number.isInteger(Number(options?.limit))) {
114
- contextGlobals.limits = Number(options?.limit);
115
- }
116
- if (options?.blockedItems && Array.isArray(options.blockedItems)) {
117
- contextGlobals.blockedItems = options.blockedItems;
118
- }
119
- let cartContents;
120
- if (typeof cart === 'function') {
121
- try {
122
- const cartFuncContents = cart();
123
- if (Array.isArray(cartFuncContents)) {
124
- cartContents = cartFuncContents;
90
+ });
91
+ new DomTargeter(targetsArr, async (target, elem, originalElem) => {
92
+ if (target.profile?.profile) {
93
+ const profileRequestGlobals = { ...requestGlobals, ...target.profile?.options, tag: target.profile.profile };
94
+ const profileContext = deepmerge(this.context, { globals: scriptContextGlobals, profile: target.profile });
95
+ if (elemContext.custom) {
96
+ profileContext.custom = elemContext.custom;
97
+ }
98
+ readyTheController(this, elem, profileContext, profileCount, originalElem, profileRequestGlobals);
125
99
  }
126
- }
127
- catch (e) {
128
- this.logger.warn(`Error getting cart contents from function`, e);
129
- }
130
- }
131
- else if (Array.isArray(cart)) {
132
- cartContents = cart;
133
- }
134
- if (Array.isArray(cartContents)) {
135
- this.tracker.cookies.cart.set(cartContents);
136
- contextGlobals.cart = this.tracker.cookies.cart.get();
137
- }
138
- profileCount[tag] = profileCount[tag] + 1 || 1;
139
- const defaultGlobals = {
140
- limits: 20,
141
- };
142
- const globals = deepmerge(deepmerge(deepmerge(defaultGlobals, this.config.client?.globals || {}), this.config.config?.globals || {}), contextGlobals);
143
- const controllerConfig = {
144
- id: `recommend_${tag}_${profileCount[tag] - 1}`,
145
- tag,
146
- batched: options?.batched ?? true,
147
- realtime: Boolean(options?.realtime),
148
- ...this.config.config,
149
- globals,
150
- };
151
- // try to find an existing controller by similar configuration
152
- let controller = Object.keys(this.controller)
153
- .map((id) => this.controller[id])
154
- .filter((controller) => {
155
- return (JSON.stringify({
156
- batched: controller.config.batched,
157
- branch: controller.config.branch,
158
- globals: controller.config.globals,
159
- tag: controller.config.tag,
160
- realtime: controller.config.realtime,
161
- }) ==
162
- JSON.stringify({
163
- batched: controllerConfig.batched,
164
- branch: controllerConfig.branch,
165
- globals: controllerConfig.globals,
166
- tag: controllerConfig.tag,
167
- realtime: controllerConfig.realtime,
168
- }));
169
- })[0];
170
- if (!controller) {
171
- // no existing controller found of same configuration - creating a new controller
172
- const createRecommendationController = (await import('../create/createRecommendationController')).default;
173
- controller = createRecommendationController({
174
- url: this.config.url,
175
- controller: controllerConfig,
176
- context,
177
- mode: this.config.mode,
178
- }, { client: this.client, tracker: this.tracker });
179
- }
180
- this.uses.forEach((attachements) => controller.use(attachements));
181
- this.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
182
- this.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
183
- // run a search on the controller if it has not yet and it is not currently
184
- if (!controller.store.loaded && !controller.store.loading) {
185
- await controller.search();
186
- }
187
- controller.addTargeter(this.targeter);
188
- this.controller[controller.config.id] = controller;
189
- window.searchspring.controller = window.searchspring.controller || {};
190
- window.searchspring.controller[controller.config.id] = controller;
191
- const profileVars = controller.store.profile.display.templateParameters;
192
- const component = controller.store.profile.display.template?.component;
193
- if (controller.store.error) {
194
- //something went wrong
195
- //err was already logged - nothing to do.
196
- return;
197
- }
198
- if (!controller.store.profile.display.template) {
199
- this.logger.error(`profile '${tag}' found on the following element is missing a template!\n${elem?.outerHTML}`);
200
- return;
100
+ });
101
+ }
102
+ else {
103
+ // using the "legacy" method
104
+ const { profile, products, product, seed, options, batched, shopper, shopperId } = elemContext;
105
+ const profileRequestGlobals = {
106
+ tag: profile,
107
+ batched: batched ?? true,
108
+ batchId: 1,
109
+ products: products || (product && [product]) || (seed && [seed]),
110
+ cart: elemContext.cart && getArrayFunc(elemContext.cart),
111
+ shopper: shopper?.id || shopperId,
112
+ ...options,
113
+ };
114
+ readyTheController(this, elem, elemContext, profileCount, originalElem, profileRequestGlobals);
201
115
  }
202
- if (!profileVars) {
203
- this.logger.error(`profile '${tag}' found on the following element is missing templateParameters!\n${elem?.outerHTML}`);
204
- return;
205
- }
206
- if (!component) {
207
- this.logger.error(`profile '${tag}' found on the following element is missing a component!\n${elem?.outerHTML}`);
208
- return;
209
- }
210
- const RecommendationsComponent = this.config.components[component] &&
211
- (await this.config.components[component]());
212
- if (!RecommendationsComponent) {
213
- this.logger.error(`profile '${tag}' found on the following element is expecting component mapping for '${component}' - verify instantiator config.\n${elem?.outerHTML}`);
214
- return;
215
- }
216
- setTimeout(() => {
217
- if (injectedElem) {
218
- render(_jsx(RecommendationsComponent, { controller: controller }), injectedElem);
219
- }
220
- });
221
116
  });
222
117
  }
223
118
  plugin(func, ...args) {
@@ -230,3 +125,120 @@ export class RecommendationInstantiator {
230
125
  this.uses.push(attachments);
231
126
  }
232
127
  }
128
+ async function readyTheController(instance, injectedElem, context, profileCount, elem, controllerGlobals) {
129
+ const { batched, batchId, realtime, cart, tag } = controllerGlobals;
130
+ if (!tag) {
131
+ // FEEDBACK: change message depending on script integration type (profile vs. legacy)
132
+ instance.logger.warn(`'profile' is missing from <script> tag, skipping this profile`, elem);
133
+ return;
134
+ }
135
+ if (Array.isArray(cart)) {
136
+ instance.tracker.cookies.cart.set(cart);
137
+ }
138
+ profileCount[tag] = profileCount[tag] + 1 || 1;
139
+ const defaultGlobals = {
140
+ limit: 20,
141
+ };
142
+ const globals = deepmerge.all([
143
+ defaultGlobals,
144
+ instance.config.client?.globals || {},
145
+ instance.config.config?.globals || {},
146
+ controllerGlobals,
147
+ ]);
148
+ const controllerConfig = {
149
+ id: `recommend_${tag}_${profileCount[tag] - 1}`,
150
+ tag,
151
+ batched: batched ?? true,
152
+ realtime: Boolean(realtime),
153
+ batchId: batchId,
154
+ ...instance.config.config,
155
+ globals,
156
+ };
157
+ // try to find an existing controller by similar configuration
158
+ let controller = Object.keys(instance.controller)
159
+ .map((id) => instance.controller[id])
160
+ .filter((controller) => {
161
+ return (JSON.stringify({
162
+ batched: controller.config.batched,
163
+ branch: controller.config.branch,
164
+ globals: controller.config.globals,
165
+ tag: controller.config.tag,
166
+ realtime: controller.config.realtime,
167
+ }) ==
168
+ JSON.stringify({
169
+ batched: controllerConfig.batched,
170
+ branch: controllerConfig.branch,
171
+ globals: controllerConfig.globals,
172
+ tag: controllerConfig.tag,
173
+ realtime: controllerConfig.realtime,
174
+ }));
175
+ })[0];
176
+ if (!controller) {
177
+ // no existing controller found of same configuration - creating a new controller
178
+ const createRecommendationController = (await import('../create/createRecommendationController')).default;
179
+ controller = createRecommendationController({
180
+ url: instance.config.url,
181
+ controller: controllerConfig,
182
+ context,
183
+ mode: instance.config.mode,
184
+ }, { client: instance.client, tracker: instance.tracker });
185
+ instance.uses.forEach((attachements) => controller.use(attachements));
186
+ instance.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
187
+ instance.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
188
+ }
189
+ // run a search on the controller if it has not yet and it is not currently
190
+ if (!controller.store.loaded && !controller.store.loading) {
191
+ await controller.search();
192
+ }
193
+ controller.addTargeter(instance.targeter);
194
+ instance.controller[controller.config.id] = controller;
195
+ window.searchspring.controller = window.searchspring.controller || {};
196
+ window.searchspring.controller[controller.config.id] = controller;
197
+ const profileVars = controller.store.profile.display.templateParameters;
198
+ const component = controller.store.profile.display.template?.component;
199
+ if (controller.store.error) {
200
+ //something went wrong
201
+ //err was already logged - nothing to do.
202
+ return;
203
+ }
204
+ if (!controller.store.profile.display.template) {
205
+ instance.logger.error(`profile '${tag}' found on the following element is missing a template!\n${elem?.outerHTML}`);
206
+ return;
207
+ }
208
+ if (!profileVars) {
209
+ instance.logger.error(`profile '${tag}' found on the following element is missing templateParameters!\n${elem?.outerHTML}`);
210
+ return;
211
+ }
212
+ if (!component) {
213
+ instance.logger.error(`profile '${tag}' found on the following element is missing a component!\n${elem?.outerHTML}`);
214
+ return;
215
+ }
216
+ const RecommendationsComponent = instance.config.components[component] &&
217
+ (await instance.config.components[component]());
218
+ if (!RecommendationsComponent) {
219
+ instance.logger.error(`profile '${tag}' found on the following element is expecting component mapping for '${component}' - verify instantiator config.\n${elem?.outerHTML}`);
220
+ return;
221
+ }
222
+ setTimeout(() => {
223
+ if (injectedElem) {
224
+ render(_jsx(RecommendationsComponent, { controller: controller }), injectedElem);
225
+ }
226
+ });
227
+ }
228
+ function getArrayFunc(arrayOrFunc) {
229
+ if (typeof arrayOrFunc === 'function') {
230
+ try {
231
+ const funcContents = arrayOrFunc();
232
+ if (Array.isArray(funcContents)) {
233
+ return funcContents;
234
+ }
235
+ }
236
+ catch (e) {
237
+ // function didn't return an array
238
+ }
239
+ }
240
+ else if (Array.isArray(arrayOrFunc)) {
241
+ return arrayOrFunc;
242
+ }
243
+ return [];
244
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searchspring/snap-preact",
3
- "version": "0.59.0",
3
+ "version": "0.60.0",
4
4
  "description": "Snap Preact",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -20,17 +20,17 @@
20
20
  "test:watch": "jest --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@searchspring/snap-client": "^0.59.0",
24
- "@searchspring/snap-controller": "^0.59.0",
25
- "@searchspring/snap-event-manager": "^0.59.0",
26
- "@searchspring/snap-logger": "^0.59.0",
27
- "@searchspring/snap-platforms": "^0.59.0",
28
- "@searchspring/snap-preact-components": "^0.59.0",
29
- "@searchspring/snap-profiler": "^0.59.0",
30
- "@searchspring/snap-store-mobx": "^0.59.0",
31
- "@searchspring/snap-toolbox": "^0.59.0",
32
- "@searchspring/snap-tracker": "^0.59.0",
33
- "@searchspring/snap-url-manager": "^0.59.0",
23
+ "@searchspring/snap-client": "^0.60.0",
24
+ "@searchspring/snap-controller": "^0.60.0",
25
+ "@searchspring/snap-event-manager": "^0.60.0",
26
+ "@searchspring/snap-logger": "^0.60.0",
27
+ "@searchspring/snap-platforms": "^0.60.0",
28
+ "@searchspring/snap-preact-components": "^0.60.0",
29
+ "@searchspring/snap-profiler": "^0.60.0",
30
+ "@searchspring/snap-store-mobx": "^0.60.0",
31
+ "@searchspring/snap-toolbox": "^0.60.0",
32
+ "@searchspring/snap-tracker": "^0.60.0",
33
+ "@searchspring/snap-url-manager": "^0.60.0",
34
34
  "deepmerge": "4.3.1",
35
35
  "intersection-observer": "0.12.0",
36
36
  "is-plain-object": "5.0.0"
@@ -43,5 +43,5 @@
43
43
  "files": [
44
44
  "dist/**/*"
45
45
  ],
46
- "gitHead": "3106e08ab0114c0bb0de8f7d7beb6f65968f9c75"
46
+ "gitHead": "c1b320737bc856b18032888f7b6825fd4706def9"
47
47
  }