shogun-button-react 1.5.1 → 1.5.6
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/CHANGELOG.md +54 -0
- package/README.md +457 -103
- package/dist/components/ShogunButton.d.ts +17 -0
- package/dist/components/ShogunButton.js +97 -15
- package/dist/connector.js +17 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/plugins/GunAdvancedPlugin.d.ts +79 -0
- package/dist/plugins/GunAdvancedPlugin.js +498 -0
- package/dist/types/connector-options.d.ts +6 -0
- package/package.json +2 -2
|
@@ -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
|
+
}
|
|
@@ -30,10 +30,16 @@ export interface ShogunConnectorOptions {
|
|
|
30
30
|
redirectUri?: string;
|
|
31
31
|
}>;
|
|
32
32
|
};
|
|
33
|
+
enableGunDebug?: boolean;
|
|
34
|
+
enableConnectionMonitoring?: boolean;
|
|
35
|
+
defaultPageSize?: number;
|
|
36
|
+
connectionTimeout?: number;
|
|
37
|
+
debounceInterval?: number;
|
|
33
38
|
}
|
|
34
39
|
export interface ShogunConnectorResult {
|
|
35
40
|
sdk: ShogunCore;
|
|
36
41
|
options: ShogunConnectorOptions;
|
|
37
42
|
registerPlugin: (plugin: any) => boolean;
|
|
38
43
|
hasPlugin: (name: string) => boolean;
|
|
44
|
+
gunPlugin: any;
|
|
39
45
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shogun-button-react",
|
|
3
3
|
"description": "Shogun connector button",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.6",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"src/styles/index.css"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ethers": "^6.13.5",
|
|
35
35
|
"prettier": "^3.5.3",
|
|
36
36
|
"rxjs": "^7.8.1",
|
|
37
|
-
"shogun-core": "^1.5.
|
|
37
|
+
"shogun-core": "^1.5.2"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react": "^18.0.0",
|