@searchspring/snap-preact 0.77.0 → 0.79.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.
@@ -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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"}
@@ -111,20 +111,22 @@ var RecommendationInstantiator = /** @class */ (function () {
111
111
  selector: "".concat(this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]', ", script[type=\"searchspring/recommend\"][profile=\"email\"]"),
112
112
  autoRetarget: true,
113
113
  clickRetarget: true,
114
+ navigationRetarget: true,
114
115
  emptyTarget: false,
115
116
  },
116
117
  {
117
118
  selector: 'script[type="searchspring/recommendations"]',
118
119
  autoRetarget: true,
119
120
  clickRetarget: true,
121
+ navigationRetarget: true,
120
122
  emptyTarget: false,
121
123
  },
122
- ], function (target, elem, _originalElem, targeter) { return __awaiter(_this, void 0, void 0, function () {
124
+ ], function (target, elem) { return __awaiter(_this, void 0, void 0, function () {
123
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;
124
126
  var _this = this;
125
127
  var _a;
126
128
  return __generator(this, function (_b) {
127
- this.targeter = this.targeter || targeter;
129
+ this.cleanupStaleControllers();
128
130
  scriptElement = elem;
129
131
  elemContext = (0, snap_toolbox_1.getContext)([
130
132
  'shopperId',
@@ -154,12 +156,13 @@ var RecommendationInstantiator = /** @class */ (function () {
154
156
  }));
155
157
  // create a per-profile DomTargeter for each profile so each controller
156
158
  // gets its own targeter tracking its specific element
157
- scriptContextProfiles.forEach(function (profile) {
159
+ scriptContextProfiles.forEach(function (profile, index) {
158
160
  if (profile.selector) {
159
161
  var profileTarget = {
160
162
  selector: profile.selector,
161
163
  autoRetarget: true,
162
164
  profile: profile,
165
+ order: index,
163
166
  };
164
167
  // track the controller for this profile so multiple matched elements share it
165
168
  var profileControllerPromise_1;
@@ -169,15 +172,18 @@ var RecommendationInstantiator = /** @class */ (function () {
169
172
  return __generator(this, function (_d) {
170
173
  switch (_d.label) {
171
174
  case 0:
172
- // skip retarget if the source script element was removed from the DOM (SPA navigation)
173
- if (!scriptElement.isConnected) {
175
+ // skip retarget if the source script element was removed and release the current target
176
+ if (scriptElement.isConnected === false) {
177
+ if (targetElem) {
178
+ targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
179
+ }
174
180
  return [2 /*return*/];
175
181
  }
176
182
  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];
177
- profileRequestGlobals = __assign(__assign({}, requestGlobals_1), { profile: (_c = target.profile) === null || _c === void 0 ? void 0 : _c.options, tag: target.profile.tag || target.profile.profile });
183
+ 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 });
178
184
  profileContext = (0, deepmerge_1.default)(this.context, defined({ globals: scriptContextGlobals_1, profile: target.profile }));
179
185
  if (elemContext.custom) {
180
- profileContext.custom = elemContext.custom;
186
+ profileContext.custom = (0, deepmerge_1.default)(profileContext.custom, elemContext.custom);
181
187
  }
182
188
  if (!!profileControllerPromise_1) return [3 /*break*/, 1];
183
189
  // first element match — create the controller
@@ -217,8 +223,11 @@ var RecommendationInstantiator = /** @class */ (function () {
217
223
  // create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
218
224
  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 () {
219
225
  return __generator(this, function (_a) {
220
- // skip retarget if the source script element was removed from the DOM (SPA navigation)
221
- if (!scriptElement.isConnected) {
226
+ // skip retarget if the source script element was removed and release the current target
227
+ if (scriptElement.isConnected === false) {
228
+ if (targetElem) {
229
+ targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
230
+ }
222
231
  return [2 /*return*/];
223
232
  }
224
233
  readyTheController(this, targetElem, legacyContext_1, profileCount, scriptElement, profileRequestGlobals_1, targeter);
@@ -254,8 +263,14 @@ var RecommendationInstantiator = /** @class */ (function () {
254
263
  var _a;
255
264
  var controller = _this.controller[id];
256
265
  var targeters = Object.values(controller.targeters);
257
- var hasConnectedTarget = targeters.some(function (targeter) { return targeter.getTargetedElems().some(function (elem) { return elem.isConnected; }); });
266
+ var hasConnectedTarget = targeters.some(function (targeter) {
267
+ return targeter.getTargetedElems().some(function (elem) {
268
+ var attr = elem.isConnected !== false && elem.getAttribute('ss-controller-id');
269
+ return attr === id;
270
+ });
271
+ });
258
272
  if (!hasConnectedTarget) {
273
+ Object.keys(controller.targeters).forEach(function (targeterId) { return controller.targeters[targeterId].destroy(); });
259
274
  controller.targeters = {};
260
275
  delete _this.controller[id];
261
276
  if ((_a = window.searchspring) === null || _a === void 0 ? void 0 : _a.controller) {
@@ -293,8 +308,6 @@ function readyTheController(instance, targetElem, context, profileCount, scriptE
293
308
  if (profile === null || profile === void 0 ? void 0 : profile.branch) {
294
309
  controllerConfigBase.branch = profile === null || profile === void 0 ? void 0 : profile.branch;
295
310
  }
296
- // clean up controllers whose rendered elements are no longer in the DOM (SPA navigation)
297
- instance.cleanupStaleControllers();
298
311
  profileCount[tag] = profileCount[tag] + 1 || 1;
299
312
  controllerConfig = __assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1) }, controllerConfigBase);
300
313
  controller = (0, create_1.createRecommendationController)({
@@ -303,6 +316,10 @@ function readyTheController(instance, targetElem, context, profileCount, scriptE
303
316
  context: context,
304
317
  mode: instance.config.mode,
305
318
  }, { client: instance.client, tracker: instance.tracker });
319
+ // mark element with controller id so cleanupStaleControllers knows it's active
320
+ if (targetElem) {
321
+ targetElem.setAttribute('ss-controller-id', controller.id);
322
+ }
306
323
  instance.uses.forEach(function (attachements) { return controller.use(attachements); });
307
324
  instance.plugins.forEach(function (plugin) { return controller.plugin.apply(controller, __spreadArray([plugin.func], plugin.args, false)); });
308
325
  instance.middleware.forEach(function (middleware) { return controller.on.apply(controller, __spreadArray([middleware.event], middleware.func, false)); });
@@ -349,6 +366,10 @@ function renderController(instance, controller, targetElem, scriptElem) {
349
366
  return __generator(this, function (_c) {
350
367
  switch (_c.label) {
351
368
  case 0:
369
+ // update the element with the controller id
370
+ if (targetElem) {
371
+ targetElem.setAttribute('ss-controller-id', controller.id);
372
+ }
352
373
  tag = controller.config.tag;
353
374
  component = (_a = controller.store.profile.display.template) === null || _a === void 0 ? void 0 : _a.component;
354
375
  if (!component) {
@@ -368,7 +389,6 @@ function renderController(instance, controller, targetElem, scriptElem) {
368
389
  return [2 /*return*/];
369
390
  }
370
391
  setTimeout(function () {
371
- targetElem.setAttribute('ss-controller-id', controller.config.id);
372
392
  (0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), targetElem);
373
393
  });
374
394
  return [2 /*return*/];
@@ -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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"}
@@ -47,16 +47,18 @@ export class RecommendationInstantiator {
47
47
  selector: `${this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]'}, script[type="searchspring/recommend"][profile="email"]`,
48
48
  autoRetarget: true,
49
49
  clickRetarget: true,
50
+ navigationRetarget: true,
50
51
  emptyTarget: false,
51
52
  },
52
53
  {
53
54
  selector: 'script[type="searchspring/recommendations"]',
54
55
  autoRetarget: true,
55
56
  clickRetarget: true,
57
+ navigationRetarget: true,
56
58
  emptyTarget: false,
57
59
  },
58
- ], async (target, elem, _originalElem, targeter) => {
59
- this.targeter = this.targeter || targeter;
60
+ ], async (target, elem) => {
61
+ this.cleanupStaleControllers();
60
62
  const scriptElement = elem;
61
63
  const elemContext = getContext([
62
64
  'shopperId',
@@ -91,29 +93,33 @@ export class RecommendationInstantiator {
91
93
  };
92
94
  // create a per-profile DomTargeter for each profile so each controller
93
95
  // gets its own targeter tracking its specific element
94
- scriptContextProfiles.forEach((profile) => {
96
+ scriptContextProfiles.forEach((profile, index) => {
95
97
  if (profile.selector) {
96
98
  const profileTarget = {
97
99
  selector: profile.selector,
98
100
  autoRetarget: true,
99
101
  profile,
102
+ order: index,
100
103
  };
101
104
  // track the controller for this profile so multiple matched elements share it
102
105
  let profileControllerPromise;
103
106
  new DomTargeter([profileTarget], async (target, targetElem, _originalElem, targeter) => {
104
- // skip retarget if the source script element was removed from the DOM (SPA navigation)
105
- if (!scriptElement.isConnected) {
107
+ // skip retarget if the source script element was removed and release the current target
108
+ if (scriptElement.isConnected === false) {
109
+ if (targetElem) {
110
+ targeter?.releaseTargets([targetElem]);
111
+ }
106
112
  return;
107
113
  }
108
114
  if (target.profile?.profile || target.profile?.tag) {
109
115
  const profileRequestGlobals = {
110
116
  ...requestGlobals,
111
- profile: target.profile?.options,
117
+ profile: { ...target.profile?.options, order: target.order },
112
118
  tag: target.profile.tag || target.profile.profile, // have to support both tag and profile due to having profile at release, but will favor tag
113
119
  };
114
120
  const profileContext = deepmerge(this.context, defined({ globals: scriptContextGlobals, profile: target.profile }));
115
121
  if (elemContext.custom) {
116
- profileContext.custom = elemContext.custom;
122
+ profileContext.custom = deepmerge(profileContext.custom, elemContext.custom);
117
123
  }
118
124
  if (!profileControllerPromise) {
119
125
  // first element match — create the controller
@@ -155,8 +161,11 @@ export class RecommendationInstantiator {
155
161
  const legacyContext = deepmerge(this.context, elemContext);
156
162
  // create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
157
163
  new DomTargeter([{ selector: `[searchspring-recommend="${profileAttr}"]`, name: `legacy_${profile}_${profileCount[profile || ''] || 0}` }], async (_target, targetElem, _originalElem, targeter) => {
158
- // skip retarget if the source script element was removed from the DOM (SPA navigation)
159
- if (!scriptElement.isConnected) {
164
+ // skip retarget if the source script element was removed and release the current target
165
+ if (scriptElement.isConnected === false) {
166
+ if (targetElem) {
167
+ targeter?.releaseTargets([targetElem]);
168
+ }
160
169
  return;
161
170
  }
162
171
  readyTheController(this, targetElem, legacyContext, profileCount, scriptElement, profileRequestGlobals, targeter);
@@ -178,8 +187,12 @@ export class RecommendationInstantiator {
178
187
  Object.keys(this.controller).forEach((id) => {
179
188
  const controller = this.controller[id];
180
189
  const targeters = Object.values(controller.targeters);
181
- const hasConnectedTarget = targeters.some((targeter) => targeter.getTargetedElems().some((elem) => elem.isConnected));
190
+ const hasConnectedTarget = targeters.some((targeter) => targeter.getTargetedElems().some((elem) => {
191
+ const attr = elem.isConnected !== false && elem.getAttribute('ss-controller-id');
192
+ return attr === id;
193
+ }));
182
194
  if (!hasConnectedTarget) {
195
+ Object.keys(controller.targeters).forEach((targeterId) => controller.targeters[targeterId].destroy());
183
196
  controller.targeters = {};
184
197
  delete this.controller[id];
185
198
  if (window.searchspring?.controller) {
@@ -216,8 +229,6 @@ async function readyTheController(instance, targetElem, context, profileCount, s
216
229
  if (profile?.branch) {
217
230
  controllerConfigBase.branch = profile?.branch;
218
231
  }
219
- // clean up controllers whose rendered elements are no longer in the DOM (SPA navigation)
220
- instance.cleanupStaleControllers();
221
232
  profileCount[tag] = profileCount[tag] + 1 || 1;
222
233
  const controllerConfig = {
223
234
  id: `recommend_${tag}_${profileCount[tag] - 1}`,
@@ -229,6 +240,10 @@ async function readyTheController(instance, targetElem, context, profileCount, s
229
240
  context,
230
241
  mode: instance.config.mode,
231
242
  }, { client: instance.client, tracker: instance.tracker });
243
+ // mark element with controller id so cleanupStaleControllers knows it's active
244
+ if (targetElem) {
245
+ targetElem.setAttribute('ss-controller-id', controller.id);
246
+ }
232
247
  instance.uses.forEach((attachements) => controller.use(attachements));
233
248
  instance.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
234
249
  instance.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
@@ -262,6 +277,10 @@ async function readyTheController(instance, targetElem, context, profileCount, s
262
277
  return controller;
263
278
  }
264
279
  async function renderController(instance, controller, targetElem, scriptElem) {
280
+ // update the element with the controller id
281
+ if (targetElem) {
282
+ targetElem.setAttribute('ss-controller-id', controller.id);
283
+ }
265
284
  const tag = controller.config.tag;
266
285
  const component = controller.store.profile.display.template?.component;
267
286
  if (!component) {
@@ -275,7 +294,6 @@ async function renderController(instance, controller, targetElem, scriptElem) {
275
294
  return;
276
295
  }
277
296
  setTimeout(() => {
278
- targetElem.setAttribute('ss-controller-id', controller.config.id);
279
297
  render(_jsx(RecommendationsComponent, { controller: controller }), targetElem);
280
298
  });
281
299
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searchspring/snap-preact",
3
- "version": "0.77.0",
3
+ "version": "0.79.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.77.0",
24
- "@searchspring/snap-controller": "0.77.0",
25
- "@searchspring/snap-event-manager": "0.77.0",
26
- "@searchspring/snap-logger": "0.77.0",
27
- "@searchspring/snap-platforms": "0.77.0",
28
- "@searchspring/snap-preact-components": "0.77.0",
29
- "@searchspring/snap-profiler": "0.77.0",
30
- "@searchspring/snap-store-mobx": "0.77.0",
31
- "@searchspring/snap-toolbox": "0.77.0",
32
- "@searchspring/snap-tracker": "0.77.0",
33
- "@searchspring/snap-url-manager": "0.77.0",
23
+ "@searchspring/snap-client": "0.79.0",
24
+ "@searchspring/snap-controller": "0.79.0",
25
+ "@searchspring/snap-event-manager": "0.79.0",
26
+ "@searchspring/snap-logger": "0.79.0",
27
+ "@searchspring/snap-platforms": "0.79.0",
28
+ "@searchspring/snap-preact-components": "0.79.0",
29
+ "@searchspring/snap-profiler": "0.79.0",
30
+ "@searchspring/snap-store-mobx": "0.79.0",
31
+ "@searchspring/snap-toolbox": "0.79.0",
32
+ "@searchspring/snap-tracker": "0.79.0",
33
+ "@searchspring/snap-url-manager": "0.79.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": "d7a25a5ade47e4561f49af70f6f929b7331cd15e"
46
+ "gitHead": "909e8cfd98fae2c6de81de2e9b0c68e07649f76f"
47
47
  }