vg-x07df 1.8.0 → 1.8.1

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.
@@ -214,7 +214,8 @@ var useChatStore = zustand.create()(
214
214
  createdAt: envelope.ts,
215
215
  version: 1,
216
216
  reactions: {},
217
- status: "sent"
217
+ status: "sent",
218
+ filename: envelope.payload?.meta?.filename
218
219
  };
219
220
  state.byId[envelope.entryId] = entry;
220
221
  state.order.push(envelope.entryId);
@@ -297,6 +298,13 @@ var useChatStore = zustand.create()(
297
298
  }
298
299
  }
299
300
  }),
301
+ addFile: (file, filename) => set((state) => {
302
+ const values = Object.values(state.byId);
303
+ const entryArr = values.filter((val) => val.filename === filename);
304
+ const entry = entryArr[0];
305
+ entry.file = file;
306
+ state.byId[entry.id] = entry;
307
+ }),
300
308
  addEntryOptimistic: (entry) => set((state) => {
301
309
  state.byId[entry.id] = entry;
302
310
  state.order.push(entry.id);
@@ -470,6 +478,27 @@ var ChatService = class {
470
478
  }
471
479
  }
472
480
  );
481
+ this.room.registerByteStreamHandler("chat:v1", async (reader, participantInfo) => {
482
+ try {
483
+ const info = reader.info;
484
+ const filename = info.name;
485
+ reader.onProgress = (progress) => {
486
+ console.log(`${progress ? (progress * 100).toFixed(0) : "undefined"}% of ${filename} downloaded`);
487
+ };
488
+ const parts = (await reader.readAll()).map((chunk) => chunk.slice());
489
+ const fileBlob = new Blob(parts, { type: info.mimeType });
490
+ this.handleIncomingFile(fileBlob, filename, info.mimeType);
491
+ console.log(
492
+ `File "${info.name}" received from ${participantInfo.identity}
493
+ Topic: ${info.topic}
494
+ Timestamp: ${info.timestamp}
495
+ ID: ${info.id}
496
+ Size: ${info.size}`
497
+ );
498
+ } catch (error) {
499
+ logger.error("Error reading file stream", error);
500
+ }
501
+ });
473
502
  this.isSubscribed = true;
474
503
  }
