@useinsider/guido 3.18.2-beta.83b62a8 → 3.18.2-beta.8ef3138

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 CHANGED
@@ -561,26 +561,6 @@ import {
561
561
  import '@useinsider/guido/style';
562
562
  ```
563
563
 
564
- ### Subpath entries
565
-
566
- Two surfaces also ship as their own entry points. Importing one pulls in only its
567
- own dependencies, so a consumer that needs the store or the tracking-id helpers
568
- never loads the editor:
569
-
570
- ```typescript
571
- // Live editor state, published by the editor into the host's shared Pinia instance.
572
- // Store id `guidoEmailEditor` is the cross-app contract — read it, do not redeclare it.
573
- import { useGuidoEmailEditorStore } from '@useinsider/guido/editor-state';
574
- import type { GuidoEmailEditorState } from '@useinsider/guido/editor-state';
575
-
576
- // Persistent link ids for the click heatmap.
577
- import { assignTrackingIds, TRACK_ID_ATTRIBUTE } from '@useinsider/guido/tracking-ids';
578
- import type { TrackingIdResult } from '@useinsider/guido/tracking-ids';
579
- ```
580
-
581
- Both are re-exported from the root barrel as well; the subpath is what keeps the
582
- editor out of the consumer's module graph.
583
-
584
564
  ---
585
565
 
586
566
  ## Constants
@@ -1,64 +1,64 @@
1
- import { defineComponent as A, ref as c, computed as b, toRef as h, nextTick as C } from "vue";
2
- import N from "../../wrappers/WpDrawer.vue.js";
3
- import { useTranslations as O } from "../../../composables/useTranslations.js";
1
+ import { defineComponent as _, ref as c, computed as h, watch as C, toRef as N, nextTick as O } from "vue";
2
+ import b from "../../wrappers/WpDrawer.vue.js";
3
+ import { useTranslations as D } from "../../../composables/useTranslations.js";
4
4
  import { useTemplateNameValidator as x } from "../../../composables/validators/saveAsTemplate.js";
5
5
  import { useTemplateLibraryApi as B } from "../../../services/templateLibraryApi.js";
6
- import { useEditorStore as D } from "../../../stores/editor.js";
7
- import { useSaveAsTemplateStore as k } from "../../../stores/save-as-template.js";
8
- import { InMultiSelect as I, InBasicTextInput as M } from "@useinsider/design-system-vue";
9
- import { useDebounceFn as V } from "../../../node_modules/@vueuse/shared/index.js";
10
- const H = /* @__PURE__ */ A({
6
+ import { useEditorStore as k } from "../../../stores/editor.js";
7
+ import { useSaveAsTemplateStore as I } from "../../../stores/save-as-template.js";
8
+ import { InMultiSelect as M, InBasicTextInput as V } from "@useinsider/design-system-vue";
9
+ import { useDebounceFn as E } from "../../../node_modules/@vueuse/shared/index.js";
10
+ const J = /* @__PURE__ */ _({
11
11
  __name: "SaveAsTemplateDrawer",
12
- setup(E) {
13
- const o = O(), n = D(), t = k(), { createTemplate: m } = B(), a = c(!1), r = c(!1), l = c(""), f = b(() => ({
12
+ setup(R) {
13
+ const s = D(), o = k(), t = I(), { createTemplate: m } = B(), a = c(!1), n = c(!1), r = c(""), f = h(() => ({
14
14
  primaryButton: {
15
15
  styling: "solid",
16
16
  type: "primary",
17
- labelText: o(a.value ? "newsletter.saving" : "products.save"),
17
+ labelText: s(a.value ? "newsletter.saving" : "products.save"),
18
18
  loadingStatus: a.value,
19
19
  disabledStatus: t.skeletonStatus
20
20
  },
21
21
  cancelOrBackButton: {
22
22
  styling: "ghost",
23
23
  type: "secondary",
24
- labelText: o("products.cancel"),
24
+ labelText: s("products.cancel"),
25
25
  disabledStatus: a.value
26
26
  }
27
- })), u = () => {
28
- l.value = "", n.isSaveAsTemplateDrawerOpen = !1;
29
- }, i = async () => {
30
- const e = h(t, "templateName"), { success: s, errorMessage: _ } = await x(e).validate();
31
- return l.value = _, s;
32
- }, v = V(async (e) => {
33
- t.templateName = e, await i();
34
- }, 500), g = async (e) => {
35
- r.value = !0, await t.addCategory(e), r.value = !1;
36
- }, y = (e) => {
27
+ })), p = () => {
28
+ r.value = "", o.isSaveAsTemplateDrawerOpen = !1;
29
+ }, l = async () => {
30
+ const e = N(t, "templateName"), { success: i, errorMessage: A } = await x(e).validate();
31
+ return r.value = A, i;
32
+ }, v = E(async (e) => {
33
+ t.templateName = e, await l();
34
+ }, 500), S = async (e) => {
35
+ n.value = !0, await t.addCategory(e), n.value = !1;
36
+ }, T = (e) => {
37
37
  t.selectedCategories = e;
38
- }, S = (e) => {
38
+ }, g = (e) => {
39
39
  e && (t.selectedCategories = e);
40
- }, T = () => {
40
+ }, y = () => {
41
41
  t.selectedCategories = [];
42
42
  }, w = async () => {
43
- if (a.value = !0, !await i()) {
43
+ if (a.value = !0, !await l()) {
44
44
  a.value = !1;
45
45
  return;
46
46
  }
47
- const s = await m();
48
- a.value = !1, s && u();
49
- }, p = () => {
50
- C(() => {
47
+ const i = await m();
48
+ a.value = !1, i && p();
49
+ }, u = () => {
50
+ O(() => {
51
51
  const e = document.querySelector("input#guido__template-name-input");
52
52
  e == null || e.focus();
53
53
  });
54
54
  }, d = async () => {
55
- t.$reset(), await t.fetchCategories(), t.skeletonStatus = !1, p();
55
+ t.$reset(), await t.fetchCategories(), t.skeletonStatus = !1, u();
56
56
  };
57
- return n.$subscribe((e, { isSaveAsTemplateDrawerOpen: s }) => {
58
- s && d();
59
- }), { __sfc: !0, trans: o, editorStore: n, saveAsTemplateStore: t, createTemplate: m, isSaving: a, isAddingOption: r, templateNameError: l, footerButtonGroupOptions: f, closeModal: u, validateTemplateName: i, handleTemplateName: v, handleAddOption: g, handleCategoryChange: y, handleSelectAllOptions: S, handleResetAllOptions: T, saveTemplate: w, focusToInput: p, initializeDrawer: d, WpDrawer: N, InBasicTextInput: M, InMultiSelect: I };
57
+ return C(() => o.isSaveAsTemplateDrawerOpen, (e) => {
58
+ e && d();
59
+ }), { __sfc: !0, trans: s, editorStore: o, saveAsTemplateStore: t, createTemplate: m, isSaving: a, isAddingOption: n, templateNameError: r, footerButtonGroupOptions: f, closeModal: p, validateTemplateName: l, handleTemplateName: v, handleAddOption: S, handleCategoryChange: T, handleSelectAllOptions: g, handleResetAllOptions: y, saveTemplate: w, focusToInput: u, initializeDrawer: d, WpDrawer: b, InBasicTextInput: V, InMultiSelect: M };
60
60
  }
61
61
  });
62
62
  export {
63
- H as default
63
+ J as default
64
64
  };
@@ -1,59 +1,54 @@
1
- import { useActionsApi as v } from "./useActionsApi.js";
2
- import { useEditorLock as C } from "./useEditorLock.js";
1
+ import { useActionsApi as b } from "./useActionsApi.js";
2
+ import { useEditorLock as v } from "./useEditorLock.js";
3
3
  import { useConfigStore as T } from "../stores/config.js";
4
4
  import { useEditorStore as w } from "../stores/editor.js";
5
5
  import { useGuidoEmailEditorStore as y } from "../stores/guido-email-editor.js";
6
- import { watch as c, onUnmounted as z } from "vue";
7
- const B = 500, G = () => {
8
- const i = w(), u = y(), d = T(), { getTemplateData: l } = v(), { runExclusive: m, isEditorBusy: p } = C();
9
- let o = null, n = !1;
10
- const r = () => {
6
+ import { watch as a, onUnmounted as B } from "vue";
7
+ const C = 500, L = () => {
8
+ const i = w(), u = y(), l = T(), { getTemplateData: d } = b(), { runExclusive: m, isEditorBusy: p } = v();
9
+ let o = null, s = !1;
10
+ const n = () => {
11
11
  o && (clearTimeout(o), o = null);
12
- }, a = (t) => {
13
- r(), o = setTimeout(() => {
12
+ }, c = (t) => {
13
+ n(), o = setTimeout(() => {
14
14
  o = null, t();
15
- }, B);
15
+ }, C);
16
16
  }, e = async () => {
17
- var t, s;
18
- if (!(n || !i.isStripoInitialized)) {
17
+ var t, r;
18
+ if (!(s || !i.isStripoInitialized)) {
19
19
  if (p()) {
20
- a(() => void e());
20
+ c(() => void e());
21
21
  return;
22
22
  }
23
23
  try {
24
- const { html: E, css: I } = await m(l), b = ((s = (t = d.config) == null ? void 0 : t.identity) == null ? void 0 : s.templateId) ?? "";
25
- if (n)
24
+ const { html: E, css: g } = await m(d), I = ((r = (t = l.config) == null ? void 0 : t.identity) == null ? void 0 : r.templateId) ?? "";
25
+ if (s)
26
26
  return;
27
27
  u.$patch({
28
28
  html: E ?? "",
29
- css: I ?? "",
30
- templateId: b,
29
+ css: g ?? "",
30
+ templateId: I,
31
31
  lastUpdatedAt: Date.now()
32
32
  });
33
33
  } catch {
34
34
  }
35
35
  }
36
- }, f = () => a(() => void e()), h = c(
36
+ }, f = () => c(() => void e()), h = a(
37
37
  () => i.isStripoInitialized,
38
38
  (t) => {
39
39
  t && e();
40
40
  },
41
41
  { immediate: !0 }
42
- ), S = c(
43
- () => i.changeSeq,
44
- () => {
45
- i.isStripoInitialized && f();
46
- }
47
- ), g = c(
42
+ ), S = a(
48
43
  () => i.hasChanges,
49
- (t, s) => {
50
- !t && s && i.isStripoInitialized && (r(), e());
44
+ (t, r) => {
45
+ i.isStripoInitialized && (t ? f() : r && (n(), e()));
51
46
  }
52
47
  );
53
- z(() => {
54
- n = !0, r(), h(), S(), g();
48
+ B(() => {
49
+ s = !0, n(), h(), S();
55
50
  });
56
51
  };
57
52
  export {
58
- G as useGuidoStateBridge
53
+ L as useGuidoStateBridge
59
54
  };
@@ -1,14 +1,16 @@
1
- import { getCsrfToken as H } from "../utils/genericUtil.js";
2
- import { ref as p, computed as T } from "vue";
3
- const k = (b = {}) => {
4
- const h = p(!1), a = p(null), u = p(null), g = T(() => h.value), y = T(() => a.value !== null), v = {
1
+ import { getCsrfToken as O } from "../utils/genericUtil.js";
2
+ import { ref as m, computed as T } from "vue";
3
+ const X = (b = {}) => {
4
+ const p = m(!1), a = m(null), u = m(null), g = T(() => p.value), y = T(() => a.value !== null), v = {
5
5
  baseURL: "",
6
6
  timeout: 1e4,
7
7
  retry: 0,
8
8
  retryDelay: 1e3,
9
9
  headers: {
10
10
  "Content-Type": "application/json",
11
- "X-CSRF-TOKEN": H()
11
+ "X-CSRF-TOKEN": O(),
12
+ Accept: "application/json",
13
+ "X-Requested-With": "XMLHttpRequest"
12
14
  },
13
15
  ...b
14
16
  }, w = (e, s) => {
@@ -22,22 +24,22 @@ const k = (b = {}) => {
22
24
  }, e);
23
25
  }), x = (e) => new Promise((s) => {
24
26
  setTimeout(s, e);
25
- }), i = async (e, s, t, D = {}) => {
26
- a.value = null, h.value = !0, u.value = new AbortController();
27
- const n = { ...v, ...D }, L = w(s, n.baseURL), c = {
27
+ }), i = async (e, s, t, L = {}) => {
28
+ a.value = null, p.value = !0, u.value = new AbortController();
29
+ const n = { ...v, ...L }, D = w(s, n.baseURL), c = {
28
30
  method: e,
29
31
  headers: { ...n.headers },
30
32
  signal: u.value.signal,
31
33
  ...n
32
34
  };
33
35
  t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete c.headers["Content-Type"], c.body = t) : c.body = JSON.stringify(t));
34
- const E = async (m = 0) => {
36
+ const E = async (h = 0) => {
35
37
  try {
36
- const o = [fetch(L, c)];
38
+ const o = [fetch(D, c)];
37
39
  n.timeout && o.push(P(n.timeout));
38
40
  const r = await Promise.race(o);
39
41
  if (!r.ok) {
40
- const O = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(O);
42
+ const H = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(H);
41
43
  throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
42
44
  }
43
45
  let f;
@@ -50,19 +52,19 @@ const k = (b = {}) => {
50
52
  };
51
53
  } catch (o) {
52
54
  const r = o instanceof Error && o.name === "AbortError";
53
- if (m < (n.retry || 0) && !r)
54
- return await x(n.retryDelay || 1e3), E(m + 1);
55
+ if (h < (n.retry || 0) && !r)
56
+ return await x(n.retryDelay || 1e3), E(h + 1);
55
57
  throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
56
58
  }
57
59
  };
58
60
  try {
59
61
  return await E();
60
62
  } finally {
61
- h.value = !1, u.value = null;
63
+ p.value = !1, u.value = null;
62
64
  }
63
- }, C = (e, s) => i("GET", e, void 0, s), $ = (e, s, t) => i("POST", e, s, t), R = (e, s, t) => i("PUT", e, s, t), U = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), W = (e) => {
65
+ }, C = (e, s) => i("GET", e, void 0, s), R = (e, s, t) => i("POST", e, s, t), $ = (e, s, t) => i("PUT", e, s, t), q = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), U = (e) => {
64
66
  u.value && u.value.abort(e);
65
- }, q = () => {
67
+ }, W = () => {
66
68
  a.value = null;
67
69
  };
68
70
  return {
@@ -73,14 +75,14 @@ const k = (b = {}) => {
73
75
  // Methods
74
76
  request: i,
75
77
  get: C,
76
- post: $,
77
- put: R,
78
- patch: U,
78
+ post: R,
79
+ put: $,
80
+ patch: q,
79
81
  delete: A,
80
- cancel: W,
81
- clearError: q
82
+ cancel: U,
83
+ clearError: W
82
84
  };
83
85
  };
84
86
  export {
85
- k as useHttp
87
+ X as useHttp
86
88
  };
@@ -1,6 +1,6 @@
1
- import { useActionsApi as x } from "./useActionsApi.js";
2
- import { useBlocksConfig as L } from "./useBlocksConfig.js";
3
- import { useConfig as O } from "./useConfig.js";
1
+ import { useActionsApi as L } from "./useActionsApi.js";
2
+ import { useBlocksConfig as O } from "./useBlocksConfig.js";
3
+ import { useConfig as q } from "./useConfig.js";
4
4
  import { useCustomInterfaceAppearance as H } from "./useCustomInterfaceAppearance.js";
5
5
  import { useFullStoryBridge as N } from "./useFullStoryBridge.js";
6
6
  import { useModuleRepair as j } from "./useModuleRepair.js";
@@ -17,7 +17,7 @@ import { buildMergeTagEntries as W, flattenDynamicContentList as Y } from "../ut
17
17
  import Z from "../package.json.js";
18
18
  let n = null;
19
19
  const Ce = () => {
20
- const { features: c, template: u, isFeatureEnabled: m } = O(), { handleError: p, showToaster: k } = G(), { getToken: B, getCustomFonts: M, getSyncModulesStatus: T } = K(), { handleEvent: v } = z(), { handleModuleAdd: F } = j(), { getStripoBlocksConfig: A } = L(), { getStripoNotifications: V } = $(), f = () => n || (n = new Promise((i, s) => {
20
+ const { features: c, template: u, isFeatureEnabled: m } = q(), { handleError: p, showToaster: k } = G(), { getToken: B, getCustomFonts: M, getSyncModulesStatus: T } = K(), { handleEvent: v } = z(), { handleModuleAdd: F } = j(), { getStripoBlocksConfig: A } = O(), { getStripoNotifications: V } = $(), f = () => n || (n = new Promise((i, s) => {
21
21
  var d;
22
22
  if (document.getElementById("UiEditorScript")) {
23
23
  i();
@@ -88,8 +88,8 @@ const Ce = () => {
88
88
  },
89
89
  onTemplateLoaded() {
90
90
  try {
91
- const { importCss: t } = H(), { activateCustomViewStyles: l, updateTimerInClonedTemplate: I } = x(), { injectFullStory: q } = N();
92
- t(), l(), q(), I(), o.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
91
+ const { importCss: t } = H(), { activateCustomViewStyles: l, updateTimerInClonedTemplate: I } = L(), { injectFullStory: x } = N();
92
+ t(), l(), x(), I(), o.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
93
93
  e.hasChanges = !1;
94
94
  }, 1e3);
95
95
  } catch (t) {
@@ -106,7 +106,7 @@ const Ce = () => {
106
106
  e.isVersionHistoryOpen = t;
107
107
  },
108
108
  onDataChanged() {
109
- e.hasChanges = !0, e.changeSeq += 1;
109
+ e.hasChanges = !0;
110
110
  },
111
111
  onEvent: v,
112
112
  onModuleAdd: F,
package/dist/library.js CHANGED
@@ -1,20 +1,18 @@
1
- import { default as a } from "./components/Guido.vue.js";
2
- import { MessageType as t, ProductType as d } from "./@types/config/schemas.js";
1
+ import { default as e } from "./components/Guido.vue.js";
2
+ import { MessageType as f, ProductType as s } from "./@types/config/schemas.js";
3
3
  import "./@types/config/defaults.js";
4
- import { getValidationErrors as s, isValidConfig as p, parseConfig as g, parseConfigSafe as m, validateConfig as n } from "./@types/config/validator.js";
5
- import { assignTrackingIds as u, readTrackFloor as x, readTrackSeq as T } from "./utils/linkTrackingIds.js";
6
- import { useGuidoEmailEditorStore as C } from "./stores/guido-email-editor.js";
4
+ import { getValidationErrors as d, isValidConfig as p, parseConfig as g, parseConfigSafe as n, validateConfig as l } from "./@types/config/validator.js";
5
+ import { assignTrackingIds as T, readTrackFloor as c, readTrackSeq as x } from "./utils/linkTrackingIds.js";
7
6
  export {
8
- a as Guido,
9
- t as MessageType,
10
- d as ProductType,
11
- u as assignTrackingIds,
12
- s as getValidationErrors,
7
+ e as Guido,
8
+ f as MessageType,
9
+ s as ProductType,
10
+ T as assignTrackingIds,
11
+ d as getValidationErrors,
13
12
  p as isValidConfig,
14
13
  g as parseConfig,
15
- m as parseConfigSafe,
16
- x as readTrackFloor,
17
- T as readTrackSeq,
18
- C as useGuidoEmailEditorStore,
19
- n as validateConfig
14
+ n as parseConfigSafe,
15
+ c as readTrackFloor,
16
+ x as readTrackSeq,
17
+ l as validateConfig
20
18
  };
@@ -4,13 +4,14 @@ import { useToaster as C } from "../composables/useToaster.js";
4
4
  import { useTranslations as h } from "../composables/useTranslations.js";
5
5
  import { useLiquidValidator as S } from "../composables/validators/useLiquidValidator.js";
6
6
  import { EditorType as v } from "../enums/defaults.js";
7
- import { ToasterTypeOptions as N } from "../enums/toaster.js";
8
- import { useRecommendationExtensionStore as x } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
- import { useSaveAsTemplateStore as E } from "../stores/save-as-template.js";
7
+ import { ToasterTypeOptions as x } from "../enums/toaster.js";
8
+ import { useRecommendationExtensionStore as E } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
+ import { useSaveAsTemplateStore as N } from "../stores/save-as-template.js";
10
10
  import { base64EncodeWithSpecialChars as r } from "../utils/base64.js";
11
+ import { isPlainObject as P } from "../utils/genericUtil.js";
11
12
  import { useTemplatePreparation as A } from "../utils/templatePreparation.js";
12
- const j = () => {
13
- const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: g } = S(), u = h();
13
+ const B = () => {
14
+ const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: f } = S(), u = h();
14
15
  return {
15
16
  getCategories: async () => {
16
17
  try {
@@ -40,10 +41,10 @@ const j = () => {
40
41
  createTemplate: async () => {
41
42
  var e, t, d, y;
42
43
  try {
43
- const { prepareTemplateDetails: i } = A(), s = E(), a = await i();
44
- if (p("liquidSyntax") && !await g(a.compiledHtml))
44
+ const { prepareTemplateDetails: i } = A(), s = N(), a = await i();
45
+ if (p("liquidSyntax") && !await f(a.compiledHtml))
45
46
  return !1;
46
- const f = {
47
+ const T = {
47
48
  name: s.getTemplateName,
48
49
  categories: s.getSelectedCategoryIds,
49
50
  productId: ((t = (e = c.value) == null ? void 0 : e.partner) == null ? void 0 : t.productType) || 0,
@@ -54,7 +55,7 @@ const j = () => {
54
55
  unsubscriptionPreferencePageStatus: !1,
55
56
  unsubscriptionPreferencePages: [],
56
57
  recommendationCampaignUrls: r(
57
- x().recommendationCampaignUrls
58
+ E().recommendationCampaignUrls
58
59
  ),
59
60
  recommendationConfigs: r({}),
60
61
  isGuido: !0,
@@ -66,16 +67,18 @@ const j = () => {
66
67
  css: a.css,
67
68
  dynamicContentList: a.dynamicContentList
68
69
  })
69
- }, { data: { type: T } } = await m(
70
+ }, { data: g } = await m(
70
71
  "/newsletter/template-library/create-template",
71
- f
72
+ T
72
73
  );
73
- return T === "alert" ? (l({
74
+ if (!P(g))
75
+ throw new Error("Unexpected create-template response");
76
+ return g.type === "alert" ? (l({
74
77
  message: u(
75
78
  "newsletter.template-library-save-alert",
76
79
  { templateName: s.getTemplateName }
77
80
  ),
78
- type: N.Error
81
+ type: x.Error
79
82
  }), !1) : (l({
80
83
  message: u(
81
84
  "newsletter.template-library-save-success",
@@ -90,5 +93,5 @@ const j = () => {
90
93
  };
91
94
  };
92
95
  export {
93
- j as useTemplateLibraryApi
96
+ B as useTemplateLibraryApi
94
97
  };
@@ -1,26 +1,22 @@
1
1
  /**
2
2
  * Outbound bridge — publishes the current editor's html/css to the shared
3
- * Pinia store `guidoEmailEditor`. cortex-fe reads it at chat-stream submit
4
- * time and forwards it as `clientState.editor`, which is what enables
3
+ * Pinia store `guidoEmailEditor` so cortex-fe can read it at chat-stream
4
+ * submit time and forward it as `clientState.editor`. This is what enables
5
5
  * sub-case 1.3 (refine an already-loaded template via the email-agent).
6
6
  *
7
7
  * The bridge writes on three triggers:
8
8
  *
9
9
  * 1. Stripo finishes initializing — first snapshot.
10
- * 2. Every document change, via the `changeSeq` counter — debounced 500 ms
11
- * so a streaming Stripo edit doesn't thrash the store.
10
+ * 2. Editor `hasChanges` flips to true — debounced 500 ms so a streaming
11
+ * Stripo edit doesn't thrash the store.
12
12
  * 3. Editor `hasChanges` flips back to false (post-save / autosave) —
13
13
  * immediate, since this is the canonical "saved" snapshot.
14
14
  *
15
15
  * `getTemplateData()` is a Stripo iframe call; it must not run before
16
16
  * `isStripoInitialized` is true. The bridge guards against that.
17
17
  *
18
- * The store is written even with no reader attached — it has zero overhead,
19
- * and a late reader still finds consistent state.
20
- *
21
- * Readers are not optional any more, so treat the publish timing as part of
22
- * the contract: the store ships as `@useinsider/guido/editor-state`, and
23
- * email-fe imports it to scan the live html for its Array of Objects lock.
24
- * Weakening a trigger here silently breaks that lock in the consumer.
18
+ * If cortex-fe isn't loaded the store still gets written — that's fine;
19
+ * the store has zero overhead and any future reader will find consistent
20
+ * state. The bridge is a one-way pipe with no consumer dependency.
25
21
  */
26
22
  export declare const useGuidoStateBridge: () => void;
@@ -2,7 +2,5 @@ export { default as Guido } from './components/Guido.vue';
2
2
  export type { GuidoConfig, GuidoConfigInput, IdentityConfig, PartnerConfig, TemplateConfig, TemplateMigrationConfig, LegacyRecommendationConfig, EditorConfig, UIConfig, FeaturesConfig, BlocksConfig, CompilerConfig, DynamicContent, EmailHeader, DefaultBlockType, CustomBlockType, ValidationResult, ValidationError, } from './@types/config';
3
3
  export { validateConfig, parseConfig, parseConfigSafe, isValidConfig, getValidationErrors, MessageType, ProductType, } from './@types/config';
4
4
  export { assignTrackingIds, readTrackFloor, readTrackSeq } from './public/trackingIds';
5
- export { useGuidoEmailEditorStore } from './public/editorState';
6
- export type { GuidoEmailEditorState } from './public/editorState';
7
5
  export type { StripoEventType } from './@types/events';
8
6
  export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, DynamicContentNode, DynamicContentList, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
@@ -4,10 +4,6 @@
4
4
  * Importing from here pulls in nothing else, so the editor never enters a
5
5
  * consumer's module graph. Re-export surface only: this is the contract,
6
6
  * `utils/linkTrackingIds` is the implementation and stays free to move.
7
- *
8
- * Relative, not the `@@/Utils/` alias: vue-tsc copies the specifier into the emitted
9
- * .d.ts verbatim, and a consumer's TypeScript cannot resolve our alias table. A relative
10
- * path resolves against dist/src/, so the published types actually load.
11
7
  */
12
- export { assignTrackingIds, readTrackFloor, readTrackSeq, TRACK_ID_ATTRIBUTE, TRACK_SEQ_ATTRIBUTE, } from '../utils/linkTrackingIds';
13
- export type { TrackingIdResult } from '../utils/linkTrackingIds';
8
+ export { assignTrackingIds, readTrackFloor, readTrackSeq, TRACK_ID_ATTRIBUTE, TRACK_SEQ_ATTRIBUTE, } from '@@/Utils/linkTrackingIds';
9
+ export type { TrackingIdResult } from '@@/Utils/linkTrackingIds';
@@ -6,7 +6,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
6
6
  isPreviewModeOpen: boolean;
7
7
  editorVisualMode: string;
8
8
  hasChanges: boolean;
9
- changeSeq: number;
10
9
  isStripoInitialized: boolean;
11
10
  templateId: string;
12
11
  syncModulesEnabled: boolean;
@@ -20,7 +19,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
20
19
  isPreviewModeOpen: boolean;
21
20
  editorVisualMode: string;
22
21
  hasChanges: boolean;
23
- changeSeq: number;
24
22
  isStripoInitialized: boolean;
25
23
  templateId: string;
26
24
  syncModulesEnabled: boolean;
@@ -33,7 +31,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
33
31
  isPreviewModeOpen: boolean;
34
32
  editorVisualMode: string;
35
33
  hasChanges: boolean;
36
- changeSeq: number;
37
34
  isStripoInitialized: boolean;
38
35
  templateId: string;
39
36
  syncModulesEnabled: boolean;
@@ -47,7 +44,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
47
44
  isPreviewModeOpen: boolean;
48
45
  editorVisualMode: string;
49
46
  hasChanges: boolean;
50
- changeSeq: number;
51
47
  isStripoInitialized: boolean;
52
48
  templateId: string;
53
49
  syncModulesEnabled: boolean;
@@ -60,7 +56,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
60
56
  isPreviewModeOpen: boolean;
61
57
  editorVisualMode: string;
62
58
  hasChanges: boolean;
63
- changeSeq: number;
64
59
  isStripoInitialized: boolean;
65
60
  templateId: string;
66
61
  syncModulesEnabled: boolean;
@@ -74,7 +69,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
74
69
  isPreviewModeOpen: boolean;
75
70
  editorVisualMode: string;
76
71
  hasChanges: boolean;
77
- changeSeq: number;
78
72
  isStripoInitialized: boolean;
79
73
  templateId: string;
80
74
  syncModulesEnabled: boolean;
@@ -87,7 +81,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
87
81
  isPreviewModeOpen: boolean;
88
82
  editorVisualMode: string;
89
83
  hasChanges: boolean;
90
- changeSeq: number;
91
84
  isStripoInitialized: boolean;
92
85
  templateId: string;
93
86
  syncModulesEnabled: boolean;
@@ -101,7 +94,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
101
94
  isPreviewModeOpen: boolean;
102
95
  editorVisualMode: string;
103
96
  hasChanges: boolean;
104
- changeSeq: number;
105
97
  isStripoInitialized: boolean;
106
98
  templateId: string;
107
99
  syncModulesEnabled: boolean;
@@ -114,7 +106,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
114
106
  isPreviewModeOpen: boolean;
115
107
  editorVisualMode: string;
116
108
  hasChanges: boolean;
117
- changeSeq: number;
118
109
  isStripoInitialized: boolean;
119
110
  templateId: string;
120
111
  syncModulesEnabled: boolean;
@@ -128,7 +119,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
128
119
  isPreviewModeOpen: boolean;
129
120
  editorVisualMode: string;
130
121
  hasChanges: boolean;
131
- changeSeq: number;
132
122
  isStripoInitialized: boolean;
133
123
  templateId: string;
134
124
  syncModulesEnabled: boolean;
@@ -141,7 +131,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
141
131
  isPreviewModeOpen: boolean;
142
132
  editorVisualMode: string;
143
133
  hasChanges: boolean;
144
- changeSeq: number;
145
134
  isStripoInitialized: boolean;
146
135
  templateId: string;
147
136
  syncModulesEnabled: boolean;
@@ -155,7 +144,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
155
144
  isPreviewModeOpen: boolean;
156
145
  editorVisualMode: string;
157
146
  hasChanges: boolean;
158
- changeSeq: number;
159
147
  isStripoInitialized: boolean;
160
148
  templateId: string;
161
149
  syncModulesEnabled: boolean;
@@ -168,7 +156,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
168
156
  isPreviewModeOpen: boolean;
169
157
  editorVisualMode: string;
170
158
  hasChanges: boolean;
171
- changeSeq: number;
172
159
  isStripoInitialized: boolean;
173
160
  templateId: string;
174
161
  syncModulesEnabled: boolean;
@@ -182,7 +169,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
182
169
  isPreviewModeOpen: boolean;
183
170
  editorVisualMode: string;
184
171
  hasChanges: boolean;
185
- changeSeq: number;
186
172
  isStripoInitialized: boolean;
187
173
  templateId: string;
188
174
  syncModulesEnabled: boolean;
@@ -195,7 +181,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
195
181
  isPreviewModeOpen: boolean;
196
182
  editorVisualMode: string;
197
183
  hasChanges: boolean;
198
- changeSeq: number;
199
184
  isStripoInitialized: boolean;
200
185
  templateId: string;
201
186
  syncModulesEnabled: boolean;
@@ -209,7 +194,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
209
194
  isPreviewModeOpen: boolean;
210
195
  editorVisualMode: string;
211
196
  hasChanges: boolean;
212
- changeSeq: number;
213
197
  isStripoInitialized: boolean;
214
198
  templateId: string;
215
199
  syncModulesEnabled: boolean;
@@ -222,7 +206,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
222
206
  isPreviewModeOpen: boolean;
223
207
  editorVisualMode: string;
224
208
  hasChanges: boolean;
225
- changeSeq: number;
226
209
  isStripoInitialized: boolean;
227
210
  templateId: string;
228
211
  syncModulesEnabled: boolean;
@@ -236,7 +219,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
236
219
  isPreviewModeOpen: boolean;
237
220
  editorVisualMode: string;
238
221
  hasChanges: boolean;
239
- changeSeq: number;
240
222
  isStripoInitialized: boolean;
241
223
  templateId: string;
242
224
  syncModulesEnabled: boolean;
@@ -249,7 +231,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
249
231
  isPreviewModeOpen: boolean;
250
232
  editorVisualMode: string;
251
233
  hasChanges: boolean;
252
- changeSeq: number;
253
234
  isStripoInitialized: boolean;
254
235
  templateId: string;
255
236
  syncModulesEnabled: boolean;
@@ -263,7 +244,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
263
244
  isPreviewModeOpen: boolean;
264
245
  editorVisualMode: string;
265
246
  hasChanges: boolean;
266
- changeSeq: number;
267
247
  isStripoInitialized: boolean;
268
248
  templateId: string;
269
249
  syncModulesEnabled: boolean;
@@ -276,7 +256,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
276
256
  isPreviewModeOpen: boolean;
277
257
  editorVisualMode: string;
278
258
  hasChanges: boolean;
279
- changeSeq: number;
280
259
  isStripoInitialized: boolean;
281
260
  templateId: string;
282
261
  syncModulesEnabled: boolean;
@@ -290,7 +269,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
290
269
  isPreviewModeOpen: boolean;
291
270
  editorVisualMode: string;
292
271
  hasChanges: boolean;
293
- changeSeq: number;
294
272
  isStripoInitialized: boolean;
295
273
  templateId: string;
296
274
  syncModulesEnabled: boolean;
@@ -303,7 +281,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
303
281
  isPreviewModeOpen: boolean;
304
282
  editorVisualMode: string;
305
283
  hasChanges: boolean;
306
- changeSeq: number;
307
284
  isStripoInitialized: boolean;
308
285
  templateId: string;
309
286
  syncModulesEnabled: boolean;
@@ -317,7 +294,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
317
294
  isPreviewModeOpen: boolean;
318
295
  editorVisualMode: string;
319
296
  hasChanges: boolean;
320
- changeSeq: number;
321
297
  isStripoInitialized: boolean;
322
298
  templateId: string;
323
299
  syncModulesEnabled: boolean;
@@ -330,7 +306,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
330
306
  isPreviewModeOpen: boolean;
331
307
  editorVisualMode: string;
332
308
  hasChanges: boolean;
333
- changeSeq: number;
334
309
  isStripoInitialized: boolean;
335
310
  templateId: string;
336
311
  syncModulesEnabled: boolean;
@@ -1,41 +1,41 @@
1
- /** The published editor snapshot — the shape a consumer reads off the shared store. */
2
- export interface GuidoEmailEditorState {
1
+ /**
2
+ * Outbound contract Guido publishes to the host's shared Pinia singleton so
3
+ * cortex-fe can pick up the current editor state and forward it as
4
+ * `clientState.editor` on the next chat-stream POST.
5
+ *
6
+ * State + getters only — `useGuidoStateBridge` writes via `$patch`, no actions
7
+ * live here (architecture invariant).
8
+ *
9
+ * Store id `guidoEmailEditor` is cross-MFE: cortex-fe reads it via
10
+ * `pinia._s.get('guidoEmailEditor')` at runtime. The internal Guido editor
11
+ * store keeps id `guidoEditor` — these are intentionally separate. The
12
+ * internal store carries UI state that cortex-fe should not see; this public
13
+ * store carries the contract Guido is willing to share.
14
+ */
15
+ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", {
3
16
  /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
4
17
  html: string;
5
18
  /** Current Stripo CSS — es-p* utility classes used by the html. */
6
19
  css: string;
7
20
  /** Wall-clock ms when html/css were last written by the bridge. */
8
21
  lastUpdatedAt: number;
9
- /** Template id from the editor config, so a consumer can scope per-template. */
22
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
10
23
  templateId: string;
11
- }
12
- /**
13
- * Outbound contract Guido publishes to the host's shared Pinia singleton so a
14
- * consumer can read the current editor state: cortex-fe forwards it as
15
- * `clientState.editor` on the next chat-stream POST, email-fe scans it for the
16
- * Array of Objects lock.
17
- *
18
- * Published as `@useinsider/guido/editor-state` and from the root barrel, so a
19
- * consumer imports this store instead of re-declaring one under the same id.
20
- *
21
- * State + getters only, no actions. `useGuidoStateBridge` is the only intended
22
- * writer, but that is Guido's own convention rather than something the store
23
- * enforces: publishing the definition hands a consumer `$patch` as well, exactly
24
- * as the runtime `pinia._s` probe always did.
25
- *
26
- * Store id `guidoEmailEditor` is cross-MFE: cortex-fe reads it via
27
- * `pinia._s.get('guidoEmailEditor')` at runtime rather than importing it, so the
28
- * id stays part of the contract. The internal Guido editor store keeps id
29
- * `guidoEditor` — these are intentionally separate. The internal store carries
30
- * UI state a consumer should not see; this public store carries the contract
31
- * Guido is willing to share.
32
- */
33
- export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", GuidoEmailEditorState, {
24
+ }, {
34
25
  /** True once the bridge has published at least one snapshot. */
35
26
  hasSnapshot: (state: {
36
27
  html: string;
37
28
  css: string;
38
29
  lastUpdatedAt: number;
39
30
  templateId: string;
40
- } & import("pinia").PiniaCustomStateProperties<GuidoEmailEditorState>) => boolean;
31
+ } & import("pinia").PiniaCustomStateProperties<{
32
+ /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
33
+ html: string;
34
+ /** Current Stripo CSS — es-p* utility classes used by the html. */
35
+ css: string;
36
+ /** Wall-clock ms when html/css were last written by the bridge. */
37
+ lastUpdatedAt: number;
38
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
39
+ templateId: string;
40
+ }>) => boolean;
41
41
  }, {}>;
@@ -30,3 +30,9 @@ export declare const replaceString: (string?: string, values?: Record<string, st
30
30
  * a string nor a number becomes ''.
31
31
  */
32
32
  export declare const asText: (value: unknown) => string;
33
+ /**
34
+ * Narrows an unknown API value to a plain JSON object. Arrays and exotic
35
+ * objects (Blob, Date, FormData) are rejected, so a response body that useHttp
36
+ * parsed as text or blob can never be read as a JSON payload.
37
+ */
38
+ export declare const isPlainObject: <T>(value: T) => value is T & Record<string, unknown>;
@@ -8,10 +8,6 @@ const o = e("guidoEditor", {
8
8
  isPreviewModeOpen: !1,
9
9
  editorVisualMode: "desktop",
10
10
  hasChanges: !1,
11
- // Bumped on every Stripo document change. `hasChanges` is a latch that stays
12
- // true until a save, so it cannot signal the second edit onwards; watchers
13
- // that need every change (the outbound state bridge) watch this instead.
14
- changeSeq: 0,
15
11
  isStripoInitialized: !1,
16
12
  templateId: "",
17
13
  syncModulesEnabled: !1,
@@ -1,9 +1,13 @@
1
1
  import { defineStore as e } from "pinia";
2
2
  const d = e("guidoEmailEditor", {
3
3
  state: () => ({
4
+ /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
4
5
  html: "",
6
+ /** Current Stripo CSS — es-p* utility classes used by the html. */
5
7
  css: "",
8
+ /** Wall-clock ms when html/css were last written by the bridge. */
6
9
  lastUpdatedAt: 0,
10
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
7
11
  templateId: ""
8
12
  }),
9
13
  getters: {
@@ -1,69 +1,75 @@
1
- const o = (t) => {
2
- const a = t.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((l) => l.trim()), [s] = a, r = {
3
- text: t.label,
1
+ const o = (a) => {
2
+ const t = a.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((e) => e.trim()), [s] = t, r = {
3
+ text: a.label,
4
4
  value: s || ""
5
5
  };
6
- if (a.length >= 2) {
7
- const [, l, e] = a;
8
- if (l.startsWith("default:")) {
9
- let n = l.slice(8).trim();
6
+ if (t.length >= 2) {
7
+ const [, e, l] = t;
8
+ if (e.startsWith("default:")) {
9
+ let n = e.slice(8).trim();
10
10
  n.startsWith('"') && n.endsWith('"') && (n = n.slice(1, -1)), r.fallback = n;
11
11
  } else {
12
- const n = l.includes("=") ? { key: l.split("=")[0].trim(), value: l.split("=")[1].trim() } : null;
13
- n ? r.format = n : e || (r.fallback = l), e && (r.fallback = e);
12
+ const n = e.includes("=") ? { key: e.split("=")[0].trim(), value: e.split("=")[1].trim() } : null;
13
+ n ? r.format = n : l || (r.fallback = e), l && (r.fallback = l);
14
14
  }
15
15
  }
16
16
  return r;
17
- }, f = (t, c = !1) => t.map((a) => {
18
- if (a.format)
17
+ }, u = (a, c = !1) => a.map((t) => {
18
+ if (t.format)
19
19
  return {
20
- label: `${a.text} | ${a.format.key}=${a.format.value}`,
21
- value: `{{${a.value}|${a.format.key}=${a.format.value}}}`
20
+ label: `${t.text} | ${t.format.key}=${t.format.value}`,
21
+ value: `{{${t.value}|${t.format.key}=${t.format.value}}}`
22
22
  };
23
23
  if (c) {
24
- if (!a.fallback)
24
+ if (!t.fallback)
25
25
  return {
26
- label: a.text,
27
- value: `{{ ${a.value} }}`
26
+ label: t.text,
27
+ value: `{{ ${t.value} }}`
28
28
  };
29
- const r = !Number.isNaN(Number(a.fallback)) && a.fallback.trim() !== "" ? a.fallback : `"${a.fallback}"`;
29
+ const r = !Number.isNaN(Number(t.fallback)) && t.fallback.trim() !== "" ? t.fallback : `"${t.fallback}"`;
30
30
  return {
31
- label: `${a.text} | ${a.fallback}`,
32
- value: `{{ ${a.value} | default: ${r} }}`
31
+ label: `${t.text} | ${t.fallback}`,
32
+ value: `{{ ${t.value} | default: ${r} }}`
33
33
  };
34
34
  }
35
35
  return {
36
- label: a.fallback ? `${a.text} | ${a.fallback}` : a.text,
37
- value: a.fallback ? `{{${a.value}|${a.fallback}}}` : `{{${a.value}}}`
36
+ label: t.fallback ? `${t.text} | ${t.fallback}` : t.text,
37
+ value: t.fallback ? `{{${t.value}|${t.fallback}}}` : `{{${t.value}}}`
38
38
  };
39
- }), b = (t) => {
40
- const c = [], a = /* @__PURE__ */ new Set(), s = (l) => {
41
- Array.isArray(l) && l.forEach((e) => {
42
- const n = [...e.children ?? [], ...e.select_items ?? []];
39
+ }), b = (a) => {
40
+ const c = [], t = /* @__PURE__ */ new Set(), s = (e) => {
41
+ Array.isArray(e) && e.forEach((l) => {
42
+ const n = [...l.children ?? [], ...l.select_items ?? []];
43
43
  if (n.length > 0) {
44
44
  s(n);
45
45
  return;
46
46
  }
47
- const u = e.text || e.tag_text;
48
- u && e.value && !a.has(e.value) && (a.add(e.value), c.push({ text: u, value: e.value }));
47
+ const f = l.text || l.tag_text;
48
+ f && l.value && !t.has(l.value) && (t.add(l.value), c.push({ text: f, value: l.value }));
49
49
  });
50
- }, [r] = Object.values(t ?? {});
50
+ }, [r] = Object.values(a ?? {});
51
51
  return s(r), c;
52
- }, i = (t, c, a = !1) => {
53
- const s = new Set(t.map((l) => l.value)), r = c.filter((l) => s.has(l.value) ? !1 : (s.add(l.value), !0));
52
+ }, i = (a, c, t = !1) => {
53
+ const s = new Set(a.map((e) => e.value)), r = c.filter((e) => s.has(e.value) ? !1 : (s.add(e.value), !0));
54
54
  return [
55
- ...f(t, a),
56
- ...f(r, a)
55
+ ...u(a, t),
56
+ ...u(r, t)
57
57
  ];
58
- }, v = () => {
59
- var t;
60
- return ((t = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : t.getAttribute("content")) ?? "";
61
- }, k = (t) => typeof t == "string" ? t : typeof t == "number" ? String(t) : "";
58
+ }, k = () => {
59
+ var a;
60
+ return ((a = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : a.getAttribute("content")) ?? "";
61
+ }, v = (a) => typeof a == "string" ? a : typeof a == "number" ? String(a) : "", y = (a) => {
62
+ if (a === null || typeof a != "object" || Array.isArray(a))
63
+ return !1;
64
+ const c = Object.getPrototypeOf(a);
65
+ return c === Object.prototype || c === null;
66
+ };
62
67
  export {
63
- k as asText,
68
+ v as asText,
64
69
  i as buildMergeTagEntries,
65
- f as dynamicContentToMergeTags,
70
+ u as dynamicContentToMergeTags,
66
71
  b as flattenDynamicContentList,
67
- v as getCsrfToken,
72
+ k as getCsrfToken,
73
+ y as isPlainObject,
68
74
  o as mergeTagToDynamicContent
69
75
  };
@@ -1,30 +1,31 @@
1
1
  import { useActionsApi as k } from "../composables/useActionsApi.js";
2
2
  import { useConfig as U } from "../composables/useConfig.js";
3
3
  import { useHtmlCompiler as x } from "../composables/useHtmlCompiler.js";
4
- import { DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as a } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
5
- import { useRecommendationExtensionStore as T } from "../extensions/Blocks/Recommendation/store/recommendation.js";
4
+ import { DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as n } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
5
+ import { useRecommendationExtensionStore as A } from "../extensions/Blocks/Recommendation/store/recommendation.js";
6
6
  import { mapLegacyStrategy as L } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
7
- import { DATA_ATTRIBUTES as C } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
7
+ import { DATA_ATTRIBUTES as T } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
8
8
  import { parsePageList as R } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
9
9
  import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
10
10
  import { useEditorStore as z } from "../stores/editor.js";
11
- import { useUnsubscribeStore as _ } from "../stores/unsubscribe.js";
11
+ import { useUnsubscribeStore as O } from "../stores/unsubscribe.js";
12
+ import { isPlainObject as _ } from "./genericUtil.js";
12
13
  import { assignTrackingIds as v } from "./linkTrackingIds.js";
13
- function O(l) {
14
- const c = new DOMParser().parseFromString(l, "text/html").querySelectorAll(`[${C.PAGE_LIST}]`), t = [];
15
- return c.forEach((i) => {
16
- const o = i.getAttribute(C.PAGE_LIST);
14
+ function M(l) {
15
+ const i = new DOMParser().parseFromString(l, "text/html").querySelectorAll(`[${T.PAGE_LIST}]`), t = [];
16
+ return i.forEach((c) => {
17
+ const o = c.getAttribute(T.PAGE_LIST);
17
18
  o && t.push(...R(o));
18
19
  }), [...new Set(t)];
19
20
  }
20
- async function M(l) {
21
- const n = new DOMParser().parseFromString(l, "text/html").querySelectorAll(".recommendation-block-v2");
22
- if (n.length === 0)
21
+ async function q(l) {
22
+ const a = new DOMParser().parseFromString(l, "text/html").querySelectorAll(".recommendation-block-v2");
23
+ if (a.length === 0)
23
24
  return;
24
- const c = T();
25
- n.forEach((t) => {
25
+ const i = A();
26
+ a.forEach((t) => {
26
27
  var r, d, g, f, s, y;
27
- const i = t.getAttribute("recommendation-id"), o = i ? Number(i) : NaN;
28
+ const c = t.getAttribute("recommendation-id"), o = c ? Number(c) : NaN;
28
29
  if (!Number.isFinite(o))
29
30
  return;
30
31
  const p = t.getAttribute("esd-ext-config");
@@ -36,21 +37,21 @@ async function M(l) {
36
37
  } catch {
37
38
  return;
38
39
  }
39
- if (!e || typeof e != "object" || Array.isArray(e))
40
+ if (!_(e))
40
41
  return;
41
42
  const b = {
42
43
  // Normalize legacy strategy keys (e.g. `mostViewed` → `mostPopular`) so
43
44
  // already-saved blocks that never re-run the migrator don't emit a
44
45
  // strategy-less campaign URL. `||` also catches '' / undefined (SD-144882).
45
- strategy: L(e.strategy) || a.strategy,
46
- strategyId: e.strategyId ?? a.strategyId,
47
- language: e.language ?? a.language,
48
- size: e.size ?? a.size,
46
+ strategy: L(e.strategy) || n.strategy,
47
+ strategyId: e.strategyId ?? n.strategyId,
48
+ language: e.language ?? n.language,
49
+ size: e.size ?? n.size,
49
50
  // Spread the default arrays so each block gets a fresh reference
50
51
  // instead of sharing the singleton in DEFAULT_NODE_CONFIG.
51
- productIds: e.productIds ?? [...a.productIds],
52
- filters: e.filters ?? [...a.filters],
53
- shuffleProducts: e.shuffleProducts ?? a.shuffleProducts,
52
+ productIds: e.productIds ?? [...n.productIds],
53
+ filters: e.filters ?? [...n.filters],
54
+ shuffleProducts: e.shuffleProducts ?? n.shuffleProducts,
54
55
  currencyCode: ((r = e.currency) == null ? void 0 : r.code) ?? m.code,
55
56
  currencySymbol: ((d = e.currency) == null ? void 0 : d.symbol) ?? m.symbol,
56
57
  currencyAlignment: ((g = e.currency) == null ? void 0 : g.alignment) ?? m.alignment,
@@ -58,10 +59,10 @@ async function M(l) {
58
59
  currencyDecimalSeparator: ((s = e.currency) == null ? void 0 : s.decimalSeparator) ?? m.decimalSeparator,
59
60
  currencyThousandSeparator: ((y = e.currency) == null ? void 0 : y.thousandSeparator) ?? m.thousandSeparator
60
61
  };
61
- c.seedBlockUrlConfig(o, b);
62
+ i.seedBlockUrlConfig(o, b);
62
63
  });
63
64
  try {
64
- await c.fetchRecommendationCreateData();
65
+ await i.fetchRecommendationCreateData();
65
66
  } catch (t) {
66
67
  console.warn(
67
68
  "Recommendation reference data pre-load failed; validator will skip the availability check.",
@@ -69,24 +70,24 @@ async function M(l) {
69
70
  );
70
71
  }
71
72
  }
72
- const Z = () => {
73
- const l = N(), u = z(), n = _(), { getCompiledEmail: c, getTemplateData: t, updateHtmlAndCss: i } = k(), { compileHtml: o, compileAmpHtml: p } = x(), { isFeatureEnabled: e } = U();
73
+ const te = () => {
74
+ const l = N(), u = z(), a = O(), { getCompiledEmail: i, getTemplateData: t, updateHtmlAndCss: c } = k(), { compileHtml: o, compileAmpHtml: p } = x(), { isFeatureEnabled: e } = U();
74
75
  return {
75
76
  prepareTemplateDetails: async () => {
76
77
  let { html: r, css: d, syncModulesIds: g = [] } = await t();
77
78
  if (e("linkTrackingIds"))
78
79
  try {
79
80
  const { html: h, changed: F, nextSeq: H } = v(r, u.trackIdSessionFloor);
80
- u.trackIdSessionFloor = H, F && (r = h, await i(h, d));
81
+ u.trackIdSessionFloor = H, F && (r = h, await c(h, d));
81
82
  } catch (h) {
82
83
  console.error("Tracking-id step failed, saving anyway:", h);
83
84
  }
84
- const { html: f, ampHtml: s = "", ampErrors: y = [] } = await c({
85
+ const { html: f, ampHtml: s = "", ampErrors: y = [] } = await i({
85
86
  minimize: !0,
86
87
  resetDataSavedFlag: !1
87
88
  });
88
- n.selectedUnsubscribePages.length && await n.fetchTemplates(), await M(r);
89
- const { compiledHtml: I, stats: S, appliedRules: w } = o(f), D = s && p(s).compiledHtml, E = l.getSelectedDynamicContentList, P = T(), A = O(r);
89
+ a.selectedUnsubscribePages.length && await a.fetchTemplates(), await q(r);
90
+ const { compiledHtml: I, stats: S, appliedRules: w } = o(f), D = s && p(s).compiledHtml, P = l.getSelectedDynamicContentList, E = A(), C = M(r);
90
91
  return console.debug("HTML Compilation Stats:", {
91
92
  originalSize: S.originalSize,
92
93
  compiledSize: S.compiledSize,
@@ -94,7 +95,7 @@ const Z = () => {
94
95
  appliedRules: w,
95
96
  executionTime: `${S.executionTime.toFixed(2)}ms`
96
97
  }), {
97
- dynamicContentList: E,
98
+ dynamicContentList: P,
98
99
  compiledHtml: I,
99
100
  rawHtml: r,
100
101
  css: d,
@@ -102,18 +103,18 @@ const Z = () => {
102
103
  ampErrors: y,
103
104
  modules: g.map(Number),
104
105
  recommendation: {
105
- campaignUrls: P.recommendationCampaignUrls,
106
+ campaignUrls: E.recommendationCampaignUrls,
106
107
  configs: {}
107
108
  },
108
109
  unsubscribe: {
109
- status: A.length > 0,
110
- config: A
110
+ status: C.length > 0,
111
+ config: C
111
112
  }
112
113
  };
113
114
  }
114
115
  };
115
116
  };
116
117
  export {
117
- O as getHtmlReferencedUnsubscribePages,
118
- Z as useTemplatePreparation
118
+ M as getHtmlReferencedUnsubscribePages,
119
+ te as useTemplatePreparation
119
120
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.18.2-beta.83b62a8",
3
+ "version": "3.18.2-beta.8ef3138",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -18,10 +18,6 @@
18
18
  "types": "./dist/src/public/trackingIds.d.ts",
19
19
  "import": "./dist/public/trackingIds.js"
20
20
  },
21
- "./editor-state": {
22
- "types": "./dist/src/public/editorState.d.ts",
23
- "import": "./dist/public/editorState.js"
24
- },
25
21
  "./style": "./dist/guido.css"
26
22
  },
27
23
  "scripts": {
@@ -1,4 +0,0 @@
1
- import { useGuidoEmailEditorStore as e } from "../stores/guido-email-editor.js";
2
- export {
3
- e as useGuidoEmailEditorStore
4
- };
@@ -1,14 +0,0 @@
1
- /**
2
- * Published as `@useinsider/guido/editor-state` — the live editor snapshot Guido
3
- * writes into the host's shared Pinia singleton.
4
- *
5
- * Importing from here pulls in nothing but pinia, so the editor never enters a
6
- * consumer's module graph. Re-export surface only: this is the contract,
7
- * `stores/guido-email-editor` is the implementation and stays free to move.
8
- *
9
- * Consumers read the store by importing it; the id `guidoEmailEditor` remains
10
- * part of the contract for cortex-fe, which probes `pinia._s` at runtime instead
11
- * of taking a build-time dependency on this package.
12
- */
13
- export { useGuidoEmailEditorStore } from '../stores/guido-email-editor';
14
- export type { GuidoEmailEditorState } from '../stores/guido-email-editor';