@trap_stevo/filetide 0.0.66 → 0.0.67
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/cjs/FileMessager.js
CHANGED
|
@@ -19,6 +19,10 @@ const {
|
|
|
19
19
|
const {
|
|
20
20
|
FileTransferManager
|
|
21
21
|
} = require("./HUDManagers/FileTransferManager");
|
|
22
|
+
const {
|
|
23
|
+
aggregateMultiAverageChartData,
|
|
24
|
+
aggregateChartData
|
|
25
|
+
} = require("./HUDManagers/TidalyticsUtilityManager");
|
|
22
26
|
const TideSentinelManager = require("./HUDManagers/TideSentinelManager");
|
|
23
27
|
const HUDTargetQueue = require("./HUDManagers/HUDTargetQueueManager");
|
|
24
28
|
const {
|
|
@@ -132,6 +136,899 @@ class FileMessager {
|
|
|
132
136
|
clearAllTidalytics() {
|
|
133
137
|
return tidalytics.clearAllMetrics();
|
|
134
138
|
}
|
|
139
|
+
attachTiderPresenceVisualStream(options = {}) {
|
|
140
|
+
const {
|
|
141
|
+
visualDataConfigurations = {},
|
|
142
|
+
mode = "buffer",
|
|
143
|
+
forward
|
|
144
|
+
} = options;
|
|
145
|
+
if (!forward) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
async function handle() {
|
|
149
|
+
if (mode === "signal") {
|
|
150
|
+
forward("rehydrate");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const result = await getTiderPresenceVisualData(visualDataConfigurations);
|
|
154
|
+
forward(result);
|
|
155
|
+
}
|
|
156
|
+
tidalytics.events.on("metric:created:tider:offline", handle);
|
|
157
|
+
tidalytics.events.on("metric:created:tider:online", handle);
|
|
158
|
+
}
|
|
159
|
+
attachAlreadyOnlineVisualStream(options = {}) {
|
|
160
|
+
const {
|
|
161
|
+
visualDataConfigurations = {},
|
|
162
|
+
mode = "buffer",
|
|
163
|
+
forward
|
|
164
|
+
} = options;
|
|
165
|
+
if (!forward) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
async function handle() {
|
|
169
|
+
if (mode === "signal") {
|
|
170
|
+
forward("rehydrate");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const result = await getAlreadyOnlineVisualData(visualDataConfigurations);
|
|
174
|
+
forward(result);
|
|
175
|
+
}
|
|
176
|
+
tidalytics.events.on("metric:created:tider:already-online", handle);
|
|
177
|
+
}
|
|
178
|
+
attachTiderBanVisualStream(options = {}) {
|
|
179
|
+
const {
|
|
180
|
+
visualDataConfigurations = {},
|
|
181
|
+
mode = "buffer",
|
|
182
|
+
forward
|
|
183
|
+
} = options;
|
|
184
|
+
if (!forward) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
async function handle() {
|
|
188
|
+
if (mode === "signal") {
|
|
189
|
+
forward("rehydrate");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const result = await getTiderBanVisualData(visualDataConfigurations);
|
|
193
|
+
forward(result);
|
|
194
|
+
}
|
|
195
|
+
tidalytics.events.on("metric:created:tider:unbanned", handle);
|
|
196
|
+
tidalytics.events.on("metric:created:tider:banned", handle);
|
|
197
|
+
tidalytics.events.on("metric:created:tider:kicked", handle);
|
|
198
|
+
}
|
|
199
|
+
attachTideFileTransferVisualStream(options = {}) {
|
|
200
|
+
const {
|
|
201
|
+
visualDataConfigurations = {},
|
|
202
|
+
mode = "buffer",
|
|
203
|
+
forward
|
|
204
|
+
} = options;
|
|
205
|
+
if (!forward) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
async function handle() {
|
|
209
|
+
if (mode === "signal") {
|
|
210
|
+
forward("rehydrate");
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const result = await getTideFileTransferVisualData(visualDataConfigurations);
|
|
214
|
+
forward(result);
|
|
215
|
+
}
|
|
216
|
+
tidalytics.events.on("metric:created:tide:completed-transfer", handle);
|
|
217
|
+
tidalytics.events.on("metric:created:tide:incoming-transfer", handle);
|
|
218
|
+
tidalytics.events.on("metric:created:tide:incoming-file", handle);
|
|
219
|
+
}
|
|
220
|
+
attachTideTransferStateVisualStream(options = {}) {
|
|
221
|
+
const {
|
|
222
|
+
visualDataConfigurations = {},
|
|
223
|
+
mode = "buffer",
|
|
224
|
+
forward
|
|
225
|
+
} = options;
|
|
226
|
+
if (!forward) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
async function handle() {
|
|
230
|
+
if (mode === "signal") {
|
|
231
|
+
forward("rehydrate");
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const result = await getTideTransferStateVisualData(visualDataConfigurations);
|
|
235
|
+
forward(result);
|
|
236
|
+
}
|
|
237
|
+
tidalytics.events.on("metric:created:tide:transfer-state", handle);
|
|
238
|
+
}
|
|
239
|
+
attachFileListVisualStream(options = {}) {
|
|
240
|
+
const {
|
|
241
|
+
visualDataConfigurations = {},
|
|
242
|
+
mode = "buffer",
|
|
243
|
+
forward
|
|
244
|
+
} = options;
|
|
245
|
+
if (!forward) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
async function handle() {
|
|
249
|
+
if (mode === "signal") {
|
|
250
|
+
forward("rehydrate");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const result = await getFileListVisualData(visualDataConfigurations);
|
|
254
|
+
forward(result);
|
|
255
|
+
}
|
|
256
|
+
tidalytics.events.on("metric:created:file-list:received", handle);
|
|
257
|
+
tidalytics.events.on("metric:created:file-list:request", handle);
|
|
258
|
+
}
|
|
259
|
+
attachTideBarrierVisualStream(options = {}) {
|
|
260
|
+
const {
|
|
261
|
+
visualDataConfigurations = {},
|
|
262
|
+
mode = "buffer",
|
|
263
|
+
forward
|
|
264
|
+
} = options;
|
|
265
|
+
if (!forward) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
async function handle() {
|
|
269
|
+
if (mode === "signal") {
|
|
270
|
+
forward("rehydrate");
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const result = await getTideBarrierVisualData(visualDataConfigurations);
|
|
274
|
+
forward(result);
|
|
275
|
+
}
|
|
276
|
+
tidalytics.events.on("metric:created:tide-barrier:accepted", handle);
|
|
277
|
+
tidalytics.events.on("metric:created:tide-barrier:denied", handle);
|
|
278
|
+
}
|
|
279
|
+
async getTiderPresenceVisualData(options = {}) {
|
|
280
|
+
const {
|
|
281
|
+
interval = "1d",
|
|
282
|
+
limit = Infinity,
|
|
283
|
+
filter = {},
|
|
284
|
+
mode = "all"
|
|
285
|
+
} = options;
|
|
286
|
+
const sources = ["storage", "memory"];
|
|
287
|
+
const [storedOnline, storedOffline] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
288
|
+
...filter,
|
|
289
|
+
tags: {
|
|
290
|
+
"tider:online": "tider:online"
|
|
291
|
+
}
|
|
292
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
293
|
+
...filter,
|
|
294
|
+
tags: {
|
|
295
|
+
"tider:offline": "tider:offline"
|
|
296
|
+
}
|
|
297
|
+
})]);
|
|
298
|
+
const [liveOnline] = await Promise.all([this.getTidalyticsSince(interval, sources[1], {
|
|
299
|
+
...filter,
|
|
300
|
+
tags: {
|
|
301
|
+
"tider:online": "tider:online"
|
|
302
|
+
}
|
|
303
|
+
})]);
|
|
304
|
+
const onlineMetrics = [...storedOnline, ...liveOnline];
|
|
305
|
+
const offlineMetrics = storedOffline;
|
|
306
|
+
const sessionsByKey = {};
|
|
307
|
+
for (const event of onlineMetrics) {
|
|
308
|
+
const user = event.metadata?.user;
|
|
309
|
+
const connectionID = event.metadata?.connectionID;
|
|
310
|
+
const connectedOn = event.metadata?.connectedOn || event.timestamp;
|
|
311
|
+
const key = `${user}_${connectionID}`;
|
|
312
|
+
sessionsByKey[key] = {
|
|
313
|
+
sessionDuration: null,
|
|
314
|
+
disconnectedOn: null,
|
|
315
|
+
connectionID,
|
|
316
|
+
connectedOn,
|
|
317
|
+
user
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
for (const event of offlineMetrics) {
|
|
321
|
+
const user = event.metadata?.user;
|
|
322
|
+
const connectionID = event.metadata?.connectionID;
|
|
323
|
+
const disconnectedOn = event.timestamp;
|
|
324
|
+
const key = `${user}_${connectionID}`;
|
|
325
|
+
if (sessionsByKey[key]) {
|
|
326
|
+
sessionsByKey[key].sessionDuration = disconnectedOn - sessionsByKey[key].connectedOn;
|
|
327
|
+
sessionsByKey[key].disconnectedOn = disconnectedOn;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
let allSessions = Object.values(sessionsByKey);
|
|
331
|
+
if (mode === "online") {
|
|
332
|
+
allSessions = allSessions.filter(session => session.disconnectedOn === null);
|
|
333
|
+
} else if (mode === "offline") {
|
|
334
|
+
allSessions = allSessions.filter(session => session.disconnectedOn !== null);
|
|
335
|
+
}
|
|
336
|
+
return limit === Infinity ? allSessions : allSessions.slice(-limit).reverse();
|
|
337
|
+
}
|
|
338
|
+
async getAlreadyOnlineVisualData(options = {}) {
|
|
339
|
+
const {
|
|
340
|
+
interval = "1d",
|
|
341
|
+
filter = {},
|
|
342
|
+
limit = Infinity,
|
|
343
|
+
format = "raw",
|
|
344
|
+
chartConfig = {}
|
|
345
|
+
} = options;
|
|
346
|
+
const fullChartConfig = {
|
|
347
|
+
groupBy: "metadata.user",
|
|
348
|
+
mode: "count",
|
|
349
|
+
valueKey: "value",
|
|
350
|
+
metadataFields: null,
|
|
351
|
+
previewLimit: 3,
|
|
352
|
+
...chartConfig
|
|
353
|
+
};
|
|
354
|
+
const sources = ["storage", "memory"];
|
|
355
|
+
const [alreadyOnlineEvents, onlineJoins] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
356
|
+
...filter,
|
|
357
|
+
tags: {
|
|
358
|
+
"tider:already-online": "tider:already-online"
|
|
359
|
+
}
|
|
360
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
361
|
+
...filter,
|
|
362
|
+
tags: {
|
|
363
|
+
"tider:online": "tider:online"
|
|
364
|
+
}
|
|
365
|
+
})]);
|
|
366
|
+
const entries = alreadyOnlineEvents.map(e => ({
|
|
367
|
+
...e,
|
|
368
|
+
type: "already-online"
|
|
369
|
+
})).sort((a, b) => b.timestamp - a.timestamp);
|
|
370
|
+
const joinCountsByUser = {};
|
|
371
|
+
for (const evt of onlineJoins) {
|
|
372
|
+
const user = evt.metadata?.user;
|
|
373
|
+
if (!user) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
joinCountsByUser[user] = (joinCountsByUser[user] || 0) + 1;
|
|
377
|
+
}
|
|
378
|
+
if (format === "chart") {
|
|
379
|
+
const result = fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
380
|
+
...fullChartConfig,
|
|
381
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
382
|
+
}) : aggregateChartData(entries, {
|
|
383
|
+
...fullChartConfig,
|
|
384
|
+
typeKey: "type"
|
|
385
|
+
});
|
|
386
|
+
return result.map(entry => {
|
|
387
|
+
const userKey = entry.label;
|
|
388
|
+
const totalJoins = joinCountsByUser[userKey] || 0;
|
|
389
|
+
return {
|
|
390
|
+
...entry,
|
|
391
|
+
totalJoins,
|
|
392
|
+
collisionRate: totalJoins > 0 ? +(entry.count / totalJoins).toFixed(3) : 0
|
|
393
|
+
};
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
397
|
+
}
|
|
398
|
+
async getTiderBanVisualData(options = {}) {
|
|
399
|
+
const {
|
|
400
|
+
interval = "1d",
|
|
401
|
+
filter = {},
|
|
402
|
+
limit = Infinity,
|
|
403
|
+
format = "raw",
|
|
404
|
+
chartConfig = {}
|
|
405
|
+
} = options;
|
|
406
|
+
const fullChartConfig = {
|
|
407
|
+
groupBy: "type",
|
|
408
|
+
mode: "count",
|
|
409
|
+
...chartConfig
|
|
410
|
+
};
|
|
411
|
+
const sources = ["storage", "memory"];
|
|
412
|
+
const [banned, kicked, unbanned] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
413
|
+
...filter,
|
|
414
|
+
tags: {
|
|
415
|
+
"tider:banned": "tider:banned"
|
|
416
|
+
}
|
|
417
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
418
|
+
...filter,
|
|
419
|
+
tags: {
|
|
420
|
+
"tider:kicked": "tider:kicked"
|
|
421
|
+
}
|
|
422
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
423
|
+
...filter,
|
|
424
|
+
tags: {
|
|
425
|
+
"tider:unbanned": "tider:unbanned"
|
|
426
|
+
}
|
|
427
|
+
})]);
|
|
428
|
+
const entries = [...banned.map(e => ({
|
|
429
|
+
...e,
|
|
430
|
+
type: "banned"
|
|
431
|
+
})), ...kicked.map(e => ({
|
|
432
|
+
...e,
|
|
433
|
+
type: "kicked"
|
|
434
|
+
})), ...unbanned.map(e => ({
|
|
435
|
+
...e,
|
|
436
|
+
type: "unbanned"
|
|
437
|
+
}))].sort((a, b) => b.timestamp - a.timestamp);
|
|
438
|
+
if (format === "chart") {
|
|
439
|
+
return fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
440
|
+
...fullChartConfig,
|
|
441
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
442
|
+
}) : aggregateChartData(entries, {
|
|
443
|
+
...fullChartConfig,
|
|
444
|
+
typeKey: "type"
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
448
|
+
}
|
|
449
|
+
async getTideFileTransferVisualData(options = {}) {
|
|
450
|
+
const {
|
|
451
|
+
interval = "1d",
|
|
452
|
+
filter = {},
|
|
453
|
+
limit = Infinity,
|
|
454
|
+
format = "raw",
|
|
455
|
+
chartConfig = {}
|
|
456
|
+
} = options;
|
|
457
|
+
const fullChartConfig = {
|
|
458
|
+
groupBy: "type",
|
|
459
|
+
mode: "count",
|
|
460
|
+
...chartConfig
|
|
461
|
+
};
|
|
462
|
+
const sources = ["storage", "memory"];
|
|
463
|
+
const [incomingTransfers, incoming, completed] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
464
|
+
...filter,
|
|
465
|
+
tags: {
|
|
466
|
+
"tide:incoming-transfer": "tide:incoming-transfer"
|
|
467
|
+
}
|
|
468
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
469
|
+
...filter,
|
|
470
|
+
tags: {
|
|
471
|
+
"tide:incoming-file": "tide:incoming-file"
|
|
472
|
+
}
|
|
473
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
474
|
+
...filter,
|
|
475
|
+
tags: {
|
|
476
|
+
"tide:completed-transfer": "tide:completed-transfer"
|
|
477
|
+
}
|
|
478
|
+
})]);
|
|
479
|
+
const entries = [...incomingTransfers.map(e => ({
|
|
480
|
+
...e,
|
|
481
|
+
type: "incoming-transfer"
|
|
482
|
+
})), ...incoming.map(e => ({
|
|
483
|
+
...e,
|
|
484
|
+
type: "incoming"
|
|
485
|
+
})), ...completed.map(e => ({
|
|
486
|
+
...e,
|
|
487
|
+
type: "completed"
|
|
488
|
+
}))].sort((a, b) => b.timestamp - a.timestamp);
|
|
489
|
+
if (format === "chart") {
|
|
490
|
+
return fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
491
|
+
...fullChartConfig,
|
|
492
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
493
|
+
}) : aggregateChartData(entries, {
|
|
494
|
+
...fullChartConfig,
|
|
495
|
+
typeKey: "type"
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
499
|
+
}
|
|
500
|
+
async getTideTransferStateVisualData(options = {}) {
|
|
501
|
+
const {
|
|
502
|
+
interval = "1d",
|
|
503
|
+
filter = {},
|
|
504
|
+
limit = Infinity,
|
|
505
|
+
format = "raw",
|
|
506
|
+
chartConfig = {}
|
|
507
|
+
} = options;
|
|
508
|
+
const fullChartConfig = {
|
|
509
|
+
groupBy: "metadata.transferStateID",
|
|
510
|
+
mode: "average",
|
|
511
|
+
valueKey: "metadata.speed",
|
|
512
|
+
metadataFields: ["senderID", "recipientID", "transferProgress", "speed", "transferETA", "fileName"],
|
|
513
|
+
previewLimit: 3,
|
|
514
|
+
...chartConfig
|
|
515
|
+
};
|
|
516
|
+
const sources = ["storage", "memory"];
|
|
517
|
+
const [transferStates] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
518
|
+
...filter,
|
|
519
|
+
tags: {
|
|
520
|
+
"tide:transfer-state": "tide:transfer-state"
|
|
521
|
+
}
|
|
522
|
+
})]);
|
|
523
|
+
const entries = transferStates.map(e => ({
|
|
524
|
+
...e,
|
|
525
|
+
type: "transfer-state"
|
|
526
|
+
})).sort((a, b) => b.timestamp - a.timestamp);
|
|
527
|
+
if (format === "chart") {
|
|
528
|
+
return fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
529
|
+
...fullChartConfig,
|
|
530
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
531
|
+
}) : aggregateChartData(entries, {
|
|
532
|
+
...fullChartConfig,
|
|
533
|
+
typeKey: "type"
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
537
|
+
}
|
|
538
|
+
async getFileListActivityVisualData(options = {}) {
|
|
539
|
+
const {
|
|
540
|
+
interval = "1d",
|
|
541
|
+
filter = {},
|
|
542
|
+
limit = Infinity,
|
|
543
|
+
format = "raw",
|
|
544
|
+
chartConfig = {}
|
|
545
|
+
} = options;
|
|
546
|
+
const fullChartConfig = {
|
|
547
|
+
groupBy: "type",
|
|
548
|
+
mode: "count",
|
|
549
|
+
...chartConfig
|
|
550
|
+
};
|
|
551
|
+
const sources = ["storage", "memory"];
|
|
552
|
+
const [requested, received] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
553
|
+
...filter,
|
|
554
|
+
tags: {
|
|
555
|
+
"file-list:request": "file-list:request"
|
|
556
|
+
}
|
|
557
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
558
|
+
...filter,
|
|
559
|
+
tags: {
|
|
560
|
+
"file-list:received": "file-list:received"
|
|
561
|
+
}
|
|
562
|
+
})]);
|
|
563
|
+
const entries = [...requested.map(e => ({
|
|
564
|
+
...e,
|
|
565
|
+
type: "requested"
|
|
566
|
+
})), ...received.map(e => ({
|
|
567
|
+
...e,
|
|
568
|
+
type: "received"
|
|
569
|
+
}))].sort((a, b) => b.timestamp - a.timestamp);
|
|
570
|
+
if (format === "chart") {
|
|
571
|
+
return fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
572
|
+
...fullChartConfig,
|
|
573
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
574
|
+
}) : aggregateChartData(entries, {
|
|
575
|
+
...fullChartConfig,
|
|
576
|
+
typeKey: "type"
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
580
|
+
}
|
|
581
|
+
async getTideBarrierVisualData(options = {}) {
|
|
582
|
+
const {
|
|
583
|
+
interval = "1d",
|
|
584
|
+
filter = {},
|
|
585
|
+
limit = Infinity,
|
|
586
|
+
format = "raw",
|
|
587
|
+
chartConfig = {}
|
|
588
|
+
} = options;
|
|
589
|
+
const fullChartConfig = {
|
|
590
|
+
groupBy: "type",
|
|
591
|
+
mode: "count",
|
|
592
|
+
...chartConfig
|
|
593
|
+
};
|
|
594
|
+
const sources = ["storage", "memory"];
|
|
595
|
+
const [accepted, denied] = await Promise.all([this.getTidalyticsSince(interval, sources[0], {
|
|
596
|
+
...filter,
|
|
597
|
+
tags: {
|
|
598
|
+
"tide-barrier:accepted": "tide-barrier:accepted"
|
|
599
|
+
}
|
|
600
|
+
}), this.getTidalyticsSince(interval, sources[0], {
|
|
601
|
+
...filter,
|
|
602
|
+
tags: {
|
|
603
|
+
"tide-barrier:denied": "tide-barrier:denied"
|
|
604
|
+
}
|
|
605
|
+
})]);
|
|
606
|
+
const entries = [...accepted.map(e => ({
|
|
607
|
+
...e,
|
|
608
|
+
type: "accepted"
|
|
609
|
+
})), ...denied.map(e => ({
|
|
610
|
+
...e,
|
|
611
|
+
type: "denied"
|
|
612
|
+
}))].sort((a, b) => b.timestamp - a.timestamp);
|
|
613
|
+
if (format === "chart") {
|
|
614
|
+
return fullChartConfig.mode === "average" ? aggregateMultiAverageChartData(entries, {
|
|
615
|
+
...fullChartConfig,
|
|
616
|
+
groupBy: [].concat(fullChartConfig.groupBy)
|
|
617
|
+
}) : aggregateChartData(entries, {
|
|
618
|
+
...fullChartConfig,
|
|
619
|
+
typeKey: "type"
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
return limit === Infinity ? entries : entries.slice(0, limit);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// --- File Messager Tide Actions Management ---
|
|
626
|
+
|
|
627
|
+
async getTideCompletedTransferActions({
|
|
628
|
+
interval = "1d",
|
|
629
|
+
limit = 50,
|
|
630
|
+
source = "storage",
|
|
631
|
+
filter = {}
|
|
632
|
+
} = {}) {
|
|
633
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
634
|
+
...filter,
|
|
635
|
+
tags: {
|
|
636
|
+
"tide:completed-transfer": "tide:completed-transfer"
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
if (!Array.isArray(rawMetrics)) {
|
|
640
|
+
return [];
|
|
641
|
+
}
|
|
642
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
643
|
+
return limitedMetrics.map(event => ({
|
|
644
|
+
tideActionID: "tide-completed-transfer",
|
|
645
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
646
|
+
tideActionDetails: {
|
|
647
|
+
recipientID: event.metadata?.recipientID,
|
|
648
|
+
senderID: event.metadata?.senderID,
|
|
649
|
+
path: event.metadata?.path,
|
|
650
|
+
fileSize: event.metadata?.fileSize,
|
|
651
|
+
fileName: event.metadata?.fileName,
|
|
652
|
+
completedChunks: event.metadata?.completedChunks,
|
|
653
|
+
totalChunks: event.metadata?.totalChunks,
|
|
654
|
+
chunkSize: event.metadata?.chunkSize
|
|
655
|
+
}
|
|
656
|
+
}));
|
|
657
|
+
}
|
|
658
|
+
async getTideTransferStateActions({
|
|
659
|
+
interval = "1d",
|
|
660
|
+
limit = Infinity,
|
|
661
|
+
source = "storage",
|
|
662
|
+
filter = {}
|
|
663
|
+
} = {}) {
|
|
664
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
665
|
+
...filter,
|
|
666
|
+
tags: {
|
|
667
|
+
"tide:transfer-state": "tide:transfer-state"
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
if (!Array.isArray(rawMetrics)) {
|
|
671
|
+
return [];
|
|
672
|
+
}
|
|
673
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
674
|
+
return limitedMetrics.map(event => ({
|
|
675
|
+
tideActionID: "tide-transfer-state",
|
|
676
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
677
|
+
tideActionDetails: {
|
|
678
|
+
transferStateID: event.metadata?.transferStateID,
|
|
679
|
+
recipientID: event.metadata?.recipientID,
|
|
680
|
+
senderID: event.metadata?.senderID,
|
|
681
|
+
path: event.metadata?.path,
|
|
682
|
+
startTime: event.metadata?.startTime,
|
|
683
|
+
currentTransferredSize: event.metadata?.currentTransferredSize,
|
|
684
|
+
speed: event.metadata?.speed,
|
|
685
|
+
transferProgress: event.metadata?.transferProgress,
|
|
686
|
+
transferSize: event.metadata?.transferSize,
|
|
687
|
+
transferETA: event.metadata?.transferETA,
|
|
688
|
+
fileName: event.metadata?.fileName
|
|
689
|
+
}
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
async getTideIncomingFileActions({
|
|
693
|
+
interval = "1d",
|
|
694
|
+
limit = 50,
|
|
695
|
+
source = "storage",
|
|
696
|
+
filter = {}
|
|
697
|
+
} = {}) {
|
|
698
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
699
|
+
...filter,
|
|
700
|
+
tags: {
|
|
701
|
+
"tide:incoming-file": "tide:incoming-file"
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
if (!Array.isArray(rawMetrics)) {
|
|
705
|
+
return [];
|
|
706
|
+
}
|
|
707
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
708
|
+
return limitedMetrics.map(event => ({
|
|
709
|
+
tideActionID: "tide-incoming-file",
|
|
710
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
711
|
+
tideActionDetails: {
|
|
712
|
+
recipientID: event.metadata?.recipientID,
|
|
713
|
+
senderID: event.metadata?.senderID,
|
|
714
|
+
path: event.metadata?.path,
|
|
715
|
+
fileSize: event.metadata?.fileSize,
|
|
716
|
+
fileName: event.metadata?.fileName,
|
|
717
|
+
totalChunks: event.metadata?.totalChunks,
|
|
718
|
+
chunkSize: event.metadata?.chunkSize
|
|
719
|
+
}
|
|
720
|
+
}));
|
|
721
|
+
}
|
|
722
|
+
async getTideIncomingTransferActions({
|
|
723
|
+
interval = "1d",
|
|
724
|
+
limit = 50,
|
|
725
|
+
source = "storage",
|
|
726
|
+
filter = {}
|
|
727
|
+
} = {}) {
|
|
728
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
729
|
+
...filter,
|
|
730
|
+
tags: {
|
|
731
|
+
"tide:incoming-transfer": "tide:incoming-transfer"
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
if (!Array.isArray(rawMetrics)) {
|
|
735
|
+
return [];
|
|
736
|
+
}
|
|
737
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
738
|
+
return limitedMetrics.map(event => ({
|
|
739
|
+
tideActionID: "tide-incoming-transfer",
|
|
740
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
741
|
+
tideActionDetails: {
|
|
742
|
+
recipientID: event.metadata?.recipientID,
|
|
743
|
+
senderID: event.metadata?.senderID,
|
|
744
|
+
fileSize: event.metadata?.fileSize,
|
|
745
|
+
fileName: event.metadata?.fileName,
|
|
746
|
+
path: event.metadata?.path,
|
|
747
|
+
startedOn: event.metadata?.startedOn
|
|
748
|
+
}
|
|
749
|
+
}));
|
|
750
|
+
}
|
|
751
|
+
async getTideBarrierAcceptedActions({
|
|
752
|
+
interval = "1d",
|
|
753
|
+
limit = 50,
|
|
754
|
+
source = "storage",
|
|
755
|
+
filter = {}
|
|
756
|
+
} = {}) {
|
|
757
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
758
|
+
...filter,
|
|
759
|
+
tags: {
|
|
760
|
+
"tide-barrier:accepted": "tide-barrier:accepted"
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
if (!Array.isArray(rawMetrics)) {
|
|
764
|
+
return [];
|
|
765
|
+
}
|
|
766
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
767
|
+
return limitedMetrics.map(event => ({
|
|
768
|
+
tideActionID: "tide-barrier-accepted",
|
|
769
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
770
|
+
tideActionDetails: {
|
|
771
|
+
recipientID: event.metadata?.recipientID,
|
|
772
|
+
transferID: event.metadata?.transferID,
|
|
773
|
+
senderID: event.metadata?.senderID,
|
|
774
|
+
tideItemCount: event.metadata?.tideItemCount,
|
|
775
|
+
tideItemSize: event.metadata?.tideItemSize,
|
|
776
|
+
tideTransferContentType: event.metadata?.tideTransferContentType,
|
|
777
|
+
tideTransferType: event.metadata?.tideTransferType,
|
|
778
|
+
tideDestinationPath: event.metadata?.tideDestinationPath,
|
|
779
|
+
tideOriginPath: event.metadata?.tideOriginPath
|
|
780
|
+
}
|
|
781
|
+
}));
|
|
782
|
+
}
|
|
783
|
+
async getTideBarrierDeniedActions({
|
|
784
|
+
interval = "1d",
|
|
785
|
+
limit = 50,
|
|
786
|
+
source = "storage",
|
|
787
|
+
filter = {}
|
|
788
|
+
} = {}) {
|
|
789
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
790
|
+
...filter,
|
|
791
|
+
tags: {
|
|
792
|
+
"tide-barrier:denied": "tide-barrier:denied"
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
if (!Array.isArray(rawMetrics)) {
|
|
796
|
+
return [];
|
|
797
|
+
}
|
|
798
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
799
|
+
return limitedMetrics.map(event => ({
|
|
800
|
+
tideActionID: "tide-barrier-denied",
|
|
801
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
802
|
+
tideActionDetails: {
|
|
803
|
+
recipientID: event.metadata?.recipientID,
|
|
804
|
+
transferID: event.metadata?.transferID,
|
|
805
|
+
senderID: event.metadata?.senderID,
|
|
806
|
+
tideItemCount: event.metadata?.tideItemCount,
|
|
807
|
+
tideItemSize: event.metadata?.tideItemSize,
|
|
808
|
+
tideTransferContentType: event.metadata?.tideTransferContentType,
|
|
809
|
+
tideTransferType: event.metadata?.tideTransferType,
|
|
810
|
+
tideDestinationPath: event.metadata?.tideDestinationPath,
|
|
811
|
+
tideOriginPath: event.metadata?.tideOriginPath
|
|
812
|
+
}
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
async getFileListReceivedActions({
|
|
816
|
+
interval = "1d",
|
|
817
|
+
limit = 50,
|
|
818
|
+
source = "storage",
|
|
819
|
+
filter = {}
|
|
820
|
+
} = {}) {
|
|
821
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
822
|
+
...filter,
|
|
823
|
+
tags: {
|
|
824
|
+
"file-list:received": "file-list:received"
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
if (!Array.isArray(rawMetrics)) {
|
|
828
|
+
return [];
|
|
829
|
+
}
|
|
830
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
831
|
+
return limitedMetrics.map(event => ({
|
|
832
|
+
tideActionID: "file-list-received",
|
|
833
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
834
|
+
tideActionDetails: {
|
|
835
|
+
recipientID: event.metadata?.recipientID,
|
|
836
|
+
senderID: event.metadata?.senderID,
|
|
837
|
+
totalItems: event.metadata?.totalItems,
|
|
838
|
+
runningOn: event.metadata?.runningOn
|
|
839
|
+
}
|
|
840
|
+
}));
|
|
841
|
+
}
|
|
842
|
+
async getFileListRequestActions({
|
|
843
|
+
interval = "1d",
|
|
844
|
+
limit = 50,
|
|
845
|
+
source = "storage",
|
|
846
|
+
filter = {}
|
|
847
|
+
} = {}) {
|
|
848
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
849
|
+
...filter,
|
|
850
|
+
tags: {
|
|
851
|
+
"file-list:request": "file-list:request"
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
if (!Array.isArray(rawMetrics)) {
|
|
855
|
+
return [];
|
|
856
|
+
}
|
|
857
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
858
|
+
return limitedMetrics.map(event => ({
|
|
859
|
+
tideActionID: "file-list-request",
|
|
860
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
861
|
+
tideActionDetails: {
|
|
862
|
+
recipientID: event.metadata?.recipientID,
|
|
863
|
+
requesterID: event.metadata?.requesterID,
|
|
864
|
+
depth: event.metadata?.depth
|
|
865
|
+
}
|
|
866
|
+
}));
|
|
867
|
+
}
|
|
868
|
+
async getTiderBannedActions({
|
|
869
|
+
interval = "1d",
|
|
870
|
+
limit = 50,
|
|
871
|
+
source = "storage",
|
|
872
|
+
filter = {}
|
|
873
|
+
} = {}) {
|
|
874
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
875
|
+
...filter,
|
|
876
|
+
tags: {
|
|
877
|
+
"tider:banned": "tider:banned"
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
if (!Array.isArray(rawMetrics)) {
|
|
881
|
+
return [];
|
|
882
|
+
}
|
|
883
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
884
|
+
return limitedMetrics.map(event => ({
|
|
885
|
+
tideActionID: "ban-client-activated",
|
|
886
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
887
|
+
tideActionDetails: {
|
|
888
|
+
clientID: event.metadata?.clientID,
|
|
889
|
+
options: event.metadata?.options
|
|
890
|
+
}
|
|
891
|
+
}));
|
|
892
|
+
}
|
|
893
|
+
async getTiderKickedActions({
|
|
894
|
+
interval = "1d",
|
|
895
|
+
limit = 50,
|
|
896
|
+
source = "storage",
|
|
897
|
+
filter = {}
|
|
898
|
+
} = {}) {
|
|
899
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
900
|
+
...filter,
|
|
901
|
+
tags: {
|
|
902
|
+
"tider:kicked": "tider:kicked"
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
if (!Array.isArray(rawMetrics)) {
|
|
906
|
+
return [];
|
|
907
|
+
}
|
|
908
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
909
|
+
return limitedMetrics.map(event => ({
|
|
910
|
+
tideActionID: "kick-client-activated",
|
|
911
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
912
|
+
tideActionDetails: {
|
|
913
|
+
clientID: event.metadata?.clientID,
|
|
914
|
+
options: event.metadata?.options
|
|
915
|
+
}
|
|
916
|
+
}));
|
|
917
|
+
}
|
|
918
|
+
async getTiderUnbannedActions({
|
|
919
|
+
interval = "1d",
|
|
920
|
+
limit = 50,
|
|
921
|
+
source = "storage",
|
|
922
|
+
filter = {}
|
|
923
|
+
} = {}) {
|
|
924
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
925
|
+
...filter,
|
|
926
|
+
tags: {
|
|
927
|
+
"tider:unbanned": "tider:unbanned"
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
if (!Array.isArray(rawMetrics)) {
|
|
931
|
+
return [];
|
|
932
|
+
}
|
|
933
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
934
|
+
return limitedMetrics.map(event => ({
|
|
935
|
+
tideActionID: "unban-client-activated",
|
|
936
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
937
|
+
tideActionDetails: {
|
|
938
|
+
clientID: event.metadata?.clientID
|
|
939
|
+
}
|
|
940
|
+
}));
|
|
941
|
+
}
|
|
942
|
+
async getTiderAlreadyOnlineActions({
|
|
943
|
+
interval = "1d",
|
|
944
|
+
limit = 50,
|
|
945
|
+
source = "storage",
|
|
946
|
+
filter = {}
|
|
947
|
+
} = {}) {
|
|
948
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
949
|
+
...filter,
|
|
950
|
+
tags: {
|
|
951
|
+
"tider:already-online": "tider:already-online"
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
if (!Array.isArray(rawMetrics)) {
|
|
955
|
+
return [];
|
|
956
|
+
}
|
|
957
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
958
|
+
return limitedMetrics.map(event => ({
|
|
959
|
+
tideActionID: "tider-already-online",
|
|
960
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
961
|
+
tideActionDetails: {
|
|
962
|
+
currentTideChannel: event.metadata?.currentTideChannel || "file-room",
|
|
963
|
+
originUser: event.metadata?.originUser,
|
|
964
|
+
user: event.metadata?.user,
|
|
965
|
+
connectionID: event.metadata?.connectionID,
|
|
966
|
+
pClientID: event.metadata?.pClientID,
|
|
967
|
+
tideID: event.metadata?.tideID,
|
|
968
|
+
connectedOn: event.metadata?.connectedOn
|
|
969
|
+
}
|
|
970
|
+
}));
|
|
971
|
+
}
|
|
972
|
+
async getTiderOnlineActions({
|
|
973
|
+
interval = "1d",
|
|
974
|
+
limit = 50,
|
|
975
|
+
source = "storage",
|
|
976
|
+
filter = {}
|
|
977
|
+
} = {}) {
|
|
978
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
979
|
+
...filter,
|
|
980
|
+
tags: {
|
|
981
|
+
"tider:online": "tider:online"
|
|
982
|
+
}
|
|
983
|
+
});
|
|
984
|
+
if (!rawMetrics || !Array.isArray(rawMetrics)) {
|
|
985
|
+
return [];
|
|
986
|
+
}
|
|
987
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
988
|
+
return limitedMetrics.map(event => ({
|
|
989
|
+
tideActionID: "tider-online",
|
|
990
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
991
|
+
tideActionDetails: {
|
|
992
|
+
currentTideChannel: event.metadata?.currentTideChannel || "file-room",
|
|
993
|
+
connectedOn: event.metadata?.connectedOn,
|
|
994
|
+
originUser: event.metadata?.originUser,
|
|
995
|
+
user: event.metadata?.user,
|
|
996
|
+
connectionID: event.metadata?.connectionID,
|
|
997
|
+
pClientID: event.metadata?.pClientID,
|
|
998
|
+
tideID: event.metadata?.tideID
|
|
999
|
+
}
|
|
1000
|
+
}));
|
|
1001
|
+
}
|
|
1002
|
+
async getTiderOfflineActions({
|
|
1003
|
+
interval = "1d",
|
|
1004
|
+
limit = 50,
|
|
1005
|
+
source = "storage",
|
|
1006
|
+
filter = {}
|
|
1007
|
+
} = {}) {
|
|
1008
|
+
const rawMetrics = await this.getTidalyticsSince(interval, source, {
|
|
1009
|
+
...filter,
|
|
1010
|
+
tags: {
|
|
1011
|
+
"tider:offline": "tider:offline"
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
if (!rawMetrics || !Array.isArray(rawMetrics)) {
|
|
1015
|
+
return [];
|
|
1016
|
+
}
|
|
1017
|
+
const limitedMetrics = rawMetrics.slice(-limit).reverse();
|
|
1018
|
+
return limitedMetrics.map(event => ({
|
|
1019
|
+
tideActionID: "tider-offline",
|
|
1020
|
+
tideActionDate: event.timestamp || Date.now(),
|
|
1021
|
+
tideActionDetails: {
|
|
1022
|
+
currentTideChannel: event.metadata?.currentTideChannel || "file-room",
|
|
1023
|
+
connectedOn: event.metadata?.connectedOn,
|
|
1024
|
+
originUser: event.metadata?.originUser,
|
|
1025
|
+
user: event.metadata?.user,
|
|
1026
|
+
connectionID: event.metadata?.connectionID,
|
|
1027
|
+
pClientID: event.metadata?.pClientID,
|
|
1028
|
+
tideID: event.metadata?.tideID
|
|
1029
|
+
}
|
|
1030
|
+
}));
|
|
1031
|
+
}
|
|
135
1032
|
|
|
136
1033
|
// --- File Messager Tide Sentinel Management ---
|
|
137
1034
|
|
|
@@ -1197,7 +2094,7 @@ class FileMessager {
|
|
|
1197
2094
|
currentTideChannel: clientDetails.currentTideChannel || "file-room",
|
|
1198
2095
|
originUser: clientDetails.originClientID,
|
|
1199
2096
|
user: clientDetails.clientID,
|
|
1200
|
-
connectionID:
|
|
2097
|
+
connectionID: clientData.connectionID,
|
|
1201
2098
|
pClientID: clientDetails.pClientID,
|
|
1202
2099
|
tideID: clientDetails.tideID,
|
|
1203
2100
|
connectedOn: clientDetails.connectedOn
|
|
@@ -1210,7 +2107,7 @@ class FileMessager {
|
|
|
1210
2107
|
currentTideChannel: clientDetails.currentTideChannel || "file-room",
|
|
1211
2108
|
originUser: clientDetails.originClientID,
|
|
1212
2109
|
user: clientDetails.clientID,
|
|
1213
|
-
connectionID:
|
|
2110
|
+
connectionID: clientData.connectionID,
|
|
1214
2111
|
pClientID: clientDetails.pClientID,
|
|
1215
2112
|
tideID: clientDetails.tideID,
|
|
1216
2113
|
connectedOn: clientDetails.connectedOn
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function getNestedData(obj, path) {
|
|
4
|
+
return path.split(".").reduce((acc, part) => acc?.[part], obj);
|
|
5
|
+
}
|
|
6
|
+
;
|
|
7
|
+
function pickData(data, keys) {
|
|
8
|
+
if (!keys) {
|
|
9
|
+
return data;
|
|
10
|
+
}
|
|
11
|
+
return keys.reduce((acc, key) => {
|
|
12
|
+
if (data[key] !== undefined) {
|
|
13
|
+
acc[key] = data[key];
|
|
14
|
+
}
|
|
15
|
+
return acc;
|
|
16
|
+
}, {});
|
|
17
|
+
}
|
|
18
|
+
;
|
|
19
|
+
function aggregateMultiAverageChartData(events, {
|
|
20
|
+
groupBy = ["user"],
|
|
21
|
+
valueKey = "metadata.fileSize",
|
|
22
|
+
timestampKey = "timestamp",
|
|
23
|
+
metadataFields = null,
|
|
24
|
+
previewLimit = 3
|
|
25
|
+
} = {}) {
|
|
26
|
+
const buckets = {};
|
|
27
|
+
for (const event of events) {
|
|
28
|
+
const labelParts = groupBy.map(path => {
|
|
29
|
+
if (path === "time") {
|
|
30
|
+
return event[timestampKey];
|
|
31
|
+
}
|
|
32
|
+
if (path === "user") {
|
|
33
|
+
return event.metadata?.clientID || event.metadata?.senderID || "unknown";
|
|
34
|
+
}
|
|
35
|
+
if (path === "type") {
|
|
36
|
+
return event.type || "unknown";
|
|
37
|
+
}
|
|
38
|
+
return getNestedData(event, path) ?? "unknown";
|
|
39
|
+
});
|
|
40
|
+
const label = labelParts.join(" | ");
|
|
41
|
+
const value = getNestedData(event, valueKey);
|
|
42
|
+
if (typeof value !== "number") {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!buckets[label]) {
|
|
46
|
+
buckets[label] = {
|
|
47
|
+
previewFileNames: [],
|
|
48
|
+
previewMetadata: [],
|
|
49
|
+
timestamps: [],
|
|
50
|
+
values: [],
|
|
51
|
+
total: 0,
|
|
52
|
+
count: 0
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const bucket = buckets[label];
|
|
56
|
+
bucket.total += value;
|
|
57
|
+
bucket.count += 1;
|
|
58
|
+
bucket.values.push(value);
|
|
59
|
+
bucket.timestamps.push(event[timestampKey]);
|
|
60
|
+
const fileName = getNestedData(event, "metadata.fileName");
|
|
61
|
+
if (fileName && bucket.previewFileNames.length < previewLimit) {
|
|
62
|
+
bucket.previewFileNames.push(fileName);
|
|
63
|
+
}
|
|
64
|
+
if (bucket.previewMetadata.length < previewLimit) {
|
|
65
|
+
bucket.previewMetadata.push(pickData(event.metadata || {}, metadataFields));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return Object.entries(buckets).map(([label, bucket]) => ({
|
|
69
|
+
firstTimestamp: Math.min(...bucket.timestamps),
|
|
70
|
+
lastTimestamp: Math.max(...bucket.timestamps),
|
|
71
|
+
previewFileNames: bucket.previewFileNames,
|
|
72
|
+
previewMetadata: bucket.previewMetadata,
|
|
73
|
+
minValue: Math.min(...bucket.values),
|
|
74
|
+
maxValue: Math.max(...bucket.values),
|
|
75
|
+
average: +(total / count).toFixed(2),
|
|
76
|
+
total: bucket.total,
|
|
77
|
+
count: bucket.count,
|
|
78
|
+
label
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
;
|
|
82
|
+
function aggregateChartData(events, {
|
|
83
|
+
groupBy = "type",
|
|
84
|
+
typeKey = "type",
|
|
85
|
+
userKey = "metadata.clientID",
|
|
86
|
+
timestampKey = "timestamp",
|
|
87
|
+
valueKey = "value",
|
|
88
|
+
mode = "count",
|
|
89
|
+
metadataFields = null,
|
|
90
|
+
previewLimit = 3
|
|
91
|
+
} = {}) {
|
|
92
|
+
const buckets = {};
|
|
93
|
+
for (const event of events) {
|
|
94
|
+
let label;
|
|
95
|
+
if (groupBy === "time") {
|
|
96
|
+
label = event[timestampKey];
|
|
97
|
+
} else if (groupBy === "user") {
|
|
98
|
+
label = getNestedData(event, userKey) || "unknown";
|
|
99
|
+
} else {
|
|
100
|
+
label = event[typeKey] || "other";
|
|
101
|
+
}
|
|
102
|
+
const type = event[typeKey] || "other";
|
|
103
|
+
const value = mode === "sum" ? getNestedData(event, valueKey) || 0 : 1;
|
|
104
|
+
if (!buckets[type]) {
|
|
105
|
+
buckets[type] = {
|
|
106
|
+
previewFileNames: [],
|
|
107
|
+
previewMetadata: [],
|
|
108
|
+
timestamps: [],
|
|
109
|
+
values: [],
|
|
110
|
+
count: 0,
|
|
111
|
+
total: 0,
|
|
112
|
+
type
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const bucket = buckets[type];
|
|
116
|
+
bucket.total += value;
|
|
117
|
+
bucket.count += 1;
|
|
118
|
+
bucket.values.push(value);
|
|
119
|
+
bucket.timestamps.push(event[timestampKey]);
|
|
120
|
+
const fileName = getNestedData(event, "metadata.fileName");
|
|
121
|
+
if (fileName && bucket.previewFileNames.length < previewLimit) {
|
|
122
|
+
bucket.previewFileNames.push(fileName);
|
|
123
|
+
}
|
|
124
|
+
if (bucket.previewMetadata.length < previewLimit) {
|
|
125
|
+
bucket.previewMetadata.push(pickData(event.metadata || {}, metadataFields));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return Object.entries(buckets).map(([type, bucket]) => ({
|
|
129
|
+
average: +(bucket.total / bucket.count).toFixed(2),
|
|
130
|
+
firstTimestamp: Math.min(...bucket.timestamps),
|
|
131
|
+
lastTimestamp: Math.max(...bucket.timestamps),
|
|
132
|
+
previewFileNames: bucket.previewFileNames,
|
|
133
|
+
previewMetadata: bucket.previewMetadata,
|
|
134
|
+
minValue: Math.min(...bucket.values),
|
|
135
|
+
maxValue: Math.max(...bucket.values),
|
|
136
|
+
total: bucket.total,
|
|
137
|
+
count: bucket.count,
|
|
138
|
+
label: type,
|
|
139
|
+
type
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
module.exports = {
|
|
143
|
+
aggregateMultiAverageChartData,
|
|
144
|
+
aggregateChartData,
|
|
145
|
+
getNestedData
|
|
146
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trap_stevo/filetide",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.67",
|
|
4
4
|
"description": "Revolutionizing real-time file transfer with seamless, instant communication across any device. Deliver files instantly, regardless of platform, and experience unparalleled speed and control in managing transfers. Elevate your file-sharing capabilities with a tool designed for precision, efficiency, and effortless connectivity.",
|
|
5
5
|
"main": "dist/cjs/FileTide.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@trap_stevo/iotide": "^0.0.43",
|
|
38
38
|
"@trap_stevo/iotide-client": "^0.0.25",
|
|
39
|
-
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.
|
|
39
|
+
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.48",
|
|
40
40
|
"@trap_stevo/metrictide": "^0.0.3",
|
|
41
41
|
"@trap_stevo/timelyst": "^0.0.5",
|
|
42
42
|
"chalk": "^4.1.2",
|