skikrumb-api 2.1.3 → 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 +26 -0
- package/dist/index.js +160 -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;
|
|
@@ -33,6 +34,7 @@ export declare const skiKrumb: (options?: {
|
|
|
33
34
|
readApiKeys: () => Promise<apiKeys>;
|
|
34
35
|
readDeviceDailyDistance: (deviceSerialNumber: string) => Promise<unknown>;
|
|
35
36
|
readDeviceData: (deviceSerialNumber: string, limit?: number) => Promise<unknown>;
|
|
37
|
+
readDataForDevices: (query: QueryDevice) => Promise<Device[]>;
|
|
36
38
|
readGateways: () => Promise<Gateways>;
|
|
37
39
|
readShippingRates: (rateRequest: RateRequest) => Promise<Rates>;
|
|
38
40
|
sendMobileLocation: (payload: {
|
|
@@ -44,6 +46,30 @@ export declare const skiKrumb: (options?: {
|
|
|
44
46
|
createSharingLink: (shareRequest: ShareLinkRequest) => Promise<ShareLinkResponse>;
|
|
45
47
|
previewSharingLink: (token: string) => Promise<SharePreviewResponse>;
|
|
46
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
|
+
}>;
|
|
47
73
|
createRealtimeClient: (userId: string, sessionToken?: string, supabaseToken?: string) => SkiKrumbRealtimeClient;
|
|
48
74
|
};
|
|
49
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
|
}
|
|
@@ -279,6 +277,15 @@ export const skiKrumb = (options = {
|
|
|
279
277
|
throw error;
|
|
280
278
|
}
|
|
281
279
|
};
|
|
280
|
+
const readDataForDevices = async (query) => {
|
|
281
|
+
if (!query.serial_numbers)
|
|
282
|
+
throw new Error('Serial number is required');
|
|
283
|
+
return request
|
|
284
|
+
.get('devices/data', {
|
|
285
|
+
searchParams: new URLSearchParams({ ...query }),
|
|
286
|
+
})
|
|
287
|
+
.json();
|
|
288
|
+
};
|
|
282
289
|
const readGateways = async () => {
|
|
283
290
|
try {
|
|
284
291
|
const response = await request.get('gateways').json();
|
|
@@ -386,12 +393,146 @@ export const skiKrumb = (options = {
|
|
|
386
393
|
.json();
|
|
387
394
|
return response;
|
|
388
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
|
+
};
|
|
389
529
|
return {
|
|
390
530
|
createDevice,
|
|
391
531
|
readDevices,
|
|
392
532
|
readApiKeys,
|
|
393
533
|
readDeviceDailyDistance,
|
|
394
534
|
readDeviceData,
|
|
535
|
+
readDataForDevices,
|
|
395
536
|
readGateways,
|
|
396
537
|
readShippingRates,
|
|
397
538
|
sendMobileLocation,
|
|
@@ -400,6 +541,13 @@ export const skiKrumb = (options = {
|
|
|
400
541
|
createSharingLink,
|
|
401
542
|
previewSharingLink,
|
|
402
543
|
acceptSharingLink,
|
|
544
|
+
shareBack,
|
|
545
|
+
deleteFamilyShare,
|
|
546
|
+
updateFamilyShare,
|
|
547
|
+
getReplayData,
|
|
548
|
+
getDailyStats,
|
|
549
|
+
getAccessibleProfiles,
|
|
550
|
+
getLatestDeviceData,
|
|
403
551
|
createRealtimeClient: (userId, sessionToken, supabaseToken) => {
|
|
404
552
|
if (!sessionToken && !options.apiKey) {
|
|
405
553
|
throw new Error('Session token or API key required for realtime client');
|
package/dist/models.d.ts
CHANGED