@@ -18,6 +18,13 @@ import {
1818import { NodeData , RoadmapData , Settings } from "./types" ;
1919import { getZIndexForNodeType } from "./zIndexHelper" ;
2020
21+ // Global flag to control persistence
22+ let persistenceEnabled = true ;
23+
24+ export function setPersistence ( enabled : boolean ) {
25+ persistenceEnabled = enabled ;
26+ }
27+
2128// Note: This is a global store for the editor. Typically only one editor instance is active at a time.
2229// If you need multiple independent editor instances, consider creating store instances per component or using context.
2330export interface EditorState {
@@ -133,6 +140,50 @@ const initialState = {
133140 showUnlockAfter : true ,
134141} ;
135142
143+ // Temporal middleware configuration
144+ const temporalConfig = {
145+ // Temporal middleware options - throttle undo history to improve drag performance
146+ equality : ( oldState : any , newState : any ) => isDeepEqual ( oldState , newState ) ,
147+ handleSet : ( handleSet : any ) =>
148+ throttle < typeof handleSet > (
149+ 500 ,
150+ ( state : any ) => {
151+ handleSet ( state ) ;
152+ } ,
153+ { noLeading : false , noTrailing : true } ,
154+ ) ,
155+ partialize : ( state : EditorState ) => {
156+ const { nodes, edges, settings } = state ;
157+ return { nodes, edges, settings } ;
158+ } ,
159+ } ;
160+
161+ // Persist middleware configuration
162+ const persistConfig = {
163+ name : "learningmap-data" , // name of the item in storage
164+ version : 1 ,
165+ partialize : ( state : EditorState ) => {
166+ const { nodes, edges, settings } = state ;
167+ return { nodes, edges, settings } ;
168+ } ,
169+ storage : {
170+ getItem : ( name : string ) => {
171+ if ( ! persistenceEnabled ) return null ;
172+ const str = localStorage . getItem ( name ) ;
173+ return str ? JSON . parse ( str ) : null ;
174+ } ,
175+ setItem : ( name : string , value : any ) => {
176+ if ( ! persistenceEnabled ) return ;
177+ localStorage . setItem ( name , JSON . stringify ( value ) ) ;
178+ } ,
179+ removeItem : ( name : string ) => {
180+ if ( ! persistenceEnabled ) return ;
181+ localStorage . removeItem ( name ) ;
182+ } ,
183+ } ,
184+ } as const ;
185+
186+ // Create the store with conditional persistence
136187export const useEditorStore = create < EditorState > ( ) (
137188 persist (
138189 temporal (
@@ -382,8 +433,8 @@ export const useEditorStore = create<EditorState>()(
382433 if ( nodesArr . length > 0 ) {
383434 const maxId = Math . max (
384435 ...nodesArr
385- . map ( ( n ) => parseInt ( n . id . replace ( / \D / g, "" ) , 10 ) )
386- . filter ( ( id ) => ! isNaN ( id ) ) ,
436+ . map ( ( n : any ) => parseInt ( n . id . replace ( / \D / g, "" ) , 10 ) )
437+ . filter ( ( id : number ) => ! isNaN ( id ) ) ,
387438 ) ;
388439 nextNodeId = maxId + 1 ;
389440 }
@@ -401,7 +452,7 @@ export const useEditorStore = create<EditorState>()(
401452 getRoadmapData : ( ) => {
402453 const state = get ( ) ;
403454 return {
404- nodes : state . nodes . map ( ( n ) => ( {
455+ nodes : state . nodes . map ( ( n : any ) => ( {
405456 id : n . id ,
406457 type : n . type ,
407458 position : n . position ,
@@ -414,8 +465,8 @@ export const useEditorStore = create<EditorState>()(
414465 data : n . data ,
415466 } ) ) ,
416467 edges : state . edges
417- . filter ( ( e ) => ! e . id . startsWith ( "debug-" ) )
418- . map ( ( e ) => ( {
468+ . filter ( ( e : any ) => ! e . id . startsWith ( "debug-" ) )
469+ . map ( ( e : any ) => ( {
419470 id : e . id ,
420471 source : e . source ,
421472 target : e . target ,
@@ -446,39 +497,17 @@ export const useEditorStore = create<EditorState>()(
446497 set ( initialState ) ;
447498 } ,
448499 } ) ,
449- {
450- // Temporal middleware options - throttle undo history to improve drag performance
451- equality : ( oldState , newState ) => isDeepEqual ( oldState , newState ) ,
452- handleSet : ( handleSet ) =>
453- throttle < typeof handleSet > (
454- 500 ,
455- ( state ) => {
456- handleSet ( state ) ;
457- } ,
458- { noLeading : false , noTrailing : true } ,
459- ) ,
460- partialize : ( state ) : any => {
461- const { nodes, edges, settings } = state ;
462- return { nodes, edges, settings } ;
463- } ,
464- } ,
500+ temporalConfig ,
465501 ) ,
466- {
467- name : "learningmap-data" , // name of the item in storage
468- version : 1 ,
469- partialize : ( state ) => {
470- const { nodes, edges, settings } = state ;
471- return { nodes, edges, settings } ;
472- } ,
473- } ,
502+ persistConfig ,
474503 ) ,
475504) ;
476505
477506type PartialEditorState = Pick < EditorState , "nodes" | "edges" | "settings" > ;
478507
479508// Hook for accessing temporal store (undo/redo)
480509export function useTemporalStore < T > (
481- selector ?: ( state : TemporalState < PartialEditorState > ) => T ,
510+ selector ?: ( state : TemporalState < any > ) => T ,
482511 equality ?: ( a : T , b : T ) => boolean ,
483512) {
484513 return useStoreWithEqualityFn ( useEditorStore . temporal , selector ! , equality ) ;
0 commit comments