@orbitconnect/react 0.1.4 → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ # Changelog — @orbitconnect/react
2
+
3
+ ## 0.1.6 (2026-05-21)
4
+
5
+ ### Added — Conversation Context System
6
+
7
+ - **Context Types** — New `ConversationContext`, `ContextActor`, and related type exports (`ConversationContextType`, `ConversationContextStatus`, `ContextActorType`)
8
+ - **`ConversationContextCard` component** — Renders a contextual info card at the top of conversations showing business context (type, title, actor, status, subtitle)
9
+ - **`conversation:context_updated` event** — Real-time context updates via WebSocket, automatically reflected in the conversation list
10
+ - **`useConversations()` enhancements:**
11
+ - `Conversation` interface now includes `context` field
12
+ - `createDirect(participantId, context?)` — accepts optional context for contextual conversations
13
+ - `createGroup(participantIds, context?)` — new method for creating group conversations with context
14
+ - Listens to `conversation:context_updated` events and updates state in real time
15
+
16
+ ### New Exports
17
+
18
+ - Types: `ConversationContext`, `ContextActor`, `ConversationContextType`, `ConversationContextStatus`, `ContextActorType`
19
+ - Component: `ConversationContextCard`
20
+
21
+ ---
22
+
23
+ ## 0.1.5 (2025-05-21)
24
+
25
+ ### Added — Offline Messaging & Queueing System
26
+
27
+ - **Offline Queue Engine** — Messages are now persisted locally (IndexedDB) before sending, guaranteeing crash safety, refresh survival, and reconnect recovery.
28
+ - **Optimistic Messaging** — Messages appear instantly in the chat UI with visual status indicators (queued → sending → sent → delivered → read).
29
+ - **Automatic Retries** — Failed messages retry with exponential backoff (2s → 5s → 15s → 30s → 60s), up to 5 attempts before marking as failed.
30
+ - **Multi-Tab Coordination** — BroadcastChannel-based leader election prevents duplicate queue flushes and syncs message state across browser tabs.
31
+ - **Network Awareness** — Monitors `navigator.onLine` and flushes the queue automatically when connectivity returns.
32
+ - **Socket Reconnect Flush** — Queue automatically flushes when the WebSocket transitions from `reconnecting` → `connected`.
33
+ - **Idempotency Deduplication** — Each message gets a unique `idempotencyKey` (sent as both body field and `Idempotency-Key` header) preventing duplicate sends on retry.
34
+ - **ACK Reconciliation** — Incoming `message:new` WebSocket events are matched against pending optimistic messages by idempotency key, replacing the placeholder with the confirmed message.
35
+
36
+ ### New Exports
37
+
38
+ - `useOfflineQueue()` hook — access queue operations (`enqueue`, `retryMessage`, `retryAll`, `pauseQueue`, `resumeQueue`, `getPendingMessages`, `clearFailedMessages`, `getQueueStatus`)
39
+ - `OfflineQueueProvider` component — automatically mounted inside `OrbitProvider`
40
+ - Types: `OrbitOfflineMessage`, `OfflineMessageStatus`, `QueueSendOptions`, `QueueEventType`
41
+
42
+ ### Enhanced
43
+
44
+ - `useMessages()` hook now:
45
+ - Routes `sendMessage()` through the offline queue (persist → optimistic UI → send)
46
+ - Restores pending messages from IndexedDB on mount
47
+ - Deduplicates `message:new` events against optimistic messages
48
+ - Returns `isOnline`, `retryFailedMessage(localId)`, `retryAllFailed()`
49
+ - `MessageBubble` component now renders offline status indicators:
50
+ - **queued** — clock icon (grey), reduced opacity
51
+ - **sending** — spinning circle (blue), reduced opacity
52
+ - **failed** — exclamation icon (red), dashed red border, "Not sent · Tap to retry" banner
53
+
54
+ ---
55
+
56
+ ## 0.1.4
57
+
58
+ Initial public release with real-time chat, voice/video calls, meetings, E2E encryption, and theming.
@@ -0,0 +1,11 @@
1
+ import type { ConversationContext } from '../../types/context';
2
+ interface ConversationContextCardProps {
3
+ context: ConversationContext;
4
+ className?: string;
5
+ }
6
+ /**
7
+ * Renders a contextual info card at the top of a conversation.
8
+ * Shows business context like booking details, service info, purchase status, etc.
9
+ */
10
+ export declare function ConversationContextCard({ context, className }: ConversationContextCardProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
@@ -17,6 +17,21 @@ export interface Conversation {
17
17
  presenceStatus?: 'online' | 'away' | 'offline';
18
18
  /** For direct conversations — the other participant's app_user_id, used to initiate calls */
19
19
  otherUserId?: string;
20
+ /** Business context attached to the conversation (booking, service, purchase, support) */
21
+ context?: {
22
+ type: string;
23
+ referenceId?: string;
24
+ title?: string;
25
+ subtitle?: string;
26
+ status?: string;
27
+ actor?: {
28
+ id: string;
29
+ type: string;
30
+ name: string;
31
+ avatar?: string;
32
+ };
33
+ metadata?: Record<string, unknown>;
34
+ } | null;
20
35
  }
21
36
  interface ConversationListProps {
22
37
  conversations: Conversation[];
@@ -42,3 +42,4 @@ export { ImageViewer } from './ImageViewer';
42
42
  export { VideoViewer } from './VideoViewer';
43
43
  export { DocumentViewer } from './DocumentViewer';
44
44
  export type { ImageViewerProps, VideoViewerProps, DocumentViewerProps } from './mediaViewerRegistry';
45
+ export { ConversationContextCard } from './ConversationContextCard';
@@ -2,6 +2,7 @@ import type { Conversation } from '../components/chat/ConversationList';
2
2
  export declare function useConversations(): {
3
3
  conversations: Conversation[];
4
4
  loading: boolean;
5
- createDirect: (participantId: string) => Promise<string>;
5
+ createDirect: (participantId: string, context?: Record<string, unknown>) => Promise<string>;
6
+ createGroup: (participantIds: string[], context?: Record<string, unknown>) => Promise<string>;
6
7
  refresh: () => void;
7
8
  };
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export { Chat, VideoCall, MeetingWidget } from './widgets';
6
6
  export type { ChatProps, MeetingWidgetProps, ChatHeaderInfo } from './widgets';
7
7
  export { useMessages, useConversations, useCall, useMeeting, useCallHistory, usePresence, useRealtime, useMedia, useNotifications } from './hooks';
8
8
  export type { ActiveCall, CallState, ActiveMeeting, MeetingState, PresenceStatus, RealtimeSession, CreateSessionInput, TransitionType, MediaObject, OrbitNotification } from './hooks';
9
+ export type { ConversationContext, ContextActor, ConversationContextType, ConversationContextStatus, ContextActorType } from './types';
9
10
  export { useOfflineQueue, OfflineQueueProvider } from './offline';
10
11
  export type { OrbitOfflineMessage, OfflineMessageStatus, QueueSendOptions, QueueEventType } from './offline';
11
12
  export { MeetingProvider, MeetingContext, useMeetingContext } from './meeting';