@cossistant/react 0.0.20 → 0.0.22

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.
Files changed (83) hide show
  1. package/conversation.d.ts +28 -0
  2. package/conversation.d.ts.map +1 -1
  3. package/hooks/index.d.ts +4 -1
  4. package/hooks/index.js +4 -1
  5. package/hooks/private/use-grouped-messages.d.ts.map +1 -1
  6. package/hooks/private/use-grouped-messages.js +3 -17
  7. package/hooks/private/use-grouped-messages.js.map +1 -1
  8. package/hooks/use-conversation-auto-seen.d.ts +1 -1
  9. package/hooks/use-conversation-auto-seen.js +30 -46
  10. package/hooks/use-conversation-auto-seen.js.map +1 -1
  11. package/hooks/use-conversation-seen.d.ts.map +1 -1
  12. package/hooks/use-conversation-seen.js +7 -3
  13. package/hooks/use-conversation-seen.js.map +1 -1
  14. package/hooks/use-new-message-sound.d.ts +23 -0
  15. package/hooks/use-new-message-sound.d.ts.map +1 -0
  16. package/hooks/use-new-message-sound.js +34 -0
  17. package/hooks/use-new-message-sound.js.map +1 -0
  18. package/hooks/use-sound-effect.d.ts +30 -0
  19. package/hooks/use-sound-effect.d.ts.map +1 -0
  20. package/hooks/use-sound-effect.js +104 -0
  21. package/hooks/use-sound-effect.js.map +1 -0
  22. package/hooks/use-typing-sound.d.ts +18 -0
  23. package/hooks/use-typing-sound.d.ts.map +1 -0
  24. package/hooks/use-typing-sound.js +38 -0
  25. package/hooks/use-typing-sound.js.map +1 -0
  26. package/index.d.ts +5 -2
  27. package/index.js +8 -6
  28. package/package.json +3 -3
  29. package/primitives/bubble.js +1 -1
  30. package/primitives/index.d.ts +3 -5
  31. package/primitives/index.js +3 -9
  32. package/primitives/index.parts.d.ts +2 -4
  33. package/primitives/index.parts.js +2 -4
  34. package/primitives/router.d.ts +19 -20
  35. package/primitives/router.d.ts.map +1 -1
  36. package/primitives/router.js +17 -11
  37. package/primitives/router.js.map +1 -1
  38. package/realtime/index.js +1 -1
  39. package/realtime/provider.js +1 -1
  40. package/realtime-events.d.ts +14 -0
  41. package/realtime-events.d.ts.map +1 -1
  42. package/schemas3.d.ts +7 -0
  43. package/schemas3.d.ts.map +1 -1
  44. package/support/components/bubble.d.ts.map +1 -1
  45. package/support/components/bubble.js +27 -4
  46. package/support/components/bubble.js.map +1 -1
  47. package/support/components/button.d.ts +1 -1
  48. package/support/components/conversation-event.js +1 -1
  49. package/support/components/conversation-event.js.map +1 -1
  50. package/support/components/conversation-timeline.d.ts.map +1 -1
  51. package/support/components/conversation-timeline.js +5 -0
  52. package/support/components/conversation-timeline.js.map +1 -1
  53. package/support/components/support-content.d.ts +2 -0
  54. package/support/components/support-content.d.ts.map +1 -1
  55. package/support/components/support-content.js +5 -2
  56. package/support/components/support-content.js.map +1 -1
  57. package/support/components/timeline-message-group.js +2 -2
  58. package/support/components/timeline-message-group.js.map +1 -1
  59. package/support/components/timeline-message-item.js +2 -2
  60. package/support/components/timeline-message-item.js.map +1 -1
  61. package/support/components/typing-indicator.d.ts.map +1 -1
  62. package/support/index.d.ts +12 -7
  63. package/support/index.d.ts.map +1 -1
  64. package/support/index.js +28 -29
  65. package/support/index.js.map +1 -1
  66. package/support/pages/conversation.d.ts.map +1 -1
  67. package/support/pages/conversation.js +19 -1
  68. package/support/pages/conversation.js.map +1 -1
  69. package/support/router.d.ts +19 -9
  70. package/support/router.d.ts.map +1 -1
  71. package/support/router.js +31 -30
  72. package/support/router.js.map +1 -1
  73. package/timeline-item.d.ts +14 -0
  74. package/timeline-item.d.ts.map +1 -1
  75. package/utils/use-render-element.d.ts.map +1 -1
  76. package/primitives/page-registry.d.ts +0 -30
  77. package/primitives/page-registry.d.ts.map +0 -1
  78. package/primitives/page-registry.js +0 -45
  79. package/primitives/page-registry.js.map +0 -1
  80. package/primitives/page.d.ts +0 -21
  81. package/primitives/page.d.ts.map +0 -1
  82. package/primitives/page.js +0 -18
  83. package/primitives/page.js.map +0 -1
