@designcrowd/library.brand-page 5.17.25-undo-15 → 5.17.25-undo-17

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.
Files changed (22) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-5QfzKqjC.js → CreatedOnBrandCrowd-de-de-CuLXf8WO.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-Dy3tcwiJ.js → CreatedOnBrandCrowd-en-us-CiW7WmjR.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BJ8hjzNX.js → CreatedOnBrandCrowd-es-es-CHDfeUkH.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Crc2IixX.js → CreatedOnBrandCrowd-fr-ca-COCbfajV.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-Crc2IixX.js → CreatedOnBrandCrowd-fr-fr-COCbfajV.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-wWrA-4hb.js → CreatedOnBrandCrowd-pt-br-B9JibEDj.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-wWrA-4hb.js → CreatedOnBrandCrowd-pt-pt-B9JibEDj.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CeYxTDS_.js → CreatedOnDcom-de-de-CB5yuGbA.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-V7XXdsPr.js → CreatedOnDcom-en-us-Di6bnyYT.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-BIu7YLYP.js → CreatedOnDcom-es-es-D7eelJRI.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-bFnkqoIY.js → CreatedOnDcom-fr-ca-0AXvFmzo.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-DVmgOG0x.js → CreatedOnDcom-fr-fr-C2lAJQvG.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CnKjkT-U.js → CreatedOnDcom-pt-br-C43vEqQQ.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-D9bVqfon.js → CreatedOnDcom-pt-pt-OFKc7eJu.js} +1 -1
  15. package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +7 -9
  16. package/lib/src/brand-page-maker/stores/history/history-store.js +61 -16
  17. package/lib/src/index.mjs +1 -1
  18. package/lib/src/{lib-CptQVW37.js → lib-6wk_GC45.js} +2940 -2917
  19. package/package.json +1 -1
  20. package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +7 -10
  21. package/src/brand-page-maker/stores/history/history-store.test.ts +94 -0
  22. package/src/brand-page-maker/stores/history/history-store.ts +73 -15
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-CptQVW37.js";
2
+ import { _ as t } from "./lib-6wk_GC45.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-CptQVW37.js";
2
+ import { _ as e } from "./lib-6wk_GC45.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-CptQVW37.js";
2
+ import { _ as e } from "./lib-6wk_GC45.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-CptQVW37.js";
2
+ import { _ as e } from "./lib-6wk_GC45.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-CptQVW37.js";
2
+ import { _ as e } from "./lib-6wk_GC45.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-CptQVW37.js";
2
+ import { _ as e } from "./lib-6wk_GC45.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-CptQVW37.js";
2
+ import { _ as M } from "./lib-6wk_GC45.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-CptQVW37.js";
2
+ import { _ as M } from "./lib-6wk_GC45.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -638,15 +638,13 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
638
638
  await brandPageMakerStore.showNextNotificationMessage();
639
639
  }
640
640
  // PRD §3 Non-Goals: undo history resets on save/publish so the
