@searchspring/snap-preact 0.76.1 → 0.78.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.
@@ -57,6 +57,7 @@ export declare class RecommendationInstantiator {
57
57
  plugin(func: (cntrlr: AbstractController, ...args: any) => Promise<void>, ...args: unknown[]): void;
58
58
  on(event: string, ...func: Middleware<unknown>[]): void;
59
59
  use(attachments: Attachments): void;
60
+ cleanupStaleControllers(): void;
60
61
  }
61
62
  type DefinedProps = {
62
63
  [key: string]: any;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
@@ -10,29 +10,6 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- var desc = Object.getOwnPropertyDescriptor(m, k);
16
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
- desc = { enumerable: true, get: function() { return m[k]; } };
18
- }
19
- Object.defineProperty(o, k2, desc);
20
- }) : (function(o, m, k, k2) {
21
- if (k2 === undefined) k2 = k;
22
- o[k2] = m[k];
23
- }));
24
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
- Object.defineProperty(o, "default", { enumerable: true, value: v });
26
- }) : function(o, v) {
27
- o["default"] = v;
28
- });
29
- var __importStar = (this && this.__importStar) || function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -90,6 +67,7 @@ var snap_toolbox_1 = require("@searchspring/snap-toolbox");
90
67
  var snap_client_1 = require("@searchspring/snap-client");
91
68
  var snap_logger_1 = require("@searchspring/snap-logger");
92
69
  var snap_tracker_1 = require("@searchspring/snap-tracker");
70
+ var create_1 = require("../create");
93
71
  var DEFAULT_BRANCH = 'production';