@@ -0,0 +1,104 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ //#region src/hooks/use-sound-effect.ts
4
+ /**
5
+ * Hook to play sound effects using the Web Audio API.
6
+ *
7
+ * @param soundPath - Path to the sound file (relative to public directory or absolute URL)
8
+ * @param options - Configuration options for the sound
9
+ * @returns Object with play, stop functions and state
10
+ *
11
+ * @example
12
+ * const { play, stop, isPlaying } = useSoundEffect('/sounds/notification.wav', {
13
+ * loop: false,
14
+ * volume: 0.5
15
+ * });
16
+ */
17
+ function useSoundEffect(soundPath, options = {}) {
18
+ const { loop = false, volume = 1, playbackRate = 1 } = options;
19
+ const [isPlaying, setIsPlaying] = useState(false);
20
+ const [isLoading, setIsLoading] = useState(true);
21
+ const [error, setError] = useState(null);
22
+ const audioContextRef = useRef(null);
23
+ const audioBufferRef = useRef(null);
24
+ const sourceNodeRef = useRef(null);
25
+ const gainNodeRef = useRef(null);
26
+ useEffect(() => {
27
+ let mounted = true;
28
+ const initAudio = async () => {
29
+ try {
30
+ if (!audioContextRef.current) audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
31
+ const response = await fetch(soundPath);
32
+ if (!response.ok) throw new Error(`Failed to load sound: ${response.statusText}`);
33
+ const arrayBuffer = await response.arrayBuffer();
34
+ const audioBuffer = await audioContextRef.current.decodeAudioData(arrayBuffer);
35
+ if (mounted) {
36
+ audioBufferRef.current = audioBuffer;
37
+ setIsLoading(false);
38
+ }
39
+ } catch (err) {
40
+ if (mounted) {
41
+ setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Failed to load sound"));
42
+ setIsLoading(false);
43
+ }
44
+ }
45
+ };
46
+ initAudio();
47
+ return () => {
48
+ mounted = false;
49
+ };
50
+ }, [soundPath]);
51
+ const play = useCallback(() => {
52
+ const audioContext = audioContextRef.current;
53
+ const audioBuffer = audioBufferRef.current;
54
+ if (!(audioContext && audioBuffer && !isLoading && !error)) return;
55
+ if (sourceNodeRef.current) try {
56
+ sourceNodeRef.current.stop();
57
+ } catch {}
58
+ const source = audioContext.createBufferSource();
59
+ source.buffer = audioBuffer;
60
+ source.loop = loop;
61
+ source.playbackRate.value = playbackRate;
62
+ const gainNode = audioContext.createGain();
63
+ gainNode.gain.value = volume;
64
+ source.connect(gainNode);
65
+ gainNode.connect(audioContext.destination);
66
+ sourceNodeRef.current = source;
67
+ gainNodeRef.current = gainNode;
68
+ source.onended = () => {
69
+ if (!loop) setIsPlaying(false);
70
+ };
71
+ source.start(0);
72
+ setIsPlaying(true);
73
+ }, [
74
+ loop,
75
+ volume,
76
+ playbackRate,
77
+ isLoading,
78
+ error
79
+ ]);
80
+ const stop = useCallback(() => {
81
+ if (sourceNodeRef.current) {
82
+ try {
83
+ sourceNodeRef.current.stop();
84
+ sourceNodeRef.current.disconnect();
85
+ } catch {}
86
+ sourceNodeRef.current = null;
87
+ }
88
+ setIsPlaying(false);
89
+ }, []);
90
+ useEffect(() => () => {
91
+ stop();
92
+ }, [stop]);
93
+ return {
94
+ play,
95
+ stop,
96
+ isPlaying,
97
+ isLoading,
98
+ error
99
+ };
100
+ }
101
+
102
+ //#endregion
103
+ export { useSoundEffect };
104
+ //# sourceMappingURL=use-sound-effect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-sound-effect.js","names":[],"sources":["../../src/hooks/use-sound-effect.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type UseSoundEffectOptions = {\n\tloop?: boolean;\n\tvolume?: number;\n\tplaybackRate?: number;\n};\n\nexport type UseSoundEffectReturn = {\n\tplay: () => void;\n\tstop: () => void;\n\tisPlaying: boolean;\n\tisLoading: boolean;\n\terror: Error | null;\n};\n\n/**\n * Hook to play sound effects using the Web Audio API.\n *\n * @param soundPath - Path to the sound file (relative to public directory or absolute URL)\n * @param options - Configuration options for the sound\n * @returns Object with play, stop functions and state\n *\n * @example\n * const { play, stop, isPlaying } = useSoundEffect('/sounds/notification.wav', {\n * loop: false,\n * volume: 0.5\n * });\n */\nexport function useSoundEffect(\n\tsoundPath: string,\n\toptions: UseSoundEffectOptions = {}\n): UseSoundEffectReturn {\n\tconst { loop = false, volume = 1.0, playbackRate = 1.0 } = options;\n\n\tconst [isPlaying, setIsPlaying] = useState(false);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<Error | null>(null);\n\n\tconst audioContextRef = useRef<AudioContext | null>(null);\n\tconst audioBufferRef = useRef<AudioBuffer | null>(null);\n\tconst sourceNodeRef = useRef<AudioBufferSourceNode | null>(null);\n\tconst gainNodeRef = useRef<GainNode | null>(null);\n\n\t// Initialize audio context and load sound\n\tuseEffect(() => {\n\t\tlet mounted = true;\n\n\t\tconst initAudio = async () => {\n\t\t\ttry {\n\t\t\t\t// Create audio context if it doesn't exist\n\t\t\t\tif (!audioContextRef.current) {\n\t\t\t\t\taudioContextRef.current = new (\n\t\t\t\t\t\twindow.AudioContext ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\twindow as typeof window & {\n\t\t\t\t\t\t\t\twebkitAudioContext?: typeof AudioContext;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t).webkitAudioContext\n\t\t\t\t\t)();\n\t\t\t\t}\n\n\t\t\t\t// Load the audio file\n\t\t\t\tconst response = await fetch(soundPath);\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to load sound: ${response.statusText}`);\n\t\t\t\t}\n\n\t\t\t\tconst arrayBuffer = await response.arrayBuffer();\n\t\t\t\tconst audioBuffer =\n\t\t\t\t\tawait audioContextRef.current.decodeAudioData(arrayBuffer);\n\n\t\t\t\tif (mounted) {\n\t\t\t\t\taudioBufferRef.current = audioBuffer;\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tif (mounted) {\n\t\t\t\t\tsetError(\n\t\t\t\t\t\terr instanceof Error ? err : new Error(\"Failed to load sound\")\n\t\t\t\t\t);\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinitAudio();\n\n\t\treturn () => {\n\t\t\tmounted = false;\n\t\t};\n\t}, [soundPath]);\n\n\t// Play sound\n\tconst play = useCallback(() => {\n\t\tconst audioContext = audioContextRef.current;\n\t\tconst audioBuffer = audioBufferRef.current;\n\n\t\tconst canPlay = audioContext && audioBuffer && !isLoading && !error;\n\n\t\tif (!canPlay) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Stop any currently playing sound\n\t\tif (sourceNodeRef.current) {\n\t\t\ttry {\n\t\t\t\tsourceNodeRef.current.stop();\n\t\t\t} catch {\n\t\t\t\t// Ignore errors if already stopped\n\t\t\t}\n\t\t}\n\n\t\t// Create new source node\n\t\tconst source = audioContext.createBufferSource();\n\t\tsource.buffer = audioBuffer;\n\t\tsource.loop = loop;\n\t\tsource.playbackRate.value = playbackRate;\n\n\t\t// Create gain node for volume control\n\t\tconst gainNode = audioContext.createGain();\n\t\tgainNode.gain.value = volume;\n\n\t\t// Connect nodes: source -> gain -> destination\n\t\tsource.connect(gainNode);\n\t\tgainNode.connect(audioContext.destination);\n\n\t\t// Store references\n\t\tsourceNodeRef.current = source;\n\t\tgainNodeRef.current = gainNode;\n\n\t\t// Handle end event\n\t\tsource.onended = () => {\n\t\t\tif (!loop) {\n\t\t\t\tsetIsPlaying(false);\n\t\t\t}\n\t\t};\n\n\t\t// Start playback\n\t\tsource.start(0);\n\t\tsetIsPlaying(true);\n\t}, [loop, volume, playbackRate, isLoading, error]);\n\n\t// Stop sound\n\tconst stop = useCallback(() => {\n\t\tif (sourceNodeRef.current) {\n\t\t\ttry {\n\t\t\t\tsourceNodeRef.current.stop();\n\t\t\t\tsourceNodeRef.current.disconnect();\n\t\t\t} catch {\n\t\t\t\t// Ignore errors if already stopped\n\t\t\t}\n\t\t\tsourceNodeRef.current = null;\n\t\t}\n\t\tsetIsPlaying(false);\n\t}, []);\n\n\t// Cleanup on unmount\n\tuseEffect(\n\t\t() => () => {\n\t\t\tstop();\n\t\t},\n\t\t[stop]\n\t);\n\n\treturn {\n\t\tplay,\n\t\tstop,\n\t\tisPlaying,\n\t\tisLoading,\n\t\terror,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,SAAgB,eACf,WACA,UAAiC,EAAE,EACZ;CACvB,MAAM,EAAE,OAAO,OAAO,SAAS,GAAK,eAAe,MAAQ;CAE3D,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,OAAO,YAAY,SAAuB,KAAK;CAEtD,MAAM,kBAAkB,OAA4B,KAAK;CACzD,MAAM,iBAAiB,OAA2B,KAAK;CACvD,MAAM,gBAAgB,OAAqC,KAAK;CAChE,MAAM,cAAc,OAAwB,KAAK;AAGjD,iBAAgB;EACf,IAAI,UAAU;EAEd,MAAM,YAAY,YAAY;AAC7B,OAAI;AAEH,QAAI,CAAC,gBAAgB,QACpB,iBAAgB,UAAU,KACzB,OAAO,gBAEN,OAGC,qBACA;IAIJ,MAAM,WAAW,MAAM,MAAM,UAAU;AACvC,QAAI,CAAC,SAAS,GACb,OAAM,IAAI,MAAM,yBAAyB,SAAS,aAAa;IAGhE,MAAM,cAAc,MAAM,SAAS,aAAa;IAChD,MAAM,cACL,MAAM,gBAAgB,QAAQ,gBAAgB,YAAY;AAE3D,QAAI,SAAS;AACZ,oBAAe,UAAU;AACzB,kBAAa,MAAM;;YAEZ,KAAK;AACb,QAAI,SAAS;AACZ,cACC,eAAe,QAAQ,sBAAM,IAAI,MAAM,uBAAuB,CAC9D;AACD,kBAAa,MAAM;;;;AAKtB,aAAW;AAEX,eAAa;AACZ,aAAU;;IAET,CAAC,UAAU,CAAC;CAGf,MAAM,OAAO,kBAAkB;EAC9B,MAAM,eAAe,gBAAgB;EACrC,MAAM,cAAc,eAAe;AAInC,MAAI,EAFY,gBAAgB,eAAe,CAAC,aAAa,CAAC,OAG7D;AAID,MAAI,cAAc,QACjB,KAAI;AACH,iBAAc,QAAQ,MAAM;UACrB;EAMT,MAAM,SAAS,aAAa,oBAAoB;AAChD,SAAO,SAAS;AAChB,SAAO,OAAO;AACd,SAAO,aAAa,QAAQ;EAG5B,MAAM,WAAW,aAAa,YAAY;AAC1C,WAAS,KAAK,QAAQ;AAGtB,SAAO,QAAQ,SAAS;AACxB,WAAS,QAAQ,aAAa,YAAY;AAG1C,gBAAc,UAAU;AACxB,cAAY,UAAU;AAGtB,SAAO,gBAAgB;AACtB,OAAI,CAAC,KACJ,cAAa,MAAM;;AAKrB,SAAO,MAAM,EAAE;AACf,eAAa,KAAK;IAChB;EAAC;EAAM;EAAQ;EAAc;EAAW;EAAM,CAAC;CAGlD,MAAM,OAAO,kBAAkB;AAC9B,MAAI,cAAc,SAAS;AAC1B,OAAI;AACH,kBAAc,QAAQ,MAAM;AAC5B,kBAAc,QAAQ,YAAY;WAC3B;AAGR,iBAAc,UAAU;;AAEzB,eAAa,MAAM;IACjB,EAAE,CAAC;AAGN,uBACa;AACX,QAAM;IAEP,CAAC,KAAK,CACN;AAED,QAAO;EACN;EACA;EACA;EACA;EACA;EACA"}
@@ -0,0 +1,18 @@
1
+ //#region src/hooks/use-typing-sound.d.ts
2
+ /**
3
+ * Hook to play a looping typing sound while someone is typing.
4
+ *
5
+ * @param isTyping - Whether someone is currently typing
6
+ * @param options - Optional configuration for volume and playback speed
7
+ *
8
+ * @example
9
+ * const { isTyping } = useTypingIndicator();
10
+ * useTypingSound(isTyping, { volume: 1.0, playbackRate: 1.2 });
11
+ */
12
+ declare function useTypingSound(isTyping: boolean, options?: {
13
+ volume?: number;
14
+ playbackRate?: number;
15
+ }): void;
16
+ //#endregion
17
+ export { useTypingSound };
18
+ //# sourceMappingURL=use-typing-sound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-typing-sound.d.ts","names":[],"sources":["../../src/hooks/use-typing-sound.ts"],"sourcesContent":[],"mappings":";;AAiBA;;;;;;;;;iBAAgB,cAAA"}
@@ -0,0 +1,38 @@
1
+ import { useSoundEffect } from "./use-sound-effect.js";
2
+ import { useEffect } from "react";
3
+
4
+ //#region src/hooks/use-typing-sound.ts
5
+ const TYPING_SOUND_PATH = "/sounds/typing-loop.wav";
6
+ /**
7
+ * Hook to play a looping typing sound while someone is typing.
8
+ *
9
+ * @param isTyping - Whether someone is currently typing
10
+ * @param options - Optional configuration for volume and playback speed
11
+ *
12
+ * @example
13
+ * const { isTyping } = useTypingIndicator();
14
+ * useTypingSound(isTyping, { volume: 1.0, playbackRate: 1.2 });
15
+ */
16
+ function useTypingSound(isTyping, options) {
17
+ const { play, stop, isPlaying } = useSoundEffect(TYPING_SOUND_PATH, {
18
+ loop: true,
19
+ volume: options?.volume ?? 1.2,
20
+ playbackRate: options?.playbackRate ?? 1
21
+ });
22
+ useEffect(() => {
23
+ if (isTyping && !isPlaying) play();
24
+ else if (!isTyping && isPlaying) stop();
25
+ }, [
26
+ isTyping,
27
+ isPlaying,
28
+ play,
29
+ stop
30
+ ]);
31
+ useEffect(() => () => {
32
+ stop();
33
+ }, [stop]);
34
+ }
35
+
36
+ //#endregion
37
+ export { useTypingSound };
38
+ //# sourceMappingURL=use-typing-sound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-typing-sound.js","names":[],"sources":["../../src/hooks/use-typing-sound.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useSoundEffect } from \"./use-sound-effect\";\n\n// Use a data URL or base64 encoded sound, or a CDN URL\n// For now, we'll use a path that can be served from public directory\nconst TYPING_SOUND_PATH = \"/sounds/typing-loop.wav\";\n\n/**\n * Hook to play a looping typing sound while someone is typing.\n *\n * @param isTyping - Whether someone is currently typing\n * @param options - Optional configuration for volume and playback speed\n *\n * @example\n * const { isTyping } = useTypingIndicator();\n * useTypingSound(isTyping, { volume: 1.0, playbackRate: 1.2 });\n */\nexport function useTypingSound(\n\tisTyping: boolean,\n\toptions?: { volume?: number; playbackRate?: number }\n): void {\n\tconst { play, stop, isPlaying } = useSoundEffect(TYPING_SOUND_PATH, {\n\t\tloop: true,\n\t\tvolume: options?.volume ?? 1.2,\n\t\tplaybackRate: options?.playbackRate ?? 1.0,\n\t});\n\n\tuseEffect(() => {\n\t\tif (isTyping && !isPlaying) {\n\t\t\tplay();\n\t\t} else if (!isTyping && isPlaying) {\n\t\t\tstop();\n\t\t}\n\t}, [isTyping, isPlaying, play, stop]);\n\n\t// Cleanup on unmount\n\tuseEffect(\n\t\t() => () => {\n\t\t\tstop();\n\t\t},\n\t\t[stop]\n\t);\n}\n"],"mappings":";;;;AAKA,MAAM,oBAAoB;;;;;;;;;;;AAY1B,SAAgB,eACf,UACA,SACO;CACP,MAAM,EAAE,MAAM,MAAM,cAAc,eAAe,mBAAmB;EACnE,MAAM;EACN,QAAQ,SAAS,UAAU;EAC3B,cAAc,SAAS,gBAAgB;EACvC,CAAC;AAEF,iBAAgB;AACf,MAAI,YAAY,CAAC,UAChB,OAAM;WACI,CAAC,YAAY,UACvB,OAAM;IAEL;EAAC;EAAU;EAAW;EAAM;EAAK,CAAC;AAGrC,uBACa;AACX,QAAM;IAEP,CAAC,KAAK,CACN"}
package/index.d.ts CHANGED
@@ -19,15 +19,17 @@ import { UseConversationsOptions, UseConversationsResult, useConversations } fro
19
19
  import { CreateConversationVariables, UseCreateConversationOptions, UseCreateConversationResult, useCreateConversation } from "./hooks/use-create-conversation.js";
