skikrumb-api 2.1.4 → 2.1.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/dist/index.d.ts +25 -0
- package/dist/index.js +150 -12
- package/dist/models.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ declare class SkiKrumbRealtimeClient {
|
|
|
10
10
|
private reconnectAttempts;
|
|
11
11
|
private maxReconnectAttempts;
|
|
12
12
|
private reconnectDelay;
|
|
13
|
+
private maxReconnectDelay;
|
|
13
14
|
constructor(sessionToken: string, userId: string, url: string, supabaseToken?: string);
|
|
14
15
|
connect(): Promise<void>;
|
|
15
16
|
private connectToWebSocket;
|
|
@@ -45,6 +46,30 @@ export declare const skiKrumb: (options?: {
|
|
|
45
46
|
createSharingLink: (shareRequest: ShareLinkRequest) => Promise<ShareLinkResponse>;
|
|
46
47
|
previewSharingLink: (token: string) => Promise<SharePreviewResponse>;
|
|
47
48
|
acceptSharingLink: (token: string, acceptRequest: ShareAcceptRequest) => Promise<ShareAcceptResponse>;
|
|
49
|
+
shareBack: (targetAccountId: string, durationDays?: number, originalFamilyId?: string) => Promise<any>;
|
|
50
|
+
deleteFamilyShare: (familyId: string) => Promise<{
|
|
51
|
+
success: boolean;
|
|
52
|
+
message?: string;
|
|
53
|
+
error?: any;
|
|
54
|
+
}>;
|
|
55
|
+
updateFamilyShare: (familyId: string, profiles: string[]) => Promise<{
|
|
56
|
+
success: boolean;
|
|
57
|
+
data?: any;
|
|
58
|
+
error?: any;
|
|
59
|
+
}>;
|
|
60
|
+
getReplayData: (serialNumber: string, date: string, size?: number) => Promise<any>;
|
|
61
|
+
getDailyStats: (serialNumber: string, date: string) => Promise<any>;
|
|
62
|
+
getAccessibleProfiles: () => Promise<{
|
|
63
|
+
success: boolean;
|
|
64
|
+
accessibleProfiles: any[];
|
|
65
|
+
profilesCount: number;
|
|
66
|
+
accessibleRegistrations: any[];
|
|
67
|
+
}>;
|
|
68
|
+
getLatestDeviceData: (serialNumber: string) => Promise<{
|
|
69
|
+
success: boolean;
|
|
70
|
+
data?: any;
|
|
71
|
+
error?: any;
|
|
72
|
+
}>;
|
|
48
73
|
createRealtimeClient: (userId: string, sessionToken?: string, supabaseToken?: string) => SkiKrumbRealtimeClient;
|
|
49
74
|
};
|
|
50
75
|
export type { Device, Gateways, QueryDevice, RateRequest, Rates, apiKeys, ExternalUserRequest, ExternalUserResponse, ShareLinkRequest, ShareLinkResponse, SharePreviewResponse, ShareAcceptRequest, ShareAcceptResponse, };
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,9 @@ class SkiKrumbRealtimeClient {
|
|
|
5
5
|
this.listeners = {};
|
|
6
6
|
this.isConnecting = false;
|
|
7
7
|
this.reconnectAttempts = 0;
|
|
8
|
-
this.maxReconnectAttempts =
|
|
9
|
-
this.reconnectDelay = 1000;
|
|
8
|
+
this.maxReconnectAttempts = Infinity; // Never stop trying
|
|
9
|
+
this.reconnectDelay = 1000; // 1 second base
|
|
10
|
+
this.maxReconnectDelay = 300000; // 5 minutes max
|
|
10
11
|
this.sessionToken = sessionToken;
|
|
11
12
|
this.supabaseToken = supabaseToken;
|
|
12
13
|
this.userId = userId;
|
|
@@ -130,12 +131,8 @@ class SkiKrumbRealtimeClient {
|
|
|
130
131
|
this.emit('disconnected', {
|
|
131
132
|
reason: event.reason || 'Connection closed',
|
|
132
133
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
this.emit('max_reconnect_attempts_reached');
|
|
138
|
-
}
|
|
134
|
+
// Always try to reconnect with smart backoff
|
|
135
|
+
this.scheduleReconnect();
|
|
139
136
|
}
|
|
140
137
|
};
|
|
141
138
|
}
|
|
@@ -147,12 +144,13 @@ class SkiKrumbRealtimeClient {
|
|
|
147
144
|
}
|
|
148
145
|
scheduleReconnect() {
|
|
149
146
|
this.reconnectAttempts++;
|
|
150
|
-
|
|
147
|
+
// Exponential backoff with 5-minute cap
|
|
148
|
+
const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1), this.maxReconnectDelay);
|
|
149
|
+
console.log(`🔄 Scheduling reconnect attempt #${this.reconnectAttempts} in ${delay / 1000}s`);
|
|
151
150
|
setTimeout(() => {
|
|
152
151
|
this.connect().catch((error) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
152
|
+
// Errors are expected during reconnection, will keep trying
|
|
153
|
+
// No max attempts check - keeps trying indefinitely with smart backoff
|
|
156
154
|
});
|
|
157
155
|
}, delay);
|
|
158
156
|
}
|
|
@@ -395,6 +393,139 @@ export const skiKrumb = (options = {
|
|
|
395
393
|
.json();
|
|
396
394
|
return response;
|
|
397
395
|
};
|
|
396
|
+
const patchSharingLink = async (token, body) => {
|
|
397
|
+
const requestWithAuth = ky.create({
|
|
398
|
+
prefixUrl: options.url,
|
|
399
|
+
headers: {
|
|
400
|
+
'Content-Type': 'application/json',
|
|
401
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
402
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
403
|
+
'x-client': options.requestedWith,
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
const response = await requestWithAuth
|
|
407
|
+
.patch(`sharing/${token}`, {
|
|
408
|
+
json: body,
|
|
409
|
+
})
|
|
410
|
+
.json();
|
|
411
|
+
return response;
|
|
412
|
+
};
|
|
413
|
+
const shareBack = async (targetAccountId, durationDays, originalFamilyId) => {
|
|
414
|
+
const requestWithAuth = ky.create({
|
|
415
|
+
prefixUrl: options.url,
|
|
416
|
+
headers: {
|
|
417
|
+
'Content-Type': 'application/json',
|
|
418
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
419
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
420
|
+
'x-client': options.requestedWith,
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
const response = await requestWithAuth
|
|
424
|
+
.post('sharing/share-back', {
|
|
425
|
+
json: {
|
|
426
|
+
target_account_id: targetAccountId,
|
|
427
|
+
duration_days: durationDays,
|
|
428
|
+
original_family_id: originalFamilyId,
|
|
429
|
+
},
|
|
430
|
+
})
|
|
431
|
+
.json();
|
|
432
|
+
return response;
|
|
433
|
+
};
|
|
434
|
+
const getReplayData = async (serialNumber, date, size = 10000) => {
|
|
435
|
+
const requestWithAuth = ky.create({
|
|
436
|
+
prefixUrl: options.url,
|
|
437
|
+
headers: {
|
|
438
|
+
'Content-Type': 'application/json',
|
|
439
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
440
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
441
|
+
'x-client': options.requestedWith,
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
const response = await requestWithAuth
|
|
445
|
+
.get(`data/replay/${serialNumber}`, {
|
|
446
|
+
searchParams: { date, size },
|
|
447
|
+
})
|
|
448
|
+
.json();
|
|
449
|
+
return response;
|
|
450
|
+
};
|
|
451
|
+
const getDailyStats = async (serialNumber, date) => {
|
|
452
|
+
const requestWithAuth = ky.create({
|
|
453
|
+
prefixUrl: options.url,
|
|
454
|
+
headers: {
|
|
455
|
+
'Content-Type': 'application/json',
|
|
456
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
457
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
458
|
+
'x-client': options.requestedWith,
|
|
459
|
+
},
|
|
460
|
+
});
|
|
461
|
+
const response = await requestWithAuth
|
|
462
|
+
.get(`data/stats/${serialNumber}`, {
|
|
463
|
+
searchParams: { date },
|
|
464
|
+
})
|
|
465
|
+
.json();
|
|
466
|
+
return response;
|
|
467
|
+
};
|
|
468
|
+
const getAccessibleProfiles = async () => {
|
|
469
|
+
const requestWithAuth = ky.create({
|
|
470
|
+
prefixUrl: options.url,
|
|
471
|
+
headers: {
|
|
472
|
+
'Content-Type': 'application/json',
|
|
473
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
474
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
475
|
+
'x-client': options.requestedWith,
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
const response = await requestWithAuth
|
|
479
|
+
.get('auth/profiles')
|
|
480
|
+
.json();
|
|
481
|
+
return response;
|
|
482
|
+
};
|
|
483
|
+
const getLatestDeviceData = async (serialNumber) => {
|
|
484
|
+
const requestWithAuth = ky.create({
|
|
485
|
+
prefixUrl: options.url,
|
|
486
|
+
headers: {
|
|
487
|
+
'Content-Type': 'application/json',
|
|
488
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
489
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
490
|
+
'x-client': options.requestedWith,
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
const response = await requestWithAuth
|
|
494
|
+
.get(`data/latest/${serialNumber}`)
|
|
495
|
+
.json();
|
|
496
|
+
return response;
|
|
497
|
+
};
|
|
498
|
+
const deleteFamilyShare = async (familyId) => {
|
|
499
|
+
const requestWithAuth = ky.create({
|
|
500
|
+
prefixUrl: options.url,
|
|
501
|
+
headers: {
|
|
502
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
503
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
504
|
+
'x-client': options.requestedWith,
|
|
505
|
+
},
|
|
506
|
+
});
|
|
507
|
+
const response = await requestWithAuth
|
|
508
|
+
.delete(`sharing/family/${familyId}`)
|
|
509
|
+
.json();
|
|
510
|
+
return response;
|
|
511
|
+
};
|
|
512
|
+
const updateFamilyShare = async (familyId, profiles) => {
|
|
513
|
+
const requestWithAuth = ky.create({
|
|
514
|
+
prefixUrl: options.url,
|
|
515
|
+
headers: {
|
|
516
|
+
'Content-Type': 'application/json',
|
|
517
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
518
|
+
'supabase-auth-token': options.supabaseToken || '',
|
|
519
|
+
'x-client': options.requestedWith,
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
const response = await requestWithAuth
|
|
523
|
+
.patch(`sharing/family/${familyId}`, {
|
|
524
|
+
json: { profiles },
|
|
525
|
+
})
|
|
526
|
+
.json();
|
|
527
|
+
return response;
|
|
528
|
+
};
|
|
398
529
|
return {
|
|
399
530
|
createDevice,
|
|
400
531
|
readDevices,
|
|
@@ -410,6 +541,13 @@ export const skiKrumb = (options = {
|
|
|
410
541
|
createSharingLink,
|
|
411
542
|
previewSharingLink,
|
|
412
543
|
acceptSharingLink,
|
|
544
|
+
shareBack,
|
|
545
|
+
deleteFamilyShare,
|
|
546
|
+
updateFamilyShare,
|
|
547
|
+
getReplayData,
|
|
548
|
+
getDailyStats,
|
|
549
|
+
getAccessibleProfiles,
|
|
550
|
+
getLatestDeviceData,
|
|
413
551
|
createRealtimeClient: (userId, sessionToken, supabaseToken) => {
|
|
414
552
|
if (!sessionToken && !options.apiKey) {
|
|
415
553
|
throw new Error('Session token or API key required for realtime client');
|
package/dist/models.d.ts
CHANGED