shogun-button-react 1.3.5 → 1.3.9

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/dist/connector.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { ShogunCore } from "shogun-core";
2
+ import { GunAdvancedPlugin } from "./plugins/GunAdvancedPlugin";
2
3
  export function shogunConnector(options) {
3
- const { peers = ["https://gun-manhattan.herokuapp.com/gun"], appName, logging, timeouts, oauth, ...restOptions } = options;
4
- const sdk = new ShogunCore({
4
+ const { peers = ["https://gun-manhattan.herokuapp.com/gun"], appName, logging, timeouts, oauth, enableGunDebug = true, enableConnectionMonitoring = true, defaultPageSize = 20, connectionTimeout = 10000, debounceInterval = 100, ...restOptions } = options;
5
+ const core = new ShogunCore({
5
6
  peers,
6
7
  scope: appName,
7
8
  logging,
@@ -9,7 +10,7 @@ export function shogunConnector(options) {
9
10
  oauth,
10
11
  });
11
12
  const setProvider = (provider) => {
12
- if (!sdk) {
13
+ if (!core) {
13
14
  return false;
14
15
  }
15
16
  try {
@@ -21,8 +22,8 @@ export function shogunConnector(options) {
21
22
  newProviderUrl = provider;
22
23
  }
23
24
  if (newProviderUrl) {
24
- if (typeof sdk.setRpcUrl === "function") {
25
- return sdk.setRpcUrl(newProviderUrl);
25
+ if (typeof core.setRpcUrl === "function") {
26
+ return core.setRpcUrl(newProviderUrl);
26
27
  }
27
28
  }
28
29
  return false;
@@ -33,15 +34,15 @@ export function shogunConnector(options) {
33
34
  }
34
35
  };
35
36
  const getCurrentProviderUrl = () => {
36
- if (sdk && typeof sdk.getRpcUrl === "function") {
37
- return sdk.getRpcUrl();
37
+ if (core && typeof core.getRpcUrl === "function") {
38
+ return core.getRpcUrl();
38
39
  }
39
40
  return null;
40
41
  };
41
42
  const registerPlugin = (plugin) => {
42
- if (sdk && typeof sdk.register === "function") {
43
+ if (core && typeof core.register === "function") {
43
44
  try {
44
- sdk.register(plugin);
45
+ core.register(plugin);
45
46
  return true;
46
47
  }
47
48
  catch (error) {
@@ -52,14 +53,31 @@ export function shogunConnector(options) {
52
53
  return false;
53
54
  };
54
55
  const hasPlugin = (name) => {
55
- return sdk ? sdk.hasPlugin(name) : false;
56
+ return core ? core.hasPlugin(name) : false;
56
57
  };
58
+ // Registra automaticamente il plugin Gun avanzato
59
+ let gunPlugin = null;
60
+ if (core) {
61
+ gunPlugin = new GunAdvancedPlugin(core, {
62
+ enableDebug: enableGunDebug,
63
+ enableConnectionMonitoring,
64
+ defaultPageSize,
65
+ connectionTimeout,
66
+ debounceInterval,
67
+ });
68
+ registerPlugin(gunPlugin);
69
+ }
70
+ // Ensure gunPlugin is always available
71
+ if (!gunPlugin) {
72
+ throw new Error("Failed to initialize GunAdvancedPlugin");
73
+ }
57
74
  return {
58
- sdk,
75
+ core,
59
76
  options,
60
77
  setProvider,
61
78
  getCurrentProviderUrl,
62
79
  registerPlugin,
63
80
  hasPlugin,
81
+ gunPlugin,
64
82
  };
65
83
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { ShogunButton, ShogunButtonProvider, useShogun } from './components/ShogunButton.js';
2
2
  import { ShogunConnectorOptions, ShogunConnectorResult } from './types/connector-options.js';
3
+ import { shogunConnector } from './connector.js';
4
+ import { GunAdvancedPlugin } from './plugins/GunAdvancedPlugin.js';
3
5
  export { ShogunButton, ShogunButtonProvider, useShogun };
6
+ export { shogunConnector };
4
7
  export * from './types/index.js';
5
8
  export { ShogunConnectorOptions, ShogunConnectorResult };
9
+ export { GunAdvancedPlugin };
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
1
  import { ShogunButton, ShogunButtonProvider, useShogun } from './components/ShogunButton.js';
2
+ import { shogunConnector } from './connector.js';
3
+ import { GunAdvancedPlugin } from './plugins/GunAdvancedPlugin.js';
2
4
  // Export components
3
5
  export { ShogunButton, ShogunButtonProvider, useShogun };
6
+ // Export connector function
7
+ export { shogunConnector };
4
8
  // Export all types
5
9
  export * from './types/index.js';
10
+ export { GunAdvancedPlugin };
@@ -0,0 +1,79 @@
1
+ import { ShogunCore } from "shogun-core";
2
+ export interface GunAdvancedPluginConfig {
3
+ enableDebug?: boolean;
4
+ enableConnectionMonitoring?: boolean;
5
+ defaultPageSize?: number;
6
+ connectionTimeout?: number;
7
+ debounceInterval?: number;
8
+ }
9
+ export interface GunCollectionOptions<T> {
10
+ pageSize?: number;
11
+ sortBy?: keyof T | ((a: T, b: T) => number);
12
+ sortOrder?: 'asc' | 'desc';
13
+ filter?: (item: T) => boolean;
14
+ enableRealtime?: boolean;
15
+ }
16
+ export interface GunCollectionResult<T> {
17
+ items: T[];
18
+ currentPage: number;
19
+ totalPages: number;
20
+ hasNextPage: boolean;
21
+ hasPrevPage: boolean;
22
+ nextPage: () => void;
23
+ prevPage: () => void;
24
+ goToPage: (page: number) => void;
25
+ isLoading: boolean;
26
+ error: string | null;
27
+ refresh: () => void;
28
+ addItem: (item: T) => Promise<void>;
29
+ updateItem: (id: string, updates: Partial<T>) => Promise<void>;
30
+ removeItem: (id: string) => Promise<void>;
31
+ }
32
+ export interface GunStateResult<T> {
33
+ data: T | null;
34
+ isLoading: boolean;
35
+ error: string | null;
36
+ update: (updates: Partial<T>) => Promise<void>;
37
+ set: (data: T) => Promise<void>;
38
+ remove: () => Promise<void>;
39
+ refresh: () => void;
40
+ }
41
+ export declare class GunAdvancedPlugin {
42
+ private sdk;
43
+ private config;
44
+ private debugEnabled;
45
+ private connectionMonitors;
46
+ private collectionCache;
47
+ constructor(sdk: ShogunCore, config?: GunAdvancedPluginConfig);
48
+ setDebugEnabled(enabled: boolean): void;
49
+ private log;
50
+ createHooks(): {
51
+ useGunState: any;
52
+ useGunCollection: any;
53
+ useGunConnection: any;
54
+ useGunDebug: any;
55
+ useGunRealtime: any;
56
+ };
57
+ useGunState<T>(path: string, defaultValue?: T): GunStateResult<T>;
58
+ useGunCollection<T>(path: string, options?: GunCollectionOptions<T>): GunCollectionResult<T>;
59
+ useGunConnection(path: string): {
60
+ isConnected: boolean;
61
+ lastSeen: Date;
62
+ error: string;
63
+ };
64
+ useGunDebug(path: string, enabled?: boolean): void;
65
+ useGunRealtime<T>(path: string, callback?: (data: T, key: string) => void): {
66
+ data: T;
67
+ key: string;
68
+ };
69
+ put(path: string, data: any): Promise<void>;
70
+ get(path: string): any;
71
+ remove(path: string): Promise<void>;
72
+ cleanup(): void;
73
+ getStats(): {
74
+ activeConnections: number;
75
+ cachedCollections: number;
76
+ debugEnabled: boolean;
77
+ config: GunAdvancedPluginConfig;
78
+ };
79
+ }
@@ -0,0 +1,498 @@
1
+ import React from 'react';
2
+ export class GunAdvancedPlugin {
3
+ constructor(sdk, config = {}) {
4
+ this.connectionMonitors = new Map();
5
+ this.collectionCache = new Map();
6
+ this.sdk = sdk;
7
+ this.config = {
8
+ enableDebug: true,
9
+ enableConnectionMonitoring: true,
10
+ defaultPageSize: 20,
11
+ connectionTimeout: 10000,
12
+ debounceInterval: 100,
13
+ ...config
14
+ };
15
+ this.debugEnabled = this.config.enableDebug;
16
+ }
17
+ setDebugEnabled(enabled) {
18
+ this.debugEnabled = enabled;
19
+ this.log('Debug mode:', enabled ? 'enabled' : 'disabled');
20
+ }
21
+ log(...args) {
22
+ if (this.debugEnabled) {
23
+ console.log('[GunAdvancedPlugin]', ...args);
24
+ }
25
+ }
26
+ createHooks() {
27
+ return {
28
+ useGunState: this.useGunState.bind(this),
29
+ useGunCollection: this.useGunCollection.bind(this),
30
+ useGunConnection: this.useGunConnection.bind(this),
31
+ useGunDebug: this.useGunDebug.bind(this),
32
+ useGunRealtime: this.useGunRealtime.bind(this),
33
+ };
34
+ }
35
+ useGunState(path, defaultValue) {
36
+ const [data, setData] = React.useState(defaultValue || null);
37
+ const [isLoading, setIsLoading] = React.useState(true);
38
+ const [error, setError] = React.useState(null);
39
+ const isMounted = React.useRef(true);
40
+ React.useEffect(() => {
41
+ var _a;
42
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
43
+ return;
44
+ setIsLoading(true);
45
+ setError(null);
46
+ const gunRef = this.sdk.gun.get(path);
47
+ const off = gunRef.on((item) => {
48
+ if (!isMounted.current)
49
+ return;
50
+ if (item) {
51
+ setData(item);
52
+ setIsLoading(false);
53
+ setError(null);
54
+ this.log(`State updated for ${path}:`, item);
55
+ }
56
+ });
57
+ const timeoutId = setTimeout(() => {
58
+ if (isLoading) {
59
+ setError('Connection timeout - no data received');
60
+ setIsLoading(false);
61
+ }
62
+ }, this.config.connectionTimeout);
63
+ return () => {
64
+ isMounted.current = false;
65
+ if (typeof off === 'function')
66
+ off();
67
+ clearTimeout(timeoutId);
68
+ };
69
+ }, [path]);
70
+ const update = async (updates) => {
71
+ var _a;
72
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
73
+ throw new Error('SDK not initialized or user not logged in');
74
+ }
75
+ try {
76
+ setError(null);
77
+ const newData = { ...data, ...updates };
78
+ await new Promise((resolve, reject) => {
79
+ this.sdk.gun.get(path).put(newData, (ack) => {
80
+ if (ack.err) {
81
+ reject(new Error(ack.err));
82
+ }
83
+ else {
84
+ resolve();
85
+ }
86
+ });
87
+ });
88
+ this.log(`State updated for ${path}:`, newData);
89
+ }
90
+ catch (err) {
91
+ const errorMsg = err.message || 'Failed to update state';
92
+ setError(errorMsg);
93
+ this.log(`Error updating state for ${path}:`, errorMsg);
94
+ throw err;
95
+ }
96
+ };
97
+ const set = async (newData) => {
98
+ var _a;
99
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
100
+ throw new Error('SDK not initialized or user not logged in');
101
+ }
102
+ try {
103
+ setError(null);
104
+ await new Promise((resolve, reject) => {
105
+ this.sdk.gun.get(path).put(newData, (ack) => {
106
+ if (ack.err) {
107
+ reject(new Error(ack.err));
108
+ }
109
+ else {
110
+ resolve();
111
+ }
112
+ });
113
+ });
114
+ this.log(`State set for ${path}:`, newData);
115
+ }
116
+ catch (err) {
117
+ const errorMsg = err.message || 'Failed to set state';
118
+ setError(errorMsg);
119
+ this.log(`Error setting state for ${path}:`, errorMsg);
120
+ throw err;
121
+ }
122
+ };
123
+ const remove = async () => {
124
+ var _a;
125
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
126
+ throw new Error('SDK not initialized or user not logged in');
127
+ }
128
+ try {
129
+ setError(null);
130
+ await new Promise((resolve, reject) => {
131
+ this.sdk.gun.get(path).put(null, (ack) => {
132
+ if (ack.err) {
133
+ reject(new Error(ack.err));
134
+ }
135
+ else {
136
+ resolve();
137
+ }
138
+ });
139
+ });
140
+ setData(null);
141
+ this.log(`State removed for ${path}`);
142
+ }
143
+ catch (err) {
144
+ const errorMsg = err.message || 'Failed to remove state';
145
+ setError(errorMsg);
146
+ this.log(`Error removing state for ${path}:`, errorMsg);
147
+ throw err;
148
+ }
149
+ };
150
+ const refresh = () => {
151
+ var _a;
152
+ setIsLoading(true);
153
+ setError(null);
154
+ if ((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) {
155
+ this.sdk.gun.get(path).once(() => { });
156
+ }
157
+ };
158
+ return {
159
+ data,
160
+ isLoading,
161
+ error,
162
+ update,
163
+ set,
164
+ remove,
165
+ refresh
166
+ };
167
+ }
168
+ useGunCollection(path, options = {}) {
169
+ const { pageSize = this.config.defaultPageSize, sortBy, sortOrder = 'desc', filter, enableRealtime = true } = options;
170
+ const [items, setItems] = React.useState([]);
171
+ const [currentPage, setCurrentPage] = React.useState(0);
172
+ const [isLoading, setIsLoading] = React.useState(true);
173
+ const [error, setError] = React.useState(null);
174
+ const [allItems, setAllItems] = React.useState([]);
175
+ const isMounted = React.useRef(true);
176
+ const cacheKey = `${path}-${JSON.stringify(options)}`;
177
+ React.useEffect(() => {
178
+ var _a;
179
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
180
+ return;
181
+ setIsLoading(true);
182
+ setError(null);
183
+ const gunRef = this.sdk.gun.get(path);
184
+ const tempItems = [];
185
+ const processItems = (items) => {
186
+ if (!isMounted.current)
187
+ return;
188
+ let processedItems = filter ? items.filter(filter) : items;
189
+ if (sortBy) {
190
+ processedItems = [...processedItems].sort((a, b) => {
191
+ if (typeof sortBy === 'function') {
192
+ return sortOrder === 'asc' ? sortBy(a, b) : sortBy(b, a);
193
+ }
194
+ const aVal = a[sortBy];
195
+ const bVal = b[sortBy];
196
+ let comparison = 0;
197
+ if (aVal < bVal)
198
+ comparison = -1;
199
+ else if (aVal > bVal)
200
+ comparison = 1;
201
+ return sortOrder === 'asc' ? comparison : -comparison;
202
+ });
203
+ }
204
+ const startIndex = currentPage * pageSize;
205
+ const endIndex = startIndex + pageSize;
206
+ const pageItems = processedItems.slice(startIndex, endIndex);
207
+ setAllItems(processedItems);
208
+ setItems(pageItems);
209
+ setIsLoading(false);
210
+ setError(null);
211
+ this.collectionCache.set(cacheKey, {
212
+ items: processedItems,
213
+ timestamp: Date.now()
214
+ });
215
+ };
216
+ const off = gunRef.map().on((item, key) => {
217
+ if (item) {
218
+ const itemWithKey = { ...item, _key: key };
219
+ tempItems.push(itemWithKey);
220
+ if (enableRealtime) {
221
+ processItems(tempItems);
222
+ }
223
+ }
224
+ });
225
+ const timeoutId = setTimeout(() => {
226
+ if (isLoading) {
227
+ setError('Connection timeout - no data received');
228
+ setIsLoading(false);
229
+ }
230
+ }, this.config.connectionTimeout);
231
+ return () => {
232
+ isMounted.current = false;
233
+ if (typeof off === 'function')
234
+ off();
235
+ clearTimeout(timeoutId);
236
+ };
237
+ }, [path, currentPage, pageSize, sortBy, sortOrder, filter, enableRealtime]);
238
+ const totalPages = Math.ceil(allItems.length / pageSize);
239
+ const hasNextPage = currentPage < totalPages - 1;
240
+ const hasPrevPage = currentPage > 0;
241
+ const nextPage = () => {
242
+ if (hasNextPage)
243
+ setCurrentPage(prev => prev + 1);
244
+ };
245
+ const prevPage = () => {
246
+ if (hasPrevPage)
247
+ setCurrentPage(prev => prev - 1);
248
+ };
249
+ const goToPage = (page) => {
250
+ if (page >= 0 && page < totalPages)
251
+ setCurrentPage(page);
252
+ };
253
+ const refresh = () => {
254
+ var _a;
255
+ setIsLoading(true);
256
+ setError(null);
257
+ this.collectionCache.delete(cacheKey);
258
+ if ((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) {
259
+ this.sdk.gun.get(path).once(() => { });
260
+ }
261
+ };
262
+ const addItem = async (item) => {
263
+ var _a;
264
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
265
+ throw new Error('SDK not initialized or user not logged in');
266
+ }
267
+ try {
268
+ setError(null);
269
+ await new Promise((resolve, reject) => {
270
+ this.sdk.gun.get(path).set(item, (ack) => {
271
+ if (ack.err) {
272
+ reject(new Error(ack.err));
273
+ }
274
+ else {
275
+ resolve();
276
+ }
277
+ });
278
+ });
279
+ this.log(`Item added to collection ${path}:`, item);
280
+ refresh();
281
+ }
282
+ catch (err) {
283
+ const errorMsg = err.message || 'Failed to add item';
284
+ setError(errorMsg);
285
+ this.log(`Error adding item to collection ${path}:`, errorMsg);
286
+ throw err;
287
+ }
288
+ };
289
+ const updateItem = async (id, updates) => {
290
+ var _a;
291
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
292
+ throw new Error('SDK not initialized or user not logged in');
293
+ }
294
+ try {
295
+ setError(null);
296
+ await new Promise((resolve, reject) => {
297
+ this.sdk.gun.get(path).get(id).put(updates, (ack) => {
298
+ if (ack.err) {
299
+ reject(new Error(ack.err));
300
+ }
301
+ else {
302
+ resolve();
303
+ }
304
+ });
305
+ });
306
+ this.log(`Item updated in collection ${path}:`, { id, updates });
307
+ refresh();
308
+ }
309
+ catch (err) {
310
+ const errorMsg = err.message || 'Failed to update item';
311
+ setError(errorMsg);
312
+ this.log(`Error updating item in collection ${path}:`, errorMsg);
313
+ throw err;
314
+ }
315
+ };
316
+ const removeItem = async (id) => {
317
+ var _a;
318
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
319
+ throw new Error('SDK not initialized or user not logged in');
320
+ }
321
+ try {
322
+ setError(null);
323
+ await new Promise((resolve, reject) => {
324
+ this.sdk.gun.get(path).get(id).put(null, (ack) => {
325
+ if (ack.err) {
326
+ reject(new Error(ack.err));
327
+ }
328
+ else {
329
+ resolve();
330
+ }
331
+ });
332
+ });
333
+ this.log(`Item removed from collection ${path}:`, id);
334
+ refresh();
335
+ }
336
+ catch (err) {
337
+ const errorMsg = err.message || 'Failed to remove item';
338
+ setError(errorMsg);
339
+ this.log(`Error removing item from collection ${path}:`, errorMsg);
340
+ throw err;
341
+ }
342
+ };
343
+ return {
344
+ items,
345
+ currentPage,
346
+ totalPages,
347
+ hasNextPage,
348
+ hasPrevPage,
349
+ nextPage,
350
+ prevPage,
351
+ goToPage,
352
+ isLoading,
353
+ error,
354
+ refresh,
355
+ addItem,
356
+ updateItem,
357
+ removeItem
358
+ };
359
+ }
360
+ useGunConnection(path) {
361
+ const [isConnected, setIsConnected] = React.useState(false);
362
+ const [lastSeen, setLastSeen] = React.useState(null);
363
+ const [error, setError] = React.useState(null);
364
+ React.useEffect(() => {
365
+ var _a;
366
+ if (!this.config.enableConnectionMonitoring || !((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
367
+ return;
368
+ let timeoutId;
369
+ const gunRef = this.sdk.gun.get(path);
370
+ const resetTimeout = () => {
371
+ clearTimeout(timeoutId);
372
+ timeoutId = window.setTimeout(() => {
373
+ setIsConnected(false);
374
+ setError('Connection timeout');
375
+ this.log(`Connection timeout for ${path}`);
376
+ }, this.config.connectionTimeout);
377
+ };
378
+ const off = gunRef.on(() => {
379
+ setIsConnected(true);
380
+ setLastSeen(new Date());
381
+ setError(null);
382
+ resetTimeout();
383
+ this.log(`Connection active for ${path}`);
384
+ });
385
+ resetTimeout();
386
+ this.connectionMonitors.set(path, { off, timeoutId });
387
+ return () => {
388
+ clearTimeout(timeoutId);
389
+ if (typeof off === 'function')
390
+ off();
391
+ this.connectionMonitors.delete(path);
392
+ };
393
+ }, [path]);
394
+ return { isConnected, lastSeen, error };
395
+ }
396
+ useGunDebug(path, enabled = true) {
397
+ React.useEffect(() => {
398
+ var _a;
399
+ if (!enabled || !this.debugEnabled || !((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
400
+ return;
401
+ this.log(`Debug mode enabled for ${path}`);
402
+ const gunRef = this.sdk.gun.get(path);
403
+ const off = gunRef.on((data, key) => {
404
+ this.log(`[${path}] Update:`, {
405
+ key,
406
+ data,
407
+ timestamp: new Date().toISOString(),
408
+ });
409
+ });
410
+ return () => {
411
+ if (typeof off === 'function')
412
+ off();
413
+ this.log(`Debug mode disabled for ${path}`);
414
+ };
415
+ }, [path, enabled]);
416
+ }
417
+ useGunRealtime(path, callback) {
418
+ const [data, setData] = React.useState(null);
419
+ const [key, setKey] = React.useState(null);
420
+ React.useEffect(() => {
421
+ var _a;
422
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
423
+ return;
424
+ const gunRef = this.sdk.gun.get(path);
425
+ const off = gunRef.on((item, itemKey) => {
426
+ if (item) {
427
+ setData(item);
428
+ setKey(itemKey);
429
+ if (callback) {
430
+ callback(item, itemKey);
431
+ }
432
+ this.log(`Realtime update for ${path}:`, { data: item, key: itemKey });
433
+ }
434
+ });
435
+ return () => {
436
+ if (typeof off === 'function')
437
+ off();
438
+ };
439
+ }, [path, callback]);
440
+ return { data, key };
441
+ }
442
+ async put(path, data) {
443
+ var _a;
444
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
445
+ throw new Error('SDK not initialized or user not logged in');
446
+ }
447
+ return new Promise((resolve, reject) => {
448
+ this.sdk.gun.get(path).put(data, (ack) => {
449
+ if (ack.err) {
450
+ reject(new Error(ack.err));
451
+ }
452
+ else {
453
+ resolve();
454
+ }
455
+ });
456
+ });
457
+ }
458
+ get(path) {
459
+ var _a;
460
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn())
461
+ return null;
462
+ return this.sdk.gun.get(path);
463
+ }
464
+ async remove(path) {
465
+ var _a;
466
+ if (!((_a = this.sdk) === null || _a === void 0 ? void 0 : _a.gun) || !this.sdk.isLoggedIn()) {
467
+ throw new Error('SDK not initialized or user not logged in');
468
+ }
469
+ return new Promise((resolve, reject) => {
470
+ this.sdk.gun.get(path).put(null, (ack) => {
471
+ if (ack.err) {
472
+ reject(new Error(ack.err));
473
+ }
474
+ else {
475
+ resolve();
476
+ }
477
+ });
478
+ });
479
+ }
480
+ cleanup() {
481
+ this.connectionMonitors.forEach(({ off, timeoutId }) => {
482
+ clearTimeout(timeoutId);
483
+ if (typeof off === 'function')
484
+ off();
485
+ });
486
+ this.connectionMonitors.clear();
487
+ this.collectionCache.clear();
488
+ this.log('Plugin cleanup completed');
489
+ }
490
+ getStats() {
491
+ return {
492
+ activeConnections: this.connectionMonitors.size,
493
+ cachedCollections: this.collectionCache.size,
494
+ debugEnabled: this.debugEnabled,
495
+ config: this.config
496
+ };
497
+ }
498
+ }