20
20
  import { UseHomePageOptions, UseHomePageReturn, useHomePage } from "./hooks/use-home-page.js";
21
21
  import { UseMessageComposerOptions, UseMessageComposerReturn, useMessageComposer } from "./hooks/use-message-composer.js";
22
+ import { useNewMessageSound } from "./hooks/use-new-message-sound.js";
22
23
  import { UseRealtimeSupportOptions, UseRealtimeSupportResult, useRealtimeSupport } from "./hooks/use-realtime-support.js";
23
24
  import { UseScrollMaskOptions, UseScrollMaskReturn, useScrollMask } from "./hooks/use-scroll-mask.js";
24
25
  import { SendMessageOptions, SendMessageResult, UseSendMessageOptions, UseSendMessageResult, useSendMessage } from "./hooks/use-send-message.js";
26
+ import { UseSoundEffectOptions, UseSoundEffectReturn, useSoundEffect } from "./hooks/use-sound-effect.js";
27
+ import { useTypingSound } from "./hooks/use-typing-sound.js";
25
28
  import { UseVisitorReturn, useVisitor } from "./hooks/use-visitor.js";
26
29
  import { WindowVisibilityFocusState, useWindowVisibilityFocus } from "./hooks/use-window-visibility-focus.js";
27
30
  import "./hooks/index.js";
