@chaterafrikang/sdk 0.1.0-beta.3 → 0.1.0-beta.4
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.cjs +49 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -11
- package/dist/index.d.ts +34 -11
- package/dist/index.js +49 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -445,15 +445,19 @@ var MessageFactory = class {
|
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
/**
|
|
448
|
-
* Create a message from server payload (confirmed message)
|
|
448
|
+
* Create a message from server payload (confirmed message).
|
|
449
|
+
* Normalizes sender_id/senderId and sender_type/senderType so either snake or camelCase from server works.
|
|
449
450
|
*/
|
|
450
451
|
static fromServerPayload(conversationId, payload) {
|
|
452
|
+
const senderId = payload.sender_id ?? payload.senderId;
|
|
453
|
+
const senderType = payload.sender_type ?? payload.senderType;
|
|
451
454
|
return {
|
|
452
455
|
id: payload.message_id,
|
|
453
456
|
conversationId,
|
|
454
457
|
content: payload.content,
|
|
455
|
-
senderId
|
|
456
|
-
|
|
458
|
+
senderId,
|
|
459
|
+
senderName: payload.sender_name,
|
|
460
|
+
senderType,
|
|
457
461
|
messageType: payload.message_type === "system" ? "system" : "text",
|
|
458
462
|
optimistic: false,
|
|
459
463
|
receiptState: "sent",
|
|
@@ -461,14 +465,18 @@ var MessageFactory = class {
|
|
|
461
465
|
};
|
|
462
466
|
}
|
|
463
467
|
/**
|
|
464
|
-
* Convert an optimistic message to confirmed (reconciliation)
|
|
468
|
+
* Convert an optimistic message to confirmed (reconciliation).
|
|
469
|
+
* Normalizes sender_id/senderId and sender_type/senderType from server payload.
|
|
465
470
|
*/
|
|
466
471
|
static confirmOptimistic(optimisticMessage, serverPayload) {
|
|
472
|
+
const senderId = serverPayload.sender_id ?? serverPayload.senderId;
|
|
473
|
+
const senderType = serverPayload.sender_type ?? serverPayload.senderType;
|
|
467
474
|
return {
|
|
468
475
|
...optimisticMessage,
|
|
469
476
|
optimistic: false,
|
|
470
|
-
senderId
|
|
471
|
-
|
|
477
|
+
senderId,
|
|
478
|
+
senderName: serverPayload.sender_name,
|
|
479
|
+
senderType,
|
|
472
480
|
receiptState: optimisticMessage.receiptState ?? "sent",
|
|
473
481
|
createdAt: serverPayload.sent_at ? new Date(serverPayload.sent_at) : optimisticMessage.createdAt
|
|
474
482
|
};
|
|
@@ -619,6 +627,10 @@ var MessageManager = class extends eventemitter3.EventEmitter {
|
|
|
619
627
|
* Map<conversationId, Map<message_id, Message>>
|
|
620
628
|
*/
|
|
621
629
|
this.confirmedMessages = /* @__PURE__ */ new Map();
|
|
630
|
+
/**
|
|
631
|
+
* Conversations we've already warned about missing sender_id (warn once per conversation)
|
|
632
|
+
*/
|
|
633
|
+
this.warnedMissingSenderId = /* @__PURE__ */ new Set();
|
|
622
634
|
this.logger = new Logger(debug);
|
|
623
635
|
this.receiptManager = new ReceiptManager(debug);
|
|
624
636
|
this.receiptManager.on("receipt", (event) => {
|
|
@@ -659,6 +671,12 @@ var MessageManager = class extends eventemitter3.EventEmitter {
|
|
|
659
671
|
const optimisticMessage = this.getOptimisticMessage(conversationId, messageId);
|
|
660
672
|
if (optimisticMessage) {
|
|
661
673
|
const reconciledMessage = this.reconcileOptimisticMessage(optimisticMessage, serverPayload);
|
|
674
|
+
if (reconciledMessage.senderId == null && !this.warnedMissingSenderId.has(conversationId)) {
|
|
675
|
+
this.warnedMissingSenderId.add(conversationId);
|
|
676
|
+
console.warn(
|
|
677
|
+
'[ChatAfrika SDK] Message payload missing sender_id (and sender_type). Clients cannot show "You" vs other participant. The realtime backend MUST include sender_id and sender_type in every type:"message" payload. See docs/REALTIME_WEBSOCKET_CONTRACT.md.'
|
|
678
|
+
);
|
|
679
|
+
}
|
|
662
680
|
this.removeOptimisticMessage(conversationId, messageId);
|
|
663
681
|
this.trackMessageId(conversationId, messageId);
|
|
664
682
|
this.trackConfirmedMessage(conversationId, messageId, reconciledMessage);
|
|
@@ -670,6 +688,12 @@ var MessageManager = class extends eventemitter3.EventEmitter {
|
|
|
670
688
|
}
|
|
671
689
|
this.trackMessageId(conversationId, messageId);
|
|
672
690
|
const message = MessageFactory.fromServerPayload(conversationId, serverPayload);
|
|
691
|
+
if (message.senderId == null && !this.warnedMissingSenderId.has(conversationId)) {
|
|
692
|
+
this.warnedMissingSenderId.add(conversationId);
|
|
693
|
+
console.warn(
|
|
694
|
+
'[ChatAfrika SDK] Message payload missing sender_id (and sender_type). Clients cannot show "You" vs other participant. The realtime backend MUST include sender_id and sender_type in every type:"message" payload. See docs/REALTIME_WEBSOCKET_CONTRACT.md.'
|
|
695
|
+
);
|
|
696
|
+
}
|
|
673
697
|
this.trackConfirmedMessage(conversationId, messageId, message);
|
|
674
698
|
this.emit("message", message);
|
|
675
699
|
this.logger.debug("Handled incoming message:", messageId);
|
|
@@ -723,17 +747,14 @@ var MessageManager = class extends eventemitter3.EventEmitter {
|
|
|
723
747
|
this.logger.warn("Receipt for unknown message:", event.messageId);
|
|
724
748
|
}
|
|
725
749
|
/**
|
|
726
|
-
* Reconcile an optimistic message with a server confirmation
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
* as an optimistic message we previously created.
|
|
730
|
-
*
|
|
750
|
+
* Reconcile an optimistic message with a server confirmation.
|
|
751
|
+
* Does not emit again so the app receives at most one event per message_id.
|
|
752
|
+
*
|
|
731
753
|
* @returns The reconciled (confirmed) message
|
|
732
754
|
*/
|
|
733
755
|
reconcileOptimisticMessage(optimisticMessage, serverPayload) {
|
|
734
756
|
const confirmedMessage = MessageFactory.confirmOptimistic(optimisticMessage, serverPayload);
|
|
735
|
-
this.
|
|
736
|
-
this.logger.debug("Reconciled optimistic message:", optimisticMessage.id);
|
|
757
|
+
this.logger.debug("Reconciled optimistic message (no second emit):", optimisticMessage.id);
|
|
737
758
|
return confirmedMessage;
|
|
738
759
|
}
|
|
739
760
|
/**
|
|
@@ -743,6 +764,15 @@ var MessageManager = class extends eventemitter3.EventEmitter {
|
|
|
743
764
|
const seenIds = this.seenMessageIds.get(conversationId);
|
|
744
765
|
return seenIds?.has(messageId) ?? false;
|
|
745
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* Track message IDs from REST history so the same message is not emitted again via WebSocket.
|
|
769
|
+
* Call after fetchMessages() so history and real-time stay deduped.
|
|
770
|
+
*/
|
|
771
|
+
trackMessageIdsFromHistory(conversationId, messageIds) {
|
|
772
|
+
for (const id of messageIds) {
|
|
773
|
+
this.trackMessageId(conversationId, id);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
746
776
|
/**
|
|
747
777
|
* Track a message ID for a conversation (for deduplication)
|
|
748
778
|
*/
|
|
@@ -1037,11 +1067,16 @@ var Conversation = class extends eventemitter3.EventEmitter {
|
|
|
1037
1067
|
"REST not configured. Set apiUrl in ChatAfrika config for fetchMessages() (token, API keys, or getRestHeaders)."
|
|
1038
1068
|
);
|
|
1039
1069
|
}
|
|
1040
|
-
|
|
1070
|
+
const result = await this.fetchMessagesCallback({
|
|
1041
1071
|
externalUserId: options?.externalUserId ?? "",
|
|
1042
1072
|
cursor: options?.cursor,
|
|
1043
1073
|
limit: options?.limit
|
|
1044
1074
|
});
|
|
1075
|
+
this.messageManager.trackMessageIdsFromHistory(
|
|
1076
|
+
this.id,
|
|
1077
|
+
result.messages.map((m) => m.id)
|
|
1078
|
+
);
|
|
1079
|
+
return result;
|
|
1045
1080
|
}
|
|
1046
1081
|
/**
|
|
1047
1082
|
* Mark conversation as joined
|