@useinsider/guido 3.19.0-beta.f884c35 → 3.19.0-beta.f8f0007

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.
@@ -12,7 +12,7 @@ var t = function() {
12
12
  s,
13
13
  !1,
14
14
  null,
15
- "59690055"
15
+ "36867e2e"
16
16
  );
17
17
  const g = n.exports;
18
18
  export {
@@ -1,4 +1,4 @@
1
- import { defineComponent as re, defineAsyncComponent as m, ref as x, computed as p, watch as W, onMounted as se, onUnmounted as ae } from "vue";
1
+ import { defineComponent as re, defineAsyncComponent as m, ref as O, computed as u, watch as x, onMounted as se, onUnmounted as ae } from "vue";
2
2
  import { useCortexBlueprintBridge as ie } from "../composables/useCortexBlueprintBridge.js";
3
3
  import { useEditorLock as ce } from "../composables/useEditorLock.js";
4
4
  import { provideGuidoActions as de } from "../composables/useGuidoActions.js";
@@ -6,25 +6,25 @@ import { useGuidoStateBridge as me } from "../composables/useGuidoStateBridge.js
6
6
  import { usePartner as le } from "../composables/usePartner.js";
7
7
  import { useStripo as ue } from "../composables/useStripo.js";
8
8
  import { useTimerClone as pe } from "../composables/useTimerClone.js";
9
- import { migrate as G } from "../config/migrator/index.js";
10
- import { ModuleFolderDefaults as z } from "../enums/defaults.js";
9
+ import { migrate as W } from "../config/migrator/index.js";
10
+ import { ModuleFolderDefaults as G } from "../enums/defaults.js";
11
11
  import { RIBBON_SELECTOR as fe } from "../enums/onboarding.js";
12
- import { useRecommendationExtensionStore as E } from "../extensions/Blocks/Recommendation/store/recommendation.js";
12
+ import { useRecommendationExtensionStore as h } from "../extensions/Blocks/Recommendation/store/recommendation.js";
13
13
  import ye from "./organisms/AutoSaveController.vue.js";
14
14
  import ge from "./organisms/base/Toaster.vue.js";
15
15
  import ve from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
16
16
  import Se from "./organisms/header/HeaderWrapper.vue.js";
17
- import he from "./organisms/LoadingWrapper.vue.js";
18
- import be from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
17
+ import be from "./organisms/LoadingWrapper.vue.js";
18
+ import he from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
19
19
  import Ee from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
20
20
  import { useStripoApi as we } from "../services/stripoApi.js";
21
21
  import { useConfigStore as Ce } from "../stores/config.js";
22
22
  import { useDynamicContentStore as De } from "../stores/dynamic-content.js";
23
- import { useEditorStore as w } from "../stores/editor.js";
23
+ import { useEditorStore as H } from "../stores/editor.js";
24
24
  import { usePreviewStore as ke } from "../stores/preview.js";
25
- import { useTemplateStore as Fe } from "../stores/template.js";
26
- import { useUnsubscribeStore as Te } from "../stores/unsubscribe.js";
27
- import { readTrackFloor as H } from "../utils/linkTrackingIds.js";
25
+ import { useTemplateStore as Te } from "../stores/template.js";
26
+ import { useUnsubscribeStore as Fe } from "../stores/unsubscribe.js";
27
+ import { readTrackFloor as $ } from "../utils/linkTrackingIds.js";
28
28
  const tt = /* @__PURE__ */ re({
29
29
  __name: "Guido",
30
30
  props: {
@@ -32,8 +32,8 @@ const tt = /* @__PURE__ */ re({
32
32
  ready: { type: Boolean, default: !0 }
33
33
  },
34
34
  emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
35
- setup($, { expose: q, emit: r }) {
36
- const a = $, K = m(
35
+ setup(z, { expose: q, emit: r }) {
36
+ const a = z, K = m(
37
37
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
38
38
  ), V = m(
39
39
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
@@ -43,32 +43,32 @@ const tt = /* @__PURE__ */ re({
43
43
  () => import("./organisms/extensions/recommendation/RemoveStrategyModal.vue.js")
44
44
  ), Q = m(
45
45
  () => import("./organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js")
46
- ), C = x(), f = x(), y = De(), D = Te(), o = Ce();
46
+ ), E = O(), p = O(), f = De(), w = Fe(), o = Ce();
47
47
  a.ready && o.init(a.config);
48
- const c = w(), X = ke(), l = p(() => c.hasChanges), { isTestPartner: Y } = le(), k = () => {
48
+ const c = H(), X = ke(), l = u(() => c.hasChanges), { isTestPartner: Y } = le(), C = () => {
49
49
  var t;
50
- return (t = C.value) == null ? void 0 : t.handleSave(!0);
51
- }, F = (t) => {
50
+ return (t = E.value) == null ? void 0 : t.handleSave(!0);
51
+ }, D = (t) => {
52
52
  c.loadingStatus = t;
53
53
  };
54
54
  ie(), me();
55
- const g = () => {
55
+ const y = () => {
56
56
  var t, e;
57
57
  return {
58
58
  emailId: o.templateId,
59
59
  userId: o.userId,
60
60
  username: o.username,
61
61
  partnerName: o.partnerName,
62
- savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || z.SAVED_MODULES,
63
- defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || z.DEFAULT_MODULES
62
+ savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || G.SAVED_MODULES,
63
+ defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || G.DEFAULT_MODULES
64
64
  };
65
- }, { initPlugin: T, preloadRuntime: I } = ue(), { runExclusive: M, beginMount: R, isCurrentMount: v } = ce();
66
- let u = 0;
67
- const { getDefaultTemplate: L } = we(), { cloneTimersOnSave: B, hasTimerBlocks: U } = pe(), Z = p(() => {
65
+ }, { initPlugin: k, preloadRuntime: T } = ue(), { runExclusive: F, beginMount: M, isCurrentMount: R } = ce();
66
+ let g = 0;
67
+ const { getDefaultTemplate: I } = we(), { cloneTimersOnSave: L, hasTimerBlocks: B } = pe(), Z = u(() => {
68
68
  var t;
69
69
  return !((t = o.ui) != null && t.showHeader);
70
- }), ee = p(() => o.isFeatureEnabled("reusableRecommendationStrategy")), te = p(
71
- () => !!E().recommendationConfigs.strategyId
70
+ }), ee = u(() => o.isFeatureEnabled("reusableRecommendationStrategy")), te = u(
71
+ () => !!h().recommendationConfigs.strategyId
72
72
  );
73
73
  de({
74
74
  onBack: () => {
@@ -78,76 +78,70 @@ const tt = /* @__PURE__ */ re({
78
78
  console.debug("guido:save:start"), r("save:start");
79
79
  },
80
80
  onSaveComplete: (t) => {
81
- const e = { ...t, metadata: g() };
81
+ const e = { ...t, metadata: y() };
82
82
  console.debug("guido:save:complete", e), r("save:complete", e);
83
83
  },
84
84
  onTestEmailClick: () => {
85
85
  console.debug("guido:test-email:click"), r("test-email:click");
86
86
  }
87
87
  });
88
- const A = (t) => {
89
- console.debug("dynamic-content:close", t), y.setSelectedDynamicContent(t), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: t }));
90
- }, P = () => {
88
+ const U = (t) => {
89
+ console.debug("dynamic-content:close", t), f.setSelectedDynamicContent(t), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: t }));
90
+ }, A = () => {
91
91
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
92
92
  };
93
- W(() => l.value, () => {
93
+ x(() => l.value, () => {
94
94
  r("on-change", l.value);
95
95
  });
96
- const S = (t) => {
96
+ const v = (t) => {
97
97
  const e = t, { attribute: s, position: d } = e.detail;
98
98
  console.debug("dynamic-content:open", e.detail), r("dynamic-content:open", s, d);
99
99
  };
100
100
  let i = null;
101
- const h = () => {
101
+ const S = () => {
102
102
  var e;
103
103
  const t = document.querySelector(fe);
104
- (e = f.value) == null || e.style.setProperty("--ribbon-offset", `${(t == null ? void 0 : t.offsetHeight) ?? 0}px`);
104
+ (e = p.value) == null || e.style.setProperty("--ribbon-offset", `${(t == null ? void 0 : t.offsetHeight) ?? 0}px`);
105
105
  }, b = async () => {
106
106
  var t;
107
107
  try {
108
108
  o.initialized || o.init(a.config), c.templateId = o.templateId;
109
- const e = o.template, s = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", _ = (e == null ? void 0 : e.preselectedDynamicContent) || [];
110
- D.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
111
- const N = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, O = o.isFeatureEnabled("linkTrackingIds");
109
+ const e = o.template, s = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", P = (e == null ? void 0 : e.preselectedDynamicContent) || [];
110
+ w.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
111
+ const _ = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, N = o.isFeatureEnabled("linkTrackingIds");
112
112
  let n = {
113
- html: s && await G(s, N),
113
+ html: s && await W(s, _),
114
114
  css: d
115
115
  };
116
- n.html || (n = await L(), n.html = await G(n.html, N));
117
- const oe = O ? H(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
118
- U(n.html) && (n.html = await B(n.html)), O && (c.trackIdSessionFloor = Math.max(oe, H(n.html)));
116
+ n.html || (n = await I(), n.html = await W(n.html, _));
117
+ const oe = N ? $(n.html, (e == null ? void 0 : e.trackIdCounter) || 0) : 0;
118
+ B(n.html) && (n.html = await L(n.html)), N && (c.trackIdSessionFloor = Math.max(oe, $(n.html)));
119
119
  const ne = {
120
- preselectedDynamicContentList: _,
120
+ preselectedDynamicContentList: P,
121
121
  onReady: () => {
122
122
  console.debug("guido:ready"), r("ready");
123
123
  }
124
124
  };
125
- u = R(), await T(n, g(), ne), y.selectedDynamicContentList = _;
125
+ g = M(), await k(n, y(), ne), f.selectedDynamicContentList = P;
126
126
  } catch (e) {
127
127
  console.error("Failed to initialize Stripo editor:", e);
128
128
  }
129
129
  };
130
130
  return se(async () => {
131
131
  var e;
132
- console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), E().$reset(), w().$reset(), Fe().$reset(), h();
133
- const t = (e = f.value) == null ? void 0 : e.parentElement;
134
- if (t && (i = new ResizeObserver(h), i.observe(t)), I(), a.ready)
132
+ console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), h().$reset(), H().$reset(), Te().$reset(), S();
133
+ const t = (e = p.value) == null ? void 0 : e.parentElement;
134
+ if (t && (i = new ResizeObserver(S), i.observe(t)), T(), a.ready)
135
135
  await b();
136
136
  else {
137
- const s = W(() => a.ready, (d) => {
137
+ const s = x(() => a.ready, (d) => {
138
138
  d && (s(), b());
139
139
  });
140
140
  }
141
- document.addEventListener("dynamic-content:open", S);
141
+ document.addEventListener("dynamic-content:open", v);
142
142
  }), ae(() => {
143
- if (i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", S), E().disposeStrategyPageReturn(), v(u))
144
- try {
145
- w().isStripoInitialized = !1;
146
- } catch (t) {
147
- console.debug("Failed to close the editor readiness gate on unmount", t);
148
- }
149
- M(async () => {
150
- if (v(u))
143
+ i == null || i.disconnect(), document.removeEventListener("dynamic-content:open", v), h().disposeStrategyPageReturn(), F(async () => {
144
+ if (R(g))
151
145
  try {
152
146
  window.UIEditor.removeEditor();
153
147
  } catch {
@@ -156,13 +150,13 @@ const tt = /* @__PURE__ */ re({
156
150
  }), o.reset();
157
151
  }), q({
158
152
  dynamicContent: {
159
- insert: A,
160
- close: P
153
+ insert: U,
154
+ close: A
161
155
  },
162
156
  hasChanges: l,
163
- saveSilent: k,
164
- setLoading: F
165
- }), { __sfc: !0, PreviewContainer: K, OnboardingWrapper: V, AssignStrategyDrawer: j, RemoveStrategyModal: J, LegacyStrategyUpdatedModal: Q, headerWrapperRef: C, wrapperRef: f, dynamicContentStore: y, unsubscribeStore: D, props: a, configStore: o, editorStore: c, previewStore: X, hasChanges: l, isTestPartner: Y, saveSilent: k, setLoading: F, emit: r, buildMetadata: g, initPlugin: T, preloadRuntime: I, runExclusive: M, beginMount: R, isCurrentMount: v, mountGeneration: u, getDefaultTemplate: L, cloneTimersOnSave: B, hasTimerBlocks: U, noHeader: Z, isRrsEnabled: ee, hasAssignedStrategy: te, insertDynamicContent: A, closeDynamicContent: P, handleDynamicContentOpen: S, ribbonObserver: i, updateRibbonOffset: h, startEditor: b, AutoSaveController: ye, Toaster: ge, FilterSelectionDrawer: ve, HeaderWrapper: Se, LoadingWrapper: he, SaveAsTemplateDrawer: be, UnsubscribeWrapper: Ee };
157
+ saveSilent: C,
158
+ setLoading: D
159
+ }), { __sfc: !0, PreviewContainer: K, OnboardingWrapper: V, AssignStrategyDrawer: j, RemoveStrategyModal: J, LegacyStrategyUpdatedModal: Q, headerWrapperRef: E, wrapperRef: p, dynamicContentStore: f, unsubscribeStore: w, props: a, configStore: o, editorStore: c, previewStore: X, hasChanges: l, isTestPartner: Y, saveSilent: C, setLoading: D, emit: r, buildMetadata: y, initPlugin: k, preloadRuntime: T, runExclusive: F, beginMount: M, isCurrentMount: R, mountGeneration: g, getDefaultTemplate: I, cloneTimersOnSave: L, hasTimerBlocks: B, noHeader: Z, isRrsEnabled: ee, hasAssignedStrategy: te, insertDynamicContent: U, closeDynamicContent: A, handleDynamicContentOpen: v, ribbonObserver: i, updateRibbonOffset: S, startEditor: b, AutoSaveController: ye, Toaster: ge, FilterSelectionDrawer: ve, HeaderWrapper: Se, LoadingWrapper: be, SaveAsTemplateDrawer: he, UnsubscribeWrapper: Ee };
166
160
  }
167
161
  });
168
162
  export {
@@ -1,138 +1,70 @@
1
- import { useEmailTemplateApplier as z, resetEmailTemplateApplier as J } from "./useEmailTemplateApplier.js";
2
- import { useToaster as Q } from "./useToaster.js";
3
- import { useTranslations as V } from "./useTranslations.js";
4
- import { ToasterTypeOptions as Z } from "../enums/toaster.js";
5
- import { useGuidoEmailEditorStore as W } from "../stores/guido-email-editor.js";
6
- import { getActivePinia as k } from "pinia";
7
- import { onUnmounted as tt, watch as et } from "vue";
8
- const rt = "email_template", nt = "chat", ot = "guido:debug:ai", it = 2, lt = 500, ct = (b, p) => `${b}:${p ?? 1}`;
9
- let S = null;
10
- const at = () => {
1
+ import { useEmailTemplateApplier as w, resetEmailTemplateApplier as _ } from "./useEmailTemplateApplier.js";
2
+ import { useToaster as I } from "./useToaster.js";
3
+ import { useTranslations as P } from "./useTranslations.js";
4
+ import { ToasterTypeOptions as S } from "../enums/toaster.js";
5
+ import { getActivePinia as v } from "pinia";
6
+ import { watch as B, onUnmounted as D } from "vue";
7
+ const x = "email_template", L = "chat", M = "guido:debug:ai", R = () => {
11
8
  if (typeof window > "u")
12
9
  return !1;
13
10
  try {
14
- return window.localStorage.getItem(ot) === "1";
11
+ return window.localStorage.getItem(M) === "1";
15
12
  } catch {
16
13
  return !1;
17
14
  }
18
- }, bt = () => {
19
- const b = k();
20
- if (!b)
15
+ }, H = () => {
16
+ const c = v();
17
+ if (!c)
21
18
  return;
22
- const p = W(), M = Symbol("cortexBlueprintBridge");
23
- S = M, p.$patch((t) => {
24
- t.bridgeActive = !0;
25
- });
26
- const { markPending: F, applyTemplate: H, applyTemplateDebounced: O } = z(), { showToaster: C } = Q(), G = V(), E = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
27
- let s = null;
28
- const d = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Set(), B = at();
29
- let w = null, m = null, A;
30
- const K = (t, r) => {
31
- B && console.debug(`[guido:cortex] msg=${t ?? "?"} type=${(r == null ? void 0 : r.type) ?? "?"}`, r);
32
- }, U = () => new Set((A == null ? void 0 : A.appliedBlueprintKeys) ?? []), Y = (t) => t instanceof Error ? t.message : String(t), D = (t, r, n, e) => {
33
- if (S !== M)
34
- return;
35
- const o = p.applyAcks[t], c = Math.max(Date.now(), ((o == null ? void 0 : o.ackAt) ?? 0) + 1), a = { status: r, requestedAt: n, ackAt: c };
36
- e !== void 0 && (a.error = Y(e)), p.$patch((l) => {
37
- l.applyAcks = { ...l.applyAcks, [t]: a };
38
- });
39
- }, I = (t) => (d.get(t) ?? 0) > 0, P = (t) => (s == null ? void 0 : s.key) === t, v = async (t, r, n) => {
40
- var a, l, h;
41
- const e = ((a = r.blueprintData) == null ? void 0 : a.html) ?? "", o = ((l = r.blueprintData) == null ? void 0 : l.css) ?? "", c = r.applyRequestedAt ?? 0;
42
- d.set(t, (d.get(t) ?? 0) + 1);
43
- try {
44
- const i = n === "debounced" ? await O(t, { html: e, css: o }) : await H(t, { html: e, css: o });
45
- if (i.status === "superseded")
46
- return;
47
- if (i.status === "applied") {
48
- E.set(t, e), u.delete(t), D(t, "applied", c);
49
- return;
50
- }
51
- const y = u.get(t), j = (y == null ? void 0 : y.html) === e ? y.count + 1 : 1;
52
- u.set(t, { html: e, count: j }), D(t, "failed", c, i.error);
53
- } catch (i) {
54
- console.error("[guido:apply] apply threw before it could settle", i), D(t, "failed", c, i);
55
- } finally {
56
- d.set(t, (d.get(t) ?? 1) - 1);
57
- const i = T.get(t);
58
- i && !I(t) && (T.delete(t), P(t) && (((h = i.blueprintData) == null ? void 0 : h.html) ?? "") !== e && v(t, i, n));
59
- }
60
- }, N = (t) => {
61
- var h;
62
- if (t.blueprintType !== rt)
63
- return;
64
- const { blueprintId: r } = t, n = (h = t.blueprintData) == null ? void 0 : h.html;
65
- if (!r || !n)
66
- return;
67
- const e = ct(r, t.version);
68
- if (!t.applyRequested) {
69
- F(e);
19
+ const l = c._s, p = l == null ? void 0 : l.get(L);
20
+ if (!p)
21
+ return;
22
+ const { markPending: d, applyTemplate: f, applyTemplateDebounced: T } = w(), { showToaster: E } = I(), h = P(), y = (r, t) => {
23
+ const e = h(r);
24
+ return e === r ? t : e;
25
+ }, i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), u = R(), A = (r, t) => {
26
+ u && console.debug(`[guido:cortex] msg=${r ?? "?"} type=${(t == null ? void 0 : t.type) ?? "?"}`, t);
27
+ }, b = (r) => {
28
+ if (r.blueprintType !== x)
70
29
  return;
71
- }
72
- const o = t.applyRequestedAt ?? 0, c = _.get(e);
73
- if (c === void 0 || o > c) {
74
- const i = c === void 0;
75
- if (_.set(e, o), u.delete(e), (!s || o >= s.requestedAt) && (s = { key: e, requestedAt: o }), i && U().has(e)) {
76
- E.set(e, n);
77
- return;
78
- }
79
- v(e, t, "immediate");
30
+ const t = r.blueprintId, e = r.blueprintData;
31
+ if (!t || !(e != null && e.html))
80
32
  return;
81
- }
82
- const a = E.get(e);
83
- if (a === n || !P(e))
33
+ if (!r.applyRequested) {
34
+ d(t);
84
35
  return;
85
- const l = u.get(e);
86
- if (!((l == null ? void 0 : l.html) === n && l.count >= it)) {
87
- if (a === void 0) {
88
- if (I(e)) {
89
- T.set(e, t);
90
- return;
91
- }
92
- v(e, t, "immediate");
93
- return;
94
- }
95
- f.get(e) !== n && (f.set(e, n), v(e, t, "debounced").finally(() => {
96
- f.get(e) === n && f.delete(e);
97
- }));
98
36
  }
99
- }, R = (t) => t === void 0 || g.has(t) ? !1 : (g.add(t), C({
100
- type: Z.Error,
101
- message: G("newsletter.ai-template-failed")
102
- }), !0), X = (t) => {
103
- Array.isArray(t) && t.forEach((r) => {
104
- const n = r == null ? void 0 : r.id;
105
- (r == null ? void 0 : r.isError) === !0 && R(n) && B && console.debug(`[guido:cortex] message-level error id=${n}`, r);
106
- const e = r == null ? void 0 : r.segments;
107
- Array.isArray(e) && e.forEach((o) => {
108
- if (o)
109
- switch (K(n, o), o.type) {
110
- case "blueprint":
111
- N(o);
112
- break;
113
- case "error":
114
- R(n);
115
- break;
116
- }
37
+ const o = i.get(t);
38
+ o === void 0 ? (i.set(t, e.html), f(t, e)) : o !== e.html && (i.set(t, e.html), T(t, e));
39
+ }, s = (r) => r === void 0 || a.has(r) ? !1 : (a.add(r), E({
40
+ type: S.Error,
41
+ message: y("newsletter.ai-template-failed", "AI couldn't generate the template. Please try again.")
42
+ }), !0), m = B(
43
+ () => p.messages,
44
+ (r) => {
45
+ Array.isArray(r) && r.forEach((t) => {
46
+ const e = t == null ? void 0 : t.id;
47
+ (t == null ? void 0 : t.isError) === !0 && s(e) && u && console.debug(`[guido:cortex] message-level error id=${e}`, t);
48
+ const o = t == null ? void 0 : t.segments;
49
+ Array.isArray(o) && o.forEach((n) => {
50
+ if (n)
51
+ switch (A(e, n), n.type) {
52
+ case "blueprint":
53
+ b(n);
54
+ break;
55
+ case "error":
56
+ s(e);
57
+ break;
58
+ }
59
+ });
117
60
  });
118
- });
119
- }, $ = () => {
120
- w !== null && (clearInterval(w), w = null);
121
- }, q = () => {
122
- var t;
123
- return (t = b._s) == null ? void 0 : t.get(nt);
124
- }, L = (t) => {
125
- A = t, m = et(() => t.messages, X, { deep: !0, immediate: !0 });
126
- }, x = q();
127
- x ? L(x) : w = setInterval(() => {
128
- const t = q();
129
- t && ($(), L(t));
130
- }, lt), tt(() => {
131
- $(), m == null || m(), A = void 0, E.clear(), f.clear(), _.clear(), u.clear(), s = null, d.clear(), T.clear(), g.clear(), S === M && (S = null, p.$patch((t) => {
132
- t.bridgeActive = !1, t.applyAcks = {};
133
- }), J());
61
+ },
62
+ { deep: !0, immediate: !0 }
63
+ );
64
+ D(() => {
65
+ m(), i.clear(), a.clear(), _();
134
66
  });
135
67
  };
136
68
  export {
137
- bt as useCortexBlueprintBridge
69
+ H as useCortexBlueprintBridge
138
70
  };
@@ -1,115 +1,59 @@
1
- import { useActionsApi as z } from "./useActionsApi.js";
2
- import { useConfig as N } from "./useConfig.js";
3
- import { useEditorLock as K } from "./useEditorLock.js";
4
- import { useToaster as R } from "./useToaster.js";
5
- import { useTranslations as F } from "./useTranslations.js";
6
- import { ToasterTypeOptions as v } from "../enums/toaster.js";
7
- import { useDynamicContentStore as G } from "../stores/dynamic-content.js";
8
- import { useEditorStore as $ } from "../stores/editor.js";
9
- import { flattenDynamicContentList as j } from "../utils/genericUtil.js";
10
- import { extractUsedDynamicContent as J } from "../utils/registerUsedDynamicContent.js";
11
- import { ref as V, watch as W } from "vue";
12
- const X = 250, U = 12e4, Y = 1e3, p = { status: "superseded" }, M = { status: "failed", error: new Error("Blueprint has no html to apply") }, a = V({}), A = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
13
- let d = null;
14
- const E = () => {
15
- d && (clearInterval(d), d = null);
16
- }, me = () => {
17
- const { updateHtmlAndCss: i } = z(), { runExclusive: O } = K(), { showToaster: P } = R(), _ = F(), { template: b } = N(), L = G(), T = $(), w = (e, t) => {
1
+ import { useActionsApi as C } from "./useActionsApi.js";
2
+ import { useConfig as h } from "./useConfig.js";
3
+ import { useToaster as D } from "./useToaster.js";
4
+ import { useTranslations as E } from "./useTranslations.js";
5
+ import { ToasterTypeOptions as f } from "../enums/toaster.js";
6
+ import { useDynamicContentStore as A } from "../stores/dynamic-content.js";
7
+ import { flattenDynamicContentList as w } from "../utils/genericUtil.js";
8
+ import { extractUsedDynamicContent as S } from "../utils/registerUsedDynamicContent.js";
9
+ import { ref as O } from "vue";
10
+ const U = 250, o = O({}), s = {}, u = /* @__PURE__ */ new Map(), z = () => {
11
+ const { updateHtmlAndCss: r } = C(), { showToaster: m } = D(), y = E(), { template: T } = h(), d = A(), g = (e, t) => {
12
+ const a = y(e);
13
+ return a === e ? t : a;
14
+ }, v = (e) => {
15
+ o.value[e] === void 0 && (o.value = { ...o.value, [e]: "pending" });
16
+ }, l = (e, t, a) => {
17
+ var c;
18
+ o.value = { ...o.value, [e]: "applying" };
18
19
  try {
19
- P({ type: e, message: _(t) });
20
- } catch (o) {
21
- console.error("[guido:apply] could not show the apply toast", o);
22
- }
23
- }, g = (e, t) => {
24
- m.get(e) !== t && (m.set(e, t), w(v.Error, "newsletter.ai-template-failed-apply"));
25
- }, y = () => {
26
- var e, t;
27
- return T.isStripoInitialized && typeof ((t = (e = window.StripoEditorApi) == null ? void 0 : e.actionsApi) == null ? void 0 : t.updateHtmlAndCss) == "function";
28
- }, Q = (e) => {
29
- a.value[e] === void 0 && (a.value = { ...a.value, [e]: "pending" });
30
- }, l = (e, t) => {
31
- a.value = { ...a.value, [e]: t };
32
- }, H = (e) => {
33
- var t;
34
- try {
35
- const o = j((t = b.value) == null ? void 0 : t.dynamicContentList), r = J(e, o);
36
- r.length > 0 && L.registerDynamicContent(r);
37
- } catch {
38
- }
39
- }, I = (e, t) => {
40
- m.delete(e), A.get(e) !== t && (A.set(e, t), w(v.Success, "newsletter.ai-template-applied"));
41
- }, h = async (e, t, o) => {
42
- const r = (u.get(e) ?? 0) + 1;
43
- u.set(e, r), l(e, "applying");
44
- try {
45
- await O(() => i(t, o));
20
+ r(t, a).catch((n) => {
21
+ console.warn("Editor did not acknowledge the template apply.", n);
22
+ }), o.value = { ...o.value, [e]: "applied" };
23
+ try {
24
+ const n = w((c = T.value) == null ? void 0 : c.dynamicContentList), i = S(t, n);
25
+ i.length > 0 && d.registerDynamicContent(i);
26
+ } catch {
27
+ }
28
+ u.get(e) !== t && (u.set(e, t), m({
29
+ type: f.Success,
30
+ message: g("newsletter.ai-template-applied", "Template applied to the editor")
31
+ }));
46
32
  } catch (n) {
47
- return u.get(e) !== r ? p : (console.error("[guido:apply] editor did not acknowledge the template apply", n), l(e, "failed"), g(e, t), { status: "failed", error: n });
48
- }
49
- return u.get(e) !== r ? p : (l(e, "applied"), H(t), I(e, t), { status: "applied" });
50
- }, B = (e) => {
51
- const t = s.get(e);
52
- t && (clearTimeout(t.timer), s.delete(e), t.settle(p));
53
- }, C = (e) => {
54
- const t = c.get(e);
55
- t && (clearTimeout(t.timer), c.delete(e), t.settle(p));
56
- }, q = () => {
57
- [...c.keys()].forEach(C);
58
- }, D = async () => {
59
- if (s.size === 0) {
60
- E();
61
- return;
33
+ o.value = { ...o.value, [e]: "failed" }, m({
34
+ type: f.Error,
35
+ message: n instanceof Error ? n.message : "Failed to apply template"
36
+ });
62
37
  }
63
- if (!y())
64
- return;
65
- E();
66
- const e = [...s.entries()];
67
- s.clear(), e.forEach(([, n]) => clearTimeout(n.timer));
68
- const t = e.pop();
69
- if (e.forEach(([n, f]) => {
70
- l(n, "failed"), f.settle({ status: "failed", error: new Error("Displaced by a newer apply") });
71
- }), !t)
38
+ }, p = (e) => {
39
+ const t = s[e];
40
+ t && (clearTimeout(t), delete s[e]);
41
+ };
42
+ return { applyStatus: o, markPending: v, applyTemplate: (e, t) => {
43
+ t.html && (p(e), l(e, t.html, t.css ?? ""));
44
+ }, applyTemplateDebounced: (e, t) => {
45
+ if (!t.html)
72
46
  return;
73
- const [o, r] = t;
74
- r.settle(await h(o, r.html, r.css));
75
- }, x = (e, t, o) => new Promise((r) => {
76
- B(e);
77
- const n = setTimeout(() => {
78
- s.delete(e), l(e, "failed"), g(e, t), r({
79
- status: "failed",
80
- error: new Error(`Editor did not become ready within ${U}ms`)
81
- });
47
+ p(e);
48
+ const { html: a } = t, c = t.css ?? "";
49
+ s[e] = setTimeout(() => {
50
+ delete s[e], l(e, a, c);
82
51
  }, U);
83
- s.set(e, { html: t, css: o, timer: n, settle: r }), l(e, "applying"), d ?? (d = setInterval(() => {
84
- D();
85
- }, Y));
86
- }), S = (e, t, o) => y() ? h(e, t, o) : x(e, t, o);
87
- return W(() => T.isStripoInitialized, (e) => {
88
- e && D();
89
- }, { immediate: !0 }), { applyStatus: a, markPending: Q, applyTemplate: (e, t) => {
90
- const { html: o } = t;
91
- return o ? (q(), S(e, o, t.css ?? "")) : Promise.resolve(M);
92
- }, applyTemplateDebounced: (e, t) => {
93
- const { html: o } = t;
94
- if (!o)
95
- return Promise.resolve(M);
96
- const r = t.css ?? "";
97
- return new Promise((n) => {
98
- C(e);
99
- const f = setTimeout(() => {
100
- c.delete(e), S(e, o, r).then(n);
101
- }, X);
102
- c.set(e, { timer: f, settle: n });
103
- });
104
52
  } };
105
- }, de = () => {
106
- c.forEach((i) => {
107
- clearTimeout(i.timer), i.settle(p);
108
- }), c.clear(), s.forEach((i) => {
109
- clearTimeout(i.timer), i.settle(p);
110
- }), s.clear(), E(), m.clear(), a.value = {};
53
+ }, G = () => {
54
+ Object.values(s).forEach(clearTimeout), Object.keys(s).forEach((r) => delete s[r]), o.value = {};
111
55
  };
112
56
  export {
113
- de as resetEmailTemplateApplier,
114
- me as useEmailTemplateApplier
57
+ G as resetEmailTemplateApplier,
58
+ z as useEmailTemplateApplier
115
59
  };
@@ -1,7 +1,7 @@
1
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 = {
2
+ import { ref as m, computed as w } from "vue";
3
+ const k = (g = {}) => {
4
+ const h = m(!1), n = m(null), u = m(null), b = w(() => h.value), y = w(() => n.value !== null), v = {
5
5
  baseURL: "",
6
6
  timeout: 1e4,
7
7
  retry: 0,
@@ -10,79 +10,90 @@ const X = (b = {}) => {
10
10
  "Content-Type": "application/json",
11
11
  "X-CSRF-TOKEN": O(),
12
12
  Accept: "application/json",
13
+ // The panel backend only answers 401/419 to ajax requests; without this a guest
14
+ // fetch gets a 302 to the login page and never sees an auth status.
13
15
  "X-Requested-With": "XMLHttpRequest"
14
16
  },
15
- ...b
16
- }, w = (e, s) => {
17
+ ...g
18
+ }, x = (e, r) => {
17
19
  if (e.startsWith("http://") || e.startsWith("https://"))
18
20
  return e;
19
- const t = s || v.baseURL || "";
21
+ const t = r || v.baseURL || "";
20
22
  return t.endsWith("/") && e.startsWith("/") ? `${t}${e.slice(1)}` : t.endsWith("/") || e.startsWith("/") ? `${t}${e}` : `${t}/${e}`;
21
- }, P = (e) => new Promise((s, t) => {
23
+ }, P = (e) => new Promise((r, t) => {
22
24
  setTimeout(() => {
23
25
  t(new Error("Request timeout"));
24
26
  }, e);
25
- }), x = (e) => new Promise((s) => {
26
- setTimeout(s, e);
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 = {
27
+ }), C = (e) => new Promise((r) => {
28
+ setTimeout(r, e);
29
+ }), i = async (e, r, t, W = {}) => {
30
+ n.value = null, h.value = !0, u.value = new AbortController();
31
+ const a = { ...v, ...W }, E = x(r, a.baseURL), c = {
30
32
  method: e,
31
- headers: { ...n.headers },
33
+ headers: { ...a.headers },
32
34
  signal: u.value.signal,
33
- ...n
35
+ ...a
34
36
  };
35
37
  t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete c.headers["Content-Type"], c.body = t) : c.body = JSON.stringify(t));
36
- const E = async (h = 0) => {
38
+ const T = async (p = 0) => {
39
+ if (window.isSessionExpired)
40
+ throw n.value = { message: "Session expired" }, new Error("Session expired");
37
41
  try {
38
- const o = [fetch(D, c)];
39
- n.timeout && o.push(P(n.timeout));
40
- const r = await Promise.race(o);
41
- if (!r.ok) {
42
- const H = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(H);
43
- throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
42
+ const o = [fetch(E, c)];
43
+ a.timeout && o.push(P(a.timeout));
44
+ const s = await Promise.race(o);
45
+ if (!s.ok) {
46
+ const D = `HTTP Error: ${s.status} ${s.statusText}`, f = new Error(D);
47
+ throw f.status = s.status, f.statusText = s.statusText, f.response = s, [401, 403, 419].includes(s.status) && Promise.resolve().then(() => s.clone().text().catch(() => "")).then((H) => window.dispatchEvent(new CustomEvent("insider:http-auth-error", {
48
+ detail: {
49
+ status: s.status,
50
+ body: H,
51
+ url: new URL(E, window.location.href).href
52
+ }
53
+ }))).catch(() => {
54
+ }), f;
44
55
  }
45
- let f;
46
- const l = r.headers.get("content-type");
47
- return l != null && l.includes("application/json") ? f = await r.json() : l != null && l.includes("text/") ? f = await r.text() : f = await r.blob(), {
48
- data: f,
49
- status: r.status,
50
- statusText: r.statusText,
51
- headers: r.headers
56
+ let d;
57
+ const l = s.headers.get("content-type");
58
+ return l != null && l.includes("application/json") ? d = await s.json() : l != null && l.includes("text/") ? d = await s.text() : d = await s.blob(), {
59
+ data: d,
60
+ status: s.status,
61
+ statusText: s.statusText,
62
+ headers: s.headers
52
63
  };
53
64
  } catch (o) {
54
- const r = o instanceof Error && o.name === "AbortError";
55
- if (h < (n.retry || 0) && !r)
56
- return await x(n.retryDelay || 1e3), E(h + 1);
57
- throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
65
+ const s = o instanceof Error && o.name === "AbortError";
66
+ if (p < (a.retry || 0) && !s)
67
+ return await C(a.retryDelay || 1e3), T(p + 1);
68
+ throw o instanceof Error ? o.name === "AbortError" ? n.value = { message: "Request was cancelled" } : n.value = { message: o.message } : n.value = o, o;
58
69
  }
59
70
  };
60
71
  try {
61
- return await E();
72
+ return await T();
62
73
  } finally {
63
- p.value = !1, u.value = null;
74
+ h.value = !1, u.value = null;
64
75
  }
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) => {
76
+ }, R = (e, r) => i("GET", e, void 0, r), U = (e, r, t) => i("POST", e, r, t), $ = (e, r, t) => i("PUT", e, r, t), q = (e, r, t) => i("PATCH", e, r, t), A = (e, r) => i("DELETE", e, void 0, r), L = (e) => {
66
77
  u.value && u.value.abort(e);
67
- }, W = () => {
68
- a.value = null;
78
+ }, S = () => {
79
+ n.value = null;
69
80
  };
70
81
  return {
71
82
  // State
72
- loading: g,
73
- error: T(() => a.value),
83
+ loading: b,
84
+ error: w(() => n.value),
74
85
  hasError: y,
75
86
  // Methods
76
87
  request: i,
77
- get: C,
78
- post: R,
88
+ get: R,
89
+ post: U,
79
90
  put: $,
80
91
  patch: q,
81
92
  delete: A,
82
- cancel: U,
83
- clearError: W
93
+ cancel: L,
94
+ clearError: S
84
95
  };
85
96
  };
86
97
  export {
87
- X as useHttp
98
+ k as useHttp
88
99
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-c61cc8ea]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-59690055]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-59690055]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-59690055]{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}
1
+ @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-c61cc8ea]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-36867e2e]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-36867e2e]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-36867e2e]{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}
@@ -17,11 +17,12 @@
17
17
  * - `error` segments (and message-level `isError` / `isCancelled`) trigger
18
18
  * a localized toaster.
19
19
  *
20
- * Every apply settles into a terminal `applyAcks` entry, so cortex moves its button on the write, not the click.
21
- *
22
20
  * In dev (`import.meta.env.DEV`) every observed segment + message-level flag
23
21
  * change is also `console.debug`-logged with the prefix `[guido:cortex]` so a
24
22
  * developer can watch the agent stream in real time. In production this is
25
23
  * gated behind `localStorage.guido:debug:ai === '1'`.
24
+ *
25
+ * If cortex-fe isn't loaded the chat store is undefined and the bridge is a
26
+ * no-op (intentional — Guido must still work standalone).
26
27
  */
27
28
  export declare const useCortexBlueprintBridge: () => void;
@@ -1,16 +1,4 @@
1
1
  type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
2
- /**
3
- * Terminal outcome of an apply; every promise here settles with one, since the bridge acks on it.
4
- * `superseded`: a newer payload for the same key replaced this one and owns the ack.
5
- */
6
- export type ApplyOutcome = {
7
- status: 'applied';
8
- } | {
9
- status: 'failed';
10
- error: unknown;
11
- } | {
12
- status: 'superseded';
13
- };
14
2
  /**
15
3
  * Applies email_template blueprints from the chat agent to the Stripo editor.
16
4
  *
@@ -21,19 +9,18 @@ export type ApplyOutcome = {
21
9
  * - manual Apply click (first apply): immediate.
22
10
  * - blueprint_update after the user has applied once: debounced 250 ms trailing
23
11
  * so rapid mid-stream updates don't thrash updateHtmlAndCss.
24
- * - a click before Stripo is ready is queued and flushed when `isStripoInitialized` flips.
25
12
  */
26
13
  export declare const useEmailTemplateApplier: () => {
27
14
  applyStatus: import("vue").Ref<Record<string, ApplyStatus>>;
28
- markPending: (key: string) => void;
29
- applyTemplate: (key: string, data: {
15
+ markPending: (blueprintId: string) => void;
16
+ applyTemplate: (blueprintId: string, data: {
30
17
  html?: string;
31
18
  css?: string;
32
- }) => Promise<ApplyOutcome>;
33
- applyTemplateDebounced: (key: string, data: {
19
+ }) => void;
20
+ applyTemplateDebounced: (blueprintId: string, data: {
34
21
  html?: string;
35
22
  css?: string;
36
- }) => Promise<ApplyOutcome>;
23
+ }) => void;
37
24
  };
38
25
  export declare const resetEmailTemplateApplier: () => void;
39
26
  export {};
@@ -1,13 +1,3 @@
1
- /** Terminal outcome of an editor write, keyed by `${blueprintId}:${version}`. */
2
- export interface ApplyAck {
3
- status: 'applied' | 'failed';
4
- /** The `applyRequestedAt` of the click this ack answers — lets cortex drop stale acks. */
5
- requestedAt: number;
6
- /** Strictly increasing per key, so two acks in the same millisecond still order. */
7
- ackAt: number;
8
- /** Stringified — cortex JSON-clones store-derived payloads, an Error would not survive. */
9
- error?: string;
10
- }
11
1
  /** The published editor snapshot — the shape a consumer reads off the shared store. */
12
2
  export interface GuidoEmailEditorState {
13
3
  /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
@@ -18,10 +8,6 @@ export interface GuidoEmailEditorState {
18
8
  lastUpdatedAt: number;
19
9
  /** Template id from the editor config, so a consumer can scope per-template. */
20
10
  templateId: string;
21
- /** True while a mounted Guido bridge is consuming the chat store. Gates cortex's Apply button. */
22
- bridgeActive: boolean;
23
- /** `${blueprintId}:${version}` → terminal outcome of the editor write, written only after it settles. */
24
- applyAcks: Record<string, ApplyAck>;
25
11
  }
26
12
  /**
27
13
  * Outbound contract Guido publishes to the host's shared Pinia singleton so a
@@ -32,11 +18,17 @@ export interface GuidoEmailEditorState {
32
18
  * Published as `@useinsider/guido/editor-state` and from the root barrel, so a
33
19
  * consumer imports this store instead of re-declaring one under the same id.
34
20
  *
35
- * State-only by contract: cortex-fe reads `pinia.state.value['guidoEmailEditor']`, which misses
36
- * actions and getters. Intended writers: `useGuidoStateBridge` and `useCortexBlueprintBridge`.
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.
37
25
  *
38
- * The id `guidoEmailEditor` is part of the cross-MFE contract; the internal
39
- * store `guidoEditor` is intentionally separate.
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.
40
32
  */
41
33
  export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", GuidoEmailEditorState, {
42
34
  /** True once the bridge has published at least one snapshot. */
@@ -45,7 +37,5 @@ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"
45
37
  css: string;
46
38
  lastUpdatedAt: number;
47
39
  templateId: string;
48
- bridgeActive: boolean;
49
- applyAcks: Record<string, ApplyAck>;
50
40
  } & import("pinia").PiniaCustomStateProperties<GuidoEmailEditorState>) => boolean;
51
41
  }, {}>;
@@ -4,9 +4,7 @@ const d = e("guidoEmailEditor", {
4
4
  html: "",
5
5
  css: "",
6
6
  lastUpdatedAt: 0,
7
- templateId: "",
8
- bridgeActive: !1,
9
- applyAcks: {}
7
+ templateId: ""
10
8
  }),
11
9
  getters: {
12
10
  /** True once the bridge has published at least one snapshot. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.19.0-beta.f884c35",
3
+ "version": "3.19.0-beta.f8f0007",
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",
@@ -38,7 +38,6 @@
38
38
  "test:e2e-mutation": "node scripts/e2e-mutation-check.mjs",
39
39
  "type-check": "vue-tsc --noEmit --project tsconfig.config.json && vue-tsc --noEmit --project tsconfig.app.json",
40
40
  "test": "vitest run --coverage",
41
- "test:run": "vitest run",
42
41
  "test:watch": "vitest",
43
42
  "test:visual-update": "npx playwright test --update-snapshots --reporter html",
44
43
  "test:e2e:coverage": "E2E_COVERAGE=true playwright test",