28
31
  import { IdentifySupportVisitor, IdentifySupportVisitorProps } from "./identify-visitor.js";
29
32
  import { SupportConfig, SupportConfigProps } from "./support-config.js";
30
- import { Page, PageProps } from "./primitives/page.js";
31
33
  import { index_d_exports } from "./primitives/index.js";
32
34
  import { CossistantContextValue, CossistantProviderProps, SupportContext, SupportProvider, SupportProviderProps, UseSupportValue, useSupport } from "./provider.js";
33
35
  import { RealtimeAuthConfig, RealtimeContextValue, RealtimeProvider, RealtimeProviderProps, useRealtimeConnection } from "./realtime/provider.js";
@@ -36,6 +38,7 @@ import { SupportRealtimeProvider } from "./realtime/support-provider.js";
36
38
  import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, setTypingState } from "./realtime/typing-store.js";
37
39
  import { RealtimeEventHandler, RealtimeEventHandlerEntry, RealtimeEventHandlersMap, RealtimeEventMeta, useRealtime } from "./realtime/use-realtime.js";
38
40
  import "./realtime/index.js";
41
+ import { CustomPage } from "./support/router.js";
39
42
  import { Text, useSupportText } from "./support/text/index.js";
40
43
  import { BubbleSlotProps, ContainerSlotProps, RouterSlotProps } from "./support/types.js";
41
44
  import { CoButton } from "./support/components/button.js";
@@ -43,4 +46,4 @@ import { Header } from "./support/components/header.js";
43
46
  import { WebSocketContextValue, WebSocketProvider, useWebSocket } from "./support/context/websocket.js";
44
47
  import { useSupportConfig, useSupportNavigation, useSupportStore } from "./support/store/support-store.js";
45
48
  import { DefaultRoutes, NavigationState, RouteRegistry, Support, SupportPage, SupportProps } from "./support/index.js";
46
- export { BubbleSlotProps, CoButton as Button, CONVERSATION_AUTO_SEEN_DELAY_MS, ContainerSlotProps, ConversationItem, ConversationLifecycleState, ConversationPreviewAssignedAgent, ConversationPreviewLastMessage, ConversationPreviewTypingParticipant, ConversationPreviewTypingState, ConversationTimelineTypingParticipant, ConversationTypingParticipant, CossistantContextValue, CossistantProviderProps, CreateConversationVariables, DefaultRoutes, GroupedMessage, Header, IdentifySupportVisitor, IdentifySupportVisitorProps, NavigationState, Page, PageProps, index_d_exports as Primitives, RealtimeAuthConfig, RealtimeContextValue, RealtimeEventHandler, RealtimeEventHandlerEntry, RealtimeEventHandlersMap, RealtimeEventMeta, RealtimeProvider, RealtimeProviderProps, RouteRegistry, RouterSlotProps, SendMessageOptions, SendMessageResult, Support, SupportConfig, SupportConfigProps, SupportContext, SupportLocale, SupportPage, SupportProps, SupportProvider, SupportProviderProps, SupportRealtimeProvider, SupportTextContentOverrides, Text, TimelineEventItem, TimelineToolItem, UseClientResult, UseComposerRefocusOptions, UseComposerRefocusReturn, UseConversationAutoSeenOptions, UseConversationHistoryPageOptions, UseConversationHistoryPageReturn, UseConversationLifecycleOptions, UseConversationLifecycleReturn, UseConversationOptions, UseConversationPageOptions, UseConversationPageReturn, UseConversationPreviewOptions, UseConversationPreviewReturn, UseConversationResult, UseConversationTimelineItemsOptions, UseConversationTimelineItemsResult, UseConversationTimelineOptions, UseConversationTimelineReturn, UseConversationsOptions, UseConversationsResult, UseCreateConversationOptions, UseCreateConversationResult, UseGroupedMessagesOptions, UseGroupedMessagesProps, UseHomePageOptions, UseHomePageReturn, UseMessageComposerOptions, UseMessageComposerReturn, UseMultimodalInputOptions, UseMultimodalInputReturn, UseRealtimeSupportOptions, UseRealtimeSupportResult, UseScrollMaskOptions, UseScrollMaskReturn, UseSendMessageOptions, UseSendMessageResult, UseSupportValue, UseVisitorReturn, WebSocketContextValue, WebSocketProvider, WindowVisibilityFocusState, applyConversationSeenEvent, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, hydrateConversationSeen, setTypingState, upsertConversationSeen, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useRealtime, useRealtimeConnection, useRealtimeSupport, useScrollMask, useSendMessage, useSupport, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useVisitor, useWebSocket, useWindowVisibilityFocus };
49
+ export { BubbleSlotProps, CoButton as Button, CONVERSATION_AUTO_SEEN_DELAY_MS, ContainerSlotProps, ConversationItem, ConversationLifecycleState, ConversationPreviewAssignedAgent, ConversationPreviewLastMessage, ConversationPreviewTypingParticipant, ConversationPreviewTypingState, ConversationTimelineTypingParticipant, ConversationTypingParticipant, CossistantContextValue, CossistantProviderProps, CreateConversationVariables, CustomPage, DefaultRoutes, GroupedMessage, Header, IdentifySupportVisitor, IdentifySupportVisitorProps, NavigationState, index_d_exports as Primitives, RealtimeAuthConfig, RealtimeContextValue, RealtimeEventHandler, RealtimeEventHandlerEntry, RealtimeEventHandlersMap, RealtimeEventMeta, RealtimeProvider, RealtimeProviderProps, RouteRegistry, RouterSlotProps, SendMessageOptions, SendMessageResult, Support, SupportConfig, SupportConfigProps, SupportContext, SupportLocale, SupportPage, SupportProps, SupportProvider, SupportProviderProps, SupportRealtimeProvider, SupportTextContentOverrides, Text, TimelineEventItem, TimelineToolItem, UseClientResult, UseComposerRefocusOptions, UseComposerRefocusReturn, UseConversationAutoSeenOptions, UseConversationHistoryPageOptions, UseConversationHistoryPageReturn, UseConversationLifecycleOptions, UseConversationLifecycleReturn, UseConversationOptions, UseConversationPageOptions, UseConversationPageReturn, UseConversationPreviewOptions, UseConversationPreviewReturn, UseConversationResult, UseConversationTimelineItemsOptions, UseConversationTimelineItemsResult, UseConversationTimelineOptions, UseConversationTimelineReturn, UseConversationsOptions, UseConversationsResult, UseCreateConversationOptions, UseCreateConversationResult, UseGroupedMessagesOptions, UseGroupedMessagesProps, UseHomePageOptions, UseHomePageReturn, UseMessageComposerOptions, UseMessageComposerReturn, UseMultimodalInputOptions, UseMultimodalInputReturn, UseRealtimeSupportOptions, UseRealtimeSupportResult, UseScrollMaskOptions, UseScrollMaskReturn, UseSendMessageOptions, UseSendMessageResult, UseSoundEffectOptions, UseSoundEffectReturn, UseSupportValue, UseVisitorReturn, WebSocketContextValue, WebSocketProvider, WindowVisibilityFocusState, applyConversationSeenEvent, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, hydrateConversationSeen, setTypingState, upsertConversationSeen, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useNewMessageSound, useRealtime, useRealtimeConnection, useRealtimeSupport, useScrollMask, useSendMessage, useSoundEffect, useSupport, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useTypingSound, useVisitor, useWebSocket, useWindowVisibilityFocus };
package/index.js CHANGED
@@ -1,15 +1,14 @@
1
1
  import { useClientQuery } from "./hooks/private/use-client-query.js";
