@useinsider/guido 3.21.0-beta.7e166b5 → 3.21.0-beta.8a9421f
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.
- package/README.md +34 -4
- package/dist/components/Guido.vue.js +3 -3
- package/dist/components/Guido.vue2.js +118 -108
- package/dist/composables/useEditorOpenMetrics.js +164 -0
- package/dist/composables/useStripo.js +94 -82
- package/dist/extensions/Blocks/Recommendation/block.js +108 -84
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +38 -34
- package/dist/guido.css +1 -1
- package/dist/library.js +12 -10
- package/dist/package.json.js +6 -4
- package/dist/public/prefetchRuntime.js +4 -0
- package/dist/src/composables/useEditorOpenMetrics.d.ts +27 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +15 -10
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +2 -0
- package/dist/src/library.d.ts +1 -0
- package/dist/src/public/prefetchRuntime.d.ts +1 -0
- package/dist/src/utils/runtimePrefetch.d.ts +4 -0
- package/dist/src/utils/stripoRuntime.d.ts +2 -0
- package/dist/static/stripo-runtime-manifest.json.js +9 -0
- package/dist/utils/runtimePrefetch.js +26 -0
- package/dist/utils/stripoRuntime.js +9 -0
- package/package.json +6 -1
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
var A = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useConfig as
|
|
5
|
-
import { BlockId as
|
|
6
|
-
import { getMigrationBannerHtml as
|
|
7
|
-
import { Block as S, BlockCompositionType as
|
|
8
|
-
import { CURRENT_CONFIG_VERSION as
|
|
9
|
-
import { RECOMMENDATION_ID_ATTR as
|
|
2
|
+
var D = (m, c, e) => c in m ? A(m, c, { enumerable: !0, configurable: !0, writable: !0, value: e }) : m[c] = e;
|
|
3
|
+
var u = (m, c, e) => D(m, typeof c != "symbol" ? c + "" : c, e);
|
|
4
|
+
import { useConfig as g } from "../../../composables/useConfig.js";
|
|
5
|
+
import { BlockId as b } from "../../../enums/block.js";
|
|
6
|
+
import { getMigrationBannerHtml as E } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as S, BlockCompositionType as v, ModificationDescription as _ } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { CURRENT_CONFIG_VERSION as N, PRE_RRS_CONFIG_VERSION as w } from "./constants/defaultConfig.js";
|
|
9
|
+
import { RECOMMENDATION_ID_ATTR as f } from "./constants/selectors.js";
|
|
10
10
|
import { regenerateMobileProductRows as M } from "./controls/main/utils.js";
|
|
11
11
|
import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as R, hasMobileLayoutOptOut as O } from "./controls/mobileLayout/cssRules.js";
|
|
12
|
-
import { RecommendationConfigService as
|
|
13
|
-
import { useRecommendationExtensionStore as
|
|
12
|
+
import { RecommendationConfigService as a } from "./services/configService.js";
|
|
13
|
+
import { useRecommendationExtensionStore as p } from "./store/recommendation.js";
|
|
14
14
|
import { getDefaultTemplate as T } from "./templates/grid/template.js";
|
|
15
15
|
import { useRecommendationBlockWarning as x } from "./useRecommendationBlockWarning.js";
|
|
16
|
-
import { registerNodeConfigWriter as k } from "./utils/nodeConfigWriter.js";
|
|
17
|
-
import { refreshArrivedStrategyBlocks as
|
|
18
|
-
const y =
|
|
19
|
-
let
|
|
20
|
-
class
|
|
16
|
+
import { registerNodeConfigWriter as k, readBlockNodeConfigs as $ } from "./utils/nodeConfigWriter.js";
|
|
17
|
+
import { refreshArrivedStrategyBlocks as q, resolveSourceConfig as H, refreshDuplicatedStrategyBlocks as F } from "./utils/strategyCommit.js";
|
|
18
|
+
const y = b.Recommendation, d = "recommendation-block-v2", C = "hide-price";
|
|
19
|
+
let B = !1;
|
|
20
|
+
class te extends S {
|
|
21
21
|
constructor() {
|
|
22
22
|
super();
|
|
23
23
|
/**
|
|
24
24
|
* Stores the ID generated in getTemplate() so onCreated() can reuse it.
|
|
25
25
|
* This avoids generating a new (different) ID in onCreated().
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
u(this, "_pendingBlockId", null);
|
|
28
28
|
/** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
|
|
29
|
-
|
|
29
|
+
u(this, "_resetSourceIds", /* @__PURE__ */ new Set());
|
|
30
30
|
/** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
|
|
31
|
+
u(this, "_unsettledDuplicateIds", /* @__PURE__ */ new Set());
|
|
32
|
+
u(this, "_arrivedBlocks", []);
|
|
33
|
+
/** Strategy each in-flight arrival or duplicate refresh is fetching, by block id, so a second one does not race it. */
|
|
34
|
+
u(this, "_refreshClaims", /* @__PURE__ */ new Map());
|
|
35
35
|
}
|
|
36
36
|
getId() {
|
|
37
37
|
return y;
|
|
@@ -40,7 +40,7 @@ class Z extends S {
|
|
|
40
40
|
return "recommendation-icon";
|
|
41
41
|
}
|
|
42
42
|
getBlockCompositionType() {
|
|
43
|
-
return
|
|
43
|
+
return v.CONTAINER;
|
|
44
44
|
}
|
|
45
45
|
getName() {
|
|
46
46
|
return this.api.translate("Recommendation Block");
|
|
@@ -51,7 +51,7 @@ class Z extends S {
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
getSettingsPanelTitleHtml() {
|
|
54
|
-
return
|
|
54
|
+
return E(
|
|
55
55
|
y,
|
|
56
56
|
this.api.translate("Recommendation Block"),
|
|
57
57
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
|
|
@@ -87,14 +87,13 @@ class Z extends S {
|
|
|
87
87
|
onCreated(e) {
|
|
88
88
|
const t = this._getRecommendationId(e);
|
|
89
89
|
if (t !== null && t > 0) {
|
|
90
|
-
if (this._detectDuplicate(t)) {
|
|
90
|
+
if (this._pendingBlockId = null, this._detectDuplicate(t)) {
|
|
91
91
|
this._handleDuplicate(e, t), this._scheduleArrivalReset(e);
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
const g = this._pendingBlockId === null;
|
|
95
94
|
setTimeout(() => {
|
|
96
95
|
if (this._getBlockElement(e)) {
|
|
97
|
-
if (
|
|
96
|
+
if (this._detectDuplicate(t)) {
|
|
98
97
|
this._handleDuplicate(e, t);
|
|
99
98
|
return;
|
|
100
99
|
}
|
|
@@ -105,34 +104,34 @@ class Z extends S {
|
|
|
105
104
|
}
|
|
106
105
|
const i = this._pendingBlockId ?? this._generateNextId();
|
|
107
106
|
this._pendingBlockId = null, this._assignRecommendationId(e, i);
|
|
108
|
-
const r =
|
|
107
|
+
const r = g().isFeatureEnabled("reusableRecommendationStrategy"), s = r && !a.hasConfig(e), { config: n, wasFreshDrop: o } = a.initializeConfig(
|
|
109
108
|
this.api,
|
|
110
109
|
e,
|
|
111
110
|
{
|
|
112
111
|
recommendationId: i,
|
|
113
|
-
configVersion: r ?
|
|
114
|
-
...s ? { partnerName:
|
|
112
|
+
configVersion: r ? N : w,
|
|
113
|
+
...s ? { partnerName: g().partnerName.value } : {},
|
|
115
114
|
// An RRS block picks a strategy, not an algorithm, and its algorithm control is
|
|
116
115
|
// hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
|
|
117
116
|
// at save for a block the user never configured.
|
|
118
117
|
...s ? { strategy: "" } : {}
|
|
119
118
|
}
|
|
120
|
-
),
|
|
121
|
-
if (
|
|
119
|
+
), l = p();
|
|
120
|
+
if (l.setCurrentBlock(i), this._stampHidePrice(e, n.priceHideIfSameAsDiscounted), o) {
|
|
122
121
|
I(this.api);
|
|
123
|
-
const
|
|
124
|
-
|
|
122
|
+
const h = this._getBlockElement(e);
|
|
123
|
+
h && (R(this.api, h, !0), M({
|
|
125
124
|
currentNode: e,
|
|
126
125
|
documentModifier: this.api.getDocumentModifier()
|
|
127
126
|
}));
|
|
128
127
|
}
|
|
129
|
-
|
|
128
|
+
l.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
|
|
130
129
|
}
|
|
131
130
|
/** Refreshes every block of an opened template: Stripo restores a stored document without `onCreated`. */
|
|
132
131
|
onDocumentInit() {
|
|
133
132
|
try {
|
|
134
133
|
const e = this.api.getDocumentRoot();
|
|
135
|
-
e && "querySelectorAll" in e && e.querySelectorAll(`.${
|
|
134
|
+
e && "querySelectorAll" in e && e.querySelectorAll(`.${d}`).forEach((t) => this._queueArrivalRefresh(t));
|
|
136
135
|
} catch (e) {
|
|
137
136
|
console.error("[recommendation] refreshing an opened strategy failed", e);
|
|
138
137
|
}
|
|
@@ -148,17 +147,17 @@ class Z extends S {
|
|
|
148
147
|
if (!(!e || !("getNodeConfig" in e))) {
|
|
149
148
|
if (!this._getRecommendationId(e)) {
|
|
150
149
|
const t = this._generateNextId();
|
|
151
|
-
this._assignRecommendationId(e, t),
|
|
150
|
+
this._assignRecommendationId(e, t), a.hasConfig(e) && a.updateConfig(
|
|
152
151
|
this.api,
|
|
153
152
|
e,
|
|
154
153
|
{ recommendationId: t },
|
|
155
154
|
"Assign recommendation ID to legacy block"
|
|
156
155
|
);
|
|
157
156
|
}
|
|
158
|
-
this._healLingeringDuplicate(e),
|
|
157
|
+
this._healLingeringDuplicate(e), a.needsMigration(e) && this._migrateFromLegacy(e), this._healHidePriceAttr(e);
|
|
159
158
|
try {
|
|
160
|
-
|
|
161
|
-
const t =
|
|
159
|
+
B || (I(this.api), B = !0);
|
|
160
|
+
const t = a.getConfig(e), i = this._getBlockElement(e);
|
|
162
161
|
if (i) {
|
|
163
162
|
const r = !t.mobileLayoutEnabled;
|
|
164
163
|
O(i) !== r && R(this.api, i, r);
|
|
@@ -175,7 +174,7 @@ class Z extends S {
|
|
|
175
174
|
*/
|
|
176
175
|
onDelete(e) {
|
|
177
176
|
const t = this._getRecommendationId(e);
|
|
178
|
-
t &&
|
|
177
|
+
t && p().removeBlockState(t);
|
|
179
178
|
}
|
|
180
179
|
/**
|
|
181
180
|
* Warns (dark advisory toaster) when the design holds more than one live
|
|
@@ -204,10 +203,10 @@ class Z extends S {
|
|
|
204
203
|
const t = /* @__PURE__ */ new Set();
|
|
205
204
|
try {
|
|
206
205
|
const i = this.api.getDocumentRoot();
|
|
207
|
-
i && "querySelectorAll" in i && i.querySelectorAll(`.${
|
|
206
|
+
i && "querySelectorAll" in i && i.querySelectorAll(`.${d}`).forEach((s) => {
|
|
208
207
|
if ("getAttribute" in s) {
|
|
209
|
-
const n = s.getAttribute(
|
|
210
|
-
t.add(
|
|
208
|
+
const n = s.getAttribute(f), o = n ? parseInt(n) : 0;
|
|
209
|
+
t.add(o), o > e && (e = o);
|
|
211
210
|
}
|
|
212
211
|
});
|
|
213
212
|
} catch {
|
|
@@ -224,42 +223,64 @@ class Z extends S {
|
|
|
224
223
|
* the renamed one depending on where the module was dropped (SD-149916).
|
|
225
224
|
*/
|
|
226
225
|
_scheduleArrivalReset(e) {
|
|
227
|
-
|
|
226
|
+
g().isFeatureEnabled("reusableRecommendationStrategy") && setTimeout(() => {
|
|
228
227
|
const t = this._getRecommendationId(e);
|
|
229
|
-
t !== null && t > 0 && !this._resetSourceIds.delete(t) &&
|
|
228
|
+
t !== null && t > 0 && !this._resetSourceIds.delete(t) && p().resetArrivedBlock(t);
|
|
230
229
|
}, 0);
|
|
231
230
|
}
|
|
232
231
|
/**
|
|
233
232
|
* Re-reads the strategy of a block that arrived with saved cards, without waiting for a click.
|
|
234
233
|
* Blocks of one opened template or dropped module arrive in one tick and refresh together.
|
|
235
234
|
*/
|
|
236
|
-
_queueArrivalRefresh(e) {
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
this.
|
|
235
|
+
_queueArrivalRefresh(e, t) {
|
|
236
|
+
g().isFeatureEnabled("reusableRecommendationStrategy") && (this._arrivedBlocks.push({ node: e, id: t }) > 1 || setTimeout(() => {
|
|
237
|
+
const i = this._arrivedBlocks;
|
|
238
|
+
this._arrivedBlocks = [];
|
|
240
239
|
try {
|
|
241
|
-
this._refreshArrivedBlocks(
|
|
242
|
-
} catch (
|
|
243
|
-
console.error("[recommendation] refreshing an arrived strategy failed",
|
|
240
|
+
this._refreshArrivedBlocks(i);
|
|
241
|
+
} catch (r) {
|
|
242
|
+
console.error("[recommendation] refreshing an arrived strategy failed", r);
|
|
244
243
|
}
|
|
245
244
|
}, 0));
|
|
246
245
|
}
|
|
247
246
|
_refreshArrivedBlocks(e) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
k(this.api);
|
|
248
|
+
const t = /* @__PURE__ */ new Set(), i = e.flatMap(({ node: r, id: s }) => {
|
|
249
|
+
const n = s ?? this._getRecommendationId(r), o = this._getBlockElement(r);
|
|
250
|
+
if (!n || !o || t.has(n))
|
|
251
|
+
return [];
|
|
252
|
+
const l = a.getConfig(o);
|
|
253
|
+
if (!this._canClaimRefresh(n, l.strategyId))
|
|
254
|
+
return [];
|
|
255
|
+
const h = { strategyId: l.strategyId };
|
|
256
|
+
return t.add(n), this._refreshClaims.set(n, h), [{ id: n, config: l, claim: h }];
|
|
251
257
|
});
|
|
252
|
-
|
|
258
|
+
i.length && q(i.map(({ id: r, config: s }) => ({ id: r, config: s }))).catch((r) => console.error("[recommendation] refreshing an arrived strategy failed", r)).finally(() => i.forEach(({ id: r, claim: s }) => this._releaseRefreshClaim(r, s)));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* A new document reports each block to onCreated and onDocumentInit, not always in one batch, so a
|
|
262
|
+
* claimed block refreshes again only once the document shows it under another strategy (a restored version).
|
|
263
|
+
*/
|
|
264
|
+
_canClaimRefresh(e, t) {
|
|
265
|
+
const i = this._refreshClaims.get(e);
|
|
266
|
+
if (!i)
|
|
267
|
+
return !0;
|
|
268
|
+
if (i.strategyId === t)
|
|
269
|
+
return !1;
|
|
270
|
+
const r = $(e);
|
|
271
|
+
return r.length > 0 && r.every((s) => s.strategyId === t);
|
|
272
|
+
}
|
|
273
|
+
_releaseRefreshClaim(e, t) {
|
|
274
|
+
this._refreshClaims.get(e) === t && this._refreshClaims.delete(e);
|
|
253
275
|
}
|
|
254
276
|
/**
|
|
255
277
|
* Heals a duplicate that slipped past the create-time `_detectDuplicate`
|
|
256
278
|
* scan (or that was persisted by an older template before SD-142352).
|
|
257
279
|
* When two blocks share a `recommendation-id`, the first occurrence in DOM
|
|
258
280
|
* order is treated as the source and any later sibling is reassigned a
|
|
259
|
-
* fresh id
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
* will seed the new id from that. Skipping `setCurrentBlock` avoids
|
|
281
|
+
* fresh id and queued for the arrival refresh, which seeds the new id's
|
|
282
|
+
* store entry from its persisted `esd-ext-config`. The source's store
|
|
283
|
+
* entry is not cloned and focus is not moved. Skipping `setCurrentBlock` avoids
|
|
263
284
|
* yanking the user's current selection mid-edit when the heal fires from
|
|
264
285
|
* `onDocumentChanged`.
|
|
265
286
|
*/
|
|
@@ -271,7 +292,7 @@ class Z extends S {
|
|
|
271
292
|
if (!i || !("querySelectorAll" in i))
|
|
272
293
|
return;
|
|
273
294
|
const r = i.querySelectorAll(
|
|
274
|
-
`.${
|
|
295
|
+
`.${d}[${f}="${t}"]`
|
|
275
296
|
);
|
|
276
297
|
if (r.length <= 1)
|
|
277
298
|
return;
|
|
@@ -279,14 +300,14 @@ class Z extends S {
|
|
|
279
300
|
if (!s)
|
|
280
301
|
return;
|
|
281
302
|
let n = -1;
|
|
282
|
-
for (let
|
|
283
|
-
if (r[
|
|
284
|
-
n =
|
|
303
|
+
for (let o = 0; o < r.length; o++)
|
|
304
|
+
if (r[o] === s) {
|
|
305
|
+
n = o;
|
|
285
306
|
break;
|
|
286
307
|
}
|
|
287
308
|
if (n <= 0)
|
|
288
309
|
return;
|
|
289
|
-
this._reassignDuplicateId(e, t);
|
|
310
|
+
this._queueArrivalRefresh(e, this._reassignDuplicateId(e, t));
|
|
290
311
|
} catch {
|
|
291
312
|
}
|
|
292
313
|
}
|
|
@@ -296,7 +317,7 @@ class Z extends S {
|
|
|
296
317
|
const t = this.api.getDocumentRoot();
|
|
297
318
|
if (t && "querySelectorAll" in t)
|
|
298
319
|
return t.querySelectorAll(
|
|
299
|
-
`.${
|
|
320
|
+
`.${d}[${f}="${e}"]`
|
|
300
321
|
).length > 1;
|
|
301
322
|
} catch {
|
|
302
323
|
}
|
|
@@ -304,11 +325,14 @@ class Z extends S {
|
|
|
304
325
|
}
|
|
305
326
|
/** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
|
|
306
327
|
_handleDuplicate(e, t) {
|
|
307
|
-
const i = this._reassignDuplicateId(e, t), r =
|
|
308
|
-
if (r.cloneBlockState(t, i), r.setCurrentBlock(i),
|
|
328
|
+
const i = this._reassignDuplicateId(e, t), r = p();
|
|
329
|
+
if (r.cloneBlockState(t, i), r.setCurrentBlock(i), g().isFeatureEnabled("reusableRecommendationStrategy")) {
|
|
309
330
|
this._resetSourceIds.add(t), k(this.api);
|
|
310
|
-
const s =
|
|
311
|
-
|
|
331
|
+
const s = a.getConfig(e), n = [
|
|
332
|
+
{ id: t, claim: { strategyId: H(t, s).strategyId } },
|
|
333
|
+
{ id: i, claim: { strategyId: s.strategyId } }
|
|
334
|
+
].filter(({ id: o }) => !this._refreshClaims.has(o));
|
|
335
|
+
n.forEach(({ id: o, claim: l }) => this._refreshClaims.set(o, l)), F(t, i, s).catch((o) => console.error("[recommendation] refreshing a duplicated strategy failed", o)).finally(() => n.forEach(({ id: o, claim: l }) => this._releaseRefreshClaim(o, l)));
|
|
312
336
|
}
|
|
313
337
|
this._warnIfMultipleBlocks();
|
|
314
338
|
}
|
|
@@ -319,13 +343,13 @@ class Z extends S {
|
|
|
319
343
|
*
|
|
320
344
|
* Used by `_handleDuplicate` at create-time (which additionally clones the
|
|
321
345
|
* store entry and focuses the new block) and by `_healLingeringDuplicate`
|
|
322
|
-
* at document-change time (which
|
|
323
|
-
*
|
|
324
|
-
*
|
|
346
|
+
* at document-change time (which skips the clone and focus change so older
|
|
347
|
+
* bug-affected templates can self-repair without disturbing the user's
|
|
348
|
+
* current selection, and queues the arrival refresh for the new id).
|
|
325
349
|
*/
|
|
326
350
|
_reassignDuplicateId(e, t) {
|
|
327
351
|
const i = this._generateNextId(), r = this._getBlockElement(e);
|
|
328
|
-
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(e, i), r && this._reassignInstanceClass(r, t, i),
|
|
352
|
+
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(e, i), r && this._reassignInstanceClass(r, t, i), a.hasConfig(e) && a.updateConfig(
|
|
329
353
|
this.api,
|
|
330
354
|
e,
|
|
331
355
|
{ recommendationId: i },
|
|
@@ -343,7 +367,7 @@ class Z extends S {
|
|
|
343
367
|
if (!("getAttribute" in e))
|
|
344
368
|
return;
|
|
345
369
|
const r = `ins-recommendation-v3-block-${t}`, s = `ins-recommendation-v3-block-${i}`, n = this.api.getDocumentModifier();
|
|
346
|
-
n.modifyHtml(e).removeClass(r).setClass(s), n.apply(new
|
|
370
|
+
n.modifyHtml(e).removeClass(r).setClass(s), n.apply(new _(
|
|
347
371
|
`Reassign recommendation instance class ${r} -> ${s}`
|
|
348
372
|
));
|
|
349
373
|
}
|
|
@@ -358,7 +382,7 @@ class Z extends S {
|
|
|
358
382
|
if (!i)
|
|
359
383
|
return;
|
|
360
384
|
const r = this.api.getDocumentModifier();
|
|
361
|
-
r.modifyHtml(i).setAttribute(
|
|
385
|
+
r.modifyHtml(i).setAttribute(f, t.toString()), r.apply(new _(`Assign recommendation ID ${t}`));
|
|
362
386
|
}
|
|
363
387
|
/**
|
|
364
388
|
* Stamps the `hide-price` attribute (read by email-service at send time) on
|
|
@@ -366,7 +390,7 @@ class Z extends S {
|
|
|
366
390
|
*/
|
|
367
391
|
_stampHidePrice(e, t) {
|
|
368
392
|
const i = this._getBlockElement(e);
|
|
369
|
-
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(
|
|
393
|
+
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(C, String(t)).apply(new _("Stamp hide-price"));
|
|
370
394
|
}
|
|
371
395
|
/**
|
|
372
396
|
* Stamps `hide-price` from config only when the block lacks the attribute —
|
|
@@ -374,9 +398,9 @@ class Z extends S {
|
|
|
374
398
|
*/
|
|
375
399
|
_healHidePriceAttr(e) {
|
|
376
400
|
const t = this._getBlockElement(e);
|
|
377
|
-
if (!t || !("getAttribute" in t) || t.getAttribute(
|
|
401
|
+
if (!t || !("getAttribute" in t) || t.getAttribute(C) !== null)
|
|
378
402
|
return;
|
|
379
|
-
const { priceHideIfSameAsDiscounted: i } =
|
|
403
|
+
const { priceHideIfSameAsDiscounted: i } = a.getConfig(e);
|
|
380
404
|
this._stampHidePrice(e, i);
|
|
381
405
|
}
|
|
382
406
|
/**
|
|
@@ -386,7 +410,7 @@ class Z extends S {
|
|
|
386
410
|
const t = this._getBlockElement(e);
|
|
387
411
|
if (!t || !("getAttribute" in t))
|
|
388
412
|
return null;
|
|
389
|
-
const i = t.getAttribute(
|
|
413
|
+
const i = t.getAttribute(f);
|
|
390
414
|
if (!i)
|
|
391
415
|
return null;
|
|
392
416
|
const r = parseInt(i);
|
|
@@ -398,19 +422,19 @@ class Z extends S {
|
|
|
398
422
|
_getBlockElement(e) {
|
|
399
423
|
if ("getAttribute" in e) {
|
|
400
424
|
const t = e.getAttribute("class");
|
|
401
|
-
if (t && t.includes(
|
|
425
|
+
if (t && t.includes(d))
|
|
402
426
|
return e;
|
|
403
427
|
}
|
|
404
|
-
return "querySelector" in e ? e.querySelector(`.${
|
|
428
|
+
return "querySelector" in e ? e.querySelector(`.${d}`) ?? null : null;
|
|
405
429
|
}
|
|
406
430
|
/**
|
|
407
431
|
* Migrate configuration from legacy format
|
|
408
432
|
*/
|
|
409
433
|
_migrateFromLegacy(e) {
|
|
410
|
-
|
|
434
|
+
a.migrateFromDataAttributes(this.api, e);
|
|
411
435
|
}
|
|
412
436
|
}
|
|
413
437
|
export {
|
|
414
438
|
y as BLOCK_ID,
|
|
415
|
-
|
|
439
|
+
te as RecommendationBlock
|
|
416
440
|
};
|
|
@@ -1,60 +1,64 @@
|
|
|
1
|
-
import { useRecommendationExtensionStore as
|
|
1
|
+
import { useRecommendationExtensionStore as f } from "../store/recommendation.js";
|
|
2
2
|
import { refreshBlockOutsidePanel as l } from "./blockRefresh.js";
|
|
3
|
-
import { toBlockUrlConfig as
|
|
4
|
-
import {
|
|
5
|
-
function
|
|
6
|
-
const r = JSON.stringify(
|
|
7
|
-
return
|
|
3
|
+
import { toBlockUrlConfig as c } from "./blockUrlConfig.js";
|
|
4
|
+
import { readBlockNodeConfigs as m, commitBlockChangeOutsidePanel as d } from "./nodeConfigWriter.js";
|
|
5
|
+
function u(n, t) {
|
|
6
|
+
const r = JSON.stringify(c(t));
|
|
7
|
+
return m(n).find((s) => JSON.stringify(c(s)) !== r) ?? t;
|
|
8
8
|
}
|
|
9
|
-
async function
|
|
10
|
-
const
|
|
11
|
-
await Promise.all(
|
|
12
|
-
if (!await
|
|
9
|
+
async function y(n, t, r = () => !0) {
|
|
10
|
+
const s = f();
|
|
11
|
+
await Promise.all(n.map(async (e) => {
|
|
12
|
+
if (!await s.refreshStrategyBlock(e))
|
|
13
13
|
return;
|
|
14
|
-
const { recommendationConfigs:
|
|
15
|
-
r(e,
|
|
14
|
+
const { recommendationConfigs: a, recommendationProducts: o } = s.blockStates[e];
|
|
15
|
+
r(e, a.size) && d(
|
|
16
16
|
e,
|
|
17
|
-
{ size:
|
|
18
|
-
|
|
17
|
+
{ size: a.size },
|
|
18
|
+
o,
|
|
19
19
|
t
|
|
20
20
|
);
|
|
21
21
|
}));
|
|
22
22
|
}
|
|
23
|
-
async function
|
|
24
|
-
const
|
|
25
|
-
(/* @__PURE__ */ new Map([[
|
|
23
|
+
async function w(n, t, r) {
|
|
24
|
+
const s = f(), e = [n, t];
|
|
25
|
+
(/* @__PURE__ */ new Map([[n, u(n, r)], [t, r]])).forEach((o, i) => {
|
|
26
26
|
var g;
|
|
27
|
-
(!!
|
|
28
|
-
}),
|
|
27
|
+
(!!o.strategyId || i === t) && ((g = s.blockStates[i]) == null ? void 0 : g.recommendationConfigs.strategyId) !== o.strategyId && s.seedBlockUrlConfig(i, c(o));
|
|
28
|
+
}), s.resetArrivedBlock(t), await y(e, "Refresh duplicated recommendation strategy");
|
|
29
29
|
}
|
|
30
|
-
async function k(
|
|
31
|
-
const t =
|
|
30
|
+
async function k(n) {
|
|
31
|
+
const t = f(), r = n.filter(({ config: e }) => !!e.strategyId);
|
|
32
32
|
if (!r.length)
|
|
33
33
|
return;
|
|
34
|
-
r.forEach(({ id: e, config:
|
|
35
|
-
const
|
|
36
|
-
await
|
|
34
|
+
r.forEach(({ id: e, config: a }) => t.seedBlockUrlConfig(e, c(a))), t.invalidateStrategies();
|
|
35
|
+
const s = new Map(r.map(({ id: e, config: a }) => [e, a]));
|
|
36
|
+
await y(
|
|
37
37
|
r.map(({ id: e }) => e),
|
|
38
38
|
"Refresh recommendation strategy",
|
|
39
|
-
(e,
|
|
39
|
+
(e, a) => {
|
|
40
|
+
const o = s.get(e);
|
|
41
|
+
return a !== (o == null ? void 0 : o.size) && m(e).some((i) => i.strategyId === (o == null ? void 0 : o.strategyId));
|
|
42
|
+
}
|
|
40
43
|
);
|
|
41
44
|
}
|
|
42
|
-
async function O(
|
|
43
|
-
if (!
|
|
45
|
+
async function O(n, t) {
|
|
46
|
+
if (!f().blockStates[n])
|
|
44
47
|
return !1;
|
|
45
|
-
const r = await l(
|
|
46
|
-
pickUpdates: ({ strategyId:
|
|
47
|
-
strategyId:
|
|
48
|
+
const r = await l(n, {
|
|
49
|
+
pickUpdates: ({ strategyId: s, strategy: e, size: a, nodeConfigVersion: o }) => ({
|
|
50
|
+
strategyId: s,
|
|
48
51
|
strategy: e,
|
|
49
|
-
size:
|
|
50
|
-
configVersion:
|
|
52
|
+
size: a,
|
|
53
|
+
configVersion: o
|
|
51
54
|
}),
|
|
52
55
|
description: t
|
|
53
56
|
});
|
|
54
|
-
return r || console.error("[recommendation] strategy change did not reach a node", { blockId:
|
|
57
|
+
return r || console.error("[recommendation] strategy change did not reach a node", { blockId: n }), r;
|
|
55
58
|
}
|
|
56
59
|
export {
|
|
57
60
|
O as commitStrategyChange,
|
|
58
61
|
k as refreshArrivedStrategyBlocks,
|
|
59
|
-
|
|
62
|
+
w as refreshDuplicatedStrategyBlocks,
|
|
63
|
+
u as resolveSourceConfig
|
|
60
64
|
};
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-baf7a5dd]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-e48cebe9]{gap:16px}.validation-error-row[data-v-e48cebe9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-e48cebe9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-e48cebe9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-
|
|
1
|
+
@charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-baf7a5dd]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-e48cebe9]{gap:16px}.validation-error-row[data-v-e48cebe9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-e48cebe9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-e48cebe9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-1a3ddd48]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-1a3ddd48]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-1a3ddd48]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-19d8cb42] .vueperslides__bullets,[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}.legacy-strategy-updated-modal[data-v-da2225a1]{position:relative;z-index:145}
|
package/dist/library.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { default as a } from "./components/Guido.vue.js";
|
|
2
|
-
import { MessageType as t, ProductType as
|
|
2
|
+
import { MessageType as t, ProductType as f } from "./@types/config/schemas.js";
|
|
3
3
|
import "./@types/config/defaults.js";
|
|
4
|
-
import { getValidationErrors as
|
|
5
|
-
import { assignTrackingIds as
|
|
4
|
+
import { getValidationErrors as p, isValidConfig as s, parseConfig as m, parseConfigSafe as g, validateConfig as n } from "./@types/config/validator.js";
|
|
5
|
+
import { assignTrackingIds as l, readTrackFloor as x, readTrackSeq as c } from "./utils/linkTrackingIds.js";
|
|
6
6
|
import { useGuidoEmailEditorStore as C } from "./stores/guido-email-editor.js";
|
|
7
|
+
import { prefetchGuidoRuntime as E } from "./utils/runtimePrefetch.js";
|
|
7
8
|
export {
|
|
8
9
|
a as Guido,
|
|
9
10
|
t as MessageType,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
f as ProductType,
|
|
12
|
+
l as assignTrackingIds,
|
|
13
|
+
p as getValidationErrors,
|
|
14
|
+
s as isValidConfig,
|
|
15
|
+
m as parseConfig,
|
|
16
|
+
g as parseConfigSafe,
|
|
17
|
+
E as prefetchGuidoRuntime,
|
|
16
18
|
x as readTrackFloor,
|
|
17
|
-
|
|
19
|
+
c as readTrackSeq,
|
|
18
20
|
C as useGuidoEmailEditorStore,
|
|
19
21
|
n as validateConfig
|
|
20
22
|
};
|
package/dist/package.json.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
const o = { stripo: { version: "2.79.0" } },
|
|
2
|
-
|
|
1
|
+
const o = "3.21.0-beta.8a9421f", s = { stripo: { version: "2.79.0" } }, t = {
|
|
2
|
+
version: o,
|
|
3
|
+
guido: s
|
|
3
4
|
};
|
|
4
5
|
export {
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
t as default,
|
|
7
|
+
s as guido,
|
|
8
|
+
o as version
|
|
7
9
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type TimedOpenPhase = 'migration' | 'default_template' | 'timer_clone';
|
|
2
|
+
export type OpenPhase = 'setup' | 'host_ready' | `${TimedOpenPhase}_start` | `${TimedOpenPhase}_end` | 'plugin_start' | 'script_ready' | 'fonts_sync_ready' | 'blocks_config_ready' | 'init_editor' | 'token_start' | 'token_end' | 'ready';
|
|
3
|
+
export type OpenOutcome = 'ready' | 'error' | 'abandoned';
|
|
4
|
+
export interface OpenContext {
|
|
5
|
+
partnerName: string;
|
|
6
|
+
productType: number;
|
|
7
|
+
templateId: string;
|
|
8
|
+
variationId: string;
|
|
9
|
+
}
|
|
10
|
+
export interface OpenTemplate {
|
|
11
|
+
html: string;
|
|
12
|
+
css: string;
|
|
13
|
+
forceRecreate: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface EditorOpenMetrics {
|
|
16
|
+
mark: (phase: OpenPhase) => void;
|
|
17
|
+
timed: <T>(phase: TimedOpenPhase, task: () => Promise<T>) => Promise<T>;
|
|
18
|
+
setContext: (context: OpenContext) => void;
|
|
19
|
+
setTemplate: (template: OpenTemplate) => void;
|
|
20
|
+
setScriptPreloaded: (preloaded: boolean) => void;
|
|
21
|
+
markReady: () => void;
|
|
22
|
+
markFailed: () => void;
|
|
23
|
+
dispose: () => void;
|
|
24
|
+
}
|
|
25
|
+
export declare const startEditorOpenMetrics: () => EditorOpenMetrics;
|
|
26
|
+
/** Binds to the session open at call time, so a remounted editor never writes into its replacement's session. */
|
|
27
|
+
export declare const useEditorOpenMetrics: () => EditorOpenMetrics;
|