1616from libtmux .snapshot .types import PaneT , SessionT , WindowT
1717from libtmux .window import Window
1818
19-
20- class SealablePaneBase (Pane , Sealable ):
19+ # Forward references
20+ if t .TYPE_CHECKING :
21+ from libtmux .snapshot .models .server import ServerSnapshot
22+ from libtmux .snapshot .types import SnapshotType
23+
24+
25+ class SnapshotBase (Sealable ):
26+ """Base class for all snapshot classes.
27+
28+ This class provides common methods for all snapshot classes, such as filtering
29+ and serialization to dictionary.
30+ """
31+
32+ _is_snapshot : bool = True
33+
34+ def to_dict (self ) -> dict [str , t .Any ]:
35+ """Convert the snapshot to a dictionary.
36+
37+ This is useful for serializing snapshots to JSON or other formats.
38+
39+ Returns
40+ -------
41+ dict[str, t.Any]
42+ A dictionary representation of the snapshot
43+
44+ Examples
45+ --------
46+ >>> from libtmux import Server
47+ >>> from libtmux.snapshot.factory import create_snapshot
48+ >>> server = Server()
49+ >>> snapshot = create_snapshot(server)
50+ >>> data = snapshot.to_dict()
51+ >>> isinstance(data, dict)
52+ True
53+ """
54+ from libtmux .snapshot .utils import snapshot_to_dict
55+
56+ return snapshot_to_dict (self )
57+
58+ def filter (
59+ self , filter_func : t .Callable [[SnapshotType ], bool ]
60+ ) -> SnapshotType | None :
61+ """Filter the snapshot tree based on a filter function.
62+
63+ This recursively filters the snapshot tree based on the filter function.
64+ Parent-child relationships are maintained in the filtered snapshot.
65+
66+ Parameters
67+ ----------
68+ filter_func : Callable[[SnapshotType], bool]
69+ A function that takes a snapshot object and returns True to keep it
70+ or False to filter it out
71+
72+ Returns
73+ -------
74+ Optional[SnapshotType]
75+ A new filtered snapshot, or None if everything was filtered out
76+
77+ Examples
78+ --------
79+ >>> from libtmux import Server
80+ >>> from libtmux.snapshot.factory import create_snapshot
81+ >>> server = Server()
82+ >>> snapshot = create_snapshot(server)
83+ >>> # Filter to include only objects with 'name' attribute
84+ >>> filtered = snapshot.filter(lambda x: hasattr(x, 'name'))
85+ """
86+ from libtmux .snapshot .utils import filter_snapshot
87+
88+ # This is safe at runtime because concrete implementations will
89+ # satisfy the type constraints
90+ return filter_snapshot (self , filter_func ) # type: ignore[arg-type]
91+
92+ def active_only (self ) -> ServerSnapshot | None :
93+ """Filter the snapshot to include only active components.
94+
95+ This is a convenience method that filters the snapshot to include only
96+ active sessions, windows, and panes.
97+
98+ Returns
99+ -------
100+ Optional[ServerSnapshot]
101+ A new filtered snapshot containing only active components, or None if
102+ there are no active components
103+
104+ Examples
105+ --------
106+ >>> from libtmux import Server
107+ >>> from libtmux.snapshot.factory import create_snapshot
108+ >>> server = Server()
109+ >>> snapshot = create_snapshot(server)
110+ >>> active = snapshot.active_only()
111+
112+ Raises
113+ ------
114+ NotImplementedError
115+ If called on a snapshot that is not a ServerSnapshot
116+ """
117+ # Only implement for ServerSnapshot
118+ if not hasattr (self , "sessions_snapshot" ):
119+ cls_name = type (self ).__name__
120+ msg = f"active_only() is only supported for ServerSnapshot, not { cls_name } "
121+ raise NotImplementedError (msg )
122+
123+ from libtmux .snapshot .utils import snapshot_active_only
124+
125+ try :
126+ # This is safe at runtime because we check for the
127+ # sessions_snapshot attribute
128+ return snapshot_active_only (self ) # type: ignore[arg-type]
129+ except ValueError :
130+ return None
131+
132+
133+ class SealablePaneBase (Pane , SnapshotBase ):
21134 """Base class for sealable pane classes."""
22135
23136
24- class SealableWindowBase (Window , Sealable , t .Generic [PaneT ]):
137+ class SealableWindowBase (Window , SnapshotBase , t .Generic [PaneT ]):
25138 """Base class for sealable window classes with generic pane type."""
26139
27140 @property
@@ -35,7 +148,7 @@ def active_pane(self) -> PaneT | None:
35148 return t .cast (t .Optional [PaneT ], super ().active_pane )
36149
37150
38- class SealableSessionBase (Session , Sealable , t .Generic [WindowT , PaneT ]):
151+ class SealableSessionBase (Session , SnapshotBase , t .Generic [WindowT , PaneT ]):
39152 """Base class for sealable session classes with generic window and pane types."""
40153
41154 @property
@@ -54,7 +167,7 @@ def active_pane(self) -> PaneT | None:
54167 return t .cast (t .Optional [PaneT ], super ().active_pane )
55168
56169
57- class SealableServerBase (Server , Sealable , t .Generic [SessionT , WindowT , PaneT ]):
170+ class SealableServerBase (Server , SnapshotBase , t .Generic [SessionT , WindowT , PaneT ]):
58171 """Generic base for sealable server with typed session, window, and pane."""
59172
60173 @property
0 commit comments