55from dataclasses import asdict , dataclass , field , is_dataclass
66from enum import Enum
77from os import getenv
8- from pickle import dumps
98from re import IGNORECASE , compile
109from types import UnionType
1110from typing import (
1211 Any ,
1312 Callable ,
13+ ClassVar ,
1414 Generic ,
1515 Iterable ,
1616 Optional ,
2121
2222from jaclang .compiler .constant import EdgeDir , T
2323from jaclang .core .utils import collect_node_connections
24-
24+ from jaclang . vendor . orjson import dumps
2525
2626GENERIC_ID_REGEX = compile (
2727 r"^(g|n|e|w):([^:]*):([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$" ,
4343TA = TypeVar ("TA" , bound = "type[Architype]" )
4444
4545
46- class ObjectType (Enum ):
46+ class AnchorType (Enum ):
4747 """Enum For Anchor Types."""
4848
4949 generic = "g"
@@ -143,7 +143,7 @@ def deserialize(cls, data: dict[str, Any]) -> Permission:
143143class Anchor :
144144 """Object Anchor."""
145145
146- type : ObjectType = ObjectType .generic
146+ type : ClassVar [ AnchorType ] = AnchorType .generic
147147 name : str = ""
148148 id : UUID = field (default_factory = uuid4 )
149149 root : Optional [UUID ] = None
@@ -164,21 +164,34 @@ def ref(ref_id: str) -> Optional[Anchor]:
164164 """Return ObjectAnchor instance if ."""
165165 if matched := GENERIC_ID_REGEX .search (ref_id ):
166166 cls : type = Anchor
167- match ObjectType (matched .group (1 )):
168- case ObjectType .node :
167+ match AnchorType (matched .group (1 )):
168+ case AnchorType .node :
169169 cls = NodeAnchor
170- case ObjectType .edge :
170+ case AnchorType .edge :
171171 cls = EdgeAnchor
172- case ObjectType .walker :
172+ case AnchorType .walker :
173173 cls = WalkerAnchor
174174 case _:
175175 pass
176176 return cls (name = matched .group (2 ), id = UUID (matched .group (3 )))
177177 return None
178178
179+ def _save (self ) -> None :
180+ """Save Anchor."""
181+ raise NotImplementedError ("_save must be implemented in subclasses" )
182+
179183 def save (self ) -> None :
180184 """Save Anchor."""
181- raise NotImplementedError ("save must be implemented in subclasses" )
185+ if self .architype :
186+ if not self .connected :
187+ self .connected = True
188+ self .sync_hash ()
189+ self ._save ()
190+ elif self .current_access_level == 0 and self .hash != (
191+ _hash := self .data_hash ()
192+ ):
193+ self .hash = _hash
194+ self ._save ()
182195
183196 def destroy (self ) -> None :
184197 """Save Anchor."""
@@ -284,6 +297,14 @@ def serialize(self) -> dict[str, object]:
284297 ),
285298 }
286299
300+ def data_hash (self ) -> int :
301+ """Get current serialization hash."""
302+ return hash (dumps (self .serialize ()))
303+
304+ def sync_hash (self ) -> None :
305+ """Sync current serialization hash."""
306+ self .hash = self .data_hash ()
307+
287308 def report (self ) -> dict [str , object ]:
288309 """Report Anchor."""
289310 return {
@@ -319,7 +340,7 @@ def __eq__(self, other: object) -> bool:
319340class NodeAnchor (Anchor ):
320341 """Node Anchor."""
321342
322- type : ObjectType = ObjectType .node
343+ type : ClassVar [ AnchorType ] = AnchorType .node
323344 architype : Optional [NodeArchitype ] = None
324345 edges : list [EdgeAnchor ] = field (default_factory = list )
325346
@@ -343,19 +364,6 @@ def _save(self) -> None:
343364
344365 jsrc .set (self )
345366
346- def save (self ) -> None :
347- """Save Anchor."""
348- if self .architype :
349- if not self .connected :
350- self .connected = True
351- self .hash = hash (dumps (self ))
352- self ._save ()
353- elif self .current_access_level > 0 and self .hash != (
354- _hash := hash (dumps (self ))
355- ):
356- self .hash = _hash
357- self ._save ()
358-
359367 def destroy (self ) -> None :
360368 """Delete Anchor."""
361369 if self .architype and self .current_access_level > 1 :
@@ -483,7 +491,7 @@ def serialize(self) -> dict[str, object]:
483491class EdgeAnchor (Anchor ):
484492 """Edge Anchor."""
485493
486- type : ObjectType = ObjectType .edge
494+ type : ClassVar [ AnchorType ] = AnchorType .edge
487495 architype : Optional [EdgeArchitype ] = None
488496 source : Optional [NodeAnchor ] = None
489497 target : Optional [NodeAnchor ] = None
@@ -512,19 +520,6 @@ def _save(self) -> None:
512520
513521 jsrc .set (self )
514522
515- def save (self ) -> None :
516- """Save Anchor."""
517- if self .architype :
518- if not self .connected :
519- self .connected = True
520- self .hash = hash (dumps (self ))
521- self ._save ()
522- elif self .current_access_level == 1 and self .hash != (
523- _hash := hash (dumps (self ))
524- ):
525- self .hash = _hash
526- self ._save ()
527-
528523 def destroy (self ) -> None :
529524 """Delete Anchor."""
530525 if self .architype and self .current_access_level == 1 :
@@ -588,7 +583,7 @@ def serialize(self) -> dict[str, object]:
588583class WalkerAnchor (Anchor ):
589584 """Walker Anchor."""
590585
591- type : ObjectType = ObjectType .walker
586+ type : ClassVar [ AnchorType ] = AnchorType .walker
592587 architype : Optional [WalkerArchitype ] = None
593588 path : list [Anchor ] = field (default_factory = list )
594589 next : list [Anchor ] = field (default_factory = list )
@@ -611,19 +606,6 @@ def _save(self) -> None:
611606
612607 ExecutionContext .get ().datasource .set (self )
613608
614- def save (self ) -> None :
615- """Save Anchor."""
616- if self .architype :
617- if not self .connected :
618- self .connected = True
619- self .hash = hash (dumps (self ))
620- self ._save ()
621- elif self .current_access_level > 1 and self .hash != (
622- _hash := hash (dumps (self ))
623- ):
624- self .hash = _hash
625- self ._save ()
626-
627609 def destroy (self ) -> None :
628610 """Delete Anchor."""
629611 if self .architype and self .current_access_level > 1 :
0 commit comments