2
2
  import { useClient } from "./hooks/private/use-rest-client.js";
3
3
  import { applyConversationSeenEvent, hydrateConversationSeen, upsertConversationSeen } from "./realtime/seen-store.js";
4
- import { SupportConfig } from "./support-config.js";
4
+ import { RealtimeProvider, useRealtimeConnection } from "./realtime/provider.js";
5
5
  import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, setTypingState } from "./realtime/typing-store.js";
6
+ import { useRealtime } from "./realtime/use-realtime.js";
7
+ import { SupportRealtimeProvider } from "./realtime/support-provider.js";
8
+ import { SupportConfig } from "./support-config.js";
6
9
  import { useScrollMask } from "./hooks/use-scroll-mask.js";
7
- import { Page } from "./primitives/page.js";
8
10
  import { useSupportConfig, useSupportNavigation, useSupportStore } from "./support/store/support-store.js";
9
11
  import { primitives_exports } from "./primitives/index.js";
10
- import { RealtimeProvider, useRealtimeConnection } from "./realtime/provider.js";
11
- import { useRealtime } from "./realtime/use-realtime.js";
12
- import { SupportRealtimeProvider } from "./realtime/support-provider.js";
13
12
  import { CoButton } from "./support/components/button.js";
14
13
  import { Header } from "./support/components/header.js";
15
14
  import { Text, useSupportText } from "./support/text/index.js";
@@ -22,10 +21,13 @@ import { useMultimodalInput } from "./hooks/private/use-multimodal-input.js";
22
21
  import { useSendMessage } from "./hooks/use-send-message.js";
23
22
  import { useMessageComposer } from "./hooks/use-message-composer.js";
24
23
  import { useConversationPage } from "./hooks/use-conversation-page.js";
24
+ import { useSoundEffect } from "./hooks/use-sound-effect.js";
25
+ import { useNewMessageSound } from "./hooks/use-new-message-sound.js";
25
26
  import { useGroupedMessages } from "./hooks/private/use-grouped-messages.js";
26
27
  import { useConversationSeen, useDebouncedConversationSeen } from "./hooks/use-conversation-seen.js";
27
28
  import { useConversationTyping } from "./hooks/use-conversation-typing.js";
28
29
  import { useConversationTimeline } from "./hooks/use-conversation-timeline.js";
30
+ import { useTypingSound } from "./hooks/use-typing-sound.js";
29
31
  import { useComposerRefocus } from "./hooks/use-composer-refocus.js";
30
32
  import { useVisitor } from "./hooks/use-visitor.js";
31
33
  import { useConversations } from "./hooks/use-conversations.js";
@@ -40,4 +42,4 @@ import { useCreateConversation } from "./hooks/use-create-conversation.js";
40
42
  import { useRealtimeSupport } from "./hooks/use-realtime-support.js";
41
43
  import { IdentifySupportVisitor } from "./identify-visitor.js";
42
44
 
43
- export { CoButton as Button, CONVERSATION_AUTO_SEEN_DELAY_MS, Header, IdentifySupportVisitor, Page, primitives_exports as Primitives, RealtimeProvider, Support, SupportConfig, SupportContext, SupportProvider, SupportRealtimeProvider, Text, WebSocketProvider, applyConversationSeenEvent, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, hydrateConversationSeen, setTypingState, upsertConversationSeen, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useRealtime, useRealtimeConnection, useRealtimeSupport, useScrollMask, useSendMessage, useSupport, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useVisitor, useWebSocket, useWindowVisibilityFocus };
45
+ export { CoButton as Button, CONVERSATION_AUTO_SEEN_DELAY_MS, Header, IdentifySupportVisitor, primitives_exports as Primitives, RealtimeProvider, Support, SupportConfig, SupportContext, SupportProvider, SupportRealtimeProvider, Text, WebSocketProvider, applyConversationSeenEvent, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, hydrateConversationSeen, setTypingState, upsertConversationSeen, useClient, useClientQuery, useComposerRefocus, useConversation, useConversationAutoSeen, useConversationHistoryPage, useConversationLifecycle, useConversationPage, useConversationPreview, useConversationSeen, useConversationTimeline, useConversationTimelineItems, useConversationTyping, useConversations, useCreateConversation, useDebouncedConversationSeen, useDefaultMessages, useGroupedMessages, useHomePage, useMessageComposer, useMultimodalInput, useNewMessageSound, useRealtime, useRealtimeConnection, useRealtimeSupport, useScrollMask, useSendMessage, useSoundEffect, useSupport, useSupportConfig, useSupportNavigation, useSupportStore, useSupportText, useTypingSound, useVisitor, useWebSocket, useWindowVisibilityFocus };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cossistant/react",
3
3
  "type": "module",
4
- "version": "0.0.20",
4
+ "version": "0.0.22",
5
5
  "private": false,
6
6
  "author": "Cossistant team",
7
7
  "description": "Headless React SDK for building AI-powered support/chat widgets. Hooks + primitives, WS-driven, TypeScript-first. Next.js-ready, Tailwind optional.",
@@ -88,8 +88,8 @@
88
88
  "*.css"
89
89
  ],