641
- // saved state becomes the new clean baseline. Gate on
642
- // `baselineCaptured` so non-undo-redo sessions are no-ops (the
643
- // baseline is only captured when the feature flag is on — see
644
- // BrandPageMaker.mixin.ts). Both Save Progress and Publish funnel
645
- // here (publish via `saveAndPublishBrandPage` → `saveBrandPage`).
646
- const historyStore = useHistoryStore();
647
- if (historyStore.baselineCaptured) {
648
- historyStore.reset();
649
- }
641
+ // saved state becomes the new clean baseline. The save was
642
+ // successful by the time we get here, so reset unconditionally
643
+ // — `reset()` itself no-ops in non-undo-redo sessions (where
644
+ // no baseline was ever captured). Both Save Progress and
645
+ // Publish funnel here (publish via `saveAndPublishBrandPage`
646
+ // → `saveBrandPage`).
647
+ useHistoryStore().reset();
650
648
  return {
651
649
  saved: true,
652
650
  canPublish: response.canPublish,
@@ -659,16 +659,22 @@ export const useHistoryStore = defineStore('history', () => {
659
659
  * drains while the watcher guard is still set, preventing the restore from
660
660
  * being re-captured as a spurious duplicate entry.
661
661
  *
662
- * `targetIndex` is where we are AFTER the pointer-move — the entry we are
663
- * about to apply. The `activePageId` we want to restore lives on that
664
- * entry. If the captured page no longer exists in the restored nav (e.g.
665
- * undoing the add of the page that was active when we captured), we walk
666
- * BACK through earlier entries to find the closest activePageId that does
667
- * exist. That gives "land on the page the user was on before the edit"
668
- * for free — the entry that captured the edit-target's parent state has
669
- * the parent page id already.
662
+ * Active-page resolution priority:
663
+ * 1. Diff against `cameFromIndex` — any page present in the target
664
+ * snapshot but absent from the source snapshot is being "restored"
665
+ * by this transition. Navigate there. Covers undo-of-delete (lands
666
+ * on the deleted page) and redo-of-add (lands on the newly-added
667
+ * page) — both of which the user expects to "follow" the change.
668
+ * Without this, undo of a page-delete would resolve via walk-back
669
+ * to whatever page the user was on at the previous baseline, not
670
+ * the page they just un-deleted.
671
+ * 2. Walk back from `targetIndex` to find the closest entry whose
672
+ * captured `activePageId` still exists in the restored snapshot.
673
+ * Covers undo-of-add (falls back to the page the user was on
674
+ * before they added the new one) and any non-page-structural
675
+ * edits.
670
676
  */
671
- async function applySnapshotString(snapshotStr, targetIndex) {
677
+ async function applySnapshotString(snapshotStr, targetIndex, cameFromIndex) {
672
678
  const brandPageMakerStore = useBrandPageMakerStore();
673
679
  let snapshot;
674
680
  try {
@@ -684,11 +690,39 @@ export const useHistoryStore = defineStore('history', () => {
684
690
  restoredPageIds.add(p.id);
685
691
  });
686
692
  let resolvedActivePageId;
687
- for (let i = targetIndex; i >= 0; i--) {
688
- const candidate = entries.value[i]?.activePageId;
689
- if (candidate && restoredPageIds.has(candidate)) {
690
- resolvedActivePageId = candidate;
691
- break;
693
+ // Step 1: diff against the source-of-transition. The first page in
694
+ // the target snapshot whose id is absent from the source is the page
695
+ // being restored/added by this apply.
696
+ const sourceEntry = entries.value[cameFromIndex];
697
+ if (sourceEntry) {
698
+ const sourcePageIds = new Set();
699
+ try {
700
+ const sourceSnap = JSON.parse(sourceEntry.snapshot);
701
+ sourceSnap.pages?.forEach((p) => {
702
+ if (p?.id)
703
+ sourcePageIds.add(p.id);
704
+ });
705
+ for (const p of snapshot.pages ?? []) {
706
+ if (p?.id && !sourcePageIds.has(p.id)) {
707
+ resolvedActivePageId = p.id;
708
+ break;
709
+ }
710
+ }
711
+ }
712
+ catch {
713
+ // Source snapshot unparseable — fall through to walk-back.
714
+ }
715
+ }
716
+ // Step 2: walk-back fallback. Used when no page-structural diff
717
+ // applies (style/content edits) or when the diff produced nothing
718
+ // viable.
719
+ if (!resolvedActivePageId) {
720
+ for (let i = targetIndex; i >= 0; i--) {
721
+ const candidate = entries.value[i]?.activePageId;
722
+ if (candidate && restoredPageIds.has(candidate)) {
723
+ resolvedActivePageId = candidate;
724
+ break;
725
+ }
692
726
  }
693
727
  }
694
728
  isApplyingSnapshot.value = true;
@@ -709,10 +743,11 @@ export const useHistoryStore = defineStore('history', () => {
709
743
  return;
710
744
  // Capture the actor of the entry we're leaving — that's the change being undone.
711
745
  const undoneActor = entries.value[currentIndex.value]?.actor;
746
+ const cameFromIndex = currentIndex.value;
712
747
  currentIndex.value -= 1;
713
748
  const target = entries.value[currentIndex.value];
714
749
  if (target) {
715
- await applySnapshotString(target.snapshot, currentIndex.value);
750
+ await applySnapshotString(target.snapshot, currentIndex.value, cameFromIndex);
716
751
  }
717
752
  eventTracker.sendUndoEvent({
718
753
  entries_count: entries.value.length,
@@ -726,10 +761,11 @@ export const useHistoryStore = defineStore('history', () => {
726
761
  const aiThreadStore = useAiWebsiteBuilderThreadStore();
727
762
  if (aiThreadStore.isProcessing)
728
763
  return;
764
+ const cameFromIndex = currentIndex.value;
729
765
  currentIndex.value += 1;
730
766
  const target = entries.value[currentIndex.value];
731
767
  if (target) {
732
- await applySnapshotString(target.snapshot, currentIndex.value);
768
+ await applySnapshotString(target.snapshot, currentIndex.value, cameFromIndex);
733
769
  }
734
770
  // Actor of the entry we're moving onto — that's the change being re-applied.
735
771
  eventTracker.sendRedoEvent({
@@ -746,12 +782,21 @@ export const useHistoryStore = defineStore('history', () => {
746
782
  * successful save (covers both Save Progress and Publish, since publish
747
783
  * routes through `saveBrandPage`).
748
784
  *
785
+ * No-ops when no baseline has ever been captured — the undo/redo feature
786
+ * is gated by `userStore.features.canUseUndoRedo` (see
787
+ * BrandPageMaker.mixin.ts), and only flagged sessions install the watcher
788
+ * + capture a baseline. Without this guard, calling reset() in an
789
+ * unflagged session would install the watcher and start eating memory
790
+ * for snapshots the user can never see.
791
+ *
749
792
  * Re-runs `captureBaseline` synchronously so the next mutation lands as
750
793
  * an actual undoable edit rather than disappearing into a fresh settle
751
794
  * window. The watcher stays installed; `installWatcher` early-returns
752
795
  * if `watcherInstalled` is already true.
753
796
  */
754
797
  function reset() {
798
+ if (!baselineCaptured.value)
799
+ return;
755
800
  cancelPendingAutoCapture();
756
801
  entries.value = [];
757
802
  currentIndex.value = -1;
package/lib/src/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-CptQVW37.js";
1
+ import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-6wk_GC45.js";
2
2
  import { createPinia as wE, setActivePinia as ZE } from "pinia";
3
3
  export {
4
4
  E as ABOUT_SECTION_SETTINGS_CONFIG,