@designcrowd/library.brand-page 5.17.25-undo-16 → 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.
- package/lib/src/{CreatedOnBrandCrowd-de-de-DoZrycKx.js → CreatedOnBrandCrowd-de-de-CuLXf8WO.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-DmxNkDLu.js → CreatedOnBrandCrowd-en-us-CiW7WmjR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-H-sFjCV8.js → CreatedOnBrandCrowd-es-es-CHDfeUkH.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-B5DkiLEB.js → CreatedOnBrandCrowd-fr-ca-COCbfajV.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-B5DkiLEB.js → CreatedOnBrandCrowd-fr-fr-COCbfajV.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-ChETDqmY.js → CreatedOnBrandCrowd-pt-br-B9JibEDj.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-ChETDqmY.js → CreatedOnBrandCrowd-pt-pt-B9JibEDj.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-CTkJ8L32.js → CreatedOnDcom-de-de-CB5yuGbA.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-CysCo5GG.js → CreatedOnDcom-en-us-Di6bnyYT.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-MMQzRb1p.js → CreatedOnDcom-es-es-D7eelJRI.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DuYHuEkT.js → CreatedOnDcom-fr-ca-0AXvFmzo.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DaxFqnuU.js → CreatedOnDcom-fr-fr-C2lAJQvG.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-BsGlw26o.js → CreatedOnDcom-pt-br-C43vEqQQ.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-_-XMVOfR.js → CreatedOnDcom-pt-pt-OFKc7eJu.js} +1 -1
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +8 -19
- package/lib/src/brand-page-maker/stores/history/history-store.js +61 -16
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-BgiRnWCM.js → lib-6wk_GC45.js} +2941 -2918
- package/package.json +1 -1
- package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +9 -21
- package/src/brand-page-maker/stores/history/history-store.test.ts +94 -0
- package/src/brand-page-maker/stores/history/history-store.ts +73 -15
|
@@ -625,25 +625,6 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
|
|
|
625
625
|
this.setTriggerSaveSuccessMessage({
|
|
626
626
|
triggerSaveSuccessMessage: true,
|
|
627
627
|
});
|
|
628
|
-
// PRD §3 Non-Goals: undo history resets on save/publish so the
|
|
629
|
-
// saved state becomes the new clean baseline. Reset BEFORE
|
|
630
|
-
// awaiting the notification toast — the post-save reactive
|
|
631
|
-
// cascade (designDraftToken update + replaceState URL rewrite
|
|
632
|
-
// → router afterEach → pageNavigation writes) starts firing
|
|
633
|
-
// immediately and would otherwise be picked up by the watcher
|
|
634
|
-
// as a fresh undoable entry, leaving the user able to undo
|
|
635
|
-
// back across the save. Gate on `baselineCaptured` so
|
|
636
|
-
// non-undo-redo sessions are no-ops (the baseline is only
|
|
637
|
-
// captured when the feature flag is on — see
|
|
638
|
-
// BrandPageMaker.mixin.ts). Both Save Progress and Publish
|
|
639
|
-
// funnel here (publish via `saveAndPublishBrandPage` →
|
|
640
|
-
// `saveBrandPage`). reset() re-baselines synchronously so the
|
|
641
|
-
// post-save cascade folds into the new baseline's settle
|
|
642
|
-
// window instead of producing extra entries.
|
|
643
|
-
const historyStore = useHistoryStore();
|
|
644
|
-
if (historyStore.baselineCaptured) {
|
|
645
|
-
historyStore.reset();
|
|
646
|
-
}
|
|
647
628
|
if (brandPageMakerStore.contentErrorCount > 0) {
|
|
648
629
|
await brandPageMakerStore.setSelectedTabName({
|
|
649
630
|
tabName: SIDE_BAR_TAB_NAMES.CONTENT_SETTINGS,
|
|
@@ -656,6 +637,14 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
|
|
|
656
637
|
await this.showSaveSuccessMessage();
|
|
657
638
|
await brandPageMakerStore.showNextNotificationMessage();
|
|
658
639
|
}
|
|
640
|
+
// PRD §3 Non-Goals: undo history resets on save/publish so the
|
|
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();
|
|
659
648
|
return {
|
|
660
649
|
saved: true,
|
|
661
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
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
* the
|
|
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
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
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-
|
|
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,
|