94
72
  var RecommendationInstantiator = /** @class */ (function () {
95
73
  function RecommendationInstantiator(config, services, context) {
@@ -127,32 +105,30 @@ var RecommendationInstantiator = /** @class */ (function () {
127
105
  this.tracker = (services === null || services === void 0 ? void 0 : services.tracker) || new snap_tracker_1.Tracker(this.config.client.globals);
128
106
  this.logger = (services === null || services === void 0 ? void 0 : services.logger) || new snap_logger_1.Logger({ prefix: 'RecommendationInstantiator ', mode: this.mode });
129
107
  var profileCount = {};
108
+ // script block targeter for "grouped" and "legacy" blocks
130
109
  this.targeter = new snap_toolbox_1.DomTargeter([
131
110
  {
132
111
  selector: "".concat(this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]', ", script[type=\"searchspring/recommend\"][profile=\"email\"]"),
133
112
  autoRetarget: true,
134
113
  clickRetarget: true,
135
- inject: {
136
- action: 'before',
137
- element: function (target, origElement) {
138
- var profile = origElement.getAttribute('profile') || '';
139
- var recsContainer = document.createElement('div');
140
- recsContainer.setAttribute('searchspring-recommend', profile);
141
- return recsContainer;
142
- },
143
- },
114
+ navigationRetarget: true,
115
+ emptyTarget: false,
144
116
  },
145
117
  {
146
118
  selector: 'script[type="searchspring/recommendations"]',
147
119
  autoRetarget: true,
148
120
  clickRetarget: true,
121
+ navigationRetarget: true,
149
122
  emptyTarget: false,
150
123
  },
151
- ], function (target, elem, originalElem) { return __awaiter(_this, void 0, void 0, function () {
152
- var elemContext, scriptContextProfiles, scriptContextGlobals_1, requestGlobals_1, targetsArr_1, profile, products, product, seed, filters, blockedItems, options, shopper, shopperId, combinedProducts, shopperIdentifier, profileRequestGlobals;
124
+ ], function (target, elem, _originalElem, targeter) { return __awaiter(_this, void 0, void 0, function () {
125
+ var scriptElement, elemContext, scriptContextProfiles, scriptContextGlobals_1, requestGlobals_1, profile, products, product, seed, filters, blockedItems, options, shopper, shopperId, combinedProducts, shopperIdentifier, profileRequestGlobals_1, profileAttr, recsContainer, legacyContext_1;
153
126
  var _this = this;
154
127
  var _a;
155
128
  return __generator(this, function (_b) {
129
+ this.cleanupStaleControllers();
130
+ this.targeter = this.targeter || targeter;
131
+ scriptElement = elem;
156
132
  elemContext = (0, snap_toolbox_1.getContext)([
157
133
  'shopperId',
158
134
  'shopper',
@@ -167,7 +143,7 @@ var RecommendationInstantiator = /** @class */ (function () {
167
143
  'custom',
168
144
  'profiles',
169
145
  'globals',
170
- ], (originalElem || elem));
146
+ ], scriptElement);
171
147
  if (elemContext.profiles && elemContext.profiles.length) {
172
148
  scriptContextProfiles = elemContext.profiles;
173
149
  scriptContextGlobals_1 = elemContext.globals;
@@ -177,42 +153,62 @@ var RecommendationInstantiator = /** @class */ (function () {
177
153
  cart: (scriptContextGlobals_1 === null || scriptContextGlobals_1 === void 0 ? void 0 : scriptContextGlobals_1.cart) && getArrayFunc(scriptContextGlobals_1.cart),
178
154
  products: scriptContextGlobals_1 === null || scriptContextGlobals_1 === void 0 ? void 0 : scriptContextGlobals_1.products,
179
155
  shopper: (_a = scriptContextGlobals_1 === null || scriptContextGlobals_1 === void 0 ? void 0 : scriptContextGlobals_1.shopper) === null || _a === void 0 ? void 0 : _a.id,
180
- batchId: Math.random(),
156
+ batchId: Math.floor(Math.random() * Number.MAX_SAFE_INTEGER),
181
157
  }));
182
- targetsArr_1 = [];
183
- // build out the targets array for each profile
184
- scriptContextProfiles.forEach(function (profile) {
158
+ // create a per-profile DomTargeter for each profile so each controller
159
+ // gets its own targeter tracking its specific element
160
+ scriptContextProfiles.forEach(function (profile, index) {
185
161
  if (profile.selector) {
186
- var targetObj = {
162
+ var profileTarget = {
187
163
  selector: profile.selector,
188
164
  autoRetarget: true,
189
- clickRetarget: true,
190
165
  profile: profile,
166
+ order: index,
191
167
  };
192
- targetsArr_1.push(targetObj);
168
+ // track the controller for this profile so multiple matched elements share it
169
+ var profileControllerPromise_1;
170
+ new snap_toolbox_1.DomTargeter([profileTarget], function (target, targetElem, _originalElem, targeter) { return __awaiter(_this, void 0, void 0, function () {
171
+ var profileRequestGlobals, profileContext, controller;
172
+ var _a, _b, _c;
173
+ return __generator(this, function (_d) {
174
+ switch (_d.label) {
175
+ case 0:
176
+ // skip retarget if the source script element was removed and release the current target
177
+ if (!scriptElement.isConnected) {
178
+ if (targetElem) {
179
+ targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
180
+ }
181
+ return [2 /*return*/];
182
+ }
183
+ if (!(((_a = target.profile) === null || _a === void 0 ? void 0 : _a.profile) || ((_b = target.profile) === null || _b === void 0 ? void 0 : _b.tag))) return [3 /*break*/, 3];
184
+ profileRequestGlobals = __assign(__assign({}, requestGlobals_1), { profile: __assign(__assign({}, (_c = target.profile) === null || _c === void 0 ? void 0 : _c.options), { order: target.order }), tag: target.profile.tag || target.profile.profile });
185
+ profileContext = (0, deepmerge_1.default)(this.context, defined({ globals: scriptContextGlobals_1, profile: target.profile }));
186
+ if (elemContext.custom) {
187
+ profileContext.custom = elemContext.custom;
188
+ }
189
+ if (!!profileControllerPromise_1) return [3 /*break*/, 1];
190
+ // first element match — create the controller
191
+ profileControllerPromise_1 = readyTheController(this, targetElem, profileContext, profileCount, scriptElement, profileRequestGlobals, targeter);
192
+ return [3 /*break*/, 3];
193
+ case 1: return [4 /*yield*/, profileControllerPromise_1];
194
+ case 2:
195
+ controller = _d.sent();
196
+ if (controller && targetElem) {
197
+ renderController(this, controller, targetElem, scriptElement);
198
+ }
199
+ _d.label = 3;
200
+ case 3: return [2 /*return*/];
201
+ }
202
+ });
203
+ }); });
193
204
  }
194
205
  });
195
- new snap_toolbox_1.DomTargeter(targetsArr_1, function (target, elem, originalElem) { return __awaiter(_this, void 0, void 0, function () {
196
- var profileRequestGlobals, profileContext;
197
- var _a, _b, _c;
198
- return __generator(this, function (_d) {
199
- if (((_a = target.profile) === null || _a === void 0 ? void 0 : _a.profile) || ((_b = target.profile) === null || _b === void 0 ? void 0 : _b.tag)) {
200
- profileRequestGlobals = __assign(__assign({}, requestGlobals_1), { profile: (_c = target.profile) === null || _c === void 0 ? void 0 : _c.options, tag: target.profile.tag || target.profile.profile });
201
- profileContext = (0, deepmerge_1.default)(this.context, defined({ globals: scriptContextGlobals_1, profile: target.profile }));
202
- if (elemContext.custom) {
203
- profileContext.custom = elemContext.custom;
204
- }
205
- readyTheController(this, elem, profileContext, profileCount, originalElem, profileRequestGlobals);
206
- }
207
- return [2 /*return*/];
208
- });
209
- }); });
210
206
  }
211
207
  else {
212
208
  profile = elemContext.profile, products = elemContext.products, product = elemContext.product, seed = elemContext.seed, filters = elemContext.filters, blockedItems = elemContext.blockedItems, options = elemContext.options, shopper = elemContext.shopper, shopperId = elemContext.shopperId;
213
209
  combinedProducts = [].concat(products || product || seed || []);
214
210
  shopperIdentifier = [shopper, shopper === null || shopper === void 0 ? void 0 : shopper.id, shopperId, shopperId === null || shopperId === void 0 ? void 0 : shopperId.id].filter(function (val) { return val && typeof val === 'string'; }).pop();
215
- profileRequestGlobals = __assign({ tag: profile }, defined({
211
+ profileRequestGlobals_1 = __assign({ tag: profile }, defined({
216
212
  products: combinedProducts.length ? combinedProducts : undefined,
217
213
  cart: elemContext.cart && getArrayFunc(elemContext.cart),
218
214
  shopper: shopperIdentifier,
@@ -220,7 +216,25 @@ var RecommendationInstantiator = /** @class */ (function () {
220
216
  blockedItems: blockedItems,
221
217
  profile: options,
222
218
  }));
223
- readyTheController(this, elem, (0, deepmerge_1.default)(this.context, elemContext), profileCount, originalElem, profileRequestGlobals);
219
+ profileAttr = scriptElement.getAttribute('profile') || '';
220
+ recsContainer = document.createElement('div');
221
+ recsContainer.setAttribute('searchspring-recommend', profileAttr);
222
+ scriptElement.before(recsContainer);
223
+ legacyContext_1 = (0, deepmerge_1.default)(this.context, elemContext);
224
+ // create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
225
+ new snap_toolbox_1.DomTargeter([{ selector: "[searchspring-recommend=\"".concat(profileAttr, "\"]"), name: "legacy_".concat(profile, "_").concat(profileCount[profile || ''] || 0) }], function (_target, targetElem, _originalElem, targeter) { return __awaiter(_this, void 0, void 0, function () {
226
+ return __generator(this, function (_a) {
227
+ // skip retarget if the source script element was removed and release the current target
228
+ if (!scriptElement.isConnected) {
229
+ if (targetElem) {
230
+ targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
231
+ }
232
+ return [2 /*return*/];
233
+ }
234
+ readyTheController(this, targetElem, legacyContext_1, profileCount, scriptElement, profileRequestGlobals_1, targeter);
235
+ return [2 /*return*/];
236
+ });
237
+ }); });
224
238
  }
225
239
  return [2 /*return*/];
226
240
  });
@@ -243,114 +257,140 @@ var RecommendationInstantiator = /** @class */ (function () {
243
257
  RecommendationInstantiator.prototype.use = function (attachments) {
244
258
  this.uses.push(attachments);
245
259
  };
260
+ // cleanup to ensure we release controllers no longer rendering in the DOM (memory leak prevention for SPA's)
261
+ RecommendationInstantiator.prototype.cleanupStaleControllers = function () {
262
+ var _this = this;
263
+ Object.keys(this.controller).forEach(function (id) {
264
+ var _a;
265
+ var controller = _this.controller[id];
266
+ var targeters = Object.values(controller.targeters);
267
+ var hasConnectedTarget = targeters.some(function (targeter) {
268
+ return targeter.getTargetedElems().some(function (elem) {
269
+ var attr = elem.isConnected && elem.getAttribute('ss-controller-id');
270
+ return attr === id;
271
+ });
272
+ });
273
+ if (!hasConnectedTarget) {
274
+ Object.keys(controller.targeters).forEach(function (targeterId) { return controller.targeters[targeterId].destroy(); });
275
+ controller.targeters = {};
276
+ delete _this.controller[id];
277
+ if ((_a = window.searchspring) === null || _a === void 0 ? void 0 : _a.controller) {
278
+ delete window.searchspring.controller[id];
279
+ }
280
+ }
281
+ });
282
+ };
246
283
  return RecommendationInstantiator;
247
284
  }());
248
285
  exports.RecommendationInstantiator = RecommendationInstantiator;
249
- function readyTheController(instance, injectedElem, context, profileCount, elem, controllerGlobals) {
250
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
286
+ function readyTheController(instance, targetElem, context, profileCount, scriptElem, controllerGlobals, targeter) {
287
+ var _a, _b, _c, _d, _e, _f, _g, _h;
251
288
  return __awaiter(this, void 0, void 0, function () {
252
- var profile, batchId, cart, tag, batched, globals, controllerConfig, controller, createRecommendationController, profileVars, component, RecommendationsComponent, _k;
253
- return __generator(this, function (_l) {
254
- switch (_l.label) {
289
+ var profile, batchId, cart, tag, batched, globals, controllerConfigBase, controllerConfig, controller, profileVars;
290
+ return __generator(this, function (_j) {
291
+ switch (_j.label) {
255
292
  case 0:
256
293
  profile = controllerGlobals.profile, batchId = controllerGlobals.batchId, cart = controllerGlobals.cart, tag = controllerGlobals.tag;
257
294
  batched = (_b = (_a = profile === null || profile === void 0 ? void 0 : profile.batched) !== null && _a !== void 0 ? _a : controllerGlobals.batched) !== null && _b !== void 0 ? _b : true;
258
295
  if (!tag) {
259
296
  // FEEDBACK: change message depending on script integration type (profile vs. legacy)
260
- instance.logger.warn("'tag' is missing from <script> tag, skipping this profile", elem);
297
+ instance.logger.warn("'tag' is missing from <script> tag, skipping this profile", scriptElem);
261
298
  return [2 /*return*/];
262
299
  }
263
300
  if (Array.isArray(cart)) {
264
301
  instance.tracker.cookies.cart.set(cart);
265
302
  }
266
- profileCount[tag] = profileCount[tag] + 1 || 1;
267
303
  globals = deepmerge_1.default.all([
268
304
  ((_c = instance.config.client) === null || _c === void 0 ? void 0 : _c.globals) || {},
269
305
  ((_d = instance.config.config) === null || _d === void 0 ? void 0 : _d.globals) || {},
270
306
  controllerGlobals,
271
307
  ]);
272
- controllerConfig = __assign(__assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1), tag: tag, batched: batched !== null && batched !== void 0 ? batched : true, realtime: Boolean((_f = (_e = context.options) === null || _e === void 0 ? void 0 : _e.realtime) !== null && _f !== void 0 ? _f : (_h = (_g = context.profile) === null || _g === void 0 ? void 0 : _g.options) === null || _h === void 0 ? void 0 : _h.realtime), batchId: batchId }, instance.config.config), { globals: globals });
308
+ controllerConfigBase = __assign(__assign({ tag: tag, batched: batched !== null && batched !== void 0 ? batched : true, realtime: Boolean((_f = (_e = context.options) === null || _e === void 0 ? void 0 : _e.realtime) !== null && _f !== void 0 ? _f : (_h = (_g = context.profile) === null || _g === void 0 ? void 0 : _g.options) === null || _h === void 0 ? void 0 : _h.realtime), batchId: batchId }, instance.config.config), { globals: globals });
273
309
  if (profile === null || profile === void 0 ? void 0 : profile.branch) {
274
- controllerConfig.branch = profile === null || profile === void 0 ? void 0 : profile.branch;
310
+ controllerConfigBase.branch = profile === null || profile === void 0 ? void 0 : profile.branch;
275
311
  }
276
- controller = Object.keys(instance.controller)
277
- .map(function (id) { return instance.controller[id]; })
278
- .filter(function (controller) {
279
- return (JSON.stringify({
280
- batched: controller.config.batched,
281
- branch: controller.config.branch,
282
- globals: controller.config.globals,
283
- tag: controller.config.tag,
284
- realtime: controller.config.realtime,
285
- }) ==
286
- JSON.stringify({
287
- batched: controllerConfig.batched,
288
- branch: controllerConfig.branch,
289
- globals: controllerConfig.globals,
290
- tag: controllerConfig.tag,
291
- realtime: controllerConfig.realtime,
292
- }));
293
- })[0];
294
- if (!!controller) return [3 /*break*/, 2];
295
- return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('../create/createRecommendationController')); })];
296
- case 1:
297
- createRecommendationController = (_l.sent()).default;
298
- controller = createRecommendationController({
312
+ profileCount[tag] = profileCount[tag] + 1 || 1;
313
+ controllerConfig = __assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1) }, controllerConfigBase);
314
+ controller = (0, create_1.createRecommendationController)({
299
315
  url: instance.config.url,
300
316
  controller: controllerConfig,
301
317
  context: context,
302
318
  mode: instance.config.mode,
303
319
  }, { client: instance.client, tracker: instance.tracker });
320
+ // mark element with controller id so cleanupStaleControllers knows it's active
321
+ if (targetElem) {
322
+ targetElem.setAttribute('ss-controller-id', controller.id);
323
+ }
304
324
  instance.uses.forEach(function (attachements) { return controller.use(attachements); });
305
325
  instance.plugins.forEach(function (plugin) { return controller.plugin.apply(controller, __spreadArray([plugin.func], plugin.args, false)); });
306
326
  instance.middleware.forEach(function (middleware) { return controller.on.apply(controller, __spreadArray([middleware.event], middleware.func, false)); });
307
- _l.label = 2;
308
- case 2:
309
- if (!!controller.store.loading) return [3 /*break*/, 4];
310
- return [4 /*yield*/, controller.search()];
311
- case 3:
312
- _l.sent();
313
- _l.label = 4;
314
- case 4:
315
- controller.addTargeter(instance.targeter);
327
+ // add controller to instantiator and global namespace
316
328
  instance.controller[controller.config.id] = controller;
317
329
  window.searchspring.controller = window.searchspring.controller || {};
318
330
  window.searchspring.controller[controller.config.id] = controller;
331
+ // register targeter on the controller for element tracking
332
+ controller.addTargeter(targeter);
333
+ if (!!controller.store.loading) return [3 /*break*/, 2];
334
+ return [4 /*yield*/, controller.search()];
335
+ case 1:
336
+ _j.sent();
337
+ _j.label = 2;
338
+ case 2:
319
339
  profileVars = controller.store.profile.display.templateParameters;
320
- component = (_j = controller.store.profile.display.template) === null || _j === void 0 ? void 0 : _j.component;
321
340
  if (controller.store.error) {
322
341
  //something went wrong
323
342
  //err was already logged - nothing to do.
324
343
  return [2 /*return*/];
325
344
  }
326
345
  if (!controller.store.profile.display.template) {
327
- 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));
346
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing a template!\n").concat(scriptElem === null || scriptElem === void 0 ? void 0 : scriptElem.outerHTML));
328
347
  return [2 /*return*/];
329
348
  }
330
349
  if (!profileVars) {
331
- 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));
350
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing templateParameters!\n").concat(scriptElem === null || scriptElem === void 0 ? void 0 : scriptElem.outerHTML));
332
351
  return [2 /*return*/];
333
352
  }
353
+ if (!targetElem) return [3 /*break*/, 4];
354
+ return [4 /*yield*/, renderController(instance, controller, targetElem, scriptElem)];
355
+ case 3:
356
+ _j.sent();
357
+ _j.label = 4;
358
+ case 4: return [2 /*return*/, controller];
359
+ }
360
+ });
361
+ });
362
+ }
363
+ function renderController(instance, controller, targetElem, scriptElem) {
364
+ var _a;
365
+ return __awaiter(this, void 0, void 0, function () {
366
+ var tag, component, RecommendationsComponent, _b;
367
+ return __generator(this, function (_c) {
368
+ switch (_c.label) {
369
+ case 0:
370
+ // update the element with the controller id
371
+ if (targetElem) {
372
+ targetElem.setAttribute('ss-controller-id', controller.id);
373
+ }
374
+ tag = controller.config.tag;
375
+ component = (_a = controller.store.profile.display.template) === null || _a === void 0 ? void 0 : _a.component;
334
376
  if (!component) {
335
- 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));
377
+ instance.logger.error("profile '".concat(tag, "' found on the following element is missing a component!\n").concat(scriptElem === null || scriptElem === void 0 ? void 0 : scriptElem.outerHTML));
336
378
  return [2 /*return*/];
337
379
  }
338
- _k = instance.config.components[component];
339
- if (!_k) return [3 /*break*/, 6];
380
+ _b = instance.config.components[component];
381
+ if (!_b) return [3 /*break*/, 2];
340
382
  return [4 /*yield*/, instance.config.components[component]()];
341
- case 5:
342
- _k = (_l.sent());
343
- _l.label = 6;
344
- case 6:
345
- RecommendationsComponent = _k;
383
+ case 1:
384
+ _b = (_c.sent());
385
+ _c.label = 2;
386
+ case 2:
387
+ RecommendationsComponent = _b;
346
388
  if (!RecommendationsComponent) {
347
- 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));
389
+ instance.logger.error("profile '".concat(tag, "' found on the following element is expecting component mapping for '").concat(component, "' - verify instantiator config.\n").concat(scriptElem === null || scriptElem === void 0 ? void 0 : scriptElem.outerHTML));
348
390
  return [2 /*return*/];
349
391
  }
350
392
  setTimeout(function () {
351
- if (injectedElem) {
352
- (0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), injectedElem);
353
- }
393
+ (0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), targetElem);
354
394
  });
355
395
  return [2 /*return*/];
356
396
  }
@@ -9,7 +9,7 @@ import type { Controllers, AbstractController, SearchControllerConfig, Autocompl
9
9
  import type { TrackerConfig, TrackerGlobals } from '@searchspring/snap-tracker';
10
10
  import type { Target, OnTarget } from '@searchspring/snap-toolbox';
11
11
  import type { UrlTranslatorConfig } from '@searchspring/snap-url-manager';
12
- import { RecommendationInstantiator, RecommendationInstantiatorConfig } from './Instantiators/RecommendationInstantiator';
12
+ import type { RecommendationInstantiator, RecommendationInstantiatorConfig } from './Instantiators/RecommendationInstantiator';
13
13
  import type { SnapControllerServices, InitialUrlConfig } from './types';
14
14
  export declare const BRANCH_COOKIE = "ssBranch";
15
15
  export declare const BRANCH_PARAM = "searchspring-preview";
@@ -1 +1 @@
1
- {"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["../../src/Snap.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["../../src/Snap.tsx"],"names":[],"mappings":"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"}
@@ -57,6 +57,7 @@ export declare class RecommendationInstantiator {
57
57
  plugin(func: (cntrlr: AbstractController, ...args: any) => Promise<void>, ...args: unknown[]): void;
58
58
  on(event: string, ...func: Middleware<unknown>[]): void;
59
59
  use(attachments: Attachments): void;
60
+ cleanupStaleControllers(): void;
60
61
  }
61
62
  type DefinedProps = {
62
63
  [key: string]: any;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import { AppMode, DomTargeter, getContext } from '@searchspring/snap-toolbox';
5
5
  import { Client } from '@searchspring/snap-client';
6
6
  import { Logger } from '@searchspring/snap-logger';
7
7
  import { Tracker } from '@searchspring/snap-tracker';
8
+ import { createRecommendationController } from '../create';
8
9
  const DEFAULT_BRANCH = 'production';
9
10
  export class RecommendationInstantiator {
10
11
  constructor(config, services, context) {
@@ -40,28 +41,26 @@ export class RecommendationInstantiator {
40
41
  this.tracker = services?.tracker || new Tracker(this.config.client.globals);
41
42
  this.logger = services?.logger || new Logger({ prefix: 'RecommendationInstantiator ', mode: this.mode });
42
43
  const profileCount = {};
44
+ // script block targeter for "grouped" and "legacy" blocks
43
45
  this.targeter = new DomTargeter([
44
46
  {
45
47
  selector: `${this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]'}, script[type="searchspring/recommend"][profile="email"]`,
46
48
  autoRetarget: true,
47
49
  clickRetarget: true,
48
- inject: {
49
- action: 'before',
50
- element: (target, origElement) => {
51
- const profile = origElement.getAttribute('profile') || '';
52
- const recsContainer = document.createElement('div');
53
- recsContainer.setAttribute('searchspring-recommend', profile);
54
- return recsContainer;
55
- },
56
- },
50
+ navigationRetarget: true,
51
+ emptyTarget: false,
57
52
  },
58
53
  {
59
54
  selector: 'script[type="searchspring/recommendations"]',
60
55
  autoRetarget: true,
61
56
  clickRetarget: true,
57
+ navigationRetarget: true,
62
58
  emptyTarget: false,
63
59
  },
64
- ], async (target, elem, originalElem) => {
60
+ ], async (target, elem, _originalElem, targeter) => {
61
+ this.cleanupStaleControllers();
62
+ this.targeter = this.targeter || targeter;
63
+ const scriptElement = elem;
65
64
  const elemContext = getContext([
66
65
  'shopperId',
67
66
  'shopper',
@@ -76,7 +75,7 @@ export class RecommendationInstantiator {
76
75
  'custom',
77
76
  'profiles',
78
77
  'globals',
79
- ], (originalElem || elem));
78
+ ], scriptElement);
80
79
  if (elemContext.profiles && elemContext.profiles.length) {
81
80
  // using the "grouped block" integration structure
82
81
  // type the new profile specific integration context variables
@@ -90,34 +89,52 @@ export class RecommendationInstantiator {
90
89
  cart: scriptContextGlobals?.cart && getArrayFunc(scriptContextGlobals.cart),
91
90
  products: scriptContextGlobals?.products,
92
91
  shopper: scriptContextGlobals?.shopper?.id,
93
- batchId: Math.random(),
92
+ batchId: Math.floor(Math.random() * Number.MAX_SAFE_INTEGER),
94
93
  }),
95
94
  };
96
- const targetsArr = [];
97
- // build out the targets array for each profile
98
- scriptContextProfiles.forEach((profile) => {
95
+ // create a per-profile DomTargeter for each profile so each controller
96
+ // gets its own targeter tracking its specific element
97
+ scriptContextProfiles.forEach((profile, index) => {
99
98
  if (profile.selector) {
100
- const targetObj = {
99
+ const profileTarget = {
101
100
  selector: profile.selector,
102
101
  autoRetarget: true,
103
- clickRetarget: true,
104
102
  profile,
103
+ order: index,
105
104
  };
106
- targetsArr.push(targetObj);
107
- }
108
- });
109
- new DomTargeter(targetsArr, async (target, elem, originalElem) => {
110
- if (target.profile?.profile || target.profile?.tag) {
111
- const profileRequestGlobals = {
112
- ...requestGlobals,
113
- profile: target.profile?.options,
114
- tag: target.profile.tag || target.profile.profile, // have to support both tag and profile due to having profile at release, but will favor tag
115
- };
116
- const profileContext = deepmerge(this.context, defined({ globals: scriptContextGlobals, profile: target.profile }));
117
- if (elemContext.custom) {
118
- profileContext.custom = elemContext.custom;
119
- }
120
- readyTheController(this, elem, profileContext, profileCount, originalElem, profileRequestGlobals);
105
+ // track the controller for this profile so multiple matched elements share it
106
+ let profileControllerPromise;
107
+ new DomTargeter([profileTarget], async (target, targetElem, _originalElem, targeter) => {
108
+ // skip retarget if the source script element was removed and release the current target
109
+ if (!scriptElement.isConnected) {
110
+ if (targetElem) {
111
+ targeter?.releaseTargets([targetElem]);
112
+ }
113
+ return;
114
+ }
115
+ if (target.profile?.profile || target.profile?.tag) {
116
+ const profileRequestGlobals = {
117
+ ...requestGlobals,
118
+ profile: { ...target.profile?.options, order: target.order },
119
+ tag: target.profile.tag || target.profile.profile, // have to support both tag and profile due to having profile at release, but will favor tag
120
+ };
121
+ const profileContext = deepmerge(this.context, defined({ globals: scriptContextGlobals, profile: target.profile }));
122
+ if (elemContext.custom) {
123
+ profileContext.custom = elemContext.custom;
124
+ }
125
+ if (!profileControllerPromise) {
126
+ // first element match — create the controller
127
+ profileControllerPromise = readyTheController(this, targetElem, profileContext, profileCount, scriptElement, profileRequestGlobals, targeter);
128
+ }
129
+ else {
130
+ // subsequent element matches — reuse the existing controller and just render
131
+ const controller = await profileControllerPromise;
132
+ if (controller && targetElem) {
133
+ renderController(this, controller, targetElem, scriptElement);
134
+ }
135
+ }
136
+ }
137
+ });
121
138
  }
122
139
  });
123
140
  }
@@ -137,7 +154,23 @@ export class RecommendationInstantiator {
137
154
  profile: options,
138
155
  }),
139
156
  };
140
- readyTheController(this, elem, deepmerge(this.context, elemContext), profileCount, originalElem, profileRequestGlobals);
157
+ // inject a render container before the script element
158
+ const profileAttr = scriptElement.getAttribute('profile') || '';
159
+ const recsContainer = document.createElement('div');
160
+ recsContainer.setAttribute('searchspring-recommend', profileAttr);
161
+ scriptElement.before(recsContainer);
162
+ const legacyContext = deepmerge(this.context, elemContext);
163
+ // create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
164
+ new DomTargeter([{ selector: `[searchspring-recommend="${profileAttr}"]`, name: `legacy_${profile}_${profileCount[profile || ''] || 0}` }], async (_target, targetElem, _originalElem, targeter) => {
165
+ // skip retarget if the source script element was removed and release the current target
166
+ if (!scriptElement.isConnected) {
167
+ if (targetElem) {
168
+ targeter?.releaseTargets([targetElem]);
169
+ }
170
+ return;
171
+ }
172
+ readyTheController(this, targetElem, legacyContext, profileCount, scriptElement, profileRequestGlobals, targeter);
173
+ });
141
174
  }
142
175
  });
143
176
  }
@@ -150,26 +183,43 @@ export class RecommendationInstantiator {
150
183
  use(attachments) {
151
184
  this.uses.push(attachments);
152
185
  }
186
+ // cleanup to ensure we release controllers no longer rendering in the DOM (memory leak prevention for SPA's)
187
+ cleanupStaleControllers() {
188
+ Object.keys(this.controller).forEach((id) => {
189
+ const controller = this.controller[id];
190
+ const targeters = Object.values(controller.targeters);
191
+ const hasConnectedTarget = targeters.some((targeter) => targeter.getTargetedElems().some((elem) => {
192
+ const attr = elem.isConnected && elem.getAttribute('ss-controller-id');
193
+ return attr === id;
194
+ }));
195
+ if (!hasConnectedTarget) {
196
+ Object.keys(controller.targeters).forEach((targeterId) => controller.targeters[targeterId].destroy());
197
+ controller.targeters = {};
198
+ delete this.controller[id];
199
+ if (window.searchspring?.controller) {
200
+ delete window.searchspring.controller[id];
201
+ }
202
+ }
203
+ });
204
+ }
153
205
  }
154
- async function readyTheController(instance, injectedElem, context, profileCount, elem, controllerGlobals) {
206
+ async function readyTheController(instance, targetElem, context, profileCount, scriptElem, controllerGlobals, targeter) {
155
207
  const { profile, batchId, cart, tag } = controllerGlobals;
156
208
  const batched = profile?.batched ?? controllerGlobals.batched ?? true;
157
209
  if (!tag) {
158
210
  // FEEDBACK: change message depending on script integration type (profile vs. legacy)
159
- instance.logger.warn(`'tag' is missing from <script> tag, skipping this profile`, elem);
211
+ instance.logger.warn(`'tag' is missing from <script> tag, skipping this profile`, scriptElem);
160
212
  return;
161
213
  }
162
214
  if (Array.isArray(cart)) {
163
215
  instance.tracker.cookies.cart.set(cart);
164
216
  }
165
- profileCount[tag] = profileCount[tag] + 1 || 1;
166
217
  const globals = deepmerge.all([
167
218
  instance.config.client?.globals || {},
168
219
  instance.config.config?.globals || {},
169
220
  controllerGlobals,
170
221
  ]);
171
- const controllerConfig = {
172
- id: `recommend_${tag}_${profileCount[tag] - 1}`,
222
+ const controllerConfigBase = {
173
223
  tag,
174
224
  batched: batched ?? true,
175
225
  realtime: Boolean(context.options?.realtime ?? context.profile?.options?.realtime),
@@ -178,77 +228,74 @@ async function readyTheController(instance, injectedElem, context, profileCount,
178
228
  globals,
179
229
  };
180
230
  if (profile?.branch) {
181
- controllerConfig.branch = profile?.branch;
231
+ controllerConfigBase.branch = profile?.branch;
182
232
  }
183
- // try to find an existing controller by similar configuration
184
- let controller = Object.keys(instance.controller)
185
- .map((id) => instance.controller[id])
186
- .filter((controller) => {
187
- return (JSON.stringify({
188
- batched: controller.config.batched,
189
- branch: controller.config.branch,
190
- globals: controller.config.globals,
191
- tag: controller.config.tag,
192
- realtime: controller.config.realtime,
193
- }) ==
194
- JSON.stringify({
195
- batched: controllerConfig.batched,
196
- branch: controllerConfig.branch,
197
- globals: controllerConfig.globals,
198
- tag: controllerConfig.tag,
199
- realtime: controllerConfig.realtime,
200
- }));
201
- })[0];
202
- if (!controller) {
203
- // no existing controller found of same configuration - creating a new controller
204
- const createRecommendationController = (await import('../create/createRecommendationController')).default;
205
- controller = createRecommendationController({
206
- url: instance.config.url,
207
- controller: controllerConfig,
208
- context,
209
- mode: instance.config.mode,
210
- }, { client: instance.client, tracker: instance.tracker });
211
- instance.uses.forEach((attachements) => controller.use(attachements));
212
- instance.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
213
- instance.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
233
+ profileCount[tag] = profileCount[tag] + 1 || 1;
234
+ const controllerConfig = {
235
+ id: `recommend_${tag}_${profileCount[tag] - 1}`,
236
+ ...controllerConfigBase,
237
+ };
238
+ const controller = createRecommendationController({
239
+ url: instance.config.url,
240
+ controller: controllerConfig,
241
+ context,
242
+ mode: instance.config.mode,
243
+ }, { client: instance.client, tracker: instance.tracker });
244
+ // mark element with controller id so cleanupStaleControllers knows it's active
245
+ if (targetElem) {
246
+ targetElem.setAttribute('ss-controller-id', controller.id);
214
247
  }
248
+ instance.uses.forEach((attachements) => controller.use(attachements));
249
+ instance.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
250
+ instance.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
251
+ // add controller to instantiator and global namespace
252
+ instance.controller[controller.config.id] = controller;
253
+ window.searchspring.controller = window.searchspring.controller || {};
254
+ window.searchspring.controller[controller.config.id] = controller;
255
+ // register targeter on the controller for element tracking
256
+ controller.addTargeter(targeter);
215
257
  // run a search on the controller if it is not currently
216
258
  if (!controller.store.loading) {
217
259
  await controller.search();
218
260
  }
219
- controller.addTargeter(instance.targeter);
220
- instance.controller[controller.config.id] = controller;
221
- window.searchspring.controller = window.searchspring.controller || {};
222
- window.searchspring.controller[controller.config.id] = controller;
223
261
  const profileVars = controller.store.profile.display.templateParameters;
224
- const component = controller.store.profile.display.template?.component;
225
262
  if (controller.store.error) {
226
263
  //something went wrong
227
264
  //err was already logged - nothing to do.
228
265
  return;
229
266
  }
230
267
  if (!controller.store.profile.display.template) {
231
- instance.logger.error(`profile '${tag}' found on the following element is missing a template!\n${elem?.outerHTML}`);
268
+ instance.logger.error(`profile '${tag}' found on the following element is missing a template!\n${scriptElem?.outerHTML}`);
232
269
  return;
233
270
  }
234
271
  if (!profileVars) {
235
- instance.logger.error(`profile '${tag}' found on the following element is missing templateParameters!\n${elem?.outerHTML}`);
272
+ instance.logger.error(`profile '${tag}' found on the following element is missing templateParameters!\n${scriptElem?.outerHTML}`);
236
273
  return;
237
274
  }
275
+ if (targetElem) {
276
+ await renderController(instance, controller, targetElem, scriptElem);
277
+ }
278
+ return controller;
279
+ }
280
+ async function renderController(instance, controller, targetElem, scriptElem) {
281
+ // update the element with the controller id
282
+ if (targetElem) {
283
+ targetElem.setAttribute('ss-controller-id', controller.id);
284
+ }
285
+ const tag = controller.config.tag;
286
+ const component = controller.store.profile.display.template?.component;
238
287
  if (!component) {
239
- instance.logger.error(`profile '${tag}' found on the following element is missing a component!\n${elem?.outerHTML}`);
288
+ instance.logger.error(`profile '${tag}' found on the following element is missing a component!\n${scriptElem?.outerHTML}`);
240
289
  return;
241
290
  }
242
291
  const RecommendationsComponent = instance.config.components[component] &&
243
292
  (await instance.config.components[component]());
244
293
  if (!RecommendationsComponent) {
245
- instance.logger.error(`profile '${tag}' found on the following element is expecting component mapping for '${component}' - verify instantiator config.\n${elem?.outerHTML}`);
294
+ instance.logger.error(`profile '${tag}' found on the following element is expecting component mapping for '${component}' - verify instantiator config.\n${scriptElem?.outerHTML}`);
246
295
  return;
247
296
  }
248
297
  setTimeout(() => {
249
- if (injectedElem) {
250
- render(_jsx(RecommendationsComponent, { controller: controller }), injectedElem);
251
- }
298
+ render(_jsx(RecommendationsComponent, { controller: controller }), targetElem);
252
299
  });
253
300
  }
254
301
  function getArrayFunc(arrayOrFunc) {
@@ -9,7 +9,7 @@ import type { Controllers, AbstractController, SearchControllerConfig, Autocompl
9
9
  import type { TrackerConfig, TrackerGlobals } from '@searchspring/snap-tracker';
10
10
  import type { Target, OnTarget } from '@searchspring/snap-toolbox';
11
11
  import type { UrlTranslatorConfig } from '@searchspring/snap-url-manager';
12
- import { RecommendationInstantiator, RecommendationInstantiatorConfig } from './Instantiators/RecommendationInstantiator';
12
+ import type { RecommendationInstantiator, RecommendationInstantiatorConfig } from './Instantiators/RecommendationInstantiator';
13
13
  import type { SnapControllerServices, InitialUrlConfig } from './types';
14
14
  export declare const BRANCH_COOKIE = "ssBranch";
15
15
  export declare const BRANCH_PARAM = "searchspring-preview";
@@ -1 +1 @@
1
- {"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["../../src/Snap.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["../../src/Snap.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searchspring/snap-preact",
3
- "version": "0.76.1",
3
+ "version": "0.78.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.76.1",
24
- "@searchspring/snap-controller": "0.76.1",
25
- "@searchspring/snap-event-manager": "0.76.1",
26
- "@searchspring/snap-logger": "0.76.1",
27
- "@searchspring/snap-platforms": "0.76.1",
28
- "@searchspring/snap-preact-components": "0.76.1",
29
- "@searchspring/snap-profiler": "0.76.1",
30
- "@searchspring/snap-store-mobx": "0.76.1",
31
- "@searchspring/snap-toolbox": "0.76.1",
32
- "@searchspring/snap-tracker": "0.76.1",
33
- "@searchspring/snap-url-manager": "0.76.1",
23
+ "@searchspring/snap-client": "0.78.0",
24
+ "@searchspring/snap-controller": "0.78.0",
25
+ "@searchspring/snap-event-manager": "0.78.0",
26
+ "@searchspring/snap-logger": "0.78.0",
27
+ "@searchspring/snap-platforms": "0.78.0",
28
+ "@searchspring/snap-preact-components": "0.78.0",
29
+ "@searchspring/snap-profiler": "0.78.0",
30
+ "@searchspring/snap-store-mobx": "0.78.0",
31
+ "@searchspring/snap-toolbox": "0.78.0",
32
+ "@searchspring/snap-tracker": "0.78.0",
33
+ "@searchspring/snap-url-manager": "0.78.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": "c834b949788f37cd5265f227e7416280587f6989"
46
+ "gitHead": "9d17504d1ba3b5131c4edeb0cb1edb6ff65ec1b0"
47
47
  }