90
90
  "dependencies": {
91
- "@cossistant/core": "0.0.20",
92
- "@cossistant/types": "0.0.20",
91
+ "@cossistant/core": "0.0.22",
92
+ "@cossistant/types": "0.0.22",
93
93
  "class-variance-authority": "^0.7.1",
94
94
  "clsx": "^2.1.1",
95
95
  "nanoid": "^5.1.5",
@@ -1,5 +1,5 @@
1
- import { useRenderElement } from "../utils/use-render-element.js";
2
1
  import { useTypingStore } from "../realtime/typing-store.js";
2
+ import { useRenderElement } from "../utils/use-render-element.js";
3
3
  import { useSupportConfig } from "../support/store/support-store.js";
4
4
  import { useSupport } from "../provider.js";
5
5
  import * as React$1 from "react";
@@ -7,9 +7,7 @@ import { SupportBubble } from "./bubble.js";
7
7
  import { Button } from "./button.js";
8
8
  import { ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading } from "./conversation-timeline.js";
9
9
  import { FileInput, MultimodalInput, SupportInput } from "./multimodal-input.js";
10
- import { Page, PageProps } from "./page.js";
11
- import { PageRegistryProvider, usePageRegistry, useRegisterPage } from "./page-registry.js";
12
- import { Router, RouterProps } from "./router.js";
10
+ import { PageDefinition, Router, RouterProps } from "./router.js";
13
11
  import { TimelineItem, TimelineItemContent, TimelineItemTimestamp } from "./timeline-item.js";
14
12
  import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator } from "./timeline-item-group.js";
15
13
  import { SupportWindow } from "./window.js";
@@ -17,8 +15,8 @@ import "./index.parts.js";
17
15
 
18
16
  //#region src/primitives/index.d.ts
19
17
  declare namespace index_d_exports {
20
- export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Page, PageProps, PageRegistryProvider, Router, RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, TypingIndicatorProps, TypingParticipant, TypingParticipantType, SupportWindow as Window, usePageRegistry, useRegisterPage };
18
+ export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, PageDefinition, Router, RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, TypingIndicatorProps, TypingParticipant, TypingParticipantType, SupportWindow as Window };
21
19
  }
22
20
  //#endregion
23
- export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Page, PageProps, PageRegistryProvider, Router, RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, TypingIndicatorProps, TypingParticipant, TypingParticipantType, SupportWindow as Window, index_d_exports, usePageRegistry, useRegisterPage };
21
+ export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, PageDefinition, Router, RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, TypingIndicatorProps, TypingParticipant, TypingParticipantType, SupportWindow as Window, index_d_exports };
24
22
  //# sourceMappingURL=index.d.ts.map
@@ -1,15 +1,13 @@
1
1
  import { __export } from "../_virtual/rolldown_runtime.js";
2
+ import { SupportConfig } from "../support-config.js";
2
3
  import { Avatar } from "./avatar/avatar.js";
3
4
  import { AvatarFallback } from "./avatar/fallback.js";
4
5
  import { AvatarImage } from "./avatar/image.js";
5
6
  import { TypingIndicator } from "../support/components/typing-indicator.js";
6
- import { SupportConfig } from "../support-config.js";
7
7
  import { SupportBubble } from "./bubble.js";
8
8
  import { Button } from "./button.js";
9
9
  import { ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading } from "./conversation-timeline.js";
10
10
  import { FileInput, MultimodalInput, SupportInput } from "./multimodal-input.js";
11
- import { PageRegistryProvider, usePageRegistry, useRegisterPage } from "./page-registry.js";
12
- import { Page } from "./page.js";
13
11
  import { Router } from "./router.js";
14
12
  import { TimelineItem, TimelineItemContent, TimelineItemTimestamp } from "./timeline-item.js";
15
13
  import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator } from "./timeline-item-group.js";
@@ -30,8 +28,6 @@ var primitives_exports = /* @__PURE__ */ __export({
30
28
  FileInput: () => FileInput,
31
29
  Input: () => SupportInput,
32
30
  MultimodalInput: () => MultimodalInput,
33
- Page: () => Page,
34
- PageRegistryProvider: () => PageRegistryProvider,
35
31
  Router: () => Router,
36
32
  TimelineItem: () => TimelineItem,
37
33
  TimelineItemContent: () => TimelineItemContent,
@@ -43,11 +39,9 @@ var primitives_exports = /* @__PURE__ */ __export({
43
39
  TimelineItemGroupSeenIndicator: () => TimelineItemGroupSeenIndicator,
44
40
  TimelineItemTimestamp: () => TimelineItemTimestamp,
45
41
  TypingIndicator: () => TypingIndicator,
46
- Window: () => SupportWindow,
47
- usePageRegistry: () => usePageRegistry,
48
- useRegisterPage: () => useRegisterPage
42
+ Window: () => SupportWindow
49
43
  });
50
44
 
51
45
  //#endregion
52
- export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Page, PageRegistryProvider, Router, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, SupportWindow as Window, primitives_exports, usePageRegistry, useRegisterPage };
46
+ export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Router, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, SupportWindow as Window, primitives_exports };
53
47
  //# sourceMappingURL=index.js.map
@@ -8,10 +8,8 @@ import { SupportBubble } from "./bubble.js";
8
8
  import { Button } from "./button.js";
9
9
  import { ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading } from "./conversation-timeline.js";
10
10
  import { FileInput, MultimodalInput, SupportInput } from "./multimodal-input.js";
11
- import { Page, PageProps } from "./page.js";
12
- import { PageRegistryProvider, usePageRegistry, useRegisterPage } from "./page-registry.js";
13
- import { Router, RouterProps } from "./router.js";
11
+ import { PageDefinition, Router, RouterProps } from "./router.js";
14
12
  import { TimelineItem, TimelineItemContent, TimelineItemTimestamp } from "./timeline-item.js";
15
13
  import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator } from "./timeline-item-group.js";
16
14
  import { SupportWindow } from "./window.js";
17
- export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Page, type PageProps, PageRegistryProvider, Router, type RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, type TypingIndicatorProps, type TypingParticipant, type TypingParticipantType, SupportWindow as Window, usePageRegistry, useRegisterPage };
15
+ export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, type PageDefinition, Router, type RouterProps, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, type TypingIndicatorProps, type TypingParticipant, type TypingParticipantType, SupportWindow as Window };
@@ -1,17 +1,15 @@
1
+ import { SupportConfig } from "../support-config.js";
1
2
  import { Avatar } from "./avatar/avatar.js";
2
3
  import { AvatarFallback } from "./avatar/fallback.js";
3
4
  import { AvatarImage } from "./avatar/image.js";
4
5
  import { TypingIndicator } from "../support/components/typing-indicator.js";
5
- import { SupportConfig } from "../support-config.js";
6
6
  import { SupportBubble } from "./bubble.js";
7
7
  import { Button } from "./button.js";
8
8
  import { ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading } from "./conversation-timeline.js";
9
9
  import { FileInput, MultimodalInput, SupportInput } from "./multimodal-input.js";
10
- import { PageRegistryProvider, usePageRegistry, useRegisterPage } from "./page-registry.js";
11
- import { Page } from "./page.js";
12
10
  import { Router } from "./router.js";
13
11
  import { TimelineItem, TimelineItemContent, TimelineItemTimestamp } from "./timeline-item.js";
14
12
  import { TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator } from "./timeline-item-group.js";
15
13
  import { SupportWindow } from "./window.js";
16
14
 
17
- export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Page, PageRegistryProvider, Router, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, SupportWindow as Window, usePageRegistry, useRegisterPage };
15
+ export { Avatar, AvatarFallback, AvatarImage, SupportBubble as Bubble, Button, SupportConfig as Config, ConversationTimeline, ConversationTimelineContainer, ConversationTimelineEmpty, ConversationTimelineLoading, FileInput, SupportInput as Input, MultimodalInput, Router, TimelineItem, TimelineItemContent, TimelineItemGroup, TimelineItemGroupAvatar, TimelineItemGroupContent, TimelineItemGroupHeader, TimelineItemGroupReadIndicator, TimelineItemGroupSeenIndicator, TimelineItemTimestamp, TypingIndicator, SupportWindow as Window };
@@ -1,35 +1,34 @@
1
1
  import React from "react";
