@cshah18/sdk 4.13.0 → 4.15.0
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/cobuy-sdk.esm.js +1657 -75
- package/dist/cobuy-sdk.esm.js.map +1 -1
- package/dist/cobuy-sdk.umd.js +1657 -75
- package/dist/cobuy-sdk.umd.js.map +1 -1
- package/dist/types/core/analytics.d.ts +55 -0
- package/dist/types/core/api-client.d.ts +33 -2
- package/dist/types/core/endpoints.d.ts +3 -0
- package/dist/types/core/socket.d.ts +3 -2
- package/dist/types/core/types.d.ts +118 -3
- package/dist/types/ui/group-list/group-list-modal.d.ts +4 -0
- package/dist/types/ui/lobby/lobby-modal.d.ts +49 -2
- package/dist/types/ui/widget/widget-root.d.ts +12 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiClient } from "./api-client";
|
|
2
|
+
import { GeoData, DeviceData } from "./types";
|
|
2
3
|
/**
|
|
3
4
|
* Analytics event interface matching backend expectations
|
|
4
5
|
*/
|
|
@@ -11,6 +12,12 @@ export interface AnalyticsEvent {
|
|
|
11
12
|
pageUrl?: string;
|
|
12
13
|
userAgent?: string;
|
|
13
14
|
sdkVersion?: string;
|
|
15
|
+
groupId?: string;
|
|
16
|
+
channel?: string;
|
|
17
|
+
totalMembers?: number;
|
|
18
|
+
errorCode?: string;
|
|
19
|
+
errorMessage?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
14
21
|
};
|
|
15
22
|
}
|
|
16
23
|
/**
|
|
@@ -35,10 +42,58 @@ export declare class AnalyticsClient {
|
|
|
35
42
|
* @internal
|
|
36
43
|
*/
|
|
37
44
|
private sendEvent;
|
|
45
|
+
/**
|
|
46
|
+
* Track session init event fired when the SDK initializes
|
|
47
|
+
*/
|
|
48
|
+
trackSessionInit(geo?: GeoData, device?: DeviceData): Promise<void>;
|
|
38
49
|
/**
|
|
39
50
|
* Track page view event
|
|
40
51
|
*/
|
|
41
52
|
trackPageView(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Track creative view event (widget rendered and visible)
|
|
55
|
+
*/
|
|
56
|
+
trackCreativeView(productId: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Track popup/lobby modal open event
|
|
59
|
+
*/
|
|
60
|
+
trackPopupOpen(productId: string, groupId?: string): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Track join attempt event (before API call)
|
|
63
|
+
*/
|
|
64
|
+
trackJoinAttempt(productId: string, groupId: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Track successful group join event
|
|
67
|
+
*/
|
|
68
|
+
trackJoinSuccess(productId: string, groupId: string): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Track join failure event
|
|
71
|
+
*/
|
|
72
|
+
trackJoinFailure(productId: string, groupId?: string, errorCode?: string, message?: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Track already joined event (user attempts to join a group they're already in)
|
|
75
|
+
*/
|
|
76
|
+
trackAlreadyJoined(productId: string, groupId?: string): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Track group full view event (user sees a fulfilled/full group)
|
|
79
|
+
*/
|
|
80
|
+
trackGroupFullView(productId: string, groupId?: string, totalMembers?: number): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Track share click event
|
|
83
|
+
*/
|
|
84
|
+
trackShareClick(productId: string, groupId?: string, channel?: string): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Track group creation attempt event
|
|
87
|
+
*/
|
|
88
|
+
trackGroupCreateAttempt(productId: string): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Track successful group creation event
|
|
91
|
+
*/
|
|
92
|
+
trackGroupCreateSuccess(productId: string, groupId: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Track group creation failure event
|
|
95
|
+
*/
|
|
96
|
+
trackGroupCreateFailure(productId: string, errorCode?: string, message?: string): Promise<void>;
|
|
42
97
|
/**
|
|
43
98
|
* Track custom event (extensible for future use)
|
|
44
99
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiRequestOptions, ApiResponse, ApiClientConfig, ProductRewardData, ProductPrimaryGroupData, GroupJoinResponseData, GroupInviteResponseData, InviteResolveResponseData, AuthStrategy, ShareChannel, Contact, CheckoutValidationData, CheckoutConfirmData } from "./types";
|
|
1
|
+
import { ApiRequestOptions, ApiResponse, ApiClientConfig, ProductRewardData, ProductContextData, ProductPrimaryGroupData, GroupJoinResponseData, GroupInviteResponseData, InviteResolveResponseData, AuthStrategy, ShareChannel, Contact, LeaveGroupResponseData, RecoverOrJoinGroupResponseData, CheckoutValidationData, CheckoutConfirmData } from "./types";
|
|
2
2
|
/**
|
|
3
3
|
* HTTP client for communicating with CoBuy API
|
|
4
4
|
*
|
|
@@ -17,8 +17,11 @@ export declare class ApiClient {
|
|
|
17
17
|
private botdScore;
|
|
18
18
|
private traceId;
|
|
19
19
|
private readonly rewardCache;
|
|
20
|
+
private readonly productContextCache;
|
|
20
21
|
private readonly REWARD_CACHE_TTL;
|
|
21
|
-
private readonly
|
|
22
|
+
private readonly PRODUCT_CONTEXT_CACHE_TTL;
|
|
23
|
+
private readonly pendingRewardRequests;
|
|
24
|
+
private readonly pendingContextRequests;
|
|
22
25
|
constructor(config: ApiClientConfig);
|
|
23
26
|
/**
|
|
24
27
|
* Update the BotD (Bot Detection) score for fraud detection
|
|
@@ -168,6 +171,18 @@ export declare class ApiClient {
|
|
|
168
171
|
* }
|
|
169
172
|
*/
|
|
170
173
|
getTraceId(): string | null;
|
|
174
|
+
private getCachedProductContext;
|
|
175
|
+
private normalizePrimaryGroup;
|
|
176
|
+
private buildRewardDataFromContext;
|
|
177
|
+
private setProductContextCache;
|
|
178
|
+
/**
|
|
179
|
+
* Get product context information
|
|
180
|
+
*
|
|
181
|
+
* Uses the consolidated bootstrap endpoint so the SDK can resolve campaign,
|
|
182
|
+
* reward, primary group, and active groups in a single request.
|
|
183
|
+
*/
|
|
184
|
+
getProductContext(productId: string): Promise<ApiResponse<ProductContextData>>;
|
|
185
|
+
private fetchProductContext;
|
|
171
186
|
/**
|
|
172
187
|
* Get product reward information
|
|
173
188
|
*
|
|
@@ -431,6 +446,22 @@ export declare class ApiClient {
|
|
|
431
446
|
* ```
|
|
432
447
|
*/
|
|
433
448
|
setContact(contact: Contact): Promise<ApiResponse<void>>;
|
|
449
|
+
/**
|
|
450
|
+
* Leave an active group for the current SDK session.
|
|
451
|
+
*/
|
|
452
|
+
leaveGroup(groupId: string, params?: {
|
|
453
|
+
leave_source?: "close_icon" | "browser_close" | "unknown";
|
|
454
|
+
leave_reason?: "voluntary_with_contact" | "voluntary_no_contact" | "unknown";
|
|
455
|
+
}): Promise<ApiResponse<LeaveGroupResponseData>>;
|
|
456
|
+
recoverOrJoinGroup(productId: string, contact?: Contact): Promise<ApiResponse<RecoverOrJoinGroupResponseData>>;
|
|
457
|
+
/**
|
|
458
|
+
* Best-effort leave signal for unload/pagehide scenarios.
|
|
459
|
+
* Uses fetch keepalive so it can run while page is closing.
|
|
460
|
+
*/
|
|
461
|
+
leaveGroupBestEffort(groupId: string, params?: {
|
|
462
|
+
leave_source?: "close_icon" | "browser_close" | "unknown";
|
|
463
|
+
leave_reason?: "voluntary_with_contact" | "voluntary_no_contact" | "unknown";
|
|
464
|
+
}): void;
|
|
434
465
|
/**
|
|
435
466
|
* Prepare checkout for a group
|
|
436
467
|
*
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
* API endpoint paths for active CoBuy backend endpoints
|
|
3
3
|
*/
|
|
4
4
|
export declare const API_ENDPOINTS: {
|
|
5
|
+
readonly PRODUCT_CONTEXT: "/v1/sdk/products/:productId/context";
|
|
5
6
|
readonly PRODUCT_REWARD: "/v1/sdk/products/:productId/reward";
|
|
6
7
|
readonly PRODUCT_PRIMARY_GROUP: "/v1/sdk/products/:productId/group/primary";
|
|
8
|
+
readonly PRODUCT_RECOVER_OR_JOIN_GROUP: "/v1/sdk/products/:productId/group/recover-or-join";
|
|
7
9
|
readonly GROUP_JOIN: "/v1/sdk/groups/:groupId/join";
|
|
10
|
+
readonly GROUP_LEAVE: "/v1/sdk/groups/:groupId/leave";
|
|
8
11
|
readonly GROUP_CREATE_AND_JOIN: "/v1/sdk/groups/new/join";
|
|
9
12
|
readonly PRODUCT_ACTIVE_GROUPS: "/v1/sdk/products/:productId/groups/active";
|
|
10
13
|
readonly GROUP_INVITE: "/v1/sdk/groups/:groupId/invite";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { InternalConfig, GroupFulfilledEvent, GroupCreatedEvent, GroupMemberJoinedEvent } from "./types";
|
|
2
|
-
export type SocketEventName = "group:member:joined" | "group:created" | "group:fulfilled";
|
|
1
|
+
import { InternalConfig, GroupFulfilledEvent, GroupCreatedEvent, GroupMemberJoinedEvent, GroupMemberLeftEvent } from "./types";
|
|
2
|
+
export type SocketEventName = "group:member:joined" | "group:member:left" | "group:created" | "group:fulfilled";
|
|
3
3
|
export interface SocketHandlers {
|
|
4
4
|
onGroupMemberJoined?: (payload: GroupMemberJoinedEvent) => void;
|
|
5
|
+
onGroupMemberLeft?: (payload: GroupMemberLeftEvent) => void;
|
|
5
6
|
onGroupCreated?: (payload: GroupCreatedEvent) => void;
|
|
6
7
|
onGroupFulfilled?: (payload: GroupFulfilledEvent) => void;
|
|
7
8
|
}
|
|
@@ -126,6 +126,29 @@ export interface PerformanceConfig {
|
|
|
126
126
|
/**
|
|
127
127
|
* Options for initializing the CoBuy SDK
|
|
128
128
|
*/
|
|
129
|
+
/**
|
|
130
|
+
* Geographic data provided by the merchant at SDK init time
|
|
131
|
+
*/
|
|
132
|
+
export interface GeoData {
|
|
133
|
+
latitude?: number;
|
|
134
|
+
longitude?: number;
|
|
135
|
+
city?: string;
|
|
136
|
+
region?: string;
|
|
137
|
+
country?: string;
|
|
138
|
+
[key: string]: unknown;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Device data provided by the merchant at SDK init time
|
|
142
|
+
*/
|
|
143
|
+
export interface DeviceData {
|
|
144
|
+
/** "mobile" | "tablet" | "desktop" */
|
|
145
|
+
type?: string;
|
|
146
|
+
os?: string;
|
|
147
|
+
browser?: string;
|
|
148
|
+
screenWidth?: number;
|
|
149
|
+
screenHeight?: number;
|
|
150
|
+
[key: string]: unknown;
|
|
151
|
+
}
|
|
129
152
|
export interface CoBuyInitOptions {
|
|
130
153
|
/**
|
|
131
154
|
* Authentication mode (default: "public")
|
|
@@ -207,6 +230,16 @@ export interface CoBuyInitOptions {
|
|
|
207
230
|
* ```
|
|
208
231
|
*/
|
|
209
232
|
performance?: PerformanceConfig;
|
|
233
|
+
/**
|
|
234
|
+
* Optional geographic data for analytics (merchant-provided)
|
|
235
|
+
* Use when the merchant's backend has resolved geo info from IP or user input
|
|
236
|
+
*/
|
|
237
|
+
geo?: GeoData;
|
|
238
|
+
/**
|
|
239
|
+
* Optional device data for analytics (merchant-provided)
|
|
240
|
+
* Collect from browser APIs (navigator, screen) and pass here
|
|
241
|
+
*/
|
|
242
|
+
device?: DeviceData;
|
|
210
243
|
}
|
|
211
244
|
/**
|
|
212
245
|
* Callback data structure for checkout events
|
|
@@ -272,6 +305,7 @@ export interface FulfilledGroup {
|
|
|
272
305
|
campaign_id: string;
|
|
273
306
|
campaign_name: string;
|
|
274
307
|
campaign_status: string;
|
|
308
|
+
campaign_redemption_method?: "online" | "offline" | "both";
|
|
275
309
|
participants_count: number;
|
|
276
310
|
max_participants: number;
|
|
277
311
|
status: string;
|
|
@@ -453,6 +487,10 @@ export interface ModalOptions {
|
|
|
453
487
|
* Offline redemption data for fulfilled groups
|
|
454
488
|
*/
|
|
455
489
|
offlineRedemption?: OfflineRedemption;
|
|
490
|
+
/**
|
|
491
|
+
* Campaign redemption method - controls which checkout options are shown
|
|
492
|
+
*/
|
|
493
|
+
redemptionMethod?: "online" | "offline" | "both";
|
|
456
494
|
/**
|
|
457
495
|
* Optional callback when modal opens
|
|
458
496
|
*/
|
|
@@ -503,7 +541,7 @@ export interface Reward {
|
|
|
503
541
|
id: string;
|
|
504
542
|
name: string;
|
|
505
543
|
type: RewardType;
|
|
506
|
-
value: string;
|
|
544
|
+
value: string | number;
|
|
507
545
|
description: string | null;
|
|
508
546
|
remaining_quantity: number;
|
|
509
547
|
total_quantity: number;
|
|
@@ -523,14 +561,56 @@ export interface RewardEligibility {
|
|
|
523
561
|
*/
|
|
524
562
|
export interface ProductRewardData {
|
|
525
563
|
productId: string;
|
|
526
|
-
reward: Reward;
|
|
564
|
+
reward: Reward | null;
|
|
565
|
+
campaign_mode?: "group" | "no_group";
|
|
566
|
+
campaign_creative_id?: string | null;
|
|
567
|
+
eligibility: RewardEligibility;
|
|
568
|
+
}
|
|
569
|
+
export interface ProductContextProductData {
|
|
570
|
+
id: string;
|
|
571
|
+
external_product_id: string | null;
|
|
572
|
+
name: string;
|
|
573
|
+
description: string | null;
|
|
574
|
+
sku: string | null;
|
|
575
|
+
price: number;
|
|
576
|
+
images: unknown[];
|
|
577
|
+
}
|
|
578
|
+
export interface ProductContextCampaignData {
|
|
579
|
+
id: string;
|
|
580
|
+
name: string;
|
|
581
|
+
description: string | null;
|
|
582
|
+
status: string | null;
|
|
583
|
+
campaign_mode?: "group" | "no_group" | null;
|
|
584
|
+
min_group_size?: number | null;
|
|
585
|
+
total_groups_count?: number | null;
|
|
586
|
+
reward_type?: string | null;
|
|
587
|
+
reward_value?: string | number | null;
|
|
588
|
+
start_date?: string | null;
|
|
589
|
+
end_date?: string | null;
|
|
590
|
+
redemption_method?: "online" | "offline" | "both" | null;
|
|
591
|
+
}
|
|
592
|
+
export interface ProductContextData {
|
|
593
|
+
product_id: string;
|
|
594
|
+
product: ProductContextProductData | null;
|
|
595
|
+
campaign: ProductContextCampaignData | null;
|
|
596
|
+
reward: Reward | null;
|
|
597
|
+
primary_group: ProductPrimaryGroupData | null;
|
|
598
|
+
active_groups: Array<ProductPrimaryGroupData & {
|
|
599
|
+
is_member?: boolean;
|
|
600
|
+
}>;
|
|
527
601
|
eligibility: RewardEligibility;
|
|
602
|
+
sdk: {
|
|
603
|
+
ready: boolean;
|
|
604
|
+
campaign_status: string | null;
|
|
605
|
+
has_primary_group: boolean;
|
|
606
|
+
active_group_count: number;
|
|
607
|
+
};
|
|
528
608
|
}
|
|
529
609
|
/**
|
|
530
610
|
* Primary group information for a product (SCRUM-284)
|
|
531
611
|
*/
|
|
532
612
|
export interface ProductPrimaryGroupData {
|
|
533
|
-
group
|
|
613
|
+
group?: ProductPrimaryGroupData | null;
|
|
534
614
|
id: string;
|
|
535
615
|
group_name: string;
|
|
536
616
|
description: string | null;
|
|
@@ -539,6 +619,7 @@ export interface ProductPrimaryGroupData {
|
|
|
539
619
|
campaign_id: string | null;
|
|
540
620
|
campaign_name: string | null;
|
|
541
621
|
campaign_status: string | null;
|
|
622
|
+
campaign_redemption_method?: "online" | "offline" | "both";
|
|
542
623
|
participants_count: number;
|
|
543
624
|
max_participants: number;
|
|
544
625
|
status: string;
|
|
@@ -558,6 +639,7 @@ export interface GroupJoinResponseData {
|
|
|
558
639
|
status: string;
|
|
559
640
|
expiry_at: string;
|
|
560
641
|
timeLeftSeconds: number;
|
|
642
|
+
campaign_redemption_method?: "online" | "offline" | "both";
|
|
561
643
|
};
|
|
562
644
|
membership: {
|
|
563
645
|
id: string;
|
|
@@ -568,6 +650,37 @@ export interface GroupJoinResponseData {
|
|
|
568
650
|
product_id: string;
|
|
569
651
|
offline_redemption?: OfflineRedemption;
|
|
570
652
|
}
|
|
653
|
+
export interface LeaveGroupResponseData {
|
|
654
|
+
left: boolean;
|
|
655
|
+
session_id: string;
|
|
656
|
+
group: {
|
|
657
|
+
id: string;
|
|
658
|
+
group_name: string;
|
|
659
|
+
description: string | null;
|
|
660
|
+
campaign_creative_id: string | null;
|
|
661
|
+
campaign_creative_name: string | null;
|
|
662
|
+
campaign_id: string | null;
|
|
663
|
+
campaign_name: string | null;
|
|
664
|
+
campaign_status: string | null;
|
|
665
|
+
campaign_redemption_method?: "online" | "offline" | "both";
|
|
666
|
+
participants_count: number;
|
|
667
|
+
max_participants: number;
|
|
668
|
+
status: string;
|
|
669
|
+
expiry_at: string;
|
|
670
|
+
timeLeftSeconds: number;
|
|
671
|
+
};
|
|
672
|
+
product_id?: string;
|
|
673
|
+
}
|
|
674
|
+
export interface RecoverOrJoinGroupResponseData extends GroupJoinResponseData {
|
|
675
|
+
recovery: {
|
|
676
|
+
recovered: boolean;
|
|
677
|
+
matched_by: "session" | "contact" | "none";
|
|
678
|
+
outcome: "existing_active_membership" | "rejoined_previous_group" | "joined_next_available_group" | "created_new_group";
|
|
679
|
+
previous_group_id?: string;
|
|
680
|
+
joined_group_id: string;
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
export type GroupMemberLeftEvent = LeaveGroupResponseData;
|
|
571
684
|
export type ShareChannel = "whatsapp" | "facebook" | "email" | "sms" | "copy_link" | "tiktok" | "x" | "other";
|
|
572
685
|
export interface GroupInviteResponseData {
|
|
573
686
|
invite_url?: string;
|
|
@@ -768,6 +881,8 @@ export interface InternalConfig {
|
|
|
768
881
|
maxRetries: number;
|
|
769
882
|
animationSpeed: "fast" | "normal" | "slow";
|
|
770
883
|
};
|
|
884
|
+
geo?: GeoData;
|
|
885
|
+
device?: DeviceData;
|
|
771
886
|
}
|
|
772
887
|
/**
|
|
773
888
|
* Group status enumeration
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiClient } from "../../core/api-client";
|
|
2
|
+
import { AnalyticsClient } from "../../core/analytics";
|
|
2
3
|
import { ProductPrimaryGroupData, GroupJoinResponseData } from "../../core/types";
|
|
3
4
|
export interface GroupListItem {
|
|
4
5
|
groupId: string;
|
|
@@ -27,12 +28,15 @@ export declare class GroupListModal {
|
|
|
27
28
|
private currentJoinedGroupId;
|
|
28
29
|
private currentProductId;
|
|
29
30
|
private currentSessionId;
|
|
31
|
+
private analyticsClient;
|
|
30
32
|
private onGroupJoined;
|
|
31
33
|
private onViewProgress;
|
|
32
34
|
private socketListenerRegistered;
|
|
33
35
|
private readonly escapeHandler;
|
|
34
36
|
private readonly handleGroupMemberJoinedEvent;
|
|
35
37
|
constructor(groups?: GroupListItem[], liveCount?: number, debug?: boolean, apiClient?: ApiClient | null);
|
|
38
|
+
/** Set the analytics client for event tracking */
|
|
39
|
+
setAnalyticsClient(client: AnalyticsClient): void;
|
|
36
40
|
/** Set callback for when a group is joined successfully */
|
|
37
41
|
setOnGroupJoined(callback: (joinData: GroupJoinResponseData) => void): void;
|
|
38
42
|
/** Set callback for when viewing progress on an already joined group */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ApiClient } from "../../core/api-client";
|
|
2
|
+
import { AnalyticsClient } from "../../core/analytics";
|
|
2
3
|
import { OfflineRedemption } from "../../core/types";
|
|
3
4
|
import { SocketManager } from "../../core/socket";
|
|
4
5
|
import "./styles/styles.css";
|
|
@@ -17,6 +18,7 @@ export interface LobbyModalData {
|
|
|
17
18
|
activities?: ActivityItem[];
|
|
18
19
|
isLocked?: boolean;
|
|
19
20
|
offlineRedemption?: OfflineRedemption;
|
|
21
|
+
redemptionMethod?: "online" | "offline" | "both";
|
|
20
22
|
}
|
|
21
23
|
export interface ActivityItem {
|
|
22
24
|
emoji: string;
|
|
@@ -31,6 +33,9 @@ export interface LobbyModalCallbacks {
|
|
|
31
33
|
onCopyLink?: (link: string) => void;
|
|
32
34
|
onShare?: () => void;
|
|
33
35
|
}
|
|
36
|
+
interface CloseOptions {
|
|
37
|
+
skipLeaveFlow?: boolean;
|
|
38
|
+
}
|
|
34
39
|
/**
|
|
35
40
|
* LobbyModal - Renders and manages the group buying lobby modal
|
|
36
41
|
*/
|
|
@@ -38,6 +43,7 @@ export declare class LobbyModal {
|
|
|
38
43
|
private readonly logger;
|
|
39
44
|
private readonly socketManager;
|
|
40
45
|
private readonly apiClient;
|
|
46
|
+
private readonly analyticsClient;
|
|
41
47
|
private modalElement;
|
|
42
48
|
private data;
|
|
43
49
|
private readonly callbacks;
|
|
@@ -48,7 +54,36 @@ export declare class LobbyModal {
|
|
|
48
54
|
private currentGroupId;
|
|
49
55
|
private shareOverlay;
|
|
50
56
|
private keyboardHandler;
|
|
51
|
-
|
|
57
|
+
private leaveFlowInProgress;
|
|
58
|
+
private leaveSignalSent;
|
|
59
|
+
private hasContactProtection;
|
|
60
|
+
private initialContactPromptTimer;
|
|
61
|
+
private contactPromptOverlay;
|
|
62
|
+
private leaveLoaderOverlay;
|
|
63
|
+
private beforeUnloadHandler;
|
|
64
|
+
private pageHideHandler;
|
|
65
|
+
private visibilityChangeHandler;
|
|
66
|
+
private readonly CONTACT_PROTECTION_PREFIX;
|
|
67
|
+
private readonly LAST_LEFT_GROUP_PREFIX;
|
|
68
|
+
constructor(data: LobbyModalData, callbacks: LobbyModalCallbacks, apiClient: ApiClient | null, socketManager?: SocketManager | null, analyticsClient?: AnalyticsClient | null, debug?: boolean);
|
|
69
|
+
private getSessionId;
|
|
70
|
+
private getContactProtectionStorageKey;
|
|
71
|
+
private getLastLeftGroupStorageKey;
|
|
72
|
+
private readContactProtectionState;
|
|
73
|
+
private persistContactProtectionState;
|
|
74
|
+
private persistLastLeftGroup;
|
|
75
|
+
private clearInitialContactPromptTimer;
|
|
76
|
+
private clearContactPromptOverlay;
|
|
77
|
+
private showBlockingLoader;
|
|
78
|
+
private hideBlockingLoader;
|
|
79
|
+
private updateContactProtectionUI;
|
|
80
|
+
private showToastMessage;
|
|
81
|
+
private trackAnalyticsEvent;
|
|
82
|
+
private saveContactValue;
|
|
83
|
+
private openContactProtectionPrompt;
|
|
84
|
+
private openUnprotectedLeaveWarning;
|
|
85
|
+
private scheduleInitialContactPrompt;
|
|
86
|
+
private leaveGroupExplicitly;
|
|
52
87
|
/**
|
|
53
88
|
* Derive lock state from data so UI reflects completion
|
|
54
89
|
*/
|
|
@@ -103,6 +138,10 @@ export declare class LobbyModal {
|
|
|
103
138
|
* Create link section (just the link box and share button, no wrapper)
|
|
104
139
|
*/
|
|
105
140
|
private createLinkSection;
|
|
141
|
+
/**
|
|
142
|
+
* Create a standalone "Checkout Online" button for the link/share section
|
|
143
|
+
*/
|
|
144
|
+
private createOnlineCheckoutButton;
|
|
106
145
|
/**
|
|
107
146
|
* Create offline redemption section
|
|
108
147
|
*/
|
|
@@ -251,10 +290,16 @@ export declare class LobbyModal {
|
|
|
251
290
|
* Clean up keyboard event listeners
|
|
252
291
|
*/
|
|
253
292
|
private removeKeyboardAccessibility;
|
|
293
|
+
private registerLifecycleLeaveHandlers;
|
|
294
|
+
private unregisterLifecycleLeaveHandlers;
|
|
295
|
+
private triggerBestEffortLeave;
|
|
296
|
+
private shouldRunLeaveFlow;
|
|
297
|
+
private inferContactType;
|
|
298
|
+
private runLeaveFlowAndClose;
|
|
254
299
|
/**
|
|
255
300
|
* Close the modal
|
|
256
301
|
*/
|
|
257
|
-
close(): void;
|
|
302
|
+
close(options?: CloseOptions): void;
|
|
258
303
|
/**
|
|
259
304
|
* Check if modal is open
|
|
260
305
|
*/
|
|
@@ -291,6 +336,7 @@ export declare class LobbyModal {
|
|
|
291
336
|
* Subscribe to socket events
|
|
292
337
|
*/
|
|
293
338
|
private subscribeToSocketEvents;
|
|
339
|
+
private unsubscribeFromSocketEvents;
|
|
294
340
|
/**
|
|
295
341
|
* Handle socket group update events
|
|
296
342
|
*/
|
|
@@ -308,3 +354,4 @@ export declare class LobbyModal {
|
|
|
308
354
|
*/
|
|
309
355
|
private updateTeamCard;
|
|
310
356
|
}
|
|
357
|
+
export {};
|
|
@@ -30,6 +30,7 @@ export declare class WidgetRoot {
|
|
|
30
30
|
private groupExpiryRefreshTriggered;
|
|
31
31
|
private offlineRedemption;
|
|
32
32
|
private offlineRedemptionModal;
|
|
33
|
+
private campaignRedemptionMethod;
|
|
33
34
|
private isRendering;
|
|
34
35
|
private renderPromise;
|
|
35
36
|
private liveRegionAnnouncer;
|
|
@@ -38,11 +39,16 @@ export declare class WidgetRoot {
|
|
|
38
39
|
private renderDebounceTimer;
|
|
39
40
|
private pendingRenderOptions;
|
|
40
41
|
private readonly RENDER_DEBOUNCE_MS;
|
|
42
|
+
private readonly LAST_LEFT_GROUP_PREFIX;
|
|
41
43
|
/**
|
|
42
44
|
* Get max retries from config (configurable via performance options)
|
|
43
45
|
*/
|
|
44
46
|
private get MAX_RETRIES();
|
|
45
47
|
constructor(config: InternalConfig, apiClient: ApiClient | null, analyticsClient?: AnalyticsClient | null);
|
|
48
|
+
private getRecoveryStorageKey;
|
|
49
|
+
private getStoredRecoveryGroupId;
|
|
50
|
+
private clearStoredRecoveryGroupId;
|
|
51
|
+
private showRecoveryToast;
|
|
46
52
|
/** Subscribe once to backend socket events routed through the host page */
|
|
47
53
|
private subscribeToSocketEvents;
|
|
48
54
|
/** Handle backend fulfillment notifications */
|
|
@@ -185,4 +191,10 @@ export declare class WidgetRoot {
|
|
|
185
191
|
* Expose current product id for optional filtering by host
|
|
186
192
|
*/
|
|
187
193
|
getProductId(): string | null;
|
|
194
|
+
/**
|
|
195
|
+
* Returns the group ID that the current user has joined via this widget, or null if the user
|
|
196
|
+
* is only an observer (has not actively joined a group this session).
|
|
197
|
+
* Used by the CoBuy host class to check membership before preparing checkout.
|
|
198
|
+
*/
|
|
199
|
+
getJoinedGroupId(): string | null;
|
|
188
200
|
}
|