@cshah18/sdk 3.0.4 → 4.0.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 +127 -29
- package/dist/cobuy-sdk.esm.js.map +1 -1
- package/dist/cobuy-sdk.umd.js +127 -29
- package/dist/cobuy-sdk.umd.js.map +1 -1
- package/dist/types/core/socket-client.d.ts +126 -0
- package/dist/types/core/types.d.ts +0 -1
- package/dist/types/ui/group-list/group-list-modal.d.ts +10 -0
- package/package.json +1 -1
- package/dist/types/core/group-channel-manager.d.ts +0 -74
package/dist/cobuy-sdk.esm.js
CHANGED
|
@@ -304,11 +304,44 @@ class GroupListModal {
|
|
|
304
304
|
this.currentSessionId = null;
|
|
305
305
|
this.onGroupJoined = null;
|
|
306
306
|
this.onViewProgress = null;
|
|
307
|
+
this.socketListenerRegistered = false;
|
|
307
308
|
this.escapeHandler = (event) => {
|
|
308
309
|
if (event.key === "Escape") {
|
|
309
310
|
this.close();
|
|
310
311
|
}
|
|
311
312
|
};
|
|
313
|
+
this.handleGroupMemberJoinedEvent = (event) => {
|
|
314
|
+
this.onGroupMemberJoined(event);
|
|
315
|
+
};
|
|
316
|
+
/** Handle group member joined socket event and update groups list */
|
|
317
|
+
this.onGroupMemberJoined = (event) => {
|
|
318
|
+
const detail = event.detail || {};
|
|
319
|
+
const productId = detail.product_id;
|
|
320
|
+
const groupData = detail.group;
|
|
321
|
+
// Only process if this is for the current product
|
|
322
|
+
if (!productId || !this.currentProductId || productId !== this.currentProductId) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (!groupData) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const groupId = groupData.id;
|
|
329
|
+
const participantsCount = groupData.participants_count;
|
|
330
|
+
if (!groupId) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// Find and update the group in the list
|
|
334
|
+
const groupIndex = this.groups.findIndex((g) => g.groupId === groupId);
|
|
335
|
+
if (groupIndex !== -1) {
|
|
336
|
+
// Update the joined count
|
|
337
|
+
if (typeof participantsCount === "number") {
|
|
338
|
+
this.groups[groupIndex].joined = participantsCount;
|
|
339
|
+
}
|
|
340
|
+
this.logger.info(`[GroupListModal] Updated group ${groupId} - participants: ${participantsCount}`);
|
|
341
|
+
// Re-render the specific group card
|
|
342
|
+
this.updateGroupCard(groupId);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
312
345
|
this.logger = new Logger(debug);
|
|
313
346
|
this.groups = groups;
|
|
314
347
|
this.liveCount = liveCount;
|
|
@@ -335,6 +368,65 @@ class GroupListModal {
|
|
|
335
368
|
hasGroup(groupId) {
|
|
336
369
|
return this.groups.some((group) => group.groupId === groupId);
|
|
337
370
|
}
|
|
371
|
+
/** Subscribe to socket events for real-time group updates */
|
|
372
|
+
subscribeToSocketEvents() {
|
|
373
|
+
if (typeof window === "undefined" || this.socketListenerRegistered) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
window.addEventListener("group:member:joined", this.handleGroupMemberJoinedEvent);
|
|
377
|
+
this.socketListenerRegistered = true;
|
|
378
|
+
this.logger.debug("[GroupListModal] Socket event listeners registered");
|
|
379
|
+
}
|
|
380
|
+
/** Unsubscribe from socket events */
|
|
381
|
+
unsubscribeFromSocketEvents() {
|
|
382
|
+
if (typeof window === "undefined" || !this.socketListenerRegistered) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
window.removeEventListener("group:member:joined", this.handleGroupMemberJoinedEvent);
|
|
386
|
+
this.socketListenerRegistered = false;
|
|
387
|
+
this.logger.debug("[GroupListModal] Socket event listeners unregistered");
|
|
388
|
+
}
|
|
389
|
+
/** Update the rendered group card with new data */
|
|
390
|
+
updateGroupCard(groupId) {
|
|
391
|
+
if (!this.overlayEl) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const groupCard = this.overlayEl.querySelector(`[data-group-id="${groupId}"]`);
|
|
395
|
+
if (!groupCard) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const group = this.groups.find((g) => g.groupId === groupId);
|
|
399
|
+
if (!group) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
// Update the progress info
|
|
403
|
+
const remaining = Math.max(group.total - group.joined, 0);
|
|
404
|
+
const joinedCountEl = groupCard.querySelector(".cobuy-joined-count");
|
|
405
|
+
const spotsLeftEl = groupCard.querySelector(".cobuy-spots-left");
|
|
406
|
+
if (joinedCountEl) {
|
|
407
|
+
joinedCountEl.textContent = `${group.joined} Joined`;
|
|
408
|
+
}
|
|
409
|
+
if (spotsLeftEl) {
|
|
410
|
+
spotsLeftEl.textContent = `${remaining} ${remaining === 1 ? "spot" : "spots"} left`;
|
|
411
|
+
}
|
|
412
|
+
// Update the progress bar
|
|
413
|
+
const progressFill = groupCard.querySelector(".cobuy-gl-progress-fill");
|
|
414
|
+
if (progressFill) {
|
|
415
|
+
const pct = Math.max(0, Math.min(100, Math.round((group.joined / group.total) * 100)));
|
|
416
|
+
progressFill.style.width = `${pct}%`;
|
|
417
|
+
}
|
|
418
|
+
// Update member avatars
|
|
419
|
+
const membersContainer = groupCard.querySelector(".cobuy-group-members");
|
|
420
|
+
if (membersContainer) {
|
|
421
|
+
// Clear existing avatars
|
|
422
|
+
membersContainer.innerHTML = "";
|
|
423
|
+
// Recreate avatars with updated joined count
|
|
424
|
+
for (let i = 0; i < group.total; i++) {
|
|
425
|
+
const avatar = this.createMemberAvatar(i >= group.joined);
|
|
426
|
+
membersContainer.appendChild(avatar);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
338
430
|
async open(productId, sessionId, joinedGroupId) {
|
|
339
431
|
if (this.overlayEl) {
|
|
340
432
|
this.logger.debug("Group list modal already open");
|
|
@@ -380,6 +472,8 @@ class GroupListModal {
|
|
|
380
472
|
this.overlayEl = overlay;
|
|
381
473
|
document.body.appendChild(overlay);
|
|
382
474
|
document.addEventListener("keydown", this.escapeHandler);
|
|
475
|
+
// Subscribe to socket events for real-time group updates
|
|
476
|
+
this.subscribeToSocketEvents();
|
|
383
477
|
requestAnimationFrame(() => {
|
|
384
478
|
overlay.classList.add("cobuy-gl-open");
|
|
385
479
|
});
|
|
@@ -477,6 +571,8 @@ class GroupListModal {
|
|
|
477
571
|
if (!this.overlayEl) {
|
|
478
572
|
return;
|
|
479
573
|
}
|
|
574
|
+
// Unsubscribe from socket events
|
|
575
|
+
this.unsubscribeFromSocketEvents();
|
|
480
576
|
// Clear any running countdown intervals to avoid leaks
|
|
481
577
|
this.countdownIntervals.forEach((id) => window.clearInterval(id));
|
|
482
578
|
this.countdownIntervals = [];
|
|
@@ -720,6 +816,7 @@ class GroupListModal {
|
|
|
720
816
|
createGroupCard(group) {
|
|
721
817
|
const card = document.createElement("div");
|
|
722
818
|
card.className = "cobuy-group-card";
|
|
819
|
+
card.setAttribute("data-group-id", group.groupId);
|
|
723
820
|
const header = document.createElement("div");
|
|
724
821
|
header.className = "cobuy-group-card-header";
|
|
725
822
|
const groupId = document.createElement("div");
|
|
@@ -2633,7 +2730,6 @@ class WidgetRoot {
|
|
|
2633
2730
|
}
|
|
2634
2731
|
/** Fetch latest group data and re-render containers */
|
|
2635
2732
|
async refreshGroupDataFromRealtime() {
|
|
2636
|
-
console.log("request group data realtime callledddd");
|
|
2637
2733
|
// Debounce rapid refreshes to prevent loops and reduce API load
|
|
2638
2734
|
const now = Date.now();
|
|
2639
2735
|
if (now - this.lastGroupDataRefreshTime < this.GROUP_REFRESH_DEBOUNCE) {
|
|
@@ -2658,6 +2754,9 @@ class WidgetRoot {
|
|
|
2658
2754
|
this.groupFulfilled = true;
|
|
2659
2755
|
}
|
|
2660
2756
|
}
|
|
2757
|
+
else {
|
|
2758
|
+
this.groupFulfilled = false;
|
|
2759
|
+
}
|
|
2661
2760
|
this.refreshRenderedContainers();
|
|
2662
2761
|
}
|
|
2663
2762
|
catch (error) {
|
|
@@ -3048,7 +3147,6 @@ class WidgetRoot {
|
|
|
3048
3147
|
let groupData = null;
|
|
3049
3148
|
if (this.apiClient) {
|
|
3050
3149
|
rewardData = await this.fetchRewardWithRetry(options.productId);
|
|
3051
|
-
console.log("from renderrrr");
|
|
3052
3150
|
groupData = await this.fetchPrimaryGroup(options.productId);
|
|
3053
3151
|
this.currentGroupData = groupData;
|
|
3054
3152
|
this.currentGroupId = (groupData === null || groupData === void 0 ? void 0 : groupData.id) || null;
|
|
@@ -3305,7 +3403,6 @@ class WidgetRoot {
|
|
|
3305
3403
|
*/
|
|
3306
3404
|
async fetchPrimaryGroup(productId) {
|
|
3307
3405
|
var _a;
|
|
3308
|
-
console.log("fetch primary group called");
|
|
3309
3406
|
if (!this.apiClient) {
|
|
3310
3407
|
return null;
|
|
3311
3408
|
}
|
|
@@ -3422,6 +3519,7 @@ class WidgetRoot {
|
|
|
3422
3519
|
createWidget(rewardData, container, options) {
|
|
3423
3520
|
const isFulfilled = this.groupFulfilled;
|
|
3424
3521
|
const activeReward = this.frozenReward || (rewardData === null || rewardData === void 0 ? void 0 : rewardData.reward) || null;
|
|
3522
|
+
this.logger.info(`activeReward: ${JSON.stringify(activeReward)}`);
|
|
3425
3523
|
const wrapper = document.createElement("div");
|
|
3426
3524
|
wrapper.className = "cobuy-widget";
|
|
3427
3525
|
wrapper.style.display = "grid";
|
|
@@ -3461,28 +3559,31 @@ class WidgetRoot {
|
|
|
3461
3559
|
rewardLine.style.opacity = "0";
|
|
3462
3560
|
rewardLine.style.animation =
|
|
3463
3561
|
"cobuy-fadeIn var(--cobuy-animation-duration, 300ms) var(--cobuy-animation-easing, ease-out) forwards";
|
|
3464
|
-
if (isFulfilled) {
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
}
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3562
|
+
// if (isFulfilled) {
|
|
3563
|
+
// const rewardText = this.formatRewardText(activeReward);
|
|
3564
|
+
// rewardLine.textContent = rewardText
|
|
3565
|
+
// ? `Reward available: ${rewardText}`
|
|
3566
|
+
// : "Reward available for this group";
|
|
3567
|
+
// rewardLine.setAttribute(
|
|
3568
|
+
// "aria-label",
|
|
3569
|
+
// rewardText ? `Reward locked in: ${rewardText}` : "Reward available for this group",
|
|
3570
|
+
// );
|
|
3571
|
+
// rewardLine.title = rewardLine.textContent;
|
|
3572
|
+
// }
|
|
3573
|
+
// else if (activeReward) {
|
|
3574
|
+
// const rewardText = this.formatRewardText(activeReward);
|
|
3575
|
+
// rewardLine.textContent = rewardText
|
|
3576
|
+
// ? `Save up to ${rewardText} with CoBuy`
|
|
3577
|
+
// : "CoBuy reward available";
|
|
3578
|
+
// rewardLine.setAttribute("aria-label", `Eligible for CoBuy reward: ${rewardLine.textContent}`);
|
|
3579
|
+
// rewardLine.title = rewardLine.textContent;
|
|
3580
|
+
// }
|
|
3581
|
+
// else {
|
|
3582
|
+
// rewardLine.textContent = "CoBuy offer loading or unavailable";
|
|
3583
|
+
// rewardLine.setAttribute("aria-label", "CoBuy offer loading or unavailable");
|
|
3584
|
+
// rewardLine.title = "CoBuy offer loading or unavailable";
|
|
3585
|
+
// rewardLine.style.color = "#6b7280";
|
|
3586
|
+
// }
|
|
3486
3587
|
sections.reward = rewardLine;
|
|
3487
3588
|
// Button - semantic button element with accessibility
|
|
3488
3589
|
const button = document.createElement("button");
|
|
@@ -8951,9 +9052,7 @@ class CoBuy {
|
|
|
8951
9052
|
const ref = window.localStorage.getItem(key);
|
|
8952
9053
|
if (ref) {
|
|
8953
9054
|
this.logger.debug(`[SDK] Retrieved checkout reference via prefix: ${key}`);
|
|
8954
|
-
const parsedGroupId = key.startsWith(`${basePrefix}_`)
|
|
8955
|
-
? key.substring(basePrefix.length + 1)
|
|
8956
|
-
: null;
|
|
9055
|
+
const parsedGroupId = key.startsWith(`${basePrefix}_`) ? key.substring(basePrefix.length + 1) : null;
|
|
8957
9056
|
return { key, checkoutRef: ref, groupId: parsedGroupId };
|
|
8958
9057
|
}
|
|
8959
9058
|
}
|
|
@@ -9374,7 +9473,6 @@ class CoBuy {
|
|
|
9374
9473
|
const pid = typeof w.getProductId === "function" ? w.getProductId() : null;
|
|
9375
9474
|
if (!productId || pid === productId) {
|
|
9376
9475
|
if (typeof w.requestRefresh === "function") {
|
|
9377
|
-
console.log("calling refresshh now");
|
|
9378
9476
|
refreshPromises.push(w.requestRefresh());
|
|
9379
9477
|
}
|
|
9380
9478
|
}
|