2
+ import { RouteRegistry } from "@cossistant/core";
2
3
 
3
4
  //#region src/primitives/router.d.ts
5
+ type PageDefinition<K extends keyof RouteRegistry = keyof RouteRegistry> = {
6
+ name: K;
7
+ component: React.ComponentType<{
8
+ params?: RouteRegistry[K];
9
+ }>;
10
+ };
4
11
  type RouterProps = {
5
- /**
6
- * Current page name to render
7
- */
8
- page: string;
9
- /**
10
- * Params to pass to the page component
11
- */
12
- params?: unknown;
13
- /**
14
- * Fallback component when page is not found
15
- */
12
+ page: keyof RouteRegistry;
13
+ params?: RouteRegistry[keyof RouteRegistry];
14
+ pages: PageDefinition[];
16
15
  fallback?: React.ComponentType<{
17
16
  params?: unknown;
18
17
  }>;
19
- /**
20
- * Children (Page components for registration)
21
- */
22
- children?: React.ReactNode;
23
18
  };
24
19
  /**
25
- * Router that renders registered pages based on current page name.
20
+ * Type-safe router that renders pages based on current page name.
21
+ * Pages are matched synchronously without effects or registries.
26
22
  *
27
23
  * @example
28
- * <Router page={currentPage} params={params} fallback={NotFoundPage}>
29
- * <Page name="HOME" component={HomePage} />
30
- * </Router>
24
+ * const pages = [
25
+ * { name: "HOME", component: HomePage },
26
+ * { name: "SETTINGS", component: SettingsPage }
27
+ * ];
28
+ *
29
+ * <Router page={currentPage} params={params} pages={pages} fallback={NotFoundPage} />
31
30
  */
32
31
  declare const Router: React.FC<RouterProps>;
33
32
  //#endregion
34
- export { Router, RouterProps };
33
+ export { PageDefinition, Router, RouterProps };
35
34
  //# sourceMappingURL=router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","names":[],"sources":["../../src/primitives/router.tsx"],"sourcesContent":[],"mappings":";;;KAGY,WAAA;;AAAZ;AA8BA;;;;;;;;;aAhBY,KAAA,CAAM;;;;;;aAKN,KAAA,CAAM;;;;;;;;;;cAWL,QAAQ,KAAA,CAAM,GAAG"}
1
+ {"version":3,"file":"router.d.ts","names":[],"sources":["../../src/primitives/router.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,+BACK,sBAAsB;QAEhC;EAHK,SAAA,EAIA,KAAA,CAAM,aAJQ,CAAA;IACT,MAAA,CAAA,EAG0B,aAH1B,CAGwC,CAHxC,CAAA;EAAsB,CAAA,CAAA;CAEhC;AACoC,KAI/B,WAAA,GAJ+B;EAAc,IAAA,EAAA,MAK5C,aAL4C;EAA7C,MAAM,CAAA,EAMR,aANQ,CAAA,MAMY,aANZ,CAAA;EAAa,KAAA,EAOvB,cAPuB,EAAA;EAInB,QAAA,CAAA,EAIA,KAAA,CAAM,aAJK,CAAA;IACV,MAAA,CAAA,EAAA,OAAA;EACH,CAAA,CAAA;CAAoB;;;;AAiB9B;;;;;;;;;cAAa,QAAQ,KAAA,CAAM,GAAG"}
@@ -1,20 +1,26 @@
1
- import { usePageRegistry } from "./page-registry.js";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
3
2
 
4
3
  //#region src/primitives/router.tsx
5
4
  /**
6
- * Router that renders registered pages based on current page name.
5
+ * Type-safe router that renders pages based on current page name.
6
+ * Pages are matched synchronously without effects or registries.
7
7
  *
8
8
  * @example
9
- * <Router page={currentPage} params={params} fallback={NotFoundPage}>
10
- * <Page name="HOME" component={HomePage} />
11
- * </Router>
9
+ * const pages = [
10
+ * { name: "HOME", component: HomePage },
11
+ * { name: "SETTINGS", component: SettingsPage }
12
+ * ];
13
+ *
14
+ * <Router page={currentPage} params={params} pages={pages} fallback={NotFoundPage} />
12
15
  */
13
- const Router = ({ page, params, fallback: Fallback, children }) => {
14
- const PageComponent = usePageRegistry().get(page);
15
- if (PageComponent) return /* @__PURE__ */ jsxs(Fragment, { children: [children, /* @__PURE__ */ jsx(PageComponent, { params })] });
16
- if (Fallback) return /* @__PURE__ */ jsxs(Fragment, { children: [children, /* @__PURE__ */ jsx(Fallback, { params })] });
17
- return /* @__PURE__ */ jsx(Fragment, { children });
16
+ const Router = ({ page, params, pages, fallback: Fallback }) => {
17
+ const matchedPage = pages.find((p) => p.name === page);
18
+ if (matchedPage) {
19
+ const Component = matchedPage.component;
20
+ return /* @__PURE__ */ jsx(Component, { params });
21
+ }
22
+ if (Fallback) return /* @__PURE__ */ jsx(Fallback, { params });
23
+ return null;
18
24
  };
19
25
 
20
26
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","names":["Router: React.FC<RouterProps>"],"sources":["../../src/primitives/router.tsx"],"sourcesContent":["import type React from \"react\";\nimport { usePageRegistry } from \"./page-registry\";\n\nexport type RouterProps = {\n\t/**\n\t * Current page name to render\n\t */\n\tpage: string;\n\n\t/**\n\t * Params to pass to the page component\n\t */\n\tparams?: unknown;\n\n\t/**\n\t * Fallback component when page is not found\n\t */\n\tfallback?: React.ComponentType<{ params?: unknown }>;\n\n\t/**\n\t * Children (Page components for registration)\n\t */\n\tchildren?: React.ReactNode;\n};\n\n/**\n * Router that renders registered pages based on current page name.\n *\n * @example\n * <Router page={currentPage} params={params} fallback={NotFoundPage}>\n * <Page name=\"HOME\" component={HomePage} />\n * </Router>\n */\nexport const Router: React.FC<RouterProps> = ({\n\tpage,\n\tparams,\n\tfallback: Fallback,\n\tchildren,\n}) => {\n\tconst registry = usePageRegistry();\n\n\t// Render children first (they register pages via useEffect)\n\t// Page components return null, so this is effectively a no-op render\n\n\t// Get the page component from registry\n\tconst PageComponent = registry.get(page);\n\n\tif (PageComponent) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{children}\n\t\t\t\t<PageComponent params={params} />\n\t\t\t</>\n\t\t);\n\t}\n\n\t// Fall back if provided\n\tif (Fallback) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{children}\n\t\t\t\t<Fallback params={params} />\n\t\t\t</>\n\t\t);\n\t}\n\n\treturn <>{children}</>;\n};\n"],"mappings":";;;;;;;;;;;;AAiCA,MAAaA,UAAiC,EAC7C,MACA,QACA,UAAU,UACV,eACK;CAOL,MAAM,gBANW,iBAAiB,CAMH,IAAI,KAAK;AAExC,KAAI,cACH,QACC,4CACE,UACD,oBAAC,iBAAsB,SAAU,IAC/B;AAKL,KAAI,SACH,QACC,4CACE,UACD,oBAAC,YAAiB,SAAU,IAC1B;AAIL,QAAO,gCAAG,WAAY"}
1
+ {"version":3,"file":"router.js","names":["Router: React.FC<RouterProps>"],"sources":["../../src/primitives/router.tsx"],"sourcesContent":["import type { RouteRegistry } from \"@cossistant/core\";\nimport type React from \"react\";\n\n// Type-safe page definition that extracts params from RouteRegistry\nexport type PageDefinition<\n\tK extends keyof RouteRegistry = keyof RouteRegistry,\n> = {\n\tname: K;\n\tcomponent: React.ComponentType<{ params?: RouteRegistry[K] }>;\n};\n\n// Router props that maintain type safety\nexport type RouterProps = {\n\tpage: keyof RouteRegistry;\n\tparams?: RouteRegistry[keyof RouteRegistry];\n\tpages: PageDefinition[];\n\tfallback?: React.ComponentType<{ params?: unknown }>;\n};\n\n/**\n * Type-safe router that renders pages based on current page name.\n * Pages are matched synchronously without effects or registries.\n *\n * @example\n * const pages = [\n * { name: \"HOME\", component: HomePage },\n * { name: \"SETTINGS\", component: SettingsPage }\n * ];\n *\n * <Router page={currentPage} params={params} pages={pages} fallback={NotFoundPage} />\n */\nexport const Router: React.FC<RouterProps> = ({\n\tpage,\n\tparams,\n\tpages,\n\tfallback: Fallback,\n}) => {\n\t// Find matching page (synchronous, no effects!)\n\tconst matchedPage = pages.find((p) => p.name === page);\n\n\tif (matchedPage) {\n\t\tconst Component = matchedPage.component;\n\t\treturn <Component params={params} />;\n\t}\n\n\t// Fall back if provided\n\tif (Fallback) {\n\t\treturn <Fallback params={params} />;\n\t}\n\n\treturn null;\n};\n"],"mappings":";;;;;;;;;;;;;;;AA+BA,MAAaA,UAAiC,EAC7C,MACA,QACA,OACA,UAAU,eACL;CAEL,MAAM,cAAc,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK;AAEtD,KAAI,aAAa;EAChB,MAAM,YAAY,YAAY;AAC9B,SAAO,oBAAC,aAAkB,SAAU;;AAIrC,KAAI,SACH,QAAO,oBAAC,YAAiB,SAAU;AAGpC,QAAO"}
package/realtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { applyConversationSeenEvent, hydrateConversationSeen, upsertConversationSeen } from "./seen-store.js";
2
- import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, setTypingState } from "./typing-store.js";
3
2
  import { RealtimeProvider, useRealtimeConnection } from "./provider.js";