475
504
  unsubscribe() {
@@ -478,7 +507,7 @@ var ChatService = class {
478
507
  getLocalParticipantId() {
479
508
  return this.room.localParticipant.identity;
480
509
  }
481
- async send(content) {
510
+ async send(content, file) {
482
511
  if (!this.isRoomReady()) {
483
512
  useRtcStore.getState().addError({
484
513
  code: "CHAT_ROOM_NOT_READY",
@@ -487,6 +516,10 @@ var ChatService = class {
487
516
  });
488
517
  return;
489
518
  }
519
+ if (content.length === 0 && typeof file !== "undefined") {
520
+ console.log("file present", typeof file);
521
+ content = file.name;
522
+ }
490
523
  const validation = validateContent(content);
491
524
  if (!validation.valid) {
492
525
  useRtcStore.getState().addError({
@@ -513,7 +546,8 @@ var ChatService = class {
513
546
  createdAt: getCurrentTimestamp(),
514
547
  version: 1,
515
548
  reactions: {},
516
- status: "sending"
549
+ status: "sending",
550
+ file
517
551
  };
518
552
  chatStore.addEntryOptimistic(entry);
519
553
  try {
@@ -525,12 +559,20 @@ var ChatService = class {
525
559
  ts: entry.createdAt,
526
560
  sender: senderInfo,
527
561
  payload: {
528
- content
562
+ content,
563
+ meta: { filename: file?.name }
529
564
  }
530
565
  };
531
566
  await this.room.localParticipant.sendText(JSON.stringify(envelope), {
532
567
  topic: "chat:v1"
533
568
  });
569
+ console.log("Sent message", entry, envelope);
570
+ if (file) {
571
+ await this.room.localParticipant.sendFile(file, {
572
+ mimeType: file.type,
573
+ topic: "chat:v1"
574
+ });
575
+ }
534
576
  chatStore.markEntrySent(entryId);
535
577
  } catch (error) {
536
578
  chatStore.markEntryFailed(entryId);
@@ -764,6 +806,14 @@ var ChatService = class {
764
806
  logger.error("Error parsing incoming message", error);
765
807
  }
766
808
  }
809
+ handleIncomingFile(blob, filename, mimeType) {
810
+ try {
811
+ const file = new File([blob], filename, { type: mimeType || blob.type });
812
+ useChatStore.getState().addFile(file, filename);
813
+ } catch (error) {
814
+ logger.error("Error parsing incoming file", error);
815
+ }
816
+ }
767
817
  getSenderInfo() {
768
818
  const localParticipant = this.room.localParticipant;
769
819
  const sender = {
@@ -795,7 +845,7 @@ function useChat() {
795
845
  [participantCache]
796
846
  );
797
847
  const send = react.useCallback(
798
- async (content) => service.send(content),
848
+ async (content, file) => service.send(content, file),
799
849
  [service]
800
850
  );
801
851
  const edit = react.useCallback(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts","../../src/channel/DataChannelContext.ts","../../src/state/types.ts","../../src/state/store.ts","../../src/channel/chat/store.ts","../../src/channel/chat/utils.ts","../../src/channel/chat/service.ts","../../src/channel/chat/useChat.ts","../../src/channel/reactions/store.ts","../../src/channel/reactions/utils.ts","../../src/channel/reactions/service.ts","../../src/channel/reactions/useReactions.ts","../../src/channel/registry.ts","../../src/channel/DataChannelProvider.tsx"],"names":["createContext","useContext","create","immer","entry","nanoid","ConnectionState","useMemo","useCallback","react","defaultState","logger","useRef","useState","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Comprehensive logging system for the Callpad Web SDK\r\n *\r\n * Features:\r\n * - Log level filtering (debug, info, warn, error)\r\n * - Environment variable configuration (DEBUG, CALLPAD_LOG_LEVEL)\r\n * - Hierarchical namespacing (callpad:socket:connection)\r\n * - Custom logger integration\r\n * - Zero-cost when disabled\r\n */\r\n\r\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\r\n\r\nexport interface LoggerOptions {\r\n level?: LogLevel;\r\n enableDebug?: boolean;\r\n customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n}\r\n\r\nexport interface CallpadLogger {\r\n debug(message: string, meta?: any): void;\r\n info(message: string, meta?: any): void;\r\n warn(message: string, meta?: any): void;\r\n error(message: string, meta?: any): void;\r\n child(namespace: string): CallpadLogger;\r\n setLevel(level: LogLevel): void;\r\n isLevelEnabled(level: LogLevel): boolean;\r\n}\r\n\r\nconst LOG_LEVELS: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n};\r\n\r\nclass CallpadLoggerImpl implements CallpadLogger {\r\n private namespace: string;\r\n private level: LogLevel;\r\n private enableDebug: boolean;\r\n private customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n\r\n constructor(namespace = \"callpad\", options: LoggerOptions = {}) {\r\n this.namespace = namespace;\r\n this.level = options.level ?? this.getDefaultLevel();\r\n this.enableDebug = options.enableDebug ?? this.shouldEnableDebug();\r\n if (options.customLogger) {\r\n this.customLogger = options.customLogger;\r\n }\r\n }\r\n\r\n private getDefaultLevel(): LogLevel {\r\n const envLevel =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__CALLPAD_LOG_LEVEL__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.CALLPAD_LOG_LEVEL;\r\n\r\n if (envLevel && this.isValidLogLevel(envLevel)) {\r\n return envLevel as LogLevel;\r\n }\r\n\r\n const isProduction =\r\n typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.NODE_ENV === \"production\";\r\n\r\n return isProduction ? \"warn\" : \"info\";\r\n }\r\n\r\n private shouldEnableDebug(): boolean {\r\n const debugEnv =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__DEBUG__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.DEBUG;\r\n\r\n if (!debugEnv) return false;\r\n\r\n const debugPatterns = debugEnv.split(/[\\s,]+/);\r\n return debugPatterns.some((pattern: string) => {\r\n if (pattern === \"*\") return true;\r\n if (pattern.endsWith(\"*\")) {\r\n const prefix = pattern.slice(0, -1);\r\n return this.namespace.startsWith(prefix);\r\n }\r\n return this.namespace === pattern;\r\n });\r\n }\r\n\r\n private isValidLogLevel(level: string): boolean {\r\n return Object.keys(LOG_LEVELS).includes(level);\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n if (level === \"debug\" && !this.enableDebug) {\r\n return false;\r\n }\r\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level];\r\n }\r\n\r\n private formatMessage(level: LogLevel, message: string, meta?: any): void {\r\n if (!this.shouldLog(level)) return;\r\n\r\n const timestamp = new Date().toISOString();\r\n const prefix = `[${timestamp}] [${this.namespace}] [${level.toUpperCase()}]`;\r\n\r\n if (this.customLogger) {\r\n this.customLogger(level, message, meta);\r\n return;\r\n }\r\n\r\n const logMethod =\r\n level === \"error\"\r\n ? console.error\r\n : level === \"warn\"\r\n ? console.warn\r\n : level === \"info\"\r\n ? console.info\r\n : console.log;\r\n\r\n if (meta !== undefined) {\r\n logMethod(`${prefix} ${message}`, meta);\r\n } else {\r\n logMethod(`${prefix} ${message}`);\r\n }\r\n }\r\n\r\n debug(message: string, meta?: any): void {\r\n this.formatMessage(\"debug\", message, meta);\r\n }\r\n\r\n info(message: string, meta?: any): void {\r\n this.formatMessage(\"info\", message, meta);\r\n }\r\n\r\n warn(message: string, meta?: any): void {\r\n this.formatMessage(\"warn\", message, meta);\r\n }\r\n\r\n error(message: string, meta?: any): void {\r\n this.formatMessage(\"error\", message, meta);\r\n }\r\n\r\n child(namespace: string): CallpadLogger {\r\n const childNamespace = `${this.namespace}:${namespace}`;\r\n const childOptions: LoggerOptions = {\r\n level: this.level,\r\n enableDebug: this.enableDebug,\r\n };\r\n if (this.customLogger) {\r\n childOptions.customLogger = this.customLogger;\r\n }\r\n return new CallpadLoggerImpl(childNamespace, childOptions);\r\n }\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n isLevelEnabled(level: LogLevel): boolean {\r\n return this.shouldLog(level);\r\n }\r\n}\r\n\r\nlet rootLogger: CallpadLogger | null = null;\r\n\r\nexport function createLogger(\r\n namespace?: string,\r\n options?: LoggerOptions\r\n): CallpadLogger {\r\n if (!namespace) {\r\n if (!rootLogger) {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n }\r\n return rootLogger;\r\n }\r\n\r\n return new CallpadLoggerImpl(`callpad:${namespace}`, options);\r\n}\r\n\r\nexport function setGlobalLoggerOptions(options: LoggerOptions): void {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n}\r\n","import { createContext, useContext } from \"react\";\r\n\r\nexport interface DataChannelContextValue {\r\n services: Map<string, any>;\r\n isReady: boolean;\r\n}\r\n\r\nexport const DataChannelContext = createContext<DataChannelContextValue | null>(\r\n null\r\n);\r\n\r\nexport function useDataChannelContext(): DataChannelContextValue {\r\n const context = useContext(DataChannelContext);\r\n if (!context) {\r\n throw new Error(\r\n \"useDataChannelContext must be used within DataChannelProvider\"\r\n );\r\n }\r\n return context;\r\n}\r\n\r\nexport function useFeatureService<T = any>(featureName: string): T {\r\n const { services } = useDataChannelContext();\r\n const service = services.get(featureName) as T;\r\n if (!service) {\r\n throw new Error(\r\n `Feature service \"${featureName}\" not found. Make sure it's enabled in DataChannelProvider.`\r\n );\r\n }\r\n\r\n return service;\r\n}\r\n","type Nullable<T> = T | null;\r\n\r\nexport type CallParticipantRole = \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n\r\nexport interface Profile {\r\n userId: string;\r\n username: string | null;\r\n firstName: string | null;\r\n lastName: string | null;\r\n profilePhoto: string | null;\r\n}\r\n\r\nexport interface ParticipantPermissions {\r\n canMute: boolean;\r\n canKick: boolean;\r\n canTransfer: boolean;\r\n canEnd: boolean;\r\n canRecord: boolean;\r\n canShareScreen: boolean;\r\n}\r\n\r\nexport interface ParticipantMetadata {\r\n userId: string | number;\r\n firstName: Nullable<string>;\r\n lastName: Nullable<string>;\r\n username: Nullable<string>;\r\n email: Nullable<string>;\r\n profilePhoto: Nullable<string>;\r\n role: CallParticipantRole;\r\n permissions: ParticipantPermissions;\r\n}\r\n\r\nexport interface LiveKitJoinInfo {\r\n token: string;\r\n roomName: string;\r\n url: string;\r\n}\r\n\r\nexport interface Session {\r\n id: string;\r\n status: \"initializing\" | \"pending\" | \"ready\" | \"active\" | \"ended\";\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n role: \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n livekitInfo?: LiveKitJoinInfo;\r\n startedAt?: string;\r\n ringTimeoutMs?: number;\r\n}\r\n\r\nexport interface IncomingInvite {\r\n callId: string;\r\n inviteId: string;\r\n caller: ParticipantMetadata;\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n expiresAt: string;\r\n expiresInMs: number;\r\n ringTimeoutMs: number;\r\n}\r\n\r\nexport interface OutgoingInvite {\r\n userId: string;\r\n status: \"sent\" | \"accepted\" | \"declined\" | \"missed\";\r\n participant?: Omit<ParticipantMetadata, \"permissions\"> | undefined;\r\n}\r\n\r\nexport interface RtcError {\r\n code: string;\r\n message: string;\r\n timestamp: number;\r\n context?: any;\r\n}\r\n\r\nexport interface RtcState {\r\n // Did we initiate the current call?\r\n initiated: boolean;\r\n\r\n // Active session (null when no active call)\r\n session: Session | null;\r\n\r\n // Incoming invitation (null when no pending invite)\r\n incomingInvite: IncomingInvite | null;\r\n\r\n outgoingInvites: Record<string, OutgoingInvite>;\r\n\r\n // Error tracking\r\n errors: RtcError[];\r\n}\r\n\r\nexport const defaultState: RtcState = {\r\n initiated: false,\r\n session: null,\r\n incomingInvite: null,\r\n outgoingInvites: {},\r\n errors: [],\r\n};\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { RtcError, RtcState } from \"./types\";\r\nimport { defaultState } from \"./types\";\r\n\r\ntype Actions = {\r\n patch: (fn: (draft: RtcState) => void) => void;\r\n reset: () => void;\r\n addError: (error: RtcError) => void;\r\n clearErrors: () => void;\r\n};\r\n\r\nexport const useRtcStore = create<RtcState & Actions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n reset: () => set(() => defaultState),\r\n\r\n addError: (error) =>\r\n set((state) => {\r\n state.errors.push(error);\r\n }),\r\n\r\n clearErrors: () =>\r\n set((state) => {\r\n state.errors = [];\r\n }),\r\n }))\r\n);\r\n\r\nexport const rtcStore = useRtcStore;\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ChatEntry, ChatState, Envelope } from \"./types\";\r\n\r\ninterface ChatActions {\r\n patch: (fn: (draft: ChatState) => void) => void;\r\n applyIncoming: (envelope: Envelope) => void;\r\n addEntryOptimistic: (entry: ChatEntry) => void;\r\n markEntrySent: (entryId: string) => void;\r\n markEntryFailed: (entryId: string) => void;\r\n applyEdit: (entryId: string, newContent: string, version: number) => void;\r\n applyRemove: (entryId: string) => void;\r\n applyReaction: (\r\n entryId: string,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n ) => void;\r\n queuePendingOp: (entryId: string, envelope: Envelope) => void;\r\n processPendingOps: (entryId: string) => void;\r\n trimOldEntries: () => void;\r\n clearChat: () => void;\r\n}\r\n\r\nconst defaultChatState: ChatState = {\r\n byId: {},\r\n order: [],\r\n pendingOps: {},\r\n participantCache: {},\r\n maxEntries: 1000,\r\n};\r\n\r\nfunction applyReactionToEntry(\r\n entry: ChatEntry,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n) {\r\n const emojiSet = entry.reactions[emoji];\r\n if (!emojiSet) {\r\n entry.reactions[emoji] = new Set();\r\n }\r\n if (op === \"add\") {\r\n entry.reactions[emoji]?.add(participantId);\r\n } else {\r\n entry.reactions[emoji]?.delete(participantId);\r\n if (entry.reactions[emoji]?.size === 0) {\r\n delete entry.reactions[emoji];\r\n }\r\n }\r\n}\r\n\r\nfunction trimEntriesIfNeeded(state: ChatState) {\r\n if (Object.keys(state.byId).length > state.maxEntries) {\r\n const entriesToRemove = Object.keys(state.byId).length - state.maxEntries;\r\n for (let i = 0; i < entriesToRemove; i++) {\r\n const oldestId = state.order[i];\r\n if (oldestId) {\r\n delete state.byId[oldestId];\r\n }\r\n }\r\n state.order = state.order.slice(entriesToRemove);\r\n }\r\n}\r\n\r\nexport const useChatStore = create<ChatState & ChatActions>()(\r\n immer((set) => ({\r\n ...defaultChatState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n applyIncoming: (envelope) =>\r\n set((state) => {\r\n if (envelope.kind === \"entry\") {\r\n if (state.byId[envelope.entryId]) {\r\n return;\r\n }\r\n\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: envelope.entryId,\r\n content: envelope.payload.content,\r\n sender: {\r\n id: envelope.sender.id,\r\n },\r\n createdAt: envelope.ts,\r\n version: 1,\r\n reactions: {},\r\n status: \"sent\",\r\n };\r\n\r\n state.byId[envelope.entryId] = entry;\r\n state.order.push(envelope.entryId);\r\n\r\n trimEntriesIfNeeded(state);\r\n\r\n const pendingOps = state.pendingOps[envelope.entryId];\r\n if (pendingOps) {\r\n delete state.pendingOps[envelope.entryId];\r\n\r\n for (const op of pendingOps) {\r\n if (op.kind === \"edit\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && op.payload.version > entry.version) {\r\n entry.content = op.payload.newContent;\r\n entry.version = op.payload.version;\r\n entry.editedAt = op.ts;\r\n }\r\n } else if (op.kind === \"remove\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = op.ts;\r\n }\r\n } else if (op.kind === \"reaction\") {\r\n if (op.sender.info) {\r\n state.participantCache[op.sender.id] = op.sender.info;\r\n }\r\n\r\n const entry = state.byId[op.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n op.payload.emoji,\r\n op.sender.id,\r\n op.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }\r\n } else if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (!entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n }\r\n }),\r\n\r\n addEntryOptimistic: (entry) =>\r\n set((state) => {\r\n state.byId[entry.id] = entry;\r\n state.order.push(entry.id);\r\n\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n markEntrySent: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"sent\";\r\n }\r\n }),\r\n\r\n markEntryFailed: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"failed\";\r\n }\r\n }),\r\n\r\n applyEdit: (entryId, newContent, version) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && version > entry.version) {\r\n entry.content = newContent;\r\n entry.version = version;\r\n entry.editedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyRemove: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyReaction: (entryId, emoji, participantId, op) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n applyReactionToEntry(entry, emoji, participantId, op);\r\n }\r\n }),\r\n\r\n queuePendingOp: (entryId, envelope) =>\r\n set((state) => {\r\n if (!state.pendingOps[entryId]) {\r\n state.pendingOps[entryId] = [];\r\n }\r\n state.pendingOps[entryId].push(envelope);\r\n }),\r\n\r\n processPendingOps: (entryId) =>\r\n set((state) => {\r\n const pendingOps = state.pendingOps[entryId];\r\n if (!pendingOps) {\r\n return;\r\n }\r\n\r\n delete state.pendingOps[entryId];\r\n\r\n for (const envelope of pendingOps) {\r\n if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }),\r\n\r\n trimOldEntries: () =>\r\n set((state) => {\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n clearChat: () => set(() => defaultChatState),\r\n }))\r\n);\r\n\r\nexport const chatStore = useChatStore;\r\n","import { nanoid } from \"nanoid\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\n\r\nexport function compareEntries(a: ChatEntry, b: ChatEntry): number {\r\n if (a.createdAt !== b.createdAt) {\r\n return a.createdAt - b.createdAt;\r\n }\r\n\r\n if (a.sender.id !== b.sender.id) {\r\n return a.sender.id.localeCompare(b.sender.id);\r\n }\r\n\r\n return a.id.localeCompare(b.id);\r\n}\r\n\r\nexport function validateContent(content: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n const trimmed = content.trim();\r\n\r\n if (trimmed.length === 0) {\r\n return { valid: false, error: \"Content cannot be empty\" };\r\n }\r\n\r\n const sizeInBytes = new TextEncoder().encode(content).length;\r\n if (sizeInBytes > 16384) {\r\n return { valid: false, error: \"Content exceeds 16KB limit\" };\r\n }\r\n\r\n return { valid: true };\r\n}\r\n\r\nexport function isValidEnvelope(data: any): data is Envelope {\r\n if (!data || typeof data !== \"object\") {\r\n return false;\r\n }\r\n\r\n if (data.v !== 1) {\r\n return false;\r\n }\r\n\r\n if (![\"entry\", \"edit\", \"remove\", \"reaction\"].includes(data.kind)) {\r\n return false;\r\n }\r\n\r\n if (\r\n typeof data.roomId !== \"string\" ||\r\n typeof data.entryId !== \"string\" ||\r\n typeof data.ts !== \"number\"\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!data.sender || typeof data.sender.id !== \"string\") {\r\n return false;\r\n }\r\n\r\n if (\r\n data.kind === \"entry\" ||\r\n data.kind === \"edit\" ||\r\n data.kind === \"reaction\"\r\n ) {\r\n if (!data.payload || typeof data.payload !== \"object\") {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function generateEntryId(): string {\r\n return nanoid();\r\n}\r\n\r\nexport function getCurrentTimestamp(): number {\r\n return Date.now();\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\nimport {\r\n generateEntryId,\r\n getCurrentTimestamp,\r\n isValidEnvelope,\r\n validateContent,\r\n} from \"./utils\";\r\n\r\nconst logger = createLogger(\"chat\");\r\n\r\nexport class ChatService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) {\r\n return;\r\n }\r\n\r\n this.room.registerTextStreamHandler(\r\n \"chat:v1\",\r\n async (reader, participantInfo) => {\r\n console.log(\"Got here: chat:v1\", participantInfo.identity)\r\n try {\r\n const text = await reader.readAll();\r\n console.log(\"Got here: chat:v1\", text)\r\n this.handleIncomingMessage(text);\r\n\r\n } catch (error) {\r\n logger.error(\"Error reading text stream\", error);\r\n }\r\n }\r\n );\r\n this.isSubscribed = true;\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async send(content: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot send message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(content);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const entryId = generateEntryId();\r\n const chatStore = useChatStore.getState();\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: entryId,\r\n content,\r\n sender: {\r\n id: senderInfo.id,\r\n },\r\n createdAt: getCurrentTimestamp(),\r\n version: 1,\r\n reactions: {},\r\n status: \"sending\",\r\n };\r\n\r\n chatStore.addEntryOptimistic(entry);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"entry\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: entry.createdAt,\r\n sender: senderInfo,\r\n payload: {\r\n content,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n chatStore.markEntrySent(entryId);\r\n } catch (error) {\r\n chatStore.markEntryFailed(entryId);\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async edit(entryId: string, newContent: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot edit message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(newContent);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only edit your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const newVersion = entry.version + 1;\r\n chatStore.applyEdit(entryId, newContent, newVersion);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"edit\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n newContent,\r\n version: newVersion,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_EDIT_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to edit message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async remove(entryId: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only remove your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n chatStore.applyRemove(entryId);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"remove\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REMOVE_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async react(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot add reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"add\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"add\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to add reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n async unreact(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"remove\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"remove\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncomingMessage(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (!isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid envelope received\", parsed);\r\n return;\r\n }\r\n\r\n useChatStore.getState().applyIncoming(parsed);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming message\", error);\r\n }\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parsing errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ChatService } from \"./service\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry } from \"./types\";\r\nimport { compareEntries } from \"./utils\";\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseChatReturn {\r\n entries: ChatEntry[];\r\n isReady: boolean;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isOwnEntry: (entry: ChatEntry) => boolean;\r\n send: (content: string) => Promise<void>;\r\n edit: (id: string, content: string) => Promise<void>;\r\n remove: (id: string) => Promise<void>;\r\n react: (id: string, emoji: string) => Promise<void>;\r\n unreact: (id: string, emoji: string) => Promise<void>;\r\n}\r\n\r\nexport function useChat(): UseChatReturn {\r\n const service = useFeatureService<ChatService>(\"chat\");\r\n\r\n const byId = useChatStore((state) => state.byId);\r\n const order = useChatStore((state) => state.order);\r\n const participantCache = useChatStore((state) => state.participantCache);\r\n\r\n const entries = useMemo(() => {\r\n return order\r\n .map((id) => byId[id])\r\n .filter((entry): entry is ChatEntry => entry !== undefined)\r\n .sort(compareEntries);\r\n }, [byId, order]);\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => {\r\n return participantCache[id] || null;\r\n },\r\n [participantCache]\r\n );\r\n\r\n const send = useCallback(\r\n async (content: string) => service.send(content),\r\n [service]\r\n );\r\n\r\n const edit = useCallback(\r\n async (id: string, content: string) => service.edit(id, content),\r\n [service]\r\n );\r\n\r\n const remove = useCallback(\r\n async (id: string) => service.remove(id),\r\n [service]\r\n );\r\n\r\n const react = useCallback(\r\n async (id: string, emoji: string) => service.react(id, emoji),\r\n [service]\r\n );\r\n\r\n const unreact = useCallback(\r\n async (id: string, emoji: string) => service.unreact(id, emoji),\r\n [service]\r\n );\r\n\r\n const isOwnEntry = useCallback(\r\n (entry: ChatEntry) => entry.sender.id === service.getLocalParticipantId(),\r\n [service]\r\n );\r\n\r\n return {\r\n entries,\r\n isReady: true,\r\n getParticipantInfo,\r\n isOwnEntry,\r\n send,\r\n edit,\r\n remove,\r\n react,\r\n unreact,\r\n };\r\n}\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport type {\r\n ParticipantReaction,\r\n ReactionEnvelope,\r\n ReactionsState,\r\n} from \"./types\";\r\n\r\ninterface ReactionsActions {\r\n setReaction: (participantId: string, reaction: ParticipantReaction) => void;\r\n clearReaction: (participantId: string) => void;\r\n upsertParticipantInfo: (id: string, info: ParticipantMetadata) => void;\r\n pruneExpired: (now?: number) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst defaultState: ReactionsState = {\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: 4000,\r\n};\r\n\r\nexport const useReactionsStore = create<ReactionsState & ReactionsActions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n setReaction: (participantId, reaction) =>\r\n set((state) => {\r\n state.reactions.set(participantId, reaction);\r\n }),\r\n\r\n clearReaction: (participantId) =>\r\n set((state) => {\r\n state.reactions.delete(participantId);\r\n }),\r\n\r\n upsertParticipantInfo: (id, info) =>\r\n set((state) => {\r\n state.participantCache[id] = info;\r\n }),\r\n\r\n pruneExpired: (now = Date.now()) =>\r\n set((state) => {\r\n const entries = Array.from(state.reactions.entries());\r\n for (const [participantId, reaction] of entries) {\r\n if (reaction.ts + state.ttlMs < now) {\r\n state.reactions.delete(participantId);\r\n }\r\n }\r\n }),\r\n\r\n clear: () =>\r\n set(() => ({\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: defaultState.ttlMs,\r\n })),\r\n }))\r\n);\r\n\r\nexport function applyIncomingReaction(envelope: ReactionEnvelope): void {\r\n const { upsertParticipantInfo, setReaction } = useReactionsStore.getState();\r\n\r\n if (envelope.sender.info) {\r\n upsertParticipantInfo(envelope.sender.id, envelope.sender.info);\r\n }\r\n\r\n setReaction(envelope.sender.id, {\r\n emoji: envelope.payload.emoji,\r\n ts: Date.now(),\r\n nonce: envelope.payload.nonce,\r\n });\r\n}\r\n","import { createLogger } from \"../../utils\";\r\n\r\nexport const logger = createLogger(\"reactions\");\r\n\r\nexport function validateEmoji(emoji: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (!emoji || typeof emoji !== \"string\") {\r\n return { valid: false, error: \"empty\" };\r\n }\r\n if (emoji.length > 10) {\r\n return { valid: false, error: \"too long\" };\r\n }\r\n return { valid: true };\r\n}\r\n\r\nexport function generateNonce(): string {\r\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { applyIncomingReaction, useReactionsStore } from \"./store\";\r\nimport type { ReactionEnvelope } from \"./types\";\r\nimport { generateNonce, validateEmoji } from \"./utils\";\r\n\r\nconst logger = createLogger(\"reactions\");\r\n\r\nexport class ReactionsService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n private pruneInterval: ReturnType<typeof setInterval> | undefined;\r\n private lastSendAt = 0;\r\n private minIntervalMs = 200;\r\n private lastRemoteTs = new Map<string, number>();\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private canSendNow(): boolean {\r\n const now = Date.now();\r\n if (now - this.lastSendAt < this.minIntervalMs) return false;\r\n this.lastSendAt = now;\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) return;\r\n\r\n this.room.registerTextStreamHandler(\"reactions:v1\", async (reader) => {\r\n try {\r\n const text = await reader.readAll();\r\n this.handleIncoming(text);\r\n } catch (err) {\r\n logger.error(\"Error reading reactions stream\", err);\r\n }\r\n });\r\n\r\n this.pruneInterval = setInterval(() => {\r\n useReactionsStore.getState().pruneExpired();\r\n }, 1000);\r\n\r\n this.isSubscribed = true;\r\n logger.info(\"ReactionsService subscribed\");\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n if (this.pruneInterval) {\r\n clearInterval(this.pruneInterval);\r\n this.pruneInterval = undefined;\r\n }\r\n logger.info(\"ReactionsService unsubscribed\");\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async sendReaction(emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_ROOM_NOT_READY\",\r\n message: \"Cannot send reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateEmoji(emoji);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_INVALID_EMOJI\",\r\n message: validation.error || \"Invalid emoji\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (!this.canSendNow()) {\r\n logger.debug(\"Rate limited, skipping send\");\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n const ts = Date.now();\r\n const nonce = generateNonce();\r\n\r\n useReactionsStore.getState().setReaction(senderInfo.id, {\r\n emoji,\r\n ts,\r\n nonce,\r\n });\r\n\r\n try {\r\n const envelope: ReactionEnvelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n ts,\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n nonce,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"reactions:v1\",\r\n });\r\n\r\n logger.debug(\"Reaction sent\", { emoji });\r\n } catch (error) {\r\n logger.error(\"Failed to send reaction\", error);\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send reaction\",\r\n timestamp: Date.now(),\r\n context: { emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncoming(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text) as ReactionEnvelope;\r\n if (!this.isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid reaction envelope received\", parsed);\r\n return;\r\n }\r\n\r\n if (parsed.sender.id === this.getLocalParticipantId()) {\r\n logger.debug(\"Ignoring self-echo reaction\");\r\n return;\r\n }\r\n\r\n const lastTs =\r\n this.lastRemoteTs.get(parsed.sender.id) ?? Number.NEGATIVE_INFINITY;\r\n if (parsed.ts < lastTs) {\r\n logger.debug(\"Ignoring out-of-order reaction\", {\r\n sender: parsed.sender.id,\r\n ts: parsed.ts,\r\n lastTs,\r\n });\r\n return;\r\n }\r\n this.lastRemoteTs.set(parsed.sender.id, parsed.ts);\r\n applyIncomingReaction(parsed);\r\n logger.debug(\"Reaction received\", { emoji: parsed.payload.emoji });\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming reaction\", error);\r\n }\r\n }\r\n\r\n private isValidEnvelope(e: any): e is ReactionEnvelope {\r\n return (\r\n e &&\r\n e.v === 1 &&\r\n e.kind === \"reaction\" &&\r\n typeof e.roomId === \"string\" &&\r\n e.roomId === this.room.name &&\r\n typeof e.ts === \"number\" &&\r\n e.ts > 0 &&\r\n typeof e.sender?.id === \"string\" &&\r\n typeof e.payload?.emoji === \"string\" &&\r\n typeof e.payload?.nonce === \"string\"\r\n );\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parse errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ReactionsService } from \"./service\";\r\nimport { useReactionsStore } from \"./store\";\r\n\r\nconst logger = createLogger(\"reactions:hook\");\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseReactionsReturn {\r\n sendReaction: (emoji: string) => Promise<void>;\r\n getReactionFor: (participantId: string) => Nullable<string>;\r\n clearReaction: (participantId: string) => void;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isReady: boolean;\r\n}\r\n\r\nexport function useReactions(): UseReactionsReturn {\r\n const service = useFeatureService<ReactionsService>(\"reactions\");\r\n\r\n const reactions = useReactionsStore((state) => state.reactions);\r\n const participantCache = useReactionsStore((state) => state.participantCache);\r\n\r\n const getReactionFor = useCallback(\r\n (participantId: string): Nullable<string> => {\r\n const reaction = reactions.get(participantId);\r\n return reaction?.emoji ?? null;\r\n },\r\n [reactions]\r\n );\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => participantCache[id] || null,\r\n [participantCache]\r\n );\r\n\r\n const sendReaction = useCallback(\r\n async (emoji: string) => {\r\n if (!service) {\r\n logger.error(\"Cannot send reaction: service not ready\");\r\n return;\r\n }\r\n return service.sendReaction(emoji);\r\n },\r\n [service]\r\n );\r\n\r\n const clearReaction = useCallback((participantId: string) => {\r\n useReactionsStore.getState().clearReaction(participantId);\r\n }, []);\r\n\r\n return {\r\n sendReaction,\r\n getReactionFor,\r\n clearReaction,\r\n getParticipantInfo,\r\n isReady: !!service,\r\n };\r\n}\r\n","import type { Room } from \"livekit-client\";\r\nimport { ChatService, useChatStore } from \"./chat\";\r\nimport { ReactionsService, useReactionsStore } from \"./reactions\";\r\nimport type { RealtimeFeature } from \"./types\";\r\n\r\nexport const FEATURES: Record<string, RealtimeFeature> = {\r\n chat: {\r\n name: \"chat\",\r\n createService: (room: Room) => new ChatService(room),\r\n cleanupStore: () => useChatStore.getState().clearChat(),\r\n },\r\n reactions: {\r\n name: \"reactions\",\r\n createService: (room: Room) => new ReactionsService(room),\r\n cleanupStore: () => useReactionsStore.getState().clear(),\r\n },\r\n};\r\n\r\nexport const DEFAULT_FEATURES = [\"chat\", \"reactions\"];\r\n","import type { Room } from \"livekit-client\";\r\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { createLogger } from \"../utils\";\r\nimport {\r\n DataChannelContext,\r\n type DataChannelContextValue,\r\n} from \"./DataChannelContext\";\r\nimport { DEFAULT_FEATURES, FEATURES } from \"./registry\";\r\n\r\nconst logger = createLogger(\"channels:provider\");\r\n\r\nexport interface DataChannelProviderProps {\r\n room: Room;\r\n features?: string[];\r\n children: ReactNode;\r\n}\r\n\r\nexport function DataChannelProvider({\r\n room,\r\n features = DEFAULT_FEATURES,\r\n children,\r\n}: DataChannelProviderProps) {\r\n const services = useRef<Map<string, any>>(new Map());\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!room) {\r\n logger.warn(\"DataChannelProvider mounted without room\");\r\n return;\r\n }\r\n\r\n logger.debug(\"Initializing features\", { features });\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n\r\n if (!feature) {\r\n logger.warn(`Feature \"${featureName}\" not found in registry`);\r\n continue;\r\n }\r\n\r\n try {\r\n logger.debug(`Initializing feature: ${featureName}`);\r\n const service = feature.createService(room);\r\n\r\n service.subscribe();\r\n services.current.set(featureName, service);\r\n\r\n logger.info(`Feature \"${featureName}\" initialized`);\r\n } catch (error) {\r\n logger.error(`Failed to initialize feature \"${featureName}\"`, error);\r\n }\r\n }\r\n\r\n setIsReady(true);\r\n logger.info(\"All features initialized\");\r\n return () => {\r\n logger.debug(\"Cleaning up features\");\r\n\r\n // Unsubscribe all services\r\n services.current.forEach((service, name) => {\r\n try {\r\n logger.debug(`Unsubscribing feature: ${name}`);\r\n service.unsubscribe();\r\n } catch (error) {\r\n logger.error(`Failed to unsubscribe feature \"${name}\"`, error);\r\n }\r\n });\r\n\r\n // Clean up stores\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n if (feature?.cleanupStore) {\r\n try {\r\n logger.debug(`Cleaning store for feature: ${featureName}`);\r\n feature.cleanupStore();\r\n } catch (error) {\r\n logger.error(`Failed to cleanup store for \"${featureName}\"`, error);\r\n }\r\n }\r\n }\r\n\r\n services.current.clear();\r\n setIsReady(false);\r\n logger.info(\"Features cleanup complete\");\r\n };\r\n }, [room, features]);\r\n\r\n const contextValue = useMemo<DataChannelContextValue>(\r\n () => ({\r\n services: services.current,\r\n isReady,\r\n }),\r\n [isReady]\r\n );\r\n\r\n return (\r\n <DataChannelContext.Provider value={contextValue}>\r\n {children}\r\n </DataChannelContext.Provider>\r\n );\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/channel/DataChannelContext.ts","../../src/state/types.ts","../../src/state/store.ts","../../src/channel/chat/store.ts","../../src/channel/chat/utils.ts","../../src/channel/chat/service.ts","../../src/channel/chat/useChat.ts","../../src/channel/reactions/store.ts","../../src/channel/reactions/utils.ts","../../src/channel/reactions/service.ts","../../src/channel/reactions/useReactions.ts","../../src/channel/registry.ts","../../src/channel/DataChannelProvider.tsx"],"names":["createContext","useContext","create","immer","entry","nanoid","ConnectionState","useMemo","useCallback","react","defaultState","logger","useRef","useState","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Comprehensive logging system for the Callpad Web SDK\r\n *\r\n * Features:\r\n * - Log level filtering (debug, info, warn, error)\r\n * - Environment variable configuration (DEBUG, CALLPAD_LOG_LEVEL)\r\n * - Hierarchical namespacing (callpad:socket:connection)\r\n * - Custom logger integration\r\n * - Zero-cost when disabled\r\n */\r\n\r\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\r\n\r\nexport interface LoggerOptions {\r\n level?: LogLevel;\r\n enableDebug?: boolean;\r\n customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n}\r\n\r\nexport interface CallpadLogger {\r\n debug(message: string, meta?: any): void;\r\n info(message: string, meta?: any): void;\r\n warn(message: string, meta?: any): void;\r\n error(message: string, meta?: any): void;\r\n child(namespace: string): CallpadLogger;\r\n setLevel(level: LogLevel): void;\r\n isLevelEnabled(level: LogLevel): boolean;\r\n}\r\n\r\nconst LOG_LEVELS: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n};\r\n\r\nclass CallpadLoggerImpl implements CallpadLogger {\r\n private namespace: string;\r\n private level: LogLevel;\r\n private enableDebug: boolean;\r\n private customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n\r\n constructor(namespace = \"callpad\", options: LoggerOptions = {}) {\r\n this.namespace = namespace;\r\n this.level = options.level ?? this.getDefaultLevel();\r\n this.enableDebug = options.enableDebug ?? this.shouldEnableDebug();\r\n if (options.customLogger) {\r\n this.customLogger = options.customLogger;\r\n }\r\n }\r\n\r\n private getDefaultLevel(): LogLevel {\r\n const envLevel =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__CALLPAD_LOG_LEVEL__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.CALLPAD_LOG_LEVEL;\r\n\r\n if (envLevel && this.isValidLogLevel(envLevel)) {\r\n return envLevel as LogLevel;\r\n }\r\n\r\n const isProduction =\r\n typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.NODE_ENV === \"production\";\r\n\r\n return isProduction ? \"warn\" : \"info\";\r\n }\r\n\r\n private shouldEnableDebug(): boolean {\r\n const debugEnv =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__DEBUG__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.DEBUG;\r\n\r\n if (!debugEnv) return false;\r\n\r\n const debugPatterns = debugEnv.split(/[\\s,]+/);\r\n return debugPatterns.some((pattern: string) => {\r\n if (pattern === \"*\") return true;\r\n if (pattern.endsWith(\"*\")) {\r\n const prefix = pattern.slice(0, -1);\r\n return this.namespace.startsWith(prefix);\r\n }\r\n return this.namespace === pattern;\r\n });\r\n }\r\n\r\n private isValidLogLevel(level: string): boolean {\r\n return Object.keys(LOG_LEVELS).includes(level);\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n if (level === \"debug\" && !this.enableDebug) {\r\n return false;\r\n }\r\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level];\r\n }\r\n\r\n private formatMessage(level: LogLevel, message: string, meta?: any): void {\r\n if (!this.shouldLog(level)) return;\r\n\r\n const timestamp = new Date().toISOString();\r\n const prefix = `[${timestamp}] [${this.namespace}] [${level.toUpperCase()}]`;\r\n\r\n if (this.customLogger) {\r\n this.customLogger(level, message, meta);\r\n return;\r\n }\r\n\r\n const logMethod =\r\n level === \"error\"\r\n ? console.error\r\n : level === \"warn\"\r\n ? console.warn\r\n : level === \"info\"\r\n ? console.info\r\n : console.log;\r\n\r\n if (meta !== undefined) {\r\n logMethod(`${prefix} ${message}`, meta);\r\n } else {\r\n logMethod(`${prefix} ${message}`);\r\n }\r\n }\r\n\r\n debug(message: string, meta?: any): void {\r\n this.formatMessage(\"debug\", message, meta);\r\n }\r\n\r\n info(message: string, meta?: any): void {\r\n this.formatMessage(\"info\", message, meta);\r\n }\r\n\r\n warn(message: string, meta?: any): void {\r\n this.formatMessage(\"warn\", message, meta);\r\n }\r\n\r\n error(message: string, meta?: any): void {\r\n this.formatMessage(\"error\", message, meta);\r\n }\r\n\r\n child(namespace: string): CallpadLogger {\r\n const childNamespace = `${this.namespace}:${namespace}`;\r\n const childOptions: LoggerOptions = {\r\n level: this.level,\r\n enableDebug: this.enableDebug,\r\n };\r\n if (this.customLogger) {\r\n childOptions.customLogger = this.customLogger;\r\n }\r\n return new CallpadLoggerImpl(childNamespace, childOptions);\r\n }\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n isLevelEnabled(level: LogLevel): boolean {\r\n return this.shouldLog(level);\r\n }\r\n}\r\n\r\nlet rootLogger: CallpadLogger | null = null;\r\n\r\nexport function createLogger(\r\n namespace?: string,\r\n options?: LoggerOptions\r\n): CallpadLogger {\r\n if (!namespace) {\r\n if (!rootLogger) {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n }\r\n return rootLogger;\r\n }\r\n\r\n return new CallpadLoggerImpl(`callpad:${namespace}`, options);\r\n}\r\n\r\nexport function setGlobalLoggerOptions(options: LoggerOptions): void {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n}\r\n","import { createContext, useContext } from \"react\";\r\n\r\nexport interface DataChannelContextValue {\r\n services: Map<string, any>;\r\n isReady: boolean;\r\n}\r\n\r\nexport const DataChannelContext = createContext<DataChannelContextValue | null>(\r\n null\r\n);\r\n\r\nexport function useDataChannelContext(): DataChannelContextValue {\r\n const context = useContext(DataChannelContext);\r\n if (!context) {\r\n throw new Error(\r\n \"useDataChannelContext must be used within DataChannelProvider\"\r\n );\r\n }\r\n return context;\r\n}\r\n\r\nexport function useFeatureService<T = any>(featureName: string): T {\r\n const { services } = useDataChannelContext();\r\n const service = services.get(featureName) as T;\r\n if (!service) {\r\n throw new Error(\r\n `Feature service \"${featureName}\" not found. Make sure it's enabled in DataChannelProvider.`\r\n );\r\n }\r\n\r\n return service;\r\n}\r\n","type Nullable<T> = T | null;\r\n\r\nexport type CallParticipantRole = \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n\r\nexport interface Profile {\r\n userId: string;\r\n username: string | null;\r\n firstName: string | null;\r\n lastName: string | null;\r\n profilePhoto: string | null;\r\n}\r\n\r\nexport interface ParticipantPermissions {\r\n canMute: boolean;\r\n canKick: boolean;\r\n canTransfer: boolean;\r\n canEnd: boolean;\r\n canRecord: boolean;\r\n canShareScreen: boolean;\r\n}\r\n\r\nexport interface ParticipantMetadata {\r\n userId: string | number;\r\n firstName: Nullable<string>;\r\n lastName: Nullable<string>;\r\n username: Nullable<string>;\r\n email: Nullable<string>;\r\n profilePhoto: Nullable<string>;\r\n role: CallParticipantRole;\r\n permissions: ParticipantPermissions;\r\n}\r\n\r\nexport interface LiveKitJoinInfo {\r\n token: string;\r\n roomName: string;\r\n url: string;\r\n}\r\n\r\nexport interface Session {\r\n id: string;\r\n status: \"initializing\" | \"pending\" | \"ready\" | \"active\" | \"ended\";\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n role: \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n livekitInfo?: LiveKitJoinInfo;\r\n startedAt?: string;\r\n ringTimeoutMs?: number;\r\n}\r\n\r\nexport interface IncomingInvite {\r\n callId: string;\r\n inviteId: string;\r\n caller: ParticipantMetadata;\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n expiresAt: string;\r\n expiresInMs: number;\r\n ringTimeoutMs: number;\r\n}\r\n\r\nexport interface OutgoingInvite {\r\n userId: string;\r\n status: \"sent\" | \"accepted\" | \"declined\" | \"missed\";\r\n participant?: Omit<ParticipantMetadata, \"permissions\"> | undefined;\r\n}\r\n\r\nexport interface RtcError {\r\n code: string;\r\n message: string;\r\n timestamp: number;\r\n context?: any;\r\n}\r\n\r\nexport interface RtcState {\r\n // Did we initiate the current call?\r\n initiated: boolean;\r\n\r\n // Active session (null when no active call)\r\n session: Session | null;\r\n\r\n // Incoming invitation (null when no pending invite)\r\n incomingInvite: IncomingInvite | null;\r\n\r\n outgoingInvites: Record<string, OutgoingInvite>;\r\n\r\n // Error tracking\r\n errors: RtcError[];\r\n}\r\n\r\nexport const defaultState: RtcState = {\r\n initiated: false,\r\n session: null,\r\n incomingInvite: null,\r\n outgoingInvites: {},\r\n errors: [],\r\n};\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { RtcError, RtcState } from \"./types\";\r\nimport { defaultState } from \"./types\";\r\n\r\ntype Actions = {\r\n patch: (fn: (draft: RtcState) => void) => void;\r\n reset: () => void;\r\n addError: (error: RtcError) => void;\r\n clearErrors: () => void;\r\n};\r\n\r\nexport const useRtcStore = create<RtcState & Actions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n reset: () => set(() => defaultState),\r\n\r\n addError: (error) =>\r\n set((state) => {\r\n state.errors.push(error);\r\n }),\r\n\r\n clearErrors: () =>\r\n set((state) => {\r\n state.errors = [];\r\n }),\r\n }))\r\n);\r\n\r\nexport const rtcStore = useRtcStore;\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ChatEntry, ChatState, Envelope } from \"./types\";\r\n\r\ninterface ChatActions {\r\n patch: (fn: (draft: ChatState) => void) => void;\r\n applyIncoming: (envelope: Envelope) => void;\r\n addFile: (file: File, filename: string) => void\r\n addEntryOptimistic: (entry: ChatEntry) => void;\r\n markEntrySent: (entryId: string) => void;\r\n markEntryFailed: (entryId: string) => void;\r\n applyEdit: (entryId: string, newContent: string, version: number) => void;\r\n applyRemove: (entryId: string) => void;\r\n applyReaction: (\r\n entryId: string,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n ) => void;\r\n queuePendingOp: (entryId: string, envelope: Envelope) => void;\r\n processPendingOps: (entryId: string) => void;\r\n trimOldEntries: () => void;\r\n clearChat: () => void;\r\n}\r\n\r\nconst defaultChatState: ChatState = {\r\n byId: {},\r\n order: [],\r\n pendingOps: {},\r\n participantCache: {},\r\n maxEntries: 1000,\r\n};\r\n\r\nfunction applyReactionToEntry(\r\n entry: ChatEntry,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n) {\r\n const emojiSet = entry.reactions[emoji];\r\n if (!emojiSet) {\r\n entry.reactions[emoji] = new Set();\r\n }\r\n if (op === \"add\") {\r\n entry.reactions[emoji]?.add(participantId);\r\n } else {\r\n entry.reactions[emoji]?.delete(participantId);\r\n if (entry.reactions[emoji]?.size === 0) {\r\n delete entry.reactions[emoji];\r\n }\r\n }\r\n}\r\n\r\nfunction trimEntriesIfNeeded(state: ChatState) {\r\n if (Object.keys(state.byId).length > state.maxEntries) {\r\n const entriesToRemove = Object.keys(state.byId).length - state.maxEntries;\r\n for (let i = 0; i < entriesToRemove; i++) {\r\n const oldestId = state.order[i];\r\n if (oldestId) {\r\n delete state.byId[oldestId];\r\n }\r\n }\r\n state.order = state.order.slice(entriesToRemove);\r\n }\r\n}\r\n\r\nexport const useChatStore = create<ChatState & ChatActions>()(\r\n immer((set) => ({\r\n ...defaultChatState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n applyIncoming: (envelope) =>\r\n set((state) => {\r\n if (envelope.kind === \"entry\") {\r\n if (state.byId[envelope.entryId]) {\r\n return;\r\n }\r\n\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: envelope.entryId,\r\n content: envelope.payload.content,\r\n sender: {\r\n id: envelope.sender.id,\r\n },\r\n createdAt: envelope.ts,\r\n version: 1,\r\n reactions: {},\r\n status: \"sent\",\r\n filename: envelope.payload?.meta?.filename\r\n };\r\n\r\n state.byId[envelope.entryId] = entry;\r\n state.order.push(envelope.entryId);\r\n\r\n trimEntriesIfNeeded(state);\r\n\r\n const pendingOps = state.pendingOps[envelope.entryId];\r\n if (pendingOps) {\r\n delete state.pendingOps[envelope.entryId];\r\n\r\n for (const op of pendingOps) {\r\n if (op.kind === \"edit\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && op.payload.version > entry.version) {\r\n entry.content = op.payload.newContent;\r\n entry.version = op.payload.version;\r\n entry.editedAt = op.ts;\r\n }\r\n } else if (op.kind === \"remove\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = op.ts;\r\n }\r\n } else if (op.kind === \"reaction\") {\r\n if (op.sender.info) {\r\n state.participantCache[op.sender.id] = op.sender.info;\r\n }\r\n\r\n const entry = state.byId[op.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n op.payload.emoji,\r\n op.sender.id,\r\n op.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }\r\n } else if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (!entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n }\r\n }),\r\n \r\n addFile: (file, filename) =>\r\n set((state) => {\r\n const values = Object.values(state.byId)\r\n const entryArr = values.filter(val => val.filename === filename)\r\n const entry = entryArr[0];\r\n entry!.file = file\r\n state.byId[entry!.id] = entry!;\r\n }),\r\n\r\n addEntryOptimistic: (entry) =>\r\n set((state) => {\r\n state.byId[entry.id] = entry;\r\n state.order.push(entry.id);\r\n\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n markEntrySent: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"sent\";\r\n }\r\n }),\r\n\r\n markEntryFailed: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"failed\";\r\n }\r\n }),\r\n\r\n applyEdit: (entryId, newContent, version) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && version > entry.version) {\r\n entry.content = newContent;\r\n entry.version = version;\r\n entry.editedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyRemove: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyReaction: (entryId, emoji, participantId, op) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n applyReactionToEntry(entry, emoji, participantId, op);\r\n }\r\n }),\r\n\r\n queuePendingOp: (entryId, envelope) =>\r\n set((state) => {\r\n if (!state.pendingOps[entryId]) {\r\n state.pendingOps[entryId] = [];\r\n }\r\n state.pendingOps[entryId].push(envelope);\r\n }),\r\n\r\n processPendingOps: (entryId) =>\r\n set((state) => {\r\n const pendingOps = state.pendingOps[entryId];\r\n if (!pendingOps) {\r\n return;\r\n }\r\n\r\n delete state.pendingOps[entryId];\r\n\r\n for (const envelope of pendingOps) {\r\n if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }),\r\n\r\n trimOldEntries: () =>\r\n set((state) => {\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n clearChat: () => set(() => defaultChatState),\r\n }))\r\n);\r\n\r\nexport const chatStore = useChatStore;\r\n","import { nanoid } from \"nanoid\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\n\r\nexport function compareEntries(a: ChatEntry, b: ChatEntry): number {\r\n if (a.createdAt !== b.createdAt) {\r\n return a.createdAt - b.createdAt;\r\n }\r\n\r\n if (a.sender.id !== b.sender.id) {\r\n return a.sender.id.localeCompare(b.sender.id);\r\n }\r\n\r\n return a.id.localeCompare(b.id);\r\n}\r\n\r\nexport function validateContent(content: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n const trimmed = content.trim();\r\n\r\n if (trimmed.length === 0) {\r\n return { valid: false, error: \"Content cannot be empty\" };\r\n }\r\n\r\n const sizeInBytes = new TextEncoder().encode(content).length;\r\n if (sizeInBytes > 16384) {\r\n return { valid: false, error: \"Content exceeds 16KB limit\" };\r\n }\r\n\r\n return { valid: true };\r\n}\r\n\r\nexport function isValidEnvelope(data: any): data is Envelope {\r\n if (!data || typeof data !== \"object\") {\r\n return false;\r\n }\r\n\r\n if (data.v !== 1) {\r\n return false;\r\n }\r\n\r\n if (![\"entry\", \"edit\", \"remove\", \"reaction\"].includes(data.kind)) {\r\n return false;\r\n }\r\n\r\n if (\r\n typeof data.roomId !== \"string\" ||\r\n typeof data.entryId !== \"string\" ||\r\n typeof data.ts !== \"number\"\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!data.sender || typeof data.sender.id !== \"string\") {\r\n return false;\r\n }\r\n\r\n if (\r\n data.kind === \"entry\" ||\r\n data.kind === \"edit\" ||\r\n data.kind === \"reaction\"\r\n ) {\r\n if (!data.payload || typeof data.payload !== \"object\") {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function generateEntryId(): string {\r\n return nanoid();\r\n}\r\n\r\nexport function getCurrentTimestamp(): number {\r\n return Date.now();\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\nimport {\r\n generateEntryId,\r\n getCurrentTimestamp,\r\n isValidEnvelope,\r\n validateContent,\r\n} from \"./utils\";\r\n\r\nconst logger = createLogger(\"chat\");\r\n\r\nexport class ChatService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) {\r\n return;\r\n }\r\n // Handles incoming text streams\r\n this.room.registerTextStreamHandler(\r\n \"chat:v1\",\r\n async (reader, participantInfo) => {\r\n console.log(\"Got here: chat:v1\", participantInfo.identity)\r\n try {\r\n const text = await reader.readAll();\r\n console.log(\"Got here: chat:v1\", text)\r\n this.handleIncomingMessage(text);\r\n\r\n } catch (error) {\r\n logger.error(\"Error reading text stream\", error);\r\n }\r\n }\r\n );\r\n\r\n // Handles incoming file streams\r\n this.room.registerByteStreamHandler('chat:v1', async (reader, participantInfo) => {\r\n try {\r\n const info = reader.info;\r\n const filename = info.name\r\n\r\n // Confirm reciept of file\r\n reader.onProgress = (progress) => {\r\n console.log(`${progress ? (progress * 100).toFixed(0) : 'undefined'}% of ${filename} downloaded`);\r\n };\r\n\r\n // Ensure BlobParts are backed by ArrayBuffer (not SharedArrayBuffer) by copying with slice().\r\n const parts = (await reader.readAll()).map((chunk) => chunk.slice());\r\n const fileBlob = new Blob(parts, { type: info.mimeType });\r\n\r\n this.handleIncomingFile(fileBlob, filename, info.mimeType)\r\n\r\n console.log(\r\n `File \"${info.name}\" received from ${participantInfo.identity}\\n` +\r\n ` Topic: ${info.topic}\\n` +\r\n ` Timestamp: ${info.timestamp}\\n` +\r\n ` ID: ${info.id}\\n` +\r\n ` Size: ${info.size}`\r\n );\r\n } catch (error) {\r\n logger.error(\"Error reading file stream\", error);\r\n }\r\n });\r\n this.isSubscribed = true;\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async send(content: string, file?: File): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot send message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (content.length === 0 && typeof file !== \"undefined\") {\r\n console.log(\"file present\", typeof file)\r\n content = file.name\r\n }\r\n\r\n const validation = validateContent(content);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const entryId = generateEntryId();\r\n const chatStore = useChatStore.getState();\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: entryId,\r\n content,\r\n sender: {\r\n id: senderInfo.id,\r\n },\r\n createdAt: getCurrentTimestamp(),\r\n version: 1,\r\n reactions: {},\r\n status: \"sending\",\r\n file: file!\r\n };\r\n\r\n chatStore.addEntryOptimistic(entry);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"entry\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: entry.createdAt,\r\n sender: senderInfo,\r\n payload: {\r\n content,\r\n meta: {filename: file?.name}\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n console.log('Sent message', entry, envelope)\r\n if (file) {\r\n await this.room.localParticipant.sendFile(file, {\r\n mimeType: file.type,\r\n topic: 'chat:v1'\r\n });\r\n }\r\n chatStore.markEntrySent(entryId);\r\n } catch (error) {\r\n chatStore.markEntryFailed(entryId);\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async edit(entryId: string, newContent: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot edit message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(newContent);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only edit your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const newVersion = entry.version + 1;\r\n chatStore.applyEdit(entryId, newContent, newVersion);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"edit\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n newContent,\r\n version: newVersion,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_EDIT_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to edit message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async remove(entryId: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only remove your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n chatStore.applyRemove(entryId);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"remove\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REMOVE_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async react(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot add reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"add\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"add\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to add reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n async unreact(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"remove\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"remove\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncomingMessage(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (!isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid envelope received\", parsed);\r\n return;\r\n }\r\n\r\n useChatStore.getState().applyIncoming(parsed);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming message\", error);\r\n }\r\n }\r\n\r\n private handleIncomingFile(blob: Blob, filename: string, mimeType: string): void {\r\n try {\r\n const file = new File([blob], filename, { type: mimeType || blob.type });\r\n\r\n useChatStore.getState().addFile(file, filename);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming file\", error);\r\n }\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parsing errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ChatService } from \"./service\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry } from \"./types\";\r\nimport { compareEntries } from \"./utils\";\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseChatReturn {\r\n entries: ChatEntry[];\r\n isReady: boolean;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isOwnEntry: (entry: ChatEntry) => boolean;\r\n send: (content: string, file?: File) => Promise<void>;\r\n edit: (id: string, content: string) => Promise<void>;\r\n remove: (id: string) => Promise<void>;\r\n react: (id: string, emoji: string) => Promise<void>;\r\n unreact: (id: string, emoji: string) => Promise<void>;\r\n}\r\n\r\nexport function useChat(): UseChatReturn {\r\n const service = useFeatureService<ChatService>(\"chat\");\r\n\r\n const byId = useChatStore((state) => state.byId);\r\n const order = useChatStore((state) => state.order);\r\n const participantCache = useChatStore((state) => state.participantCache);\r\n\r\n const entries = useMemo(() => {\r\n return order\r\n .map((id) => byId[id])\r\n .filter((entry): entry is ChatEntry => entry !== undefined)\r\n .sort(compareEntries);\r\n }, [byId, order]);\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => {\r\n return participantCache[id] || null;\r\n },\r\n [participantCache]\r\n );\r\n\r\n const send = useCallback(\r\n async (content: string, file?: File) => service.send(content, file),\r\n [service]\r\n );\r\n\r\n const edit = useCallback(\r\n async (id: string, content: string) => service.edit(id, content),\r\n [service]\r\n );\r\n\r\n const remove = useCallback(\r\n async (id: string) => service.remove(id),\r\n [service]\r\n );\r\n\r\n const react = useCallback(\r\n async (id: string, emoji: string) => service.react(id, emoji),\r\n [service]\r\n );\r\n\r\n const unreact = useCallback(\r\n async (id: string, emoji: string) => service.unreact(id, emoji),\r\n [service]\r\n );\r\n\r\n const isOwnEntry = useCallback(\r\n (entry: ChatEntry) => entry.sender.id === service.getLocalParticipantId(),\r\n [service]\r\n );\r\n\r\n return {\r\n entries,\r\n isReady: true,\r\n getParticipantInfo,\r\n isOwnEntry,\r\n send,\r\n edit,\r\n remove,\r\n react,\r\n unreact,\r\n };\r\n}\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport type {\r\n ParticipantReaction,\r\n ReactionEnvelope,\r\n ReactionsState,\r\n} from \"./types\";\r\n\r\ninterface ReactionsActions {\r\n setReaction: (participantId: string, reaction: ParticipantReaction) => void;\r\n clearReaction: (participantId: string) => void;\r\n upsertParticipantInfo: (id: string, info: ParticipantMetadata) => void;\r\n pruneExpired: (now?: number) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst defaultState: ReactionsState = {\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: 4000,\r\n};\r\n\r\nexport const useReactionsStore = create<ReactionsState & ReactionsActions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n setReaction: (participantId, reaction) =>\r\n set((state) => {\r\n state.reactions.set(participantId, reaction);\r\n }),\r\n\r\n clearReaction: (participantId) =>\r\n set((state) => {\r\n state.reactions.delete(participantId);\r\n }),\r\n\r\n upsertParticipantInfo: (id, info) =>\r\n set((state) => {\r\n state.participantCache[id] = info;\r\n }),\r\n\r\n pruneExpired: (now = Date.now()) =>\r\n set((state) => {\r\n const entries = Array.from(state.reactions.entries());\r\n for (const [participantId, reaction] of entries) {\r\n if (reaction.ts + state.ttlMs < now) {\r\n state.reactions.delete(participantId);\r\n }\r\n }\r\n }),\r\n\r\n clear: () =>\r\n set(() => ({\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: defaultState.ttlMs,\r\n })),\r\n }))\r\n);\r\n\r\nexport function applyIncomingReaction(envelope: ReactionEnvelope): void {\r\n const { upsertParticipantInfo, setReaction } = useReactionsStore.getState();\r\n\r\n if (envelope.sender.info) {\r\n upsertParticipantInfo(envelope.sender.id, envelope.sender.info);\r\n }\r\n\r\n setReaction(envelope.sender.id, {\r\n emoji: envelope.payload.emoji,\r\n ts: Date.now(),\r\n nonce: envelope.payload.nonce,\r\n });\r\n}\r\n","import { createLogger } from \"../../utils\";\r\n\r\nexport const logger = createLogger(\"reactions\");\r\n\r\nexport function validateEmoji(emoji: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (!emoji || typeof emoji !== \"string\") {\r\n return { valid: false, error: \"empty\" };\r\n }\r\n if (emoji.length > 10) {\r\n return { valid: false, error: \"too long\" };\r\n }\r\n return { valid: true };\r\n}\r\n\r\nexport function generateNonce(): string {\r\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { applyIncomingReaction, useReactionsStore } from \"./store\";\r\nimport type { ReactionEnvelope } from \"./types\";\r\nimport { generateNonce, validateEmoji } from \"./utils\";\r\n\r\nconst logger = createLogger(\"reactions\");\r\n\r\nexport class ReactionsService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n private pruneInterval: ReturnType<typeof setInterval> | undefined;\r\n private lastSendAt = 0;\r\n private minIntervalMs = 200;\r\n private lastRemoteTs = new Map<string, number>();\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private canSendNow(): boolean {\r\n const now = Date.now();\r\n if (now - this.lastSendAt < this.minIntervalMs) return false;\r\n this.lastSendAt = now;\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) return;\r\n\r\n this.room.registerTextStreamHandler(\"reactions:v1\", async (reader) => {\r\n try {\r\n const text = await reader.readAll();\r\n this.handleIncoming(text);\r\n } catch (err) {\r\n logger.error(\"Error reading reactions stream\", err);\r\n }\r\n });\r\n\r\n this.pruneInterval = setInterval(() => {\r\n useReactionsStore.getState().pruneExpired();\r\n }, 1000);\r\n\r\n this.isSubscribed = true;\r\n logger.info(\"ReactionsService subscribed\");\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n if (this.pruneInterval) {\r\n clearInterval(this.pruneInterval);\r\n this.pruneInterval = undefined;\r\n }\r\n logger.info(\"ReactionsService unsubscribed\");\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async sendReaction(emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_ROOM_NOT_READY\",\r\n message: \"Cannot send reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateEmoji(emoji);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_INVALID_EMOJI\",\r\n message: validation.error || \"Invalid emoji\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (!this.canSendNow()) {\r\n logger.debug(\"Rate limited, skipping send\");\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n const ts = Date.now();\r\n const nonce = generateNonce();\r\n\r\n useReactionsStore.getState().setReaction(senderInfo.id, {\r\n emoji,\r\n ts,\r\n nonce,\r\n });\r\n\r\n try {\r\n const envelope: ReactionEnvelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n ts,\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n nonce,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"reactions:v1\",\r\n });\r\n\r\n logger.debug(\"Reaction sent\", { emoji });\r\n } catch (error) {\r\n logger.error(\"Failed to send reaction\", error);\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send reaction\",\r\n timestamp: Date.now(),\r\n context: { emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncoming(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text) as ReactionEnvelope;\r\n if (!this.isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid reaction envelope received\", parsed);\r\n return;\r\n }\r\n\r\n if (parsed.sender.id === this.getLocalParticipantId()) {\r\n logger.debug(\"Ignoring self-echo reaction\");\r\n return;\r\n }\r\n\r\n const lastTs =\r\n this.lastRemoteTs.get(parsed.sender.id) ?? Number.NEGATIVE_INFINITY;\r\n if (parsed.ts < lastTs) {\r\n logger.debug(\"Ignoring out-of-order reaction\", {\r\n sender: parsed.sender.id,\r\n ts: parsed.ts,\r\n lastTs,\r\n });\r\n return;\r\n }\r\n this.lastRemoteTs.set(parsed.sender.id, parsed.ts);\r\n applyIncomingReaction(parsed);\r\n logger.debug(\"Reaction received\", { emoji: parsed.payload.emoji });\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming reaction\", error);\r\n }\r\n }\r\n\r\n private isValidEnvelope(e: any): e is ReactionEnvelope {\r\n return (\r\n e &&\r\n e.v === 1 &&\r\n e.kind === \"reaction\" &&\r\n typeof e.roomId === \"string\" &&\r\n e.roomId === this.room.name &&\r\n typeof e.ts === \"number\" &&\r\n e.ts > 0 &&\r\n typeof e.sender?.id === \"string\" &&\r\n typeof e.payload?.emoji === \"string\" &&\r\n typeof e.payload?.nonce === \"string\"\r\n );\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parse errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ReactionsService } from \"./service\";\r\nimport { useReactionsStore } from \"./store\";\r\n\r\nconst logger = createLogger(\"reactions:hook\");\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseReactionsReturn {\r\n sendReaction: (emoji: string) => Promise<void>;\r\n getReactionFor: (participantId: string) => Nullable<string>;\r\n clearReaction: (participantId: string) => void;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isReady: boolean;\r\n}\r\n\r\nexport function useReactions(): UseReactionsReturn {\r\n const service = useFeatureService<ReactionsService>(\"reactions\");\r\n\r\n const reactions = useReactionsStore((state) => state.reactions);\r\n const participantCache = useReactionsStore((state) => state.participantCache);\r\n\r\n const getReactionFor = useCallback(\r\n (participantId: string): Nullable<string> => {\r\n const reaction = reactions.get(participantId);\r\n return reaction?.emoji ?? null;\r\n },\r\n [reactions]\r\n );\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => participantCache[id] || null,\r\n [participantCache]\r\n );\r\n\r\n const sendReaction = useCallback(\r\n async (emoji: string) => {\r\n if (!service) {\r\n logger.error(\"Cannot send reaction: service not ready\");\r\n return;\r\n }\r\n return service.sendReaction(emoji);\r\n },\r\n [service]\r\n );\r\n\r\n const clearReaction = useCallback((participantId: string) => {\r\n useReactionsStore.getState().clearReaction(participantId);\r\n }, []);\r\n\r\n return {\r\n sendReaction,\r\n getReactionFor,\r\n clearReaction,\r\n getParticipantInfo,\r\n isReady: !!service,\r\n };\r\n}\r\n","import type { Room } from \"livekit-client\";\r\nimport { ChatService, useChatStore } from \"./chat\";\r\nimport { ReactionsService, useReactionsStore } from \"./reactions\";\r\nimport type { RealtimeFeature } from \"./types\";\r\n\r\nexport const FEATURES: Record<string, RealtimeFeature> = {\r\n chat: {\r\n name: \"chat\",\r\n createService: (room: Room) => new ChatService(room),\r\n cleanupStore: () => useChatStore.getState().clearChat(),\r\n },\r\n reactions: {\r\n name: \"reactions\",\r\n createService: (room: Room) => new ReactionsService(room),\r\n cleanupStore: () => useReactionsStore.getState().clear(),\r\n },\r\n};\r\n\r\nexport const DEFAULT_FEATURES = [\"chat\", \"reactions\"];\r\n","import type { Room } from \"livekit-client\";\r\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { createLogger } from \"../utils\";\r\nimport {\r\n DataChannelContext,\r\n type DataChannelContextValue,\r\n} from \"./DataChannelContext\";\r\nimport { DEFAULT_FEATURES, FEATURES } from \"./registry\";\r\n\r\nconst logger = createLogger(\"channels:provider\");\r\n\r\nexport interface DataChannelProviderProps {\r\n room: Room;\r\n features?: string[];\r\n children: ReactNode;\r\n}\r\n\r\nexport function DataChannelProvider({\r\n room,\r\n features = DEFAULT_FEATURES,\r\n children,\r\n}: DataChannelProviderProps) {\r\n const services = useRef<Map<string, any>>(new Map());\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!room) {\r\n logger.warn(\"DataChannelProvider mounted without room\");\r\n return;\r\n }\r\n\r\n logger.debug(\"Initializing features\", { features });\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n\r\n if (!feature) {\r\n logger.warn(`Feature \"${featureName}\" not found in registry`);\r\n continue;\r\n }\r\n\r\n try {\r\n logger.debug(`Initializing feature: ${featureName}`);\r\n const service = feature.createService(room);\r\n\r\n service.subscribe();\r\n services.current.set(featureName, service);\r\n\r\n logger.info(`Feature \"${featureName}\" initialized`);\r\n } catch (error) {\r\n logger.error(`Failed to initialize feature \"${featureName}\"`, error);\r\n }\r\n }\r\n\r\n setIsReady(true);\r\n logger.info(\"All features initialized\");\r\n return () => {\r\n logger.debug(\"Cleaning up features\");\r\n\r\n // Unsubscribe all services\r\n services.current.forEach((service, name) => {\r\n try {\r\n logger.debug(`Unsubscribing feature: ${name}`);\r\n service.unsubscribe();\r\n } catch (error) {\r\n logger.error(`Failed to unsubscribe feature \"${name}\"`, error);\r\n }\r\n });\r\n\r\n // Clean up stores\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n if (feature?.cleanupStore) {\r\n try {\r\n logger.debug(`Cleaning store for feature: ${featureName}`);\r\n feature.cleanupStore();\r\n } catch (error) {\r\n logger.error(`Failed to cleanup store for \"${featureName}\"`, error);\r\n }\r\n }\r\n }\r\n\r\n services.current.clear();\r\n setIsReady(false);\r\n logger.info(\"Features cleanup complete\");\r\n };\r\n }, [room, features]);\r\n\r\n const contextValue = useMemo<DataChannelContextValue>(\r\n () => ({\r\n services: services.current,\r\n isReady,\r\n }),\r\n [isReady]\r\n );\r\n\r\n return (\r\n <DataChannelContext.Provider value={contextValue}>\r\n {children}\r\n </DataChannelContext.Provider>\r\n );\r\n}\r\n"]}
@@ -33,12 +33,13 @@ declare class ChatService {
33
33
  subscribe(): void;
34
34
  unsubscribe(): void;
35
35
  getLocalParticipantId(): string;
36
- send(content: string): Promise<void>;
36
+ send(content: string, file?: File): Promise<void>;
37
37
  edit(entryId: string, newContent: string): Promise<void>;
38
38
  remove(entryId: string): Promise<void>;
39
39
  react(entryId: string, emoji: string): Promise<void>;
40
40
  unreact(entryId: string, emoji: string): Promise<void>;
41
41
  private handleIncomingMessage;
42
+ private handleIncomingFile;
42
43
  private getSenderInfo;
43
44
  }
44
45
 
@@ -91,6 +92,8 @@ interface ChatEntry {
91
92
  version: number;
92
93
  reactions: Record<string, Set<string>>;
93
94
  status: ChatEntryStatus;
95
+ filename?: string;
96
+ file?: File;
94
97
  }
95
98
  interface ChatState {
96
99
  byId: Record<string, ChatEntry>;
@@ -103,6 +106,7 @@ interface ChatState {
103
106
  interface ChatActions {
104
107
  patch: (fn: (draft: ChatState) => void) => void;
105
108
  applyIncoming: (envelope: Envelope) => void;
109
+ addFile: (file: File, filename: string) => void;
106
110
  addEntryOptimistic: (entry: ChatEntry) => void;
107
111
  markEntrySent: (entryId: string) => void;
108
112
  markEntryFailed: (entryId: string) => void;
@@ -124,7 +128,7 @@ interface UseChatReturn {
124
128
  isReady: boolean;
125
129
  getParticipantInfo: (id: string) => Nullable$1<ParticipantMetadata>;
126
130
  isOwnEntry: (entry: ChatEntry) => boolean;
127
- send: (content: string) => Promise<void>;
131
+ send: (content: string, file?: File) => Promise<void>;
128
132
  edit: (id: string, content: string) => Promise<void>;
129
133
  remove: (id: string) => Promise<void>;
130
134
  react: (id: string, emoji: string) => Promise<void>;
@@ -33,12 +33,13 @@ declare class ChatService {
33
33
  subscribe(): void;
34
34
  unsubscribe(): void;
35
35
  getLocalParticipantId(): string;
36
- send(content: string): Promise<void>;
36
+ send(content: string, file?: File): Promise<void>;
37
37
  edit(entryId: string, newContent: string): Promise<void>;
38
38
  remove(entryId: string): Promise<void>;
39
39
  react(entryId: string, emoji: string): Promise<void>;
40
40
  unreact(entryId: string, emoji: string): Promise<void>;
41
41
  private handleIncomingMessage;
42
+ private handleIncomingFile;
42
43
  private getSenderInfo;
43
44
  }
44
45
 
@@ -91,6 +92,8 @@ interface ChatEntry {
91
92
  version: number;
92
93
  reactions: Record<string, Set<string>>;
93
94
  status: ChatEntryStatus;
95
+ filename?: string;
96
+ file?: File;
94
97
  }
95
98
  interface ChatState {
96
99
  byId: Record<string, ChatEntry>;
@@ -103,6 +106,7 @@ interface ChatState {
103
106
  interface ChatActions {
104
107
  patch: (fn: (draft: ChatState) => void) => void;
105
108
  applyIncoming: (envelope: Envelope) => void;
109
+ addFile: (file: File, filename: string) => void;
106
110
  addEntryOptimistic: (entry: ChatEntry) => void;
107
111
  markEntrySent: (entryId: string) => void;
108
112
  markEntryFailed: (entryId: string) => void;
@@ -124,7 +128,7 @@ interface UseChatReturn {
124
128
  isReady: boolean;
125
129
  getParticipantInfo: (id: string) => Nullable$1<ParticipantMetadata>;
126
130
  isOwnEntry: (entry: ChatEntry) => boolean;
127
- send: (content: string) => Promise<void>;
131
+ send: (content: string, file?: File) => Promise<void>;
128
132
  edit: (id: string, content: string) => Promise<void>;
129
133
  remove: (id: string) => Promise<void>;
130
134
  react: (id: string, emoji: string) => Promise<void>;
@@ -212,7 +212,8 @@ var useChatStore = create()(
212
212
  createdAt: envelope.ts,
213
213
  version: 1,
214
214
  reactions: {},
215
- status: "sent"
215
+ status: "sent",
216
+ filename: envelope.payload?.meta?.filename
216
217
  };
217
218
  state.byId[envelope.entryId] = entry;
218
219
  state.order.push(envelope.entryId);
@@ -295,6 +296,13 @@ var useChatStore = create()(
295
296
  }
296
297
  }
297
298
  }),
299
+ addFile: (file, filename) => set((state) => {
300
+ const values = Object.values(state.byId);
301
+ const entryArr = values.filter((val) => val.filename === filename);
302
+ const entry = entryArr[0];
303
+ entry.file = file;
304
+ state.byId[entry.id] = entry;
305
+ }),
298
306
  addEntryOptimistic: (entry) => set((state) => {
299
307
  state.byId[entry.id] = entry;
300
308
  state.order.push(entry.id);
@@ -468,6 +476,27 @@ var ChatService = class {
468
476
  }
469
477
  }
470
478
  );
479
+ this.room.registerByteStreamHandler("chat:v1", async (reader, participantInfo) => {
480
+ try {
481
+ const info = reader.info;
482
+ const filename = info.name;
483
+ reader.onProgress = (progress) => {
484
+ console.log(`${progress ? (progress * 100).toFixed(0) : "undefined"}% of ${filename} downloaded`);
485
+ };
486
+ const parts = (await reader.readAll()).map((chunk) => chunk.slice());
487
+ const fileBlob = new Blob(parts, { type: info.mimeType });
488
+ this.handleIncomingFile(fileBlob, filename, info.mimeType);
489
+ console.log(
490
+ `File "${info.name}" received from ${participantInfo.identity}
491
+ Topic: ${info.topic}
492
+ Timestamp: ${info.timestamp}
493
+ ID: ${info.id}
494
+ Size: ${info.size}`
495
+ );
496
+ } catch (error) {
497
+ logger.error("Error reading file stream", error);
498
+ }
499
+ });
471
500
  this.isSubscribed = true;
472
501
  }
473
502
  unsubscribe() {
@@ -476,7 +505,7 @@ var ChatService = class {
476
505
  getLocalParticipantId() {
477
506
  return this.room.localParticipant.identity;
478
507
  }
479
- async send(content) {
508
+ async send(content, file) {
480
509
  if (!this.isRoomReady()) {
481
510
  useRtcStore.getState().addError({
482
511
  code: "CHAT_ROOM_NOT_READY",
@@ -485,6 +514,10 @@ var ChatService = class {
485
514
  });
486
515
  return;
487
516
  }
517
+ if (content.length === 0 && typeof file !== "undefined") {
518
+ console.log("file present", typeof file);
519
+ content = file.name;
520
+ }
488
521
  const validation = validateContent(content);
489
522
  if (!validation.valid) {
490
523
  useRtcStore.getState().addError({
@@ -511,7 +544,8 @@ var ChatService = class {
511
544
  createdAt: getCurrentTimestamp(),
512
545
  version: 1,
513
546
  reactions: {},
514
- status: "sending"
547
+ status: "sending",
548
+ file
515
549
  };
516
550
  chatStore.addEntryOptimistic(entry);
517
551
  try {
@@ -523,12 +557,20 @@ var ChatService = class {
523
557
  ts: entry.createdAt,
524
558
  sender: senderInfo,
525
559
  payload: {
526
- content
560
+ content,
561
+ meta: { filename: file?.name }
527
562
  }
528
563
  };
529
564
  await this.room.localParticipant.sendText(JSON.stringify(envelope), {
530
565
  topic: "chat:v1"
531
566
  });
567
+ console.log("Sent message", entry, envelope);
568
+ if (file) {
569
+ await this.room.localParticipant.sendFile(file, {
570
+ mimeType: file.type,
571
+ topic: "chat:v1"
572
+ });
573
+ }
532
574
  chatStore.markEntrySent(entryId);
533
575
  } catch (error) {
534
576
  chatStore.markEntryFailed(entryId);
@@ -762,6 +804,14 @@ var ChatService = class {
762
804
  logger.error("Error parsing incoming message", error);
763
805
  }
764
806
  }
807
+ handleIncomingFile(blob, filename, mimeType) {
808
+ try {
809
+ const file = new File([blob], filename, { type: mimeType || blob.type });
810
+ useChatStore.getState().addFile(file, filename);
811
+ } catch (error) {
812
+ logger.error("Error parsing incoming file", error);
813
+ }
814
+ }
765
815
  getSenderInfo() {
766
816
  const localParticipant = this.room.localParticipant;
767
817
  const sender = {
@@ -793,7 +843,7 @@ function useChat() {
793
843
  [participantCache]
794
844
  );
795
845
  const send = useCallback(
796
- async (content) => service.send(content),
846
+ async (content, file) => service.send(content, file),
797
847
  [service]
798
848
  );
799
849
  const edit = useCallback(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts","../../src/channel/DataChannelContext.ts","../../src/state/types.ts","../../src/state/store.ts","../../src/channel/chat/store.ts","../../src/channel/chat/utils.ts","../../src/channel/chat/service.ts","../../src/channel/chat/useChat.ts","../../src/channel/reactions/store.ts","../../src/channel/reactions/utils.ts","../../src/channel/reactions/service.ts","../../src/channel/reactions/useReactions.ts","../../src/channel/registry.ts","../../src/channel/DataChannelProvider.tsx"],"names":["create","immer","entry","defaultState","logger","ConnectionState","useCallback","useMemo"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Comprehensive logging system for the Callpad Web SDK\r\n *\r\n * Features:\r\n * - Log level filtering (debug, info, warn, error)\r\n * - Environment variable configuration (DEBUG, CALLPAD_LOG_LEVEL)\r\n * - Hierarchical namespacing (callpad:socket:connection)\r\n * - Custom logger integration\r\n * - Zero-cost when disabled\r\n */\r\n\r\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\r\n\r\nexport interface LoggerOptions {\r\n level?: LogLevel;\r\n enableDebug?: boolean;\r\n customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n}\r\n\r\nexport interface CallpadLogger {\r\n debug(message: string, meta?: any): void;\r\n info(message: string, meta?: any): void;\r\n warn(message: string, meta?: any): void;\r\n error(message: string, meta?: any): void;\r\n child(namespace: string): CallpadLogger;\r\n setLevel(level: LogLevel): void;\r\n isLevelEnabled(level: LogLevel): boolean;\r\n}\r\n\r\nconst LOG_LEVELS: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n};\r\n\r\nclass CallpadLoggerImpl implements CallpadLogger {\r\n private namespace: string;\r\n private level: LogLevel;\r\n private enableDebug: boolean;\r\n private customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n\r\n constructor(namespace = \"callpad\", options: LoggerOptions = {}) {\r\n this.namespace = namespace;\r\n this.level = options.level ?? this.getDefaultLevel();\r\n this.enableDebug = options.enableDebug ?? this.shouldEnableDebug();\r\n if (options.customLogger) {\r\n this.customLogger = options.customLogger;\r\n }\r\n }\r\n\r\n private getDefaultLevel(): LogLevel {\r\n const envLevel =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__CALLPAD_LOG_LEVEL__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.CALLPAD_LOG_LEVEL;\r\n\r\n if (envLevel && this.isValidLogLevel(envLevel)) {\r\n return envLevel as LogLevel;\r\n }\r\n\r\n const isProduction =\r\n typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.NODE_ENV === \"production\";\r\n\r\n return isProduction ? \"warn\" : \"info\";\r\n }\r\n\r\n private shouldEnableDebug(): boolean {\r\n const debugEnv =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__DEBUG__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.DEBUG;\r\n\r\n if (!debugEnv) return false;\r\n\r\n const debugPatterns = debugEnv.split(/[\\s,]+/);\r\n return debugPatterns.some((pattern: string) => {\r\n if (pattern === \"*\") return true;\r\n if (pattern.endsWith(\"*\")) {\r\n const prefix = pattern.slice(0, -1);\r\n return this.namespace.startsWith(prefix);\r\n }\r\n return this.namespace === pattern;\r\n });\r\n }\r\n\r\n private isValidLogLevel(level: string): boolean {\r\n return Object.keys(LOG_LEVELS).includes(level);\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n if (level === \"debug\" && !this.enableDebug) {\r\n return false;\r\n }\r\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level];\r\n }\r\n\r\n private formatMessage(level: LogLevel, message: string, meta?: any): void {\r\n if (!this.shouldLog(level)) return;\r\n\r\n const timestamp = new Date().toISOString();\r\n const prefix = `[${timestamp}] [${this.namespace}] [${level.toUpperCase()}]`;\r\n\r\n if (this.customLogger) {\r\n this.customLogger(level, message, meta);\r\n return;\r\n }\r\n\r\n const logMethod =\r\n level === \"error\"\r\n ? console.error\r\n : level === \"warn\"\r\n ? console.warn\r\n : level === \"info\"\r\n ? console.info\r\n : console.log;\r\n\r\n if (meta !== undefined) {\r\n logMethod(`${prefix} ${message}`, meta);\r\n } else {\r\n logMethod(`${prefix} ${message}`);\r\n }\r\n }\r\n\r\n debug(message: string, meta?: any): void {\r\n this.formatMessage(\"debug\", message, meta);\r\n }\r\n\r\n info(message: string, meta?: any): void {\r\n this.formatMessage(\"info\", message, meta);\r\n }\r\n\r\n warn(message: string, meta?: any): void {\r\n this.formatMessage(\"warn\", message, meta);\r\n }\r\n\r\n error(message: string, meta?: any): void {\r\n this.formatMessage(\"error\", message, meta);\r\n }\r\n\r\n child(namespace: string): CallpadLogger {\r\n const childNamespace = `${this.namespace}:${namespace}`;\r\n const childOptions: LoggerOptions = {\r\n level: this.level,\r\n enableDebug: this.enableDebug,\r\n };\r\n if (this.customLogger) {\r\n childOptions.customLogger = this.customLogger;\r\n }\r\n return new CallpadLoggerImpl(childNamespace, childOptions);\r\n }\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n isLevelEnabled(level: LogLevel): boolean {\r\n return this.shouldLog(level);\r\n }\r\n}\r\n\r\nlet rootLogger: CallpadLogger | null = null;\r\n\r\nexport function createLogger(\r\n namespace?: string,\r\n options?: LoggerOptions\r\n): CallpadLogger {\r\n if (!namespace) {\r\n if (!rootLogger) {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n }\r\n return rootLogger;\r\n }\r\n\r\n return new CallpadLoggerImpl(`callpad:${namespace}`, options);\r\n}\r\n\r\nexport function setGlobalLoggerOptions(options: LoggerOptions): void {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n}\r\n","import { createContext, useContext } from \"react\";\r\n\r\nexport interface DataChannelContextValue {\r\n services: Map<string, any>;\r\n isReady: boolean;\r\n}\r\n\r\nexport const DataChannelContext = createContext<DataChannelContextValue | null>(\r\n null\r\n);\r\n\r\nexport function useDataChannelContext(): DataChannelContextValue {\r\n const context = useContext(DataChannelContext);\r\n if (!context) {\r\n throw new Error(\r\n \"useDataChannelContext must be used within DataChannelProvider\"\r\n );\r\n }\r\n return context;\r\n}\r\n\r\nexport function useFeatureService<T = any>(featureName: string): T {\r\n const { services } = useDataChannelContext();\r\n const service = services.get(featureName) as T;\r\n if (!service) {\r\n throw new Error(\r\n `Feature service \"${featureName}\" not found. Make sure it's enabled in DataChannelProvider.`\r\n );\r\n }\r\n\r\n return service;\r\n}\r\n","type Nullable<T> = T | null;\r\n\r\nexport type CallParticipantRole = \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n\r\nexport interface Profile {\r\n userId: string;\r\n username: string | null;\r\n firstName: string | null;\r\n lastName: string | null;\r\n profilePhoto: string | null;\r\n}\r\n\r\nexport interface ParticipantPermissions {\r\n canMute: boolean;\r\n canKick: boolean;\r\n canTransfer: boolean;\r\n canEnd: boolean;\r\n canRecord: boolean;\r\n canShareScreen: boolean;\r\n}\r\n\r\nexport interface ParticipantMetadata {\r\n userId: string | number;\r\n firstName: Nullable<string>;\r\n lastName: Nullable<string>;\r\n username: Nullable<string>;\r\n email: Nullable<string>;\r\n profilePhoto: Nullable<string>;\r\n role: CallParticipantRole;\r\n permissions: ParticipantPermissions;\r\n}\r\n\r\nexport interface LiveKitJoinInfo {\r\n token: string;\r\n roomName: string;\r\n url: string;\r\n}\r\n\r\nexport interface Session {\r\n id: string;\r\n status: \"initializing\" | \"pending\" | \"ready\" | \"active\" | \"ended\";\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n role: \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n livekitInfo?: LiveKitJoinInfo;\r\n startedAt?: string;\r\n ringTimeoutMs?: number;\r\n}\r\n\r\nexport interface IncomingInvite {\r\n callId: string;\r\n inviteId: string;\r\n caller: ParticipantMetadata;\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n expiresAt: string;\r\n expiresInMs: number;\r\n ringTimeoutMs: number;\r\n}\r\n\r\nexport interface OutgoingInvite {\r\n userId: string;\r\n status: \"sent\" | \"accepted\" | \"declined\" | \"missed\";\r\n participant?: Omit<ParticipantMetadata, \"permissions\"> | undefined;\r\n}\r\n\r\nexport interface RtcError {\r\n code: string;\r\n message: string;\r\n timestamp: number;\r\n context?: any;\r\n}\r\n\r\nexport interface RtcState {\r\n // Did we initiate the current call?\r\n initiated: boolean;\r\n\r\n // Active session (null when no active call)\r\n session: Session | null;\r\n\r\n // Incoming invitation (null when no pending invite)\r\n incomingInvite: IncomingInvite | null;\r\n\r\n outgoingInvites: Record<string, OutgoingInvite>;\r\n\r\n // Error tracking\r\n errors: RtcError[];\r\n}\r\n\r\nexport const defaultState: RtcState = {\r\n initiated: false,\r\n session: null,\r\n incomingInvite: null,\r\n outgoingInvites: {},\r\n errors: [],\r\n};\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { RtcError, RtcState } from \"./types\";\r\nimport { defaultState } from \"./types\";\r\n\r\ntype Actions = {\r\n patch: (fn: (draft: RtcState) => void) => void;\r\n reset: () => void;\r\n addError: (error: RtcError) => void;\r\n clearErrors: () => void;\r\n};\r\n\r\nexport const useRtcStore = create<RtcState & Actions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n reset: () => set(() => defaultState),\r\n\r\n addError: (error) =>\r\n set((state) => {\r\n state.errors.push(error);\r\n }),\r\n\r\n clearErrors: () =>\r\n set((state) => {\r\n state.errors = [];\r\n }),\r\n }))\r\n);\r\n\r\nexport const rtcStore = useRtcStore;\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ChatEntry, ChatState, Envelope } from \"./types\";\r\n\r\ninterface ChatActions {\r\n patch: (fn: (draft: ChatState) => void) => void;\r\n applyIncoming: (envelope: Envelope) => void;\r\n addEntryOptimistic: (entry: ChatEntry) => void;\r\n markEntrySent: (entryId: string) => void;\r\n markEntryFailed: (entryId: string) => void;\r\n applyEdit: (entryId: string, newContent: string, version: number) => void;\r\n applyRemove: (entryId: string) => void;\r\n applyReaction: (\r\n entryId: string,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n ) => void;\r\n queuePendingOp: (entryId: string, envelope: Envelope) => void;\r\n processPendingOps: (entryId: string) => void;\r\n trimOldEntries: () => void;\r\n clearChat: () => void;\r\n}\r\n\r\nconst defaultChatState: ChatState = {\r\n byId: {},\r\n order: [],\r\n pendingOps: {},\r\n participantCache: {},\r\n maxEntries: 1000,\r\n};\r\n\r\nfunction applyReactionToEntry(\r\n entry: ChatEntry,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n) {\r\n const emojiSet = entry.reactions[emoji];\r\n if (!emojiSet) {\r\n entry.reactions[emoji] = new Set();\r\n }\r\n if (op === \"add\") {\r\n entry.reactions[emoji]?.add(participantId);\r\n } else {\r\n entry.reactions[emoji]?.delete(participantId);\r\n if (entry.reactions[emoji]?.size === 0) {\r\n delete entry.reactions[emoji];\r\n }\r\n }\r\n}\r\n\r\nfunction trimEntriesIfNeeded(state: ChatState) {\r\n if (Object.keys(state.byId).length > state.maxEntries) {\r\n const entriesToRemove = Object.keys(state.byId).length - state.maxEntries;\r\n for (let i = 0; i < entriesToRemove; i++) {\r\n const oldestId = state.order[i];\r\n if (oldestId) {\r\n delete state.byId[oldestId];\r\n }\r\n }\r\n state.order = state.order.slice(entriesToRemove);\r\n }\r\n}\r\n\r\nexport const useChatStore = create<ChatState & ChatActions>()(\r\n immer((set) => ({\r\n ...defaultChatState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n applyIncoming: (envelope) =>\r\n set((state) => {\r\n if (envelope.kind === \"entry\") {\r\n if (state.byId[envelope.entryId]) {\r\n return;\r\n }\r\n\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: envelope.entryId,\r\n content: envelope.payload.content,\r\n sender: {\r\n id: envelope.sender.id,\r\n },\r\n createdAt: envelope.ts,\r\n version: 1,\r\n reactions: {},\r\n status: \"sent\",\r\n };\r\n\r\n state.byId[envelope.entryId] = entry;\r\n state.order.push(envelope.entryId);\r\n\r\n trimEntriesIfNeeded(state);\r\n\r\n const pendingOps = state.pendingOps[envelope.entryId];\r\n if (pendingOps) {\r\n delete state.pendingOps[envelope.entryId];\r\n\r\n for (const op of pendingOps) {\r\n if (op.kind === \"edit\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && op.payload.version > entry.version) {\r\n entry.content = op.payload.newContent;\r\n entry.version = op.payload.version;\r\n entry.editedAt = op.ts;\r\n }\r\n } else if (op.kind === \"remove\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = op.ts;\r\n }\r\n } else if (op.kind === \"reaction\") {\r\n if (op.sender.info) {\r\n state.participantCache[op.sender.id] = op.sender.info;\r\n }\r\n\r\n const entry = state.byId[op.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n op.payload.emoji,\r\n op.sender.id,\r\n op.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }\r\n } else if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (!entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n }\r\n }),\r\n\r\n addEntryOptimistic: (entry) =>\r\n set((state) => {\r\n state.byId[entry.id] = entry;\r\n state.order.push(entry.id);\r\n\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n markEntrySent: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"sent\";\r\n }\r\n }),\r\n\r\n markEntryFailed: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"failed\";\r\n }\r\n }),\r\n\r\n applyEdit: (entryId, newContent, version) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && version > entry.version) {\r\n entry.content = newContent;\r\n entry.version = version;\r\n entry.editedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyRemove: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyReaction: (entryId, emoji, participantId, op) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n applyReactionToEntry(entry, emoji, participantId, op);\r\n }\r\n }),\r\n\r\n queuePendingOp: (entryId, envelope) =>\r\n set((state) => {\r\n if (!state.pendingOps[entryId]) {\r\n state.pendingOps[entryId] = [];\r\n }\r\n state.pendingOps[entryId].push(envelope);\r\n }),\r\n\r\n processPendingOps: (entryId) =>\r\n set((state) => {\r\n const pendingOps = state.pendingOps[entryId];\r\n if (!pendingOps) {\r\n return;\r\n }\r\n\r\n delete state.pendingOps[entryId];\r\n\r\n for (const envelope of pendingOps) {\r\n if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }),\r\n\r\n trimOldEntries: () =>\r\n set((state) => {\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n clearChat: () => set(() => defaultChatState),\r\n }))\r\n);\r\n\r\nexport const chatStore = useChatStore;\r\n","import { nanoid } from \"nanoid\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\n\r\nexport function compareEntries(a: ChatEntry, b: ChatEntry): number {\r\n if (a.createdAt !== b.createdAt) {\r\n return a.createdAt - b.createdAt;\r\n }\r\n\r\n if (a.sender.id !== b.sender.id) {\r\n return a.sender.id.localeCompare(b.sender.id);\r\n }\r\n\r\n return a.id.localeCompare(b.id);\r\n}\r\n\r\nexport function validateContent(content: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n const trimmed = content.trim();\r\n\r\n if (trimmed.length === 0) {\r\n return { valid: false, error: \"Content cannot be empty\" };\r\n }\r\n\r\n const sizeInBytes = new TextEncoder().encode(content).length;\r\n if (sizeInBytes > 16384) {\r\n return { valid: false, error: \"Content exceeds 16KB limit\" };\r\n }\r\n\r\n return { valid: true };\r\n}\r\n\r\nexport function isValidEnvelope(data: any): data is Envelope {\r\n if (!data || typeof data !== \"object\") {\r\n return false;\r\n }\r\n\r\n if (data.v !== 1) {\r\n return false;\r\n }\r\n\r\n if (![\"entry\", \"edit\", \"remove\", \"reaction\"].includes(data.kind)) {\r\n return false;\r\n }\r\n\r\n if (\r\n typeof data.roomId !== \"string\" ||\r\n typeof data.entryId !== \"string\" ||\r\n typeof data.ts !== \"number\"\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!data.sender || typeof data.sender.id !== \"string\") {\r\n return false;\r\n }\r\n\r\n if (\r\n data.kind === \"entry\" ||\r\n data.kind === \"edit\" ||\r\n data.kind === \"reaction\"\r\n ) {\r\n if (!data.payload || typeof data.payload !== \"object\") {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function generateEntryId(): string {\r\n return nanoid();\r\n}\r\n\r\nexport function getCurrentTimestamp(): number {\r\n return Date.now();\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\nimport {\r\n generateEntryId,\r\n getCurrentTimestamp,\r\n isValidEnvelope,\r\n validateContent,\r\n} from \"./utils\";\r\n\r\nconst logger = createLogger(\"chat\");\r\n\r\nexport class ChatService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) {\r\n return;\r\n }\r\n\r\n this.room.registerTextStreamHandler(\r\n \"chat:v1\",\r\n async (reader, participantInfo) => {\r\n console.log(\"Got here: chat:v1\", participantInfo.identity)\r\n try {\r\n const text = await reader.readAll();\r\n console.log(\"Got here: chat:v1\", text)\r\n this.handleIncomingMessage(text);\r\n\r\n } catch (error) {\r\n logger.error(\"Error reading text stream\", error);\r\n }\r\n }\r\n );\r\n this.isSubscribed = true;\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async send(content: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot send message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(content);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const entryId = generateEntryId();\r\n const chatStore = useChatStore.getState();\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: entryId,\r\n content,\r\n sender: {\r\n id: senderInfo.id,\r\n },\r\n createdAt: getCurrentTimestamp(),\r\n version: 1,\r\n reactions: {},\r\n status: \"sending\",\r\n };\r\n\r\n chatStore.addEntryOptimistic(entry);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"entry\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: entry.createdAt,\r\n sender: senderInfo,\r\n payload: {\r\n content,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n chatStore.markEntrySent(entryId);\r\n } catch (error) {\r\n chatStore.markEntryFailed(entryId);\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async edit(entryId: string, newContent: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot edit message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(newContent);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only edit your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const newVersion = entry.version + 1;\r\n chatStore.applyEdit(entryId, newContent, newVersion);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"edit\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n newContent,\r\n version: newVersion,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_EDIT_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to edit message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async remove(entryId: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only remove your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n chatStore.applyRemove(entryId);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"remove\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REMOVE_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async react(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot add reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"add\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"add\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to add reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n async unreact(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"remove\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"remove\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncomingMessage(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (!isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid envelope received\", parsed);\r\n return;\r\n }\r\n\r\n useChatStore.getState().applyIncoming(parsed);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming message\", error);\r\n }\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parsing errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ChatService } from \"./service\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry } from \"./types\";\r\nimport { compareEntries } from \"./utils\";\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseChatReturn {\r\n entries: ChatEntry[];\r\n isReady: boolean;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isOwnEntry: (entry: ChatEntry) => boolean;\r\n send: (content: string) => Promise<void>;\r\n edit: (id: string, content: string) => Promise<void>;\r\n remove: (id: string) => Promise<void>;\r\n react: (id: string, emoji: string) => Promise<void>;\r\n unreact: (id: string, emoji: string) => Promise<void>;\r\n}\r\n\r\nexport function useChat(): UseChatReturn {\r\n const service = useFeatureService<ChatService>(\"chat\");\r\n\r\n const byId = useChatStore((state) => state.byId);\r\n const order = useChatStore((state) => state.order);\r\n const participantCache = useChatStore((state) => state.participantCache);\r\n\r\n const entries = useMemo(() => {\r\n return order\r\n .map((id) => byId[id])\r\n .filter((entry): entry is ChatEntry => entry !== undefined)\r\n .sort(compareEntries);\r\n }, [byId, order]);\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => {\r\n return participantCache[id] || null;\r\n },\r\n [participantCache]\r\n );\r\n\r\n const send = useCallback(\r\n async (content: string) => service.send(content),\r\n [service]\r\n );\r\n\r\n const edit = useCallback(\r\n async (id: string, content: string) => service.edit(id, content),\r\n [service]\r\n );\r\n\r\n const remove = useCallback(\r\n async (id: string) => service.remove(id),\r\n [service]\r\n );\r\n\r\n const react = useCallback(\r\n async (id: string, emoji: string) => service.react(id, emoji),\r\n [service]\r\n );\r\n\r\n const unreact = useCallback(\r\n async (id: string, emoji: string) => service.unreact(id, emoji),\r\n [service]\r\n );\r\n\r\n const isOwnEntry = useCallback(\r\n (entry: ChatEntry) => entry.sender.id === service.getLocalParticipantId(),\r\n [service]\r\n );\r\n\r\n return {\r\n entries,\r\n isReady: true,\r\n getParticipantInfo,\r\n isOwnEntry,\r\n send,\r\n edit,\r\n remove,\r\n react,\r\n unreact,\r\n };\r\n}\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport type {\r\n ParticipantReaction,\r\n ReactionEnvelope,\r\n ReactionsState,\r\n} from \"./types\";\r\n\r\ninterface ReactionsActions {\r\n setReaction: (participantId: string, reaction: ParticipantReaction) => void;\r\n clearReaction: (participantId: string) => void;\r\n upsertParticipantInfo: (id: string, info: ParticipantMetadata) => void;\r\n pruneExpired: (now?: number) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst defaultState: ReactionsState = {\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: 4000,\r\n};\r\n\r\nexport const useReactionsStore = create<ReactionsState & ReactionsActions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n setReaction: (participantId, reaction) =>\r\n set((state) => {\r\n state.reactions.set(participantId, reaction);\r\n }),\r\n\r\n clearReaction: (participantId) =>\r\n set((state) => {\r\n state.reactions.delete(participantId);\r\n }),\r\n\r\n upsertParticipantInfo: (id, info) =>\r\n set((state) => {\r\n state.participantCache[id] = info;\r\n }),\r\n\r\n pruneExpired: (now = Date.now()) =>\r\n set((state) => {\r\n const entries = Array.from(state.reactions.entries());\r\n for (const [participantId, reaction] of entries) {\r\n if (reaction.ts + state.ttlMs < now) {\r\n state.reactions.delete(participantId);\r\n }\r\n }\r\n }),\r\n\r\n clear: () =>\r\n set(() => ({\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: defaultState.ttlMs,\r\n })),\r\n }))\r\n);\r\n\r\nexport function applyIncomingReaction(envelope: ReactionEnvelope): void {\r\n const { upsertParticipantInfo, setReaction } = useReactionsStore.getState();\r\n\r\n if (envelope.sender.info) {\r\n upsertParticipantInfo(envelope.sender.id, envelope.sender.info);\r\n }\r\n\r\n setReaction(envelope.sender.id, {\r\n emoji: envelope.payload.emoji,\r\n ts: Date.now(),\r\n nonce: envelope.payload.nonce,\r\n });\r\n}\r\n","import { createLogger } from \"../../utils\";\r\n\r\nexport const logger = createLogger(\"reactions\");\r\n\r\nexport function validateEmoji(emoji: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (!emoji || typeof emoji !== \"string\") {\r\n return { valid: false, error: \"empty\" };\r\n }\r\n if (emoji.length > 10) {\r\n return { valid: false, error: \"too long\" };\r\n }\r\n return { valid: true };\r\n}\r\n\r\nexport function generateNonce(): string {\r\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { applyIncomingReaction, useReactionsStore } from \"./store\";\r\nimport type { ReactionEnvelope } from \"./types\";\r\nimport { generateNonce, validateEmoji } from \"./utils\";\r\n\r\nconst logger = createLogger(\"reactions\");\r\n\r\nexport class ReactionsService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n private pruneInterval: ReturnType<typeof setInterval> | undefined;\r\n private lastSendAt = 0;\r\n private minIntervalMs = 200;\r\n private lastRemoteTs = new Map<string, number>();\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private canSendNow(): boolean {\r\n const now = Date.now();\r\n if (now - this.lastSendAt < this.minIntervalMs) return false;\r\n this.lastSendAt = now;\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) return;\r\n\r\n this.room.registerTextStreamHandler(\"reactions:v1\", async (reader) => {\r\n try {\r\n const text = await reader.readAll();\r\n this.handleIncoming(text);\r\n } catch (err) {\r\n logger.error(\"Error reading reactions stream\", err);\r\n }\r\n });\r\n\r\n this.pruneInterval = setInterval(() => {\r\n useReactionsStore.getState().pruneExpired();\r\n }, 1000);\r\n\r\n this.isSubscribed = true;\r\n logger.info(\"ReactionsService subscribed\");\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n if (this.pruneInterval) {\r\n clearInterval(this.pruneInterval);\r\n this.pruneInterval = undefined;\r\n }\r\n logger.info(\"ReactionsService unsubscribed\");\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async sendReaction(emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_ROOM_NOT_READY\",\r\n message: \"Cannot send reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateEmoji(emoji);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_INVALID_EMOJI\",\r\n message: validation.error || \"Invalid emoji\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (!this.canSendNow()) {\r\n logger.debug(\"Rate limited, skipping send\");\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n const ts = Date.now();\r\n const nonce = generateNonce();\r\n\r\n useReactionsStore.getState().setReaction(senderInfo.id, {\r\n emoji,\r\n ts,\r\n nonce,\r\n });\r\n\r\n try {\r\n const envelope: ReactionEnvelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n ts,\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n nonce,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"reactions:v1\",\r\n });\r\n\r\n logger.debug(\"Reaction sent\", { emoji });\r\n } catch (error) {\r\n logger.error(\"Failed to send reaction\", error);\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send reaction\",\r\n timestamp: Date.now(),\r\n context: { emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncoming(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text) as ReactionEnvelope;\r\n if (!this.isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid reaction envelope received\", parsed);\r\n return;\r\n }\r\n\r\n if (parsed.sender.id === this.getLocalParticipantId()) {\r\n logger.debug(\"Ignoring self-echo reaction\");\r\n return;\r\n }\r\n\r\n const lastTs =\r\n this.lastRemoteTs.get(parsed.sender.id) ?? Number.NEGATIVE_INFINITY;\r\n if (parsed.ts < lastTs) {\r\n logger.debug(\"Ignoring out-of-order reaction\", {\r\n sender: parsed.sender.id,\r\n ts: parsed.ts,\r\n lastTs,\r\n });\r\n return;\r\n }\r\n this.lastRemoteTs.set(parsed.sender.id, parsed.ts);\r\n applyIncomingReaction(parsed);\r\n logger.debug(\"Reaction received\", { emoji: parsed.payload.emoji });\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming reaction\", error);\r\n }\r\n }\r\n\r\n private isValidEnvelope(e: any): e is ReactionEnvelope {\r\n return (\r\n e &&\r\n e.v === 1 &&\r\n e.kind === \"reaction\" &&\r\n typeof e.roomId === \"string\" &&\r\n e.roomId === this.room.name &&\r\n typeof e.ts === \"number\" &&\r\n e.ts > 0 &&\r\n typeof e.sender?.id === \"string\" &&\r\n typeof e.payload?.emoji === \"string\" &&\r\n typeof e.payload?.nonce === \"string\"\r\n );\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parse errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ReactionsService } from \"./service\";\r\nimport { useReactionsStore } from \"./store\";\r\n\r\nconst logger = createLogger(\"reactions:hook\");\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseReactionsReturn {\r\n sendReaction: (emoji: string) => Promise<void>;\r\n getReactionFor: (participantId: string) => Nullable<string>;\r\n clearReaction: (participantId: string) => void;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isReady: boolean;\r\n}\r\n\r\nexport function useReactions(): UseReactionsReturn {\r\n const service = useFeatureService<ReactionsService>(\"reactions\");\r\n\r\n const reactions = useReactionsStore((state) => state.reactions);\r\n const participantCache = useReactionsStore((state) => state.participantCache);\r\n\r\n const getReactionFor = useCallback(\r\n (participantId: string): Nullable<string> => {\r\n const reaction = reactions.get(participantId);\r\n return reaction?.emoji ?? null;\r\n },\r\n [reactions]\r\n );\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => participantCache[id] || null,\r\n [participantCache]\r\n );\r\n\r\n const sendReaction = useCallback(\r\n async (emoji: string) => {\r\n if (!service) {\r\n logger.error(\"Cannot send reaction: service not ready\");\r\n return;\r\n }\r\n return service.sendReaction(emoji);\r\n },\r\n [service]\r\n );\r\n\r\n const clearReaction = useCallback((participantId: string) => {\r\n useReactionsStore.getState().clearReaction(participantId);\r\n }, []);\r\n\r\n return {\r\n sendReaction,\r\n getReactionFor,\r\n clearReaction,\r\n getParticipantInfo,\r\n isReady: !!service,\r\n };\r\n}\r\n","import type { Room } from \"livekit-client\";\r\nimport { ChatService, useChatStore } from \"./chat\";\r\nimport { ReactionsService, useReactionsStore } from \"./reactions\";\r\nimport type { RealtimeFeature } from \"./types\";\r\n\r\nexport const FEATURES: Record<string, RealtimeFeature> = {\r\n chat: {\r\n name: \"chat\",\r\n createService: (room: Room) => new ChatService(room),\r\n cleanupStore: () => useChatStore.getState().clearChat(),\r\n },\r\n reactions: {\r\n name: \"reactions\",\r\n createService: (room: Room) => new ReactionsService(room),\r\n cleanupStore: () => useReactionsStore.getState().clear(),\r\n },\r\n};\r\n\r\nexport const DEFAULT_FEATURES = [\"chat\", \"reactions\"];\r\n","import type { Room } from \"livekit-client\";\r\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { createLogger } from \"../utils\";\r\nimport {\r\n DataChannelContext,\r\n type DataChannelContextValue,\r\n} from \"./DataChannelContext\";\r\nimport { DEFAULT_FEATURES, FEATURES } from \"./registry\";\r\n\r\nconst logger = createLogger(\"channels:provider\");\r\n\r\nexport interface DataChannelProviderProps {\r\n room: Room;\r\n features?: string[];\r\n children: ReactNode;\r\n}\r\n\r\nexport function DataChannelProvider({\r\n room,\r\n features = DEFAULT_FEATURES,\r\n children,\r\n}: DataChannelProviderProps) {\r\n const services = useRef<Map<string, any>>(new Map());\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!room) {\r\n logger.warn(\"DataChannelProvider mounted without room\");\r\n return;\r\n }\r\n\r\n logger.debug(\"Initializing features\", { features });\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n\r\n if (!feature) {\r\n logger.warn(`Feature \"${featureName}\" not found in registry`);\r\n continue;\r\n }\r\n\r\n try {\r\n logger.debug(`Initializing feature: ${featureName}`);\r\n const service = feature.createService(room);\r\n\r\n service.subscribe();\r\n services.current.set(featureName, service);\r\n\r\n logger.info(`Feature \"${featureName}\" initialized`);\r\n } catch (error) {\r\n logger.error(`Failed to initialize feature \"${featureName}\"`, error);\r\n }\r\n }\r\n\r\n setIsReady(true);\r\n logger.info(\"All features initialized\");\r\n return () => {\r\n logger.debug(\"Cleaning up features\");\r\n\r\n // Unsubscribe all services\r\n services.current.forEach((service, name) => {\r\n try {\r\n logger.debug(`Unsubscribing feature: ${name}`);\r\n service.unsubscribe();\r\n } catch (error) {\r\n logger.error(`Failed to unsubscribe feature \"${name}\"`, error);\r\n }\r\n });\r\n\r\n // Clean up stores\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n if (feature?.cleanupStore) {\r\n try {\r\n logger.debug(`Cleaning store for feature: ${featureName}`);\r\n feature.cleanupStore();\r\n } catch (error) {\r\n logger.error(`Failed to cleanup store for \"${featureName}\"`, error);\r\n }\r\n }\r\n }\r\n\r\n services.current.clear();\r\n setIsReady(false);\r\n logger.info(\"Features cleanup complete\");\r\n };\r\n }, [room, features]);\r\n\r\n const contextValue = useMemo<DataChannelContextValue>(\r\n () => ({\r\n services: services.current,\r\n isReady,\r\n }),\r\n [isReady]\r\n );\r\n\r\n return (\r\n <DataChannelContext.Provider value={contextValue}>\r\n {children}\r\n </DataChannelContext.Provider>\r\n );\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts","../../src/channel/DataChannelContext.ts","../../src/state/types.ts","../../src/state/store.ts","../../src/channel/chat/store.ts","../../src/channel/chat/utils.ts","../../src/channel/chat/service.ts","../../src/channel/chat/useChat.ts","../../src/channel/reactions/store.ts","../../src/channel/reactions/utils.ts","../../src/channel/reactions/service.ts","../../src/channel/reactions/useReactions.ts","../../src/channel/registry.ts","../../src/channel/DataChannelProvider.tsx"],"names":["create","immer","entry","defaultState","logger","ConnectionState","useCallback","useMemo"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Comprehensive logging system for the Callpad Web SDK\r\n *\r\n * Features:\r\n * - Log level filtering (debug, info, warn, error)\r\n * - Environment variable configuration (DEBUG, CALLPAD_LOG_LEVEL)\r\n * - Hierarchical namespacing (callpad:socket:connection)\r\n * - Custom logger integration\r\n * - Zero-cost when disabled\r\n */\r\n\r\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\r\n\r\nexport interface LoggerOptions {\r\n level?: LogLevel;\r\n enableDebug?: boolean;\r\n customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n}\r\n\r\nexport interface CallpadLogger {\r\n debug(message: string, meta?: any): void;\r\n info(message: string, meta?: any): void;\r\n warn(message: string, meta?: any): void;\r\n error(message: string, meta?: any): void;\r\n child(namespace: string): CallpadLogger;\r\n setLevel(level: LogLevel): void;\r\n isLevelEnabled(level: LogLevel): boolean;\r\n}\r\n\r\nconst LOG_LEVELS: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n};\r\n\r\nclass CallpadLoggerImpl implements CallpadLogger {\r\n private namespace: string;\r\n private level: LogLevel;\r\n private enableDebug: boolean;\r\n private customLogger?: (level: LogLevel, message: string, meta?: any) => void;\r\n\r\n constructor(namespace = \"callpad\", options: LoggerOptions = {}) {\r\n this.namespace = namespace;\r\n this.level = options.level ?? this.getDefaultLevel();\r\n this.enableDebug = options.enableDebug ?? this.shouldEnableDebug();\r\n if (options.customLogger) {\r\n this.customLogger = options.customLogger;\r\n }\r\n }\r\n\r\n private getDefaultLevel(): LogLevel {\r\n const envLevel =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__CALLPAD_LOG_LEVEL__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.CALLPAD_LOG_LEVEL;\r\n\r\n if (envLevel && this.isValidLogLevel(envLevel)) {\r\n return envLevel as LogLevel;\r\n }\r\n\r\n const isProduction =\r\n typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.NODE_ENV === \"production\";\r\n\r\n return isProduction ? \"warn\" : \"info\";\r\n }\r\n\r\n private shouldEnableDebug(): boolean {\r\n const debugEnv =\r\n typeof window !== \"undefined\"\r\n ? (window as any).__DEBUG__\r\n : typeof globalThis !== \"undefined\" &&\r\n (globalThis as any).process?.env?.DEBUG;\r\n\r\n if (!debugEnv) return false;\r\n\r\n const debugPatterns = debugEnv.split(/[\\s,]+/);\r\n return debugPatterns.some((pattern: string) => {\r\n if (pattern === \"*\") return true;\r\n if (pattern.endsWith(\"*\")) {\r\n const prefix = pattern.slice(0, -1);\r\n return this.namespace.startsWith(prefix);\r\n }\r\n return this.namespace === pattern;\r\n });\r\n }\r\n\r\n private isValidLogLevel(level: string): boolean {\r\n return Object.keys(LOG_LEVELS).includes(level);\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n if (level === \"debug\" && !this.enableDebug) {\r\n return false;\r\n }\r\n return LOG_LEVELS[level] >= LOG_LEVELS[this.level];\r\n }\r\n\r\n private formatMessage(level: LogLevel, message: string, meta?: any): void {\r\n if (!this.shouldLog(level)) return;\r\n\r\n const timestamp = new Date().toISOString();\r\n const prefix = `[${timestamp}] [${this.namespace}] [${level.toUpperCase()}]`;\r\n\r\n if (this.customLogger) {\r\n this.customLogger(level, message, meta);\r\n return;\r\n }\r\n\r\n const logMethod =\r\n level === \"error\"\r\n ? console.error\r\n : level === \"warn\"\r\n ? console.warn\r\n : level === \"info\"\r\n ? console.info\r\n : console.log;\r\n\r\n if (meta !== undefined) {\r\n logMethod(`${prefix} ${message}`, meta);\r\n } else {\r\n logMethod(`${prefix} ${message}`);\r\n }\r\n }\r\n\r\n debug(message: string, meta?: any): void {\r\n this.formatMessage(\"debug\", message, meta);\r\n }\r\n\r\n info(message: string, meta?: any): void {\r\n this.formatMessage(\"info\", message, meta);\r\n }\r\n\r\n warn(message: string, meta?: any): void {\r\n this.formatMessage(\"warn\", message, meta);\r\n }\r\n\r\n error(message: string, meta?: any): void {\r\n this.formatMessage(\"error\", message, meta);\r\n }\r\n\r\n child(namespace: string): CallpadLogger {\r\n const childNamespace = `${this.namespace}:${namespace}`;\r\n const childOptions: LoggerOptions = {\r\n level: this.level,\r\n enableDebug: this.enableDebug,\r\n };\r\n if (this.customLogger) {\r\n childOptions.customLogger = this.customLogger;\r\n }\r\n return new CallpadLoggerImpl(childNamespace, childOptions);\r\n }\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n isLevelEnabled(level: LogLevel): boolean {\r\n return this.shouldLog(level);\r\n }\r\n}\r\n\r\nlet rootLogger: CallpadLogger | null = null;\r\n\r\nexport function createLogger(\r\n namespace?: string,\r\n options?: LoggerOptions\r\n): CallpadLogger {\r\n if (!namespace) {\r\n if (!rootLogger) {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n }\r\n return rootLogger;\r\n }\r\n\r\n return new CallpadLoggerImpl(`callpad:${namespace}`, options);\r\n}\r\n\r\nexport function setGlobalLoggerOptions(options: LoggerOptions): void {\r\n rootLogger = new CallpadLoggerImpl(\"callpad\", options);\r\n}\r\n","import { createContext, useContext } from \"react\";\r\n\r\nexport interface DataChannelContextValue {\r\n services: Map<string, any>;\r\n isReady: boolean;\r\n}\r\n\r\nexport const DataChannelContext = createContext<DataChannelContextValue | null>(\r\n null\r\n);\r\n\r\nexport function useDataChannelContext(): DataChannelContextValue {\r\n const context = useContext(DataChannelContext);\r\n if (!context) {\r\n throw new Error(\r\n \"useDataChannelContext must be used within DataChannelProvider\"\r\n );\r\n }\r\n return context;\r\n}\r\n\r\nexport function useFeatureService<T = any>(featureName: string): T {\r\n const { services } = useDataChannelContext();\r\n const service = services.get(featureName) as T;\r\n if (!service) {\r\n throw new Error(\r\n `Feature service \"${featureName}\" not found. Make sure it's enabled in DataChannelProvider.`\r\n );\r\n }\r\n\r\n return service;\r\n}\r\n","type Nullable<T> = T | null;\r\n\r\nexport type CallParticipantRole = \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n\r\nexport interface Profile {\r\n userId: string;\r\n username: string | null;\r\n firstName: string | null;\r\n lastName: string | null;\r\n profilePhoto: string | null;\r\n}\r\n\r\nexport interface ParticipantPermissions {\r\n canMute: boolean;\r\n canKick: boolean;\r\n canTransfer: boolean;\r\n canEnd: boolean;\r\n canRecord: boolean;\r\n canShareScreen: boolean;\r\n}\r\n\r\nexport interface ParticipantMetadata {\r\n userId: string | number;\r\n firstName: Nullable<string>;\r\n lastName: Nullable<string>;\r\n username: Nullable<string>;\r\n email: Nullable<string>;\r\n profilePhoto: Nullable<string>;\r\n role: CallParticipantRole;\r\n permissions: ParticipantPermissions;\r\n}\r\n\r\nexport interface LiveKitJoinInfo {\r\n token: string;\r\n roomName: string;\r\n url: string;\r\n}\r\n\r\nexport interface Session {\r\n id: string;\r\n status: \"initializing\" | \"pending\" | \"ready\" | \"active\" | \"ended\";\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n role: \"HOST\" | \"PARTICIPANT\" | \"GUEST\";\r\n livekitInfo?: LiveKitJoinInfo;\r\n startedAt?: string;\r\n ringTimeoutMs?: number;\r\n}\r\n\r\nexport interface IncomingInvite {\r\n callId: string;\r\n inviteId: string;\r\n caller: ParticipantMetadata;\r\n mode: \"AUDIO\" | \"VIDEO\";\r\n expiresAt: string;\r\n expiresInMs: number;\r\n ringTimeoutMs: number;\r\n}\r\n\r\nexport interface OutgoingInvite {\r\n userId: string;\r\n status: \"sent\" | \"accepted\" | \"declined\" | \"missed\";\r\n participant?: Omit<ParticipantMetadata, \"permissions\"> | undefined;\r\n}\r\n\r\nexport interface RtcError {\r\n code: string;\r\n message: string;\r\n timestamp: number;\r\n context?: any;\r\n}\r\n\r\nexport interface RtcState {\r\n // Did we initiate the current call?\r\n initiated: boolean;\r\n\r\n // Active session (null when no active call)\r\n session: Session | null;\r\n\r\n // Incoming invitation (null when no pending invite)\r\n incomingInvite: IncomingInvite | null;\r\n\r\n outgoingInvites: Record<string, OutgoingInvite>;\r\n\r\n // Error tracking\r\n errors: RtcError[];\r\n}\r\n\r\nexport const defaultState: RtcState = {\r\n initiated: false,\r\n session: null,\r\n incomingInvite: null,\r\n outgoingInvites: {},\r\n errors: [],\r\n};\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { RtcError, RtcState } from \"./types\";\r\nimport { defaultState } from \"./types\";\r\n\r\ntype Actions = {\r\n patch: (fn: (draft: RtcState) => void) => void;\r\n reset: () => void;\r\n addError: (error: RtcError) => void;\r\n clearErrors: () => void;\r\n};\r\n\r\nexport const useRtcStore = create<RtcState & Actions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n reset: () => set(() => defaultState),\r\n\r\n addError: (error) =>\r\n set((state) => {\r\n state.errors.push(error);\r\n }),\r\n\r\n clearErrors: () =>\r\n set((state) => {\r\n state.errors = [];\r\n }),\r\n }))\r\n);\r\n\r\nexport const rtcStore = useRtcStore;\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ChatEntry, ChatState, Envelope } from \"./types\";\r\n\r\ninterface ChatActions {\r\n patch: (fn: (draft: ChatState) => void) => void;\r\n applyIncoming: (envelope: Envelope) => void;\r\n addFile: (file: File, filename: string) => void\r\n addEntryOptimistic: (entry: ChatEntry) => void;\r\n markEntrySent: (entryId: string) => void;\r\n markEntryFailed: (entryId: string) => void;\r\n applyEdit: (entryId: string, newContent: string, version: number) => void;\r\n applyRemove: (entryId: string) => void;\r\n applyReaction: (\r\n entryId: string,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n ) => void;\r\n queuePendingOp: (entryId: string, envelope: Envelope) => void;\r\n processPendingOps: (entryId: string) => void;\r\n trimOldEntries: () => void;\r\n clearChat: () => void;\r\n}\r\n\r\nconst defaultChatState: ChatState = {\r\n byId: {},\r\n order: [],\r\n pendingOps: {},\r\n participantCache: {},\r\n maxEntries: 1000,\r\n};\r\n\r\nfunction applyReactionToEntry(\r\n entry: ChatEntry,\r\n emoji: string,\r\n participantId: string,\r\n op: \"add\" | \"remove\"\r\n) {\r\n const emojiSet = entry.reactions[emoji];\r\n if (!emojiSet) {\r\n entry.reactions[emoji] = new Set();\r\n }\r\n if (op === \"add\") {\r\n entry.reactions[emoji]?.add(participantId);\r\n } else {\r\n entry.reactions[emoji]?.delete(participantId);\r\n if (entry.reactions[emoji]?.size === 0) {\r\n delete entry.reactions[emoji];\r\n }\r\n }\r\n}\r\n\r\nfunction trimEntriesIfNeeded(state: ChatState) {\r\n if (Object.keys(state.byId).length > state.maxEntries) {\r\n const entriesToRemove = Object.keys(state.byId).length - state.maxEntries;\r\n for (let i = 0; i < entriesToRemove; i++) {\r\n const oldestId = state.order[i];\r\n if (oldestId) {\r\n delete state.byId[oldestId];\r\n }\r\n }\r\n state.order = state.order.slice(entriesToRemove);\r\n }\r\n}\r\n\r\nexport const useChatStore = create<ChatState & ChatActions>()(\r\n immer((set) => ({\r\n ...defaultChatState,\r\n\r\n patch: (fn) =>\r\n set((state) => {\r\n fn(state);\r\n }),\r\n\r\n applyIncoming: (envelope) =>\r\n set((state) => {\r\n if (envelope.kind === \"entry\") {\r\n if (state.byId[envelope.entryId]) {\r\n return;\r\n }\r\n\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: envelope.entryId,\r\n content: envelope.payload.content,\r\n sender: {\r\n id: envelope.sender.id,\r\n },\r\n createdAt: envelope.ts,\r\n version: 1,\r\n reactions: {},\r\n status: \"sent\",\r\n filename: envelope.payload?.meta?.filename\r\n };\r\n\r\n state.byId[envelope.entryId] = entry;\r\n state.order.push(envelope.entryId);\r\n\r\n trimEntriesIfNeeded(state);\r\n\r\n const pendingOps = state.pendingOps[envelope.entryId];\r\n if (pendingOps) {\r\n delete state.pendingOps[envelope.entryId];\r\n\r\n for (const op of pendingOps) {\r\n if (op.kind === \"edit\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && op.payload.version > entry.version) {\r\n entry.content = op.payload.newContent;\r\n entry.version = op.payload.version;\r\n entry.editedAt = op.ts;\r\n }\r\n } else if (op.kind === \"remove\") {\r\n const entry = state.byId[op.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = op.ts;\r\n }\r\n } else if (op.kind === \"reaction\") {\r\n if (op.sender.info) {\r\n state.participantCache[op.sender.id] = op.sender.info;\r\n }\r\n\r\n const entry = state.byId[op.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n op.payload.emoji,\r\n op.sender.id,\r\n op.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }\r\n } else if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n if (!entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n } else {\r\n if (!state.pendingOps[envelope.entryId]) {\r\n state.pendingOps[envelope.entryId] = [];\r\n }\r\n state.pendingOps[envelope.entryId]?.push(envelope);\r\n }\r\n }\r\n }),\r\n \r\n addFile: (file, filename) =>\r\n set((state) => {\r\n const values = Object.values(state.byId)\r\n const entryArr = values.filter(val => val.filename === filename)\r\n const entry = entryArr[0];\r\n entry!.file = file\r\n state.byId[entry!.id] = entry!;\r\n }),\r\n\r\n addEntryOptimistic: (entry) =>\r\n set((state) => {\r\n state.byId[entry.id] = entry;\r\n state.order.push(entry.id);\r\n\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n markEntrySent: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"sent\";\r\n }\r\n }),\r\n\r\n markEntryFailed: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n entry.status = \"failed\";\r\n }\r\n }),\r\n\r\n applyEdit: (entryId, newContent, version) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && version > entry.version) {\r\n entry.content = newContent;\r\n entry.version = version;\r\n entry.editedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyRemove: (entryId) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = Date.now();\r\n }\r\n }),\r\n\r\n applyReaction: (entryId, emoji, participantId, op) =>\r\n set((state) => {\r\n const entry = state.byId[entryId];\r\n if (entry) {\r\n applyReactionToEntry(entry, emoji, participantId, op);\r\n }\r\n }),\r\n\r\n queuePendingOp: (entryId, envelope) =>\r\n set((state) => {\r\n if (!state.pendingOps[entryId]) {\r\n state.pendingOps[entryId] = [];\r\n }\r\n state.pendingOps[entryId].push(envelope);\r\n }),\r\n\r\n processPendingOps: (entryId) =>\r\n set((state) => {\r\n const pendingOps = state.pendingOps[entryId];\r\n if (!pendingOps) {\r\n return;\r\n }\r\n\r\n delete state.pendingOps[entryId];\r\n\r\n for (const envelope of pendingOps) {\r\n if (envelope.kind === \"edit\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && envelope.payload.version > entry.version) {\r\n entry.content = envelope.payload.newContent;\r\n entry.version = envelope.payload.version;\r\n entry.editedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"remove\") {\r\n const entry = state.byId[envelope.entryId];\r\n if (entry && !entry.removedAt) {\r\n entry.removedAt = envelope.ts;\r\n }\r\n } else if (envelope.kind === \"reaction\") {\r\n if (envelope.sender.info) {\r\n state.participantCache[envelope.sender.id] = envelope.sender.info;\r\n }\r\n\r\n const entry = state.byId[envelope.entryId];\r\n if (entry) {\r\n applyReactionToEntry(\r\n entry,\r\n envelope.payload.emoji,\r\n envelope.sender.id,\r\n envelope.payload.op\r\n );\r\n }\r\n }\r\n }\r\n }),\r\n\r\n trimOldEntries: () =>\r\n set((state) => {\r\n trimEntriesIfNeeded(state);\r\n }),\r\n\r\n clearChat: () => set(() => defaultChatState),\r\n }))\r\n);\r\n\r\nexport const chatStore = useChatStore;\r\n","import { nanoid } from \"nanoid\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\n\r\nexport function compareEntries(a: ChatEntry, b: ChatEntry): number {\r\n if (a.createdAt !== b.createdAt) {\r\n return a.createdAt - b.createdAt;\r\n }\r\n\r\n if (a.sender.id !== b.sender.id) {\r\n return a.sender.id.localeCompare(b.sender.id);\r\n }\r\n\r\n return a.id.localeCompare(b.id);\r\n}\r\n\r\nexport function validateContent(content: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n const trimmed = content.trim();\r\n\r\n if (trimmed.length === 0) {\r\n return { valid: false, error: \"Content cannot be empty\" };\r\n }\r\n\r\n const sizeInBytes = new TextEncoder().encode(content).length;\r\n if (sizeInBytes > 16384) {\r\n return { valid: false, error: \"Content exceeds 16KB limit\" };\r\n }\r\n\r\n return { valid: true };\r\n}\r\n\r\nexport function isValidEnvelope(data: any): data is Envelope {\r\n if (!data || typeof data !== \"object\") {\r\n return false;\r\n }\r\n\r\n if (data.v !== 1) {\r\n return false;\r\n }\r\n\r\n if (![\"entry\", \"edit\", \"remove\", \"reaction\"].includes(data.kind)) {\r\n return false;\r\n }\r\n\r\n if (\r\n typeof data.roomId !== \"string\" ||\r\n typeof data.entryId !== \"string\" ||\r\n typeof data.ts !== \"number\"\r\n ) {\r\n return false;\r\n }\r\n\r\n if (!data.sender || typeof data.sender.id !== \"string\") {\r\n return false;\r\n }\r\n\r\n if (\r\n data.kind === \"entry\" ||\r\n data.kind === \"edit\" ||\r\n data.kind === \"reaction\"\r\n ) {\r\n if (!data.payload || typeof data.payload !== \"object\") {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function generateEntryId(): string {\r\n return nanoid();\r\n}\r\n\r\nexport function getCurrentTimestamp(): number {\r\n return Date.now();\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry, Envelope } from \"./types\";\r\nimport {\r\n generateEntryId,\r\n getCurrentTimestamp,\r\n isValidEnvelope,\r\n validateContent,\r\n} from \"./utils\";\r\n\r\nconst logger = createLogger(\"chat\");\r\n\r\nexport class ChatService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) {\r\n return;\r\n }\r\n // Handles incoming text streams\r\n this.room.registerTextStreamHandler(\r\n \"chat:v1\",\r\n async (reader, participantInfo) => {\r\n console.log(\"Got here: chat:v1\", participantInfo.identity)\r\n try {\r\n const text = await reader.readAll();\r\n console.log(\"Got here: chat:v1\", text)\r\n this.handleIncomingMessage(text);\r\n\r\n } catch (error) {\r\n logger.error(\"Error reading text stream\", error);\r\n }\r\n }\r\n );\r\n\r\n // Handles incoming file streams\r\n this.room.registerByteStreamHandler('chat:v1', async (reader, participantInfo) => {\r\n try {\r\n const info = reader.info;\r\n const filename = info.name\r\n\r\n // Confirm reciept of file\r\n reader.onProgress = (progress) => {\r\n console.log(`${progress ? (progress * 100).toFixed(0) : 'undefined'}% of ${filename} downloaded`);\r\n };\r\n\r\n // Ensure BlobParts are backed by ArrayBuffer (not SharedArrayBuffer) by copying with slice().\r\n const parts = (await reader.readAll()).map((chunk) => chunk.slice());\r\n const fileBlob = new Blob(parts, { type: info.mimeType });\r\n\r\n this.handleIncomingFile(fileBlob, filename, info.mimeType)\r\n\r\n console.log(\r\n `File \"${info.name}\" received from ${participantInfo.identity}\\n` +\r\n ` Topic: ${info.topic}\\n` +\r\n ` Timestamp: ${info.timestamp}\\n` +\r\n ` ID: ${info.id}\\n` +\r\n ` Size: ${info.size}`\r\n );\r\n } catch (error) {\r\n logger.error(\"Error reading file stream\", error);\r\n }\r\n });\r\n this.isSubscribed = true;\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async send(content: string, file?: File): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot send message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (content.length === 0 && typeof file !== \"undefined\") {\r\n console.log(\"file present\", typeof file)\r\n content = file.name\r\n }\r\n\r\n const validation = validateContent(content);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const entryId = generateEntryId();\r\n const chatStore = useChatStore.getState();\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n const entry: ChatEntry = {\r\n id: entryId,\r\n content,\r\n sender: {\r\n id: senderInfo.id,\r\n },\r\n createdAt: getCurrentTimestamp(),\r\n version: 1,\r\n reactions: {},\r\n status: \"sending\",\r\n file: file!\r\n };\r\n\r\n chatStore.addEntryOptimistic(entry);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"entry\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: entry.createdAt,\r\n sender: senderInfo,\r\n payload: {\r\n content,\r\n meta: {filename: file?.name}\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n console.log('Sent message', entry, envelope)\r\n if (file) {\r\n await this.room.localParticipant.sendFile(file, {\r\n mimeType: file.type,\r\n topic: 'chat:v1'\r\n });\r\n }\r\n chatStore.markEntrySent(entryId);\r\n } catch (error) {\r\n chatStore.markEntryFailed(entryId);\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async edit(entryId: string, newContent: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot edit message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateContent(newContent);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_INVALID_CONTENT\",\r\n message: validation.error || \"Invalid content\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only edit your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const newVersion = entry.version + 1;\r\n chatStore.applyEdit(entryId, newContent, newVersion);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"edit\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n newContent,\r\n version: newVersion,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_EDIT_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to edit message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async remove(entryId: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove message: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ENTRY_NOT_FOUND\",\r\n message: \"Entry not found\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (entry.sender.id !== senderInfo.id) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_UNAUTHORIZED\",\r\n message: \"You can only remove your own messages\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n return;\r\n }\r\n\r\n chatStore.applyRemove(entryId);\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"remove\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REMOVE_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove message\",\r\n timestamp: Date.now(),\r\n context: { entryId },\r\n });\r\n }\r\n }\r\n\r\n async react(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot add reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"add\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"add\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to add reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n async unreact(entryId: string, emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_ROOM_NOT_READY\",\r\n message: \"Cannot remove reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const chatStore = useChatStore.getState();\r\n const entry = chatStore.byId[entryId];\r\n if (!entry) {\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n if (senderInfo.info) {\r\n chatStore.patch((state) => {\r\n state.participantCache[senderInfo.id] = senderInfo.info!;\r\n });\r\n }\r\n\r\n chatStore.applyReaction(entryId, emoji, senderInfo.id, \"remove\");\r\n try {\r\n const envelope: Envelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n entryId,\r\n ts: getCurrentTimestamp(),\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n op: \"remove\",\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"chat:v1\",\r\n });\r\n } catch (error) {\r\n useRtcStore.getState().addError({\r\n code: \"CHAT_REACTION_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to remove reaction\",\r\n timestamp: Date.now(),\r\n context: { entryId, emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncomingMessage(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (!isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid envelope received\", parsed);\r\n return;\r\n }\r\n\r\n useChatStore.getState().applyIncoming(parsed);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming message\", error);\r\n }\r\n }\r\n\r\n private handleIncomingFile(blob: Blob, filename: string, mimeType: string): void {\r\n try {\r\n const file = new File([blob], filename, { type: mimeType || blob.type });\r\n\r\n useChatStore.getState().addFile(file, filename);\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming file\", error);\r\n }\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parsing errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ChatService } from \"./service\";\r\nimport { useChatStore } from \"./store\";\r\nimport type { ChatEntry } from \"./types\";\r\nimport { compareEntries } from \"./utils\";\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseChatReturn {\r\n entries: ChatEntry[];\r\n isReady: boolean;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isOwnEntry: (entry: ChatEntry) => boolean;\r\n send: (content: string, file?: File) => Promise<void>;\r\n edit: (id: string, content: string) => Promise<void>;\r\n remove: (id: string) => Promise<void>;\r\n react: (id: string, emoji: string) => Promise<void>;\r\n unreact: (id: string, emoji: string) => Promise<void>;\r\n}\r\n\r\nexport function useChat(): UseChatReturn {\r\n const service = useFeatureService<ChatService>(\"chat\");\r\n\r\n const byId = useChatStore((state) => state.byId);\r\n const order = useChatStore((state) => state.order);\r\n const participantCache = useChatStore((state) => state.participantCache);\r\n\r\n const entries = useMemo(() => {\r\n return order\r\n .map((id) => byId[id])\r\n .filter((entry): entry is ChatEntry => entry !== undefined)\r\n .sort(compareEntries);\r\n }, [byId, order]);\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => {\r\n return participantCache[id] || null;\r\n },\r\n [participantCache]\r\n );\r\n\r\n const send = useCallback(\r\n async (content: string, file?: File) => service.send(content, file),\r\n [service]\r\n );\r\n\r\n const edit = useCallback(\r\n async (id: string, content: string) => service.edit(id, content),\r\n [service]\r\n );\r\n\r\n const remove = useCallback(\r\n async (id: string) => service.remove(id),\r\n [service]\r\n );\r\n\r\n const react = useCallback(\r\n async (id: string, emoji: string) => service.react(id, emoji),\r\n [service]\r\n );\r\n\r\n const unreact = useCallback(\r\n async (id: string, emoji: string) => service.unreact(id, emoji),\r\n [service]\r\n );\r\n\r\n const isOwnEntry = useCallback(\r\n (entry: ChatEntry) => entry.sender.id === service.getLocalParticipantId(),\r\n [service]\r\n );\r\n\r\n return {\r\n entries,\r\n isReady: true,\r\n getParticipantInfo,\r\n isOwnEntry,\r\n send,\r\n edit,\r\n remove,\r\n react,\r\n unreact,\r\n };\r\n}\r\n","import { create } from \"zustand\";\r\nimport { immer } from \"zustand/middleware/immer\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport type {\r\n ParticipantReaction,\r\n ReactionEnvelope,\r\n ReactionsState,\r\n} from \"./types\";\r\n\r\ninterface ReactionsActions {\r\n setReaction: (participantId: string, reaction: ParticipantReaction) => void;\r\n clearReaction: (participantId: string) => void;\r\n upsertParticipantInfo: (id: string, info: ParticipantMetadata) => void;\r\n pruneExpired: (now?: number) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst defaultState: ReactionsState = {\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: 4000,\r\n};\r\n\r\nexport const useReactionsStore = create<ReactionsState & ReactionsActions>()(\r\n immer((set) => ({\r\n ...defaultState,\r\n\r\n setReaction: (participantId, reaction) =>\r\n set((state) => {\r\n state.reactions.set(participantId, reaction);\r\n }),\r\n\r\n clearReaction: (participantId) =>\r\n set((state) => {\r\n state.reactions.delete(participantId);\r\n }),\r\n\r\n upsertParticipantInfo: (id, info) =>\r\n set((state) => {\r\n state.participantCache[id] = info;\r\n }),\r\n\r\n pruneExpired: (now = Date.now()) =>\r\n set((state) => {\r\n const entries = Array.from(state.reactions.entries());\r\n for (const [participantId, reaction] of entries) {\r\n if (reaction.ts + state.ttlMs < now) {\r\n state.reactions.delete(participantId);\r\n }\r\n }\r\n }),\r\n\r\n clear: () =>\r\n set(() => ({\r\n reactions: new Map(),\r\n participantCache: {},\r\n ttlMs: defaultState.ttlMs,\r\n })),\r\n }))\r\n);\r\n\r\nexport function applyIncomingReaction(envelope: ReactionEnvelope): void {\r\n const { upsertParticipantInfo, setReaction } = useReactionsStore.getState();\r\n\r\n if (envelope.sender.info) {\r\n upsertParticipantInfo(envelope.sender.id, envelope.sender.info);\r\n }\r\n\r\n setReaction(envelope.sender.id, {\r\n emoji: envelope.payload.emoji,\r\n ts: Date.now(),\r\n nonce: envelope.payload.nonce,\r\n });\r\n}\r\n","import { createLogger } from \"../../utils\";\r\n\r\nexport const logger = createLogger(\"reactions\");\r\n\r\nexport function validateEmoji(emoji: string): {\r\n valid: boolean;\r\n error?: string;\r\n} {\r\n if (!emoji || typeof emoji !== \"string\") {\r\n return { valid: false, error: \"empty\" };\r\n }\r\n if (emoji.length > 10) {\r\n return { valid: false, error: \"too long\" };\r\n }\r\n return { valid: true };\r\n}\r\n\r\nexport function generateNonce(): string {\r\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n}\r\n","import { ConnectionState, type Room } from \"livekit-client\";\r\nimport { useRtcStore } from \"../../state/store\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { applyIncomingReaction, useReactionsStore } from \"./store\";\r\nimport type { ReactionEnvelope } from \"./types\";\r\nimport { generateNonce, validateEmoji } from \"./utils\";\r\n\r\nconst logger = createLogger(\"reactions\");\r\n\r\nexport class ReactionsService {\r\n private readonly room: Room;\r\n private isSubscribed = false;\r\n private pruneInterval: ReturnType<typeof setInterval> | undefined;\r\n private lastSendAt = 0;\r\n private minIntervalMs = 200;\r\n private lastRemoteTs = new Map<string, number>();\r\n\r\n constructor(room: Room) {\r\n this.room = room;\r\n }\r\n\r\n private isRoomReady(): boolean {\r\n if (!this.room) {\r\n logger.warn(\"Room not initialized\");\r\n return false;\r\n }\r\n\r\n if (this.room.state !== ConnectionState.Connected) {\r\n logger.warn(\"Room not connected\", { state: this.room.state });\r\n return false;\r\n }\r\n\r\n if (!this.room.localParticipant) {\r\n logger.warn(\"Local participant not available\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private canSendNow(): boolean {\r\n const now = Date.now();\r\n if (now - this.lastSendAt < this.minIntervalMs) return false;\r\n this.lastSendAt = now;\r\n return true;\r\n }\r\n\r\n subscribe(): void {\r\n if (this.isSubscribed) return;\r\n\r\n this.room.registerTextStreamHandler(\"reactions:v1\", async (reader) => {\r\n try {\r\n const text = await reader.readAll();\r\n this.handleIncoming(text);\r\n } catch (err) {\r\n logger.error(\"Error reading reactions stream\", err);\r\n }\r\n });\r\n\r\n this.pruneInterval = setInterval(() => {\r\n useReactionsStore.getState().pruneExpired();\r\n }, 1000);\r\n\r\n this.isSubscribed = true;\r\n logger.info(\"ReactionsService subscribed\");\r\n }\r\n\r\n unsubscribe(): void {\r\n this.isSubscribed = false;\r\n if (this.pruneInterval) {\r\n clearInterval(this.pruneInterval);\r\n this.pruneInterval = undefined;\r\n }\r\n logger.info(\"ReactionsService unsubscribed\");\r\n }\r\n\r\n getLocalParticipantId(): string {\r\n return this.room.localParticipant.identity;\r\n }\r\n\r\n async sendReaction(emoji: string): Promise<void> {\r\n if (!this.isRoomReady()) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_ROOM_NOT_READY\",\r\n message: \"Cannot send reaction: room not connected\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n const validation = validateEmoji(emoji);\r\n if (!validation.valid) {\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_INVALID_EMOJI\",\r\n message: validation.error || \"Invalid emoji\",\r\n timestamp: Date.now(),\r\n });\r\n return;\r\n }\r\n\r\n if (!this.canSendNow()) {\r\n logger.debug(\"Rate limited, skipping send\");\r\n return;\r\n }\r\n\r\n const senderInfo = this.getSenderInfo();\r\n const ts = Date.now();\r\n const nonce = generateNonce();\r\n\r\n useReactionsStore.getState().setReaction(senderInfo.id, {\r\n emoji,\r\n ts,\r\n nonce,\r\n });\r\n\r\n try {\r\n const envelope: ReactionEnvelope = {\r\n v: 1,\r\n kind: \"reaction\",\r\n roomId: this.room.name,\r\n ts,\r\n sender: senderInfo,\r\n payload: {\r\n emoji,\r\n nonce,\r\n },\r\n };\r\n\r\n await this.room.localParticipant.sendText(JSON.stringify(envelope), {\r\n topic: \"reactions:v1\",\r\n });\r\n\r\n logger.debug(\"Reaction sent\", { emoji });\r\n } catch (error) {\r\n logger.error(\"Failed to send reaction\", error);\r\n useRtcStore.getState().addError({\r\n code: \"REACTIONS_SEND_FAILED\",\r\n message:\r\n error instanceof Error ? error.message : \"Failed to send reaction\",\r\n timestamp: Date.now(),\r\n context: { emoji },\r\n });\r\n }\r\n }\r\n\r\n private handleIncoming(text: string): void {\r\n try {\r\n const parsed = JSON.parse(text) as ReactionEnvelope;\r\n if (!this.isValidEnvelope(parsed)) {\r\n logger.warn(\"Invalid reaction envelope received\", parsed);\r\n return;\r\n }\r\n\r\n if (parsed.sender.id === this.getLocalParticipantId()) {\r\n logger.debug(\"Ignoring self-echo reaction\");\r\n return;\r\n }\r\n\r\n const lastTs =\r\n this.lastRemoteTs.get(parsed.sender.id) ?? Number.NEGATIVE_INFINITY;\r\n if (parsed.ts < lastTs) {\r\n logger.debug(\"Ignoring out-of-order reaction\", {\r\n sender: parsed.sender.id,\r\n ts: parsed.ts,\r\n lastTs,\r\n });\r\n return;\r\n }\r\n this.lastRemoteTs.set(parsed.sender.id, parsed.ts);\r\n applyIncomingReaction(parsed);\r\n logger.debug(\"Reaction received\", { emoji: parsed.payload.emoji });\r\n } catch (error) {\r\n logger.error(\"Error parsing incoming reaction\", error);\r\n }\r\n }\r\n\r\n private isValidEnvelope(e: any): e is ReactionEnvelope {\r\n return (\r\n e &&\r\n e.v === 1 &&\r\n e.kind === \"reaction\" &&\r\n typeof e.roomId === \"string\" &&\r\n e.roomId === this.room.name &&\r\n typeof e.ts === \"number\" &&\r\n e.ts > 0 &&\r\n typeof e.sender?.id === \"string\" &&\r\n typeof e.payload?.emoji === \"string\" &&\r\n typeof e.payload?.nonce === \"string\"\r\n );\r\n }\r\n\r\n private getSenderInfo(): { id: string; info?: ParticipantMetadata } {\r\n const localParticipant = this.room.localParticipant;\r\n const sender: { id: string; info?: ParticipantMetadata } = {\r\n id: localParticipant.identity,\r\n };\r\n\r\n if (localParticipant.metadata) {\r\n try {\r\n sender.info = JSON.parse(\r\n localParticipant.metadata\r\n ) as ParticipantMetadata;\r\n } catch {\r\n // Ignore metadata parse errors\r\n }\r\n }\r\n\r\n return sender;\r\n }\r\n}\r\n","import { useCallback } from \"react\";\r\nimport type { ParticipantMetadata } from \"../../state/types\";\r\nimport { createLogger } from \"../../utils\";\r\nimport { useFeatureService } from \"../DataChannelContext\";\r\nimport type { ReactionsService } from \"./service\";\r\nimport { useReactionsStore } from \"./store\";\r\n\r\nconst logger = createLogger(\"reactions:hook\");\r\n\r\ntype Nullable<T> = T | null;\r\n\r\nexport interface UseReactionsReturn {\r\n sendReaction: (emoji: string) => Promise<void>;\r\n getReactionFor: (participantId: string) => Nullable<string>;\r\n clearReaction: (participantId: string) => void;\r\n getParticipantInfo: (id: string) => Nullable<ParticipantMetadata>;\r\n isReady: boolean;\r\n}\r\n\r\nexport function useReactions(): UseReactionsReturn {\r\n const service = useFeatureService<ReactionsService>(\"reactions\");\r\n\r\n const reactions = useReactionsStore((state) => state.reactions);\r\n const participantCache = useReactionsStore((state) => state.participantCache);\r\n\r\n const getReactionFor = useCallback(\r\n (participantId: string): Nullable<string> => {\r\n const reaction = reactions.get(participantId);\r\n return reaction?.emoji ?? null;\r\n },\r\n [reactions]\r\n );\r\n\r\n const getParticipantInfo = useCallback(\r\n (id: string): Nullable<ParticipantMetadata> => participantCache[id] || null,\r\n [participantCache]\r\n );\r\n\r\n const sendReaction = useCallback(\r\n async (emoji: string) => {\r\n if (!service) {\r\n logger.error(\"Cannot send reaction: service not ready\");\r\n return;\r\n }\r\n return service.sendReaction(emoji);\r\n },\r\n [service]\r\n );\r\n\r\n const clearReaction = useCallback((participantId: string) => {\r\n useReactionsStore.getState().clearReaction(participantId);\r\n }, []);\r\n\r\n return {\r\n sendReaction,\r\n getReactionFor,\r\n clearReaction,\r\n getParticipantInfo,\r\n isReady: !!service,\r\n };\r\n}\r\n","import type { Room } from \"livekit-client\";\r\nimport { ChatService, useChatStore } from \"./chat\";\r\nimport { ReactionsService, useReactionsStore } from \"./reactions\";\r\nimport type { RealtimeFeature } from \"./types\";\r\n\r\nexport const FEATURES: Record<string, RealtimeFeature> = {\r\n chat: {\r\n name: \"chat\",\r\n createService: (room: Room) => new ChatService(room),\r\n cleanupStore: () => useChatStore.getState().clearChat(),\r\n },\r\n reactions: {\r\n name: \"reactions\",\r\n createService: (room: Room) => new ReactionsService(room),\r\n cleanupStore: () => useReactionsStore.getState().clear(),\r\n },\r\n};\r\n\r\nexport const DEFAULT_FEATURES = [\"chat\", \"reactions\"];\r\n","import type { Room } from \"livekit-client\";\r\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport { createLogger } from \"../utils\";\r\nimport {\r\n DataChannelContext,\r\n type DataChannelContextValue,\r\n} from \"./DataChannelContext\";\r\nimport { DEFAULT_FEATURES, FEATURES } from \"./registry\";\r\n\r\nconst logger = createLogger(\"channels:provider\");\r\n\r\nexport interface DataChannelProviderProps {\r\n room: Room;\r\n features?: string[];\r\n children: ReactNode;\r\n}\r\n\r\nexport function DataChannelProvider({\r\n room,\r\n features = DEFAULT_FEATURES,\r\n children,\r\n}: DataChannelProviderProps) {\r\n const services = useRef<Map<string, any>>(new Map());\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n useEffect(() => {\r\n if (!room) {\r\n logger.warn(\"DataChannelProvider mounted without room\");\r\n return;\r\n }\r\n\r\n logger.debug(\"Initializing features\", { features });\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n\r\n if (!feature) {\r\n logger.warn(`Feature \"${featureName}\" not found in registry`);\r\n continue;\r\n }\r\n\r\n try {\r\n logger.debug(`Initializing feature: ${featureName}`);\r\n const service = feature.createService(room);\r\n\r\n service.subscribe();\r\n services.current.set(featureName, service);\r\n\r\n logger.info(`Feature \"${featureName}\" initialized`);\r\n } catch (error) {\r\n logger.error(`Failed to initialize feature \"${featureName}\"`, error);\r\n }\r\n }\r\n\r\n setIsReady(true);\r\n logger.info(\"All features initialized\");\r\n return () => {\r\n logger.debug(\"Cleaning up features\");\r\n\r\n // Unsubscribe all services\r\n services.current.forEach((service, name) => {\r\n try {\r\n logger.debug(`Unsubscribing feature: ${name}`);\r\n service.unsubscribe();\r\n } catch (error) {\r\n logger.error(`Failed to unsubscribe feature \"${name}\"`, error);\r\n }\r\n });\r\n\r\n // Clean up stores\r\n for (const featureName of features) {\r\n const feature = FEATURES[featureName];\r\n if (feature?.cleanupStore) {\r\n try {\r\n logger.debug(`Cleaning store for feature: ${featureName}`);\r\n feature.cleanupStore();\r\n } catch (error) {\r\n logger.error(`Failed to cleanup store for \"${featureName}\"`, error);\r\n }\r\n }\r\n }\r\n\r\n services.current.clear();\r\n setIsReady(false);\r\n logger.info(\"Features cleanup complete\");\r\n };\r\n }, [room, features]);\r\n\r\n const contextValue = useMemo<DataChannelContextValue>(\r\n () => ({\r\n services: services.current,\r\n isReady,\r\n }),\r\n [isReady]\r\n );\r\n\r\n return (\r\n <DataChannelContext.Provider value={contextValue}>\r\n {children}\r\n </DataChannelContext.Provider>\r\n );\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vg-x07df",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "Headless SDK for dubadav audio/video",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",