3
+ import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, setTypingState } from "./typing-store.js";
4
4
  import { useRealtime } from "./use-realtime.js";
5
5
  import { SupportRealtimeProvider } from "./support-provider.js";
6
6
 
@@ -2,9 +2,9 @@
2
2
 
3
3
 
4
4
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
5
- import { jsx } from "react/jsx-runtime";
6
5
  import { isValidEventType, validateRealtimeEvent } from "@cossistant/types/realtime-events";
7
6
  import useWebSocket, { ReadyState } from "react-use-websocket";
7
+ import { jsx } from "react/jsx-runtime";
8
8
 
9
9
  //#region src/realtime/provider.tsx
10
10
  const DEFAULT_HEARTBEAT_INTERVAL_MS = 15e3;
@@ -171,6 +171,13 @@ declare const realtimeSchema: {
171
171
  mediaType: ZodString;
172
172
  fileName: ZodOptional<ZodString>;
173
173
  size: ZodOptional<ZodNumber>;
174
+ }, $strip>, ZodObject<{
175
+ type: ZodLiteral<"metadata">;
176
+ source: ZodEnum<{
177
+ email: "email";
178
+ widget: "widget";
179
+ api: "api";
180
+ }>;
174
181
  }, $strip>]>>;
175
182
  userId: ZodNullable<ZodString>;
176
183
  aiAgentId: ZodNullable<ZodString>;
@@ -277,6 +284,13 @@ declare const realtimeSchema: {
277
284
  mediaType: ZodString;
278
285
  fileName: ZodOptional<ZodString>;
279
286
  size: ZodOptional<ZodNumber>;
287
+ }, $strip>, ZodObject<{
288
+ type: ZodLiteral<"metadata">;
289
+ source: ZodEnum<{
290
+ email: "email";
291
+ widget: "widget";
292
+ api: "api";
293
+ }>;
280
294
  }, $strip>]>>;
281
295
  userId: ZodNullable<ZodString>;
282
296
  aiAgentId: ZodNullable<ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmED,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,eACvD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB;;KAGnB,gBAAA,WACL,oBAAoB,cAAc,KACvC;KAEU,4BAA4B,qBACvC,qBAAqB"}
1
+ {"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmED,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,eACvD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB;;KAGnB,gBAAA,WACL,oBAAoB,cAAc,KACvC;KAEU,4BAA4B,qBACvC,qBAAqB"}
package/schemas3.d.ts CHANGED
@@ -72,6 +72,13 @@ declare const conversationSchema: ZodObject<{
72
72
  mediaType: ZodString;
73
73
  fileName: ZodOptional<ZodString>;
74
74
  size: ZodOptional<ZodNumber>;
75
+ }, $strip>, ZodObject<{
76
+ type: ZodLiteral<"metadata">;
77
+ source: ZodEnum<{
78
+ email: "email";
79
+ widget: "widget";
80
+ api: "api";
81
+ }>;
75
82
  }, $strip>]>>;
76
83
  userId: ZodNullable<ZodString>;
77
84
  aiAgentId: ZodNullable<ZodString>;
package/schemas3.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"schemas3.d.ts","names":[],"sources":["../../types/src/schemas.ts"],"sourcesContent":[],"mappings":";;;;;;cAkBa,oBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,SAAA,aAAA,YAAA,UAAA,CAAA,CAAA;EAAA,CAAA,QAAA,CAAA,CAAA;AAkB/B,CAAA,QAAY,CAAA;AAEC,KAFD,YAAA,GAAe,MAYzB,CAAA,OAZwC,kBAYxC,CAAA;cAVW,wBAAsB;;;;;;;;;;;KAYvB,gBAAA,GAAmB,cAAe"}
1
+ {"version":3,"file":"schemas3.d.ts","names":[],"sources":["../../types/src/schemas.ts"],"sourcesContent":[],"mappings":";;;;;;cAkBa,oBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAA,SAAA,aAAA,UAAA,CAAA;IAAA,SAAA,aAAA,UAAA,CAAA;IAkBnB,SAAA,WAAY;IAEX,SAAA,aAUX,YAAA,UAAA,CAAA,CAAA;;;KAZU,YAAA,GAAe,cAAe;cAE7B,wBAAsB;;;;;;;;;;;AAAA,KAYvB,gBAAA,GAAmB,MAZI,CAAA,OAYW,sBAZX,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"bubble.d.ts","names":[],"sources":["../../../src/support/components/bubble.tsx"],"sourcesContent":[],"mappings":";;;KASY,WAAA;;AAAZ,CAAA;AAIa,cAAA,MAAiB,EAAT,KAAA,CAAM,EAAG,CAAA,WAAD,CAAA"}
1
+ {"version":3,"file":"bubble.d.ts","names":[],"sources":["../../../src/support/components/bubble.tsx"],"sourcesContent":[],"mappings":";;;KAgIY,WAAA;;AAAZ,CAAA;AAIa,cAAA,MAAiB,EAAT,KAAA,CAAM,EAAG,CAAA,WAAD,CAAA"}