@memberjunction/ng-conversations 5.43.0 → 5.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +0 -1
  2. package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -1
  3. package/dist/lib/components/active-tasks/active-tasks-panel.component.js +56 -52
  4. package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
  5. package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +3 -1
  6. package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
  7. package/dist/lib/components/artifact/artifact-share-modal.component.js +52 -52
  8. package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
  9. package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
  10. package/dist/lib/components/collection/collection-form-modal.component.js +10 -14
  11. package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
  12. package/dist/lib/components/collection/collection-share-modal.component.d.ts +3 -1
  13. package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
  14. package/dist/lib/components/collection/collection-share-modal.component.js +56 -56
  15. package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
  16. package/dist/lib/components/collection/collection-tree.component.d.ts +3 -1
  17. package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
  18. package/dist/lib/components/collection/collection-tree.component.js +10 -7
  19. package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
  20. package/dist/lib/components/collection/collection-view.component.d.ts +3 -1
  21. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  22. package/dist/lib/components/collection/collection-view.component.js +29 -41
  23. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  24. package/dist/lib/components/collection/collections-full-view.component.d.ts +4 -0
  25. package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
  26. package/dist/lib/components/collection/collections-full-view.component.js +134 -166
  27. package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
  28. package/dist/lib/components/composer/ai-composer.component.d.ts +103 -0
  29. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -0
  30. package/dist/lib/components/composer/ai-composer.component.js +263 -0
  31. package/dist/lib/components/composer/ai-composer.component.js.map +1 -0
  32. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +76 -12
  33. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  34. package/dist/lib/components/conversation/conversation-chat-area.component.js +522 -158
  35. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  36. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -1
  37. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
  38. package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
  39. package/dist/lib/components/conversation/pinned-messages-panel.component.js +6 -9
  40. package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
  41. package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
  42. package/dist/lib/components/library/library-full-view.component.js +20 -24
  43. package/dist/lib/components/library/library-full-view.component.js.map +1 -1
  44. package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
  45. package/dist/lib/components/members/members-modal.component.js +10 -11
  46. package/dist/lib/components/members/members-modal.component.js.map +1 -1
  47. package/dist/lib/components/message/message-input.component.d.ts +87 -23
  48. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  49. package/dist/lib/components/message/message-input.component.js +245 -158
  50. package/dist/lib/components/message/message-input.component.js.map +1 -1
  51. package/dist/lib/components/message/message-item.component.d.ts +11 -3
  52. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  53. package/dist/lib/components/message/message-item.component.js +73 -21
  54. package/dist/lib/components/message/message-item.component.js.map +1 -1
  55. package/dist/lib/components/message/message-list.component.js +6 -9
  56. package/dist/lib/components/message/message-list.component.js.map +1 -1
  57. package/dist/lib/components/overlay/chat-overlay.component.d.ts +4 -1
  58. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  59. package/dist/lib/components/overlay/chat-overlay.component.js +9 -4
  60. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  61. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +45 -0
  62. package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +1 -1
  63. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +10 -0
  64. package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +1 -1
  65. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +46 -0
  66. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -0
  67. package/dist/lib/components/realtime/channels/client-context-channel.js +174 -0
  68. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -0
  69. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts +123 -0
  70. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.d.ts.map +1 -0
  71. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +397 -0
  72. package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js.map +1 -0
  73. package/dist/lib/components/realtime/media/media-channel-state.d.ts +103 -0
  74. package/dist/lib/components/realtime/media/media-channel-state.d.ts.map +1 -0
  75. package/dist/lib/components/realtime/media/media-channel-state.js +143 -0
  76. package/dist/lib/components/realtime/media/media-channel-state.js.map +1 -0
  77. package/dist/lib/components/realtime/media/media-channel-tools.d.ts +24 -0
  78. package/dist/lib/components/realtime/media/media-channel-tools.d.ts.map +1 -0
  79. package/dist/lib/components/realtime/media/media-channel-tools.js +107 -0
  80. package/dist/lib/components/realtime/media/media-channel-tools.js.map +1 -0
  81. package/dist/lib/components/realtime/media/media-channel.d.ts +89 -0
  82. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -0
  83. package/dist/lib/components/realtime/media/media-channel.js +253 -0
  84. package/dist/lib/components/realtime/media/media-channel.js.map +1 -0
  85. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts +141 -0
  86. package/dist/lib/components/realtime/media/realtime-media-surface.component.d.ts.map +1 -0
  87. package/dist/lib/components/realtime/media/realtime-media-surface.component.js +574 -0
  88. package/dist/lib/components/realtime/media/realtime-media-surface.component.js.map +1 -0
  89. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +59 -14
  90. package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
  91. package/dist/lib/components/realtime/realtime-activity-rail.component.js +277 -74
  92. package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
  93. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +28 -27
  94. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  95. package/dist/lib/components/realtime/realtime-agent-banner.component.js +144 -143
  96. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  97. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +12 -0
  98. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  99. package/dist/lib/components/realtime/realtime-agent-picker.component.js +105 -43
  100. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  101. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +2 -2
  102. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  103. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  104. package/dist/lib/components/realtime/realtime-composer.component.d.ts +41 -7
  105. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  106. package/dist/lib/components/realtime/realtime-composer.component.js +216 -102
  107. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  108. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +0 -2
  109. package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
  110. package/dist/lib/components/realtime/realtime-delegation-card.component.js +67 -71
  111. package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
  112. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +364 -44
  113. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  114. package/dist/lib/components/realtime/realtime-session-overlay.component.js +839 -153
  115. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  116. package/dist/lib/components/realtime/realtime-session-state.d.ts +5 -5
  117. package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
  118. package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
  119. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts +70 -0
  120. package/dist/lib/components/realtime/realtime-surface-tab-style.d.ts.map +1 -0
  121. package/dist/lib/components/realtime/realtime-surface-tab-style.js +115 -0
  122. package/dist/lib/components/realtime/realtime-surface-tab-style.js.map +1 -0
  123. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +55 -57
  124. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  125. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +165 -143
  126. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  127. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +80 -71
  128. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  129. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +83 -113
  130. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  131. package/dist/lib/components/realtime/realtime-ui-config.d.ts +270 -0
  132. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -0
  133. package/dist/lib/components/realtime/realtime-ui-config.js +212 -0
  134. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -0
  135. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  136. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  137. package/dist/lib/components/search/search-panel.component.js +92 -101
  138. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  139. package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
  140. package/dist/lib/components/share/share-modal.component.js +10 -11
  141. package/dist/lib/components/share/share-modal.component.js.map +1 -1
  142. package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
  143. package/dist/lib/components/shared/user-picker.component.js +12 -15
  144. package/dist/lib/components/shared/user-picker.component.js.map +1 -1
  145. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +11 -3
  146. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
  147. package/dist/lib/components/sidebar/conversation-sidebar.component.js +34 -10
  148. package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
  149. package/dist/lib/components/sidebar/routines-section.component.d.ts +73 -0
  150. package/dist/lib/components/sidebar/routines-section.component.d.ts.map +1 -0
  151. package/dist/lib/components/sidebar/routines-section.component.js +211 -0
  152. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -0
  153. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +12 -0
  154. package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
  155. package/dist/lib/components/tasks/tasks-dropdown.component.js +37 -1
  156. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  157. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +16 -5
  158. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  159. package/dist/lib/components/workspace/conversation-workspace.component.js +51 -31
  160. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  161. package/dist/lib/composer-plugins/agent-mention.provider.d.ts +16 -0
  162. package/dist/lib/composer-plugins/agent-mention.provider.d.ts.map +1 -0
  163. package/dist/lib/composer-plugins/agent-mention.provider.js +28 -0
  164. package/dist/lib/composer-plugins/agent-mention.provider.js.map +1 -0
  165. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +20 -0
  166. package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -0
  167. package/dist/lib/composer-plugins/base-conversation-mention.provider.js +32 -0
  168. package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -0
  169. package/dist/lib/composer-plugins/load-composer-plugins.d.ts +9 -0
  170. package/dist/lib/composer-plugins/load-composer-plugins.d.ts.map +1 -0
  171. package/dist/lib/composer-plugins/load-composer-plugins.js +17 -0
  172. package/dist/lib/composer-plugins/load-composer-plugins.js.map +1 -0
  173. package/dist/lib/composer-plugins/record-mention.provider.d.ts +14 -0
  174. package/dist/lib/composer-plugins/record-mention.provider.d.ts.map +1 -0
  175. package/dist/lib/composer-plugins/record-mention.provider.js +26 -0
  176. package/dist/lib/composer-plugins/record-mention.provider.js.map +1 -0
  177. package/dist/lib/composer-plugins/skill-command.provider.d.ts +15 -0
  178. package/dist/lib/composer-plugins/skill-command.provider.d.ts.map +1 -0
  179. package/dist/lib/composer-plugins/skill-command.provider.js +27 -0
  180. package/dist/lib/composer-plugins/skill-command.provider.js.map +1 -0
  181. package/dist/lib/conversations.module.d.ts +68 -64
  182. package/dist/lib/conversations.module.d.ts.map +1 -1
  183. package/dist/lib/conversations.module.js +69 -18
  184. package/dist/lib/conversations.module.js.map +1 -1
  185. package/dist/lib/models/conversation-state.model.d.ts +6 -3
  186. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  187. package/dist/lib/models/conversation-state.model.js.map +1 -1
  188. package/dist/lib/services/conversation-agent.service.d.ts +9 -2
  189. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  190. package/dist/lib/services/conversation-agent.service.js +26 -2
  191. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  192. package/dist/lib/services/conversation-attachment.service.d.ts +1 -1
  193. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
  194. package/dist/lib/services/conversation-attachment.service.js.map +1 -1
  195. package/dist/lib/services/mention-autocomplete.service.d.ts +42 -19
  196. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  197. package/dist/lib/services/mention-autocomplete.service.js +113 -18
  198. package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
  199. package/dist/lib/services/realtime-audio-recorder.d.ts +143 -0
  200. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -0
  201. package/dist/lib/services/realtime-audio-recorder.js +379 -0
  202. package/dist/lib/services/realtime-audio-recorder.js.map +1 -0
  203. package/dist/lib/services/realtime-pcm-wav.d.ts +75 -0
  204. package/dist/lib/services/realtime-pcm-wav.d.ts.map +1 -0
  205. package/dist/lib/services/realtime-pcm-wav.js +205 -0
  206. package/dist/lib/services/realtime-pcm-wav.js.map +1 -0
  207. package/dist/lib/services/realtime-session-review.service.d.ts +28 -1
  208. package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
  209. package/dist/lib/services/realtime-session-review.service.js +12 -3
  210. package/dist/lib/services/realtime-session-review.service.js.map +1 -1
  211. package/dist/lib/services/realtime-session.service.d.ts +210 -20
  212. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  213. package/dist/lib/services/realtime-session.service.js +452 -21
  214. package/dist/lib/services/realtime-session.service.js.map +1 -1
  215. package/dist/lib/services/realtime-sessions-adapter.js +1 -1
  216. package/dist/lib/services/realtime-sessions-adapter.js.map +1 -1
  217. package/dist/lib/services/ui-command-handler.service.d.ts +7 -2
  218. package/dist/lib/services/ui-command-handler.service.d.ts.map +1 -1
  219. package/dist/lib/services/ui-command-handler.service.js +6 -2
  220. package/dist/lib/services/ui-command-handler.service.js.map +1 -1
  221. package/dist/lib/utils/plan-mode-preference.d.ts +62 -0
  222. package/dist/lib/utils/plan-mode-preference.d.ts.map +1 -0
  223. package/dist/lib/utils/plan-mode-preference.js +130 -0
  224. package/dist/lib/utils/plan-mode-preference.js.map +1 -0
  225. package/dist/public-api.d.ts +29 -3
  226. package/dist/public-api.d.ts.map +1 -1
  227. package/dist/public-api.js +46 -3
  228. package/dist/public-api.js.map +1 -1
  229. package/package.json +30 -26
  230. package/dist/__tests__/attachment-badge.test.d.ts +0 -2
  231. package/dist/__tests__/attachment-badge.test.d.ts.map +0 -1
  232. package/dist/__tests__/attachment-badge.test.js +0 -66
  233. package/dist/__tests__/attachment-badge.test.js.map +0 -1
  234. package/dist/__tests__/channel-optional-surface.test.d.ts +0 -2
  235. package/dist/__tests__/channel-optional-surface.test.d.ts.map +0 -1
  236. package/dist/__tests__/channel-optional-surface.test.js +0 -53
  237. package/dist/__tests__/channel-optional-surface.test.js.map +0 -1
  238. package/dist/__tests__/chat-events.test.d.ts +0 -14
  239. package/dist/__tests__/chat-events.test.d.ts.map +0 -1
  240. package/dist/__tests__/chat-events.test.js +0 -109
  241. package/dist/__tests__/chat-events.test.js.map +0 -1
  242. package/dist/__tests__/collections-full-view.test.d.ts +0 -2
  243. package/dist/__tests__/collections-full-view.test.d.ts.map +0 -1
  244. package/dist/__tests__/collections-full-view.test.js +0 -225
  245. package/dist/__tests__/collections-full-view.test.js.map +0 -1
  246. package/dist/__tests__/conversation-cache.test.d.ts +0 -2
  247. package/dist/__tests__/conversation-cache.test.d.ts.map +0 -1
  248. package/dist/__tests__/conversation-cache.test.js +0 -233
  249. package/dist/__tests__/conversation-cache.test.js.map +0 -1
  250. package/dist/__tests__/conversation-naming.test.d.ts +0 -2
  251. package/dist/__tests__/conversation-naming.test.d.ts.map +0 -1
  252. package/dist/__tests__/conversation-naming.test.js +0 -110
  253. package/dist/__tests__/conversation-naming.test.js.map +0 -1
  254. package/dist/__tests__/delegation-result-parser.test.d.ts +0 -2
  255. package/dist/__tests__/delegation-result-parser.test.d.ts.map +0 -1
  256. package/dist/__tests__/delegation-result-parser.test.js +0 -107
  257. package/dist/__tests__/delegation-result-parser.test.js.map +0 -1
  258. package/dist/__tests__/distinct-artifacts.test.d.ts +0 -2
  259. package/dist/__tests__/distinct-artifacts.test.d.ts.map +0 -1
  260. package/dist/__tests__/distinct-artifacts.test.js +0 -56
  261. package/dist/__tests__/distinct-artifacts.test.js.map +0 -1
  262. package/dist/__tests__/event-wiring.test.d.ts +0 -15
  263. package/dist/__tests__/event-wiring.test.d.ts.map +0 -1
  264. package/dist/__tests__/event-wiring.test.js +0 -100
  265. package/dist/__tests__/event-wiring.test.js.map +0 -1
  266. package/dist/__tests__/index.test.d.ts +0 -2
  267. package/dist/__tests__/index.test.d.ts.map +0 -1
  268. package/dist/__tests__/index.test.js +0 -7
  269. package/dist/__tests__/index.test.js.map +0 -1
  270. package/dist/__tests__/narration-template.test.d.ts +0 -2
  271. package/dist/__tests__/narration-template.test.d.ts.map +0 -1
  272. package/dist/__tests__/narration-template.test.js +0 -76
  273. package/dist/__tests__/narration-template.test.js.map +0 -1
  274. package/dist/__tests__/notification-model.test.d.ts +0 -2
  275. package/dist/__tests__/notification-model.test.d.ts.map +0 -1
  276. package/dist/__tests__/notification-model.test.js +0 -68
  277. package/dist/__tests__/notification-model.test.js.map +0 -1
  278. package/dist/__tests__/realtime-agent-picker-models.test.d.ts +0 -2
  279. package/dist/__tests__/realtime-agent-picker-models.test.d.ts.map +0 -1
  280. package/dist/__tests__/realtime-agent-picker-models.test.js +0 -49
  281. package/dist/__tests__/realtime-agent-picker-models.test.js.map +0 -1
  282. package/dist/__tests__/realtime-audio-visuals.test.d.ts +0 -2
  283. package/dist/__tests__/realtime-audio-visuals.test.d.ts.map +0 -1
  284. package/dist/__tests__/realtime-audio-visuals.test.js +0 -123
  285. package/dist/__tests__/realtime-audio-visuals.test.js.map +0 -1
  286. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts +0 -2
  287. package/dist/__tests__/realtime-delegation-card-cancel.test.d.ts.map +0 -1
  288. package/dist/__tests__/realtime-delegation-card-cancel.test.js +0 -48
  289. package/dist/__tests__/realtime-delegation-card-cancel.test.js.map +0 -1
  290. package/dist/__tests__/realtime-disclosure.test.d.ts +0 -2
  291. package/dist/__tests__/realtime-disclosure.test.d.ts.map +0 -1
  292. package/dist/__tests__/realtime-disclosure.test.js +0 -164
  293. package/dist/__tests__/realtime-disclosure.test.js.map +0 -1
  294. package/dist/__tests__/realtime-pairing.test.d.ts +0 -2
  295. package/dist/__tests__/realtime-pairing.test.d.ts.map +0 -1
  296. package/dist/__tests__/realtime-pairing.test.js +0 -207
  297. package/dist/__tests__/realtime-pairing.test.js.map +0 -1
  298. package/dist/__tests__/realtime-review-lifecycle.test.d.ts +0 -2
  299. package/dist/__tests__/realtime-review-lifecycle.test.d.ts.map +0 -1
  300. package/dist/__tests__/realtime-review-lifecycle.test.js +0 -154
  301. package/dist/__tests__/realtime-review-lifecycle.test.js.map +0 -1
  302. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts +0 -2
  303. package/dist/__tests__/realtime-session-cancel-usage.test.d.ts.map +0 -1
  304. package/dist/__tests__/realtime-session-cancel-usage.test.js +0 -230
  305. package/dist/__tests__/realtime-session-cancel-usage.test.js.map +0 -1
  306. package/dist/__tests__/realtime-session-channels.test.d.ts +0 -2
  307. package/dist/__tests__/realtime-session-channels.test.d.ts.map +0 -1
  308. package/dist/__tests__/realtime-session-channels.test.js +0 -252
  309. package/dist/__tests__/realtime-session-channels.test.js.map +0 -1
  310. package/dist/__tests__/realtime-session-client-tools.test.d.ts +0 -2
  311. package/dist/__tests__/realtime-session-client-tools.test.d.ts.map +0 -1
  312. package/dist/__tests__/realtime-session-client-tools.test.js +0 -103
  313. package/dist/__tests__/realtime-session-client-tools.test.js.map +0 -1
  314. package/dist/__tests__/realtime-session-minimized.test.d.ts +0 -2
  315. package/dist/__tests__/realtime-session-minimized.test.d.ts.map +0 -1
  316. package/dist/__tests__/realtime-session-minimized.test.js +0 -32
  317. package/dist/__tests__/realtime-session-minimized.test.js.map +0 -1
  318. package/dist/__tests__/realtime-session-mint.test.d.ts +0 -2
  319. package/dist/__tests__/realtime-session-mint.test.d.ts.map +0 -1
  320. package/dist/__tests__/realtime-session-mint.test.js +0 -69
  321. package/dist/__tests__/realtime-session-mint.test.js.map +0 -1
  322. package/dist/__tests__/realtime-session-policy.test.d.ts +0 -2
  323. package/dist/__tests__/realtime-session-policy.test.d.ts.map +0 -1
  324. package/dist/__tests__/realtime-session-policy.test.js +0 -303
  325. package/dist/__tests__/realtime-session-policy.test.js.map +0 -1
  326. package/dist/__tests__/realtime-session-review.service.test.d.ts +0 -2
  327. package/dist/__tests__/realtime-session-review.service.test.d.ts.map +0 -1
  328. package/dist/__tests__/realtime-session-review.service.test.js +0 -743
  329. package/dist/__tests__/realtime-session-review.service.test.js.map +0 -1
  330. package/dist/__tests__/realtime-session-state.test.d.ts +0 -2
  331. package/dist/__tests__/realtime-session-state.test.d.ts.map +0 -1
  332. package/dist/__tests__/realtime-session-state.test.js +0 -83
  333. package/dist/__tests__/realtime-session-state.test.js.map +0 -1
  334. package/dist/__tests__/realtime-session-timeline-card.test.d.ts +0 -2
  335. package/dist/__tests__/realtime-session-timeline-card.test.d.ts.map +0 -1
  336. package/dist/__tests__/realtime-session-timeline-card.test.js +0 -106
  337. package/dist/__tests__/realtime-session-timeline-card.test.js.map +0 -1
  338. package/dist/__tests__/realtime-session-timeline.test.d.ts +0 -2
  339. package/dist/__tests__/realtime-session-timeline.test.d.ts.map +0 -1
  340. package/dist/__tests__/realtime-session-timeline.test.js +0 -142
  341. package/dist/__tests__/realtime-session-timeline.test.js.map +0 -1
  342. package/dist/__tests__/realtime-sessions-adapter.test.d.ts +0 -19
  343. package/dist/__tests__/realtime-sessions-adapter.test.d.ts.map +0 -1
  344. package/dist/__tests__/realtime-sessions-adapter.test.js +0 -188
  345. package/dist/__tests__/realtime-sessions-adapter.test.js.map +0 -1
  346. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts +0 -2
  347. package/dist/__tests__/realtime-surface-panel-prefs.test.d.ts.map +0 -1
  348. package/dist/__tests__/realtime-surface-panel-prefs.test.js +0 -100
  349. package/dist/__tests__/realtime-surface-panel-prefs.test.js.map +0 -1
  350. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts +0 -2
  351. package/dist/__tests__/realtime-surface-tabs-model.test.d.ts.map +0 -1
  352. package/dist/__tests__/realtime-surface-tabs-model.test.js +0 -193
  353. package/dist/__tests__/realtime-surface-tabs-model.test.js.map +0 -1
  354. package/dist/__tests__/remote-browser-audio-player.test.d.ts +0 -2
  355. package/dist/__tests__/remote-browser-audio-player.test.d.ts.map +0 -1
  356. package/dist/__tests__/remote-browser-audio-player.test.js +0 -137
  357. package/dist/__tests__/remote-browser-audio-player.test.js.map +0 -1
  358. package/dist/__tests__/remote-browser-channel.test.d.ts +0 -2
  359. package/dist/__tests__/remote-browser-channel.test.d.ts.map +0 -1
  360. package/dist/__tests__/remote-browser-channel.test.js +0 -585
  361. package/dist/__tests__/remote-browser-channel.test.js.map +0 -1
  362. package/dist/__tests__/search-service.test.d.ts +0 -2
  363. package/dist/__tests__/search-service.test.d.ts.map +0 -1
  364. package/dist/__tests__/search-service.test.js +0 -114
  365. package/dist/__tests__/search-service.test.js.map +0 -1
  366. package/dist/__tests__/slot-defaults.test.d.ts +0 -24
  367. package/dist/__tests__/slot-defaults.test.d.ts.map +0 -1
  368. package/dist/__tests__/slot-defaults.test.js +0 -63
  369. package/dist/__tests__/slot-defaults.test.js.map +0 -1
  370. package/dist/__tests__/toast-service.test.d.ts +0 -2
  371. package/dist/__tests__/toast-service.test.d.ts.map +0 -1
  372. package/dist/__tests__/toast-service.test.js +0 -143
  373. package/dist/__tests__/toast-service.test.js.map +0 -1
  374. package/dist/__tests__/user-authorization.test.d.ts +0 -2
  375. package/dist/__tests__/user-authorization.test.d.ts.map +0 -1
  376. package/dist/__tests__/user-authorization.test.js +0 -97
  377. package/dist/__tests__/user-authorization.test.js.map +0 -1
  378. package/dist/__tests__/voice-session-narration.test.d.ts +0 -2
  379. package/dist/__tests__/voice-session-narration.test.d.ts.map +0 -1
  380. package/dist/__tests__/voice-session-narration.test.js +0 -609
  381. package/dist/__tests__/voice-session-narration.test.js.map +0 -1
  382. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts +0 -2
  383. package/dist/__tests__/whiteboard-artifact-viewer.test.d.ts.map +0 -1
  384. package/dist/__tests__/whiteboard-artifact-viewer.test.js +0 -101
  385. package/dist/__tests__/whiteboard-artifact-viewer.test.js.map +0 -1
  386. package/dist/__tests__/whiteboard-channel.test.d.ts +0 -2
  387. package/dist/__tests__/whiteboard-channel.test.d.ts.map +0 -1
  388. package/dist/__tests__/whiteboard-channel.test.js +0 -260
  389. package/dist/__tests__/whiteboard-channel.test.js.map +0 -1
  390. package/dist/__tests__/whiteboard-restore-state.test.d.ts +0 -2
  391. package/dist/__tests__/whiteboard-restore-state.test.d.ts.map +0 -1
  392. package/dist/__tests__/whiteboard-restore-state.test.js +0 -108
  393. package/dist/__tests__/whiteboard-restore-state.test.js.map +0 -1
  394. package/dist/lib/components/mention/mention-dropdown.component.d.ts +0 -53
  395. package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +0 -1
  396. package/dist/lib/components/mention/mention-dropdown.component.js +0 -276
  397. package/dist/lib/components/mention/mention-dropdown.component.js.map +0 -1
  398. package/dist/lib/components/mention/mention-editor.component.d.ts +0 -256
  399. package/dist/lib/components/mention/mention-editor.component.d.ts.map +0 -1
  400. package/dist/lib/components/mention/mention-editor.component.js +0 -1233
  401. package/dist/lib/components/mention/mention-editor.component.js.map +0 -1
  402. package/dist/lib/components/message/message-input-box.component.d.ts +0 -137
  403. package/dist/lib/components/message/message-input-box.component.d.ts.map +0 -1
  404. package/dist/lib/components/message/message-input-box.component.js +0 -321
  405. package/dist/lib/components/message/message-input-box.component.js.map +0 -1
@@ -1,225 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- /**
3
- * Reproduces the template binding logic:
4
- * [parentCollection]="editingCollection ? undefined : (currentCollection || undefined)"
5
- */
6
- function resolveParentCollection(editingCollection, currentCollection) {
7
- return editingCollection ? undefined : (currentCollection || undefined);
8
- }
9
- describe('Bug 1: parentCollection binding logic', () => {
10
- const rootCollection = {
11
- ID: 'root-1',
12
- Name: 'Root Collection',
13
- ParentID: null
14
- };
15
- const childCollection = {
16
- ID: 'child-1',
17
- Name: 'Child Collection',
18
- ParentID: 'root-1'
19
- };
20
- describe('when creating a new collection', () => {
21
- it('should pass currentCollection as parentCollection at root level', () => {
22
- // At root level, currentCollection is null
23
- const parent = resolveParentCollection(undefined, null);
24
- expect(parent).toBeUndefined();
25
- });
26
- it('should pass currentCollection as parentCollection when inside a collection', () => {
27
- // Inside rootCollection, creating a new sub-collection
28
- const parent = resolveParentCollection(undefined, rootCollection);
29
- expect(parent).toBe(rootCollection);
30
- });
31
- });
32
- describe('when editing an existing collection', () => {
33
- it('should NOT pass parentCollection when editing the current collection', () => {
34
- // Inside rootCollection, editing rootCollection itself
35
- // Before fix: parentCollection = rootCollection (the collection being edited!)
36
- // After fix: parentCollection = undefined
37
- const parent = resolveParentCollection(rootCollection, rootCollection);
38
- expect(parent).toBeUndefined();
39
- });
40
- it('should NOT pass parentCollection when editing a child collection from the list', () => {
41
- // Inside rootCollection, editing childCollection from the grid
42
- const parent = resolveParentCollection(childCollection, rootCollection);
43
- expect(parent).toBeUndefined();
44
- });
45
- it('should NOT pass parentCollection when editing at root level', () => {
46
- // At root level, editing rootCollection
47
- const parent = resolveParentCollection(rootCollection, null);
48
- expect(parent).toBeUndefined();
49
- });
50
- });
51
- });
52
- /**
53
- * Reproduces the form-modal save logic for ParentID:
54
- *
55
- * if (!this.collection) {
56
- * // creating new — set ParentID from parentCollection
57
- * } else if (this.parentCollection) {
58
- * collection.ParentID = this.parentCollection.ID;
59
- * }
60
- */
61
- function simulateSave(existingCollection, parentCollection) {
62
- if (!existingCollection) {
63
- // Creating new collection — parentCollection sets ParentID (expected)
64
- return {
65
- parentIdOverwritten: !!parentCollection,
66
- newParentId: parentCollection?.ID ?? null
67
- };
68
- }
69
- else if (parentCollection) {
70
- // Editing existing — parentCollection would overwrite ParentID
71
- return {
72
- parentIdOverwritten: true,
73
- newParentId: parentCollection.ID
74
- };
75
- }
76
- // Editing existing, no parentCollection — ParentID unchanged
77
- return {
78
- parentIdOverwritten: false,
79
- newParentId: existingCollection.ParentID
80
- };
81
- }
82
- describe('Bug 1: form-modal save logic for ParentID', () => {
83
- const collection = {
84
- ID: 'col-1',
85
- Name: 'My Collection',
86
- ParentID: 'parent-1'
87
- };
88
- it('should not overwrite ParentID when editing with no parentCollection (the fix)', () => {
89
- // After fix: parentCollection is undefined when editing
90
- const result = simulateSave(collection, undefined);
91
- expect(result.parentIdOverwritten).toBe(false);
92
- expect(result.newParentId).toBe('parent-1'); // Preserved
93
- });
94
- it('would overwrite ParentID if parentCollection were passed during edit (the bug)', () => {
95
- // Before fix: parentCollection = the collection itself
96
- const result = simulateSave(collection, collection);
97
- expect(result.parentIdOverwritten).toBe(true);
98
- expect(result.newParentId).toBe('col-1'); // Self-referencing — the bug!
99
- });
100
- it('should set ParentID when creating a new child collection', () => {
101
- const parent = { ID: 'parent-1', Name: 'Parent', ParentID: null };
102
- const result = simulateSave(undefined, parent);
103
- expect(result.parentIdOverwritten).toBe(true);
104
- expect(result.newParentId).toBe('parent-1');
105
- });
106
- it('should leave ParentID null when creating a new root collection', () => {
107
- const result = simulateSave(undefined, undefined);
108
- expect(result.parentIdOverwritten).toBe(false);
109
- expect(result.newParentId).toBeNull();
110
- });
111
- });
112
- // ============================================================
113
- // Bug 2: Item counts always showing "Empty"
114
- // ============================================================
115
- /**
116
- * Reproduces the getItemCountText display logic
117
- */
118
- function getItemCountText(itemCount) {
119
- if (itemCount !== undefined) {
120
- if (itemCount === 0)
121
- return 'Empty';
122
- if (itemCount === 1)
123
- return '1 item';
124
- return `${itemCount} items`;
125
- }
126
- return '';
127
- }
128
- /**
129
- * Reproduces the item count calculation from loadItemCounts:
130
- * counts child collections + collection artifacts per parent collection
131
- */
132
- function buildItemCountMap(childCollections, collectionArtifacts) {
133
- const map = new Map();
134
- for (const child of childCollections) {
135
- map.set(child.ParentID, (map.get(child.ParentID) || 0) + 1);
136
- }
137
- for (const ca of collectionArtifacts) {
138
- map.set(ca.CollectionID, (map.get(ca.CollectionID) || 0) + 1);
139
- }
140
- return map;
141
- }
142
- describe('Bug 2: item count display', () => {
143
- describe('getItemCountText', () => {
144
- it('should return "Empty" for count 0', () => {
145
- expect(getItemCountText(0)).toBe('Empty');
146
- });
147
- it('should return "1 item" for count 1', () => {
148
- expect(getItemCountText(1)).toBe('1 item');
149
- });
150
- it('should return "N items" for count > 1', () => {
151
- expect(getItemCountText(5)).toBe('5 items');
152
- });
153
- it('should return empty string for undefined', () => {
154
- expect(getItemCountText(undefined)).toBe('');
155
- });
156
- });
157
- describe('buildItemCountMap', () => {
158
- it('should count child collections per parent', () => {
159
- const children = [
160
- { ParentID: 'col-1' },
161
- { ParentID: 'col-1' },
162
- { ParentID: 'col-2' }
163
- ];
164
- const map = buildItemCountMap(children, []);
165
- expect(map.get('col-1')).toBe(2);
166
- expect(map.get('col-2')).toBe(1);
167
- });
168
- it('should count artifacts per collection', () => {
169
- const artifacts = [
170
- { CollectionID: 'col-1' },
171
- { CollectionID: 'col-1' },
172
- { CollectionID: 'col-1' }
173
- ];
174
- const map = buildItemCountMap([], artifacts);
175
- expect(map.get('col-1')).toBe(3);
176
- });
177
- it('should sum child collections and artifacts together', () => {
178
- const children = [
179
- { ParentID: 'col-1' },
180
- { ParentID: 'col-1' }
181
- ];
182
- const artifacts = [
183
- { CollectionID: 'col-1' },
184
- { CollectionID: 'col-1' },
185
- { CollectionID: 'col-1' }
186
- ];
187
- const map = buildItemCountMap(children, artifacts);
188
- // 2 children + 3 artifacts = 5 items
189
- expect(map.get('col-1')).toBe(5);
190
- });
191
- it('should return 0 (via map miss) for collections with no items', () => {
192
- const map = buildItemCountMap([], []);
193
- expect(map.get('col-1') || 0).toBe(0);
194
- });
195
- it('should handle multiple collections independently', () => {
196
- const children = [
197
- { ParentID: 'col-1' },
198
- { ParentID: 'col-2' },
199
- { ParentID: 'col-2' }
200
- ];
201
- const artifacts = [
202
- { CollectionID: 'col-1' },
203
- { CollectionID: 'col-3' }
204
- ];
205
- const map = buildItemCountMap(children, artifacts);
206
- expect(map.get('col-1')).toBe(2); // 1 child + 1 artifact
207
- expect(map.get('col-2')).toBe(2); // 2 children
208
- expect(map.get('col-3')).toBe(1); // 1 artifact
209
- });
210
- });
211
- describe('end-to-end: count map feeds display text', () => {
212
- it('should show correct text from calculated counts', () => {
213
- const children = [{ ParentID: 'col-1' }];
214
- const artifacts = [
215
- { CollectionID: 'col-1' },
216
- { CollectionID: 'col-2' }
217
- ];
218
- const map = buildItemCountMap(children, artifacts);
219
- expect(getItemCountText(map.get('col-1') || 0)).toBe('2 items');
220
- expect(getItemCountText(map.get('col-2') || 0)).toBe('1 item');
221
- expect(getItemCountText(map.get('col-3') || 0)).toBe('Empty');
222
- });
223
- });
224
- });
225
- //# sourceMappingURL=collections-full-view.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collections-full-view.test.js","sourceRoot":"","sources":["../../src/__tests__/collections-full-view.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach } from 'vitest';\n\n/**\n * Tests for collections-full-view logic — extracted from the component\n * to verify bug fixes without Angular DI.\n *\n * Bug 1: Renaming a collection set ParentID to itself (self-referencing)\n * Bug 2: All collections showed \"Empty\" because itemCount was hardcoded to 0\n */\n\n// ============================================================\n// Bug 1: parentCollection binding when editing vs creating\n// ============================================================\n\ninterface MockCollection {\n ID: string;\n Name: string;\n ParentID: string | null;\n}\n\n/**\n * Reproduces the template binding logic:\n * [parentCollection]=\"editingCollection ? undefined : (currentCollection || undefined)\"\n */\nfunction resolveParentCollection(\n editingCollection: MockCollection | undefined,\n currentCollection: MockCollection | null\n): MockCollection | undefined {\n return editingCollection ? undefined : (currentCollection || undefined);\n}\n\ndescribe('Bug 1: parentCollection binding logic', () => {\n const rootCollection: MockCollection = {\n ID: 'root-1',\n Name: 'Root Collection',\n ParentID: null\n };\n\n const childCollection: MockCollection = {\n ID: 'child-1',\n Name: 'Child Collection',\n ParentID: 'root-1'\n };\n\n describe('when creating a new collection', () => {\n it('should pass currentCollection as parentCollection at root level', () => {\n // At root level, currentCollection is null\n const parent = resolveParentCollection(undefined, null);\n expect(parent).toBeUndefined();\n });\n\n it('should pass currentCollection as parentCollection when inside a collection', () => {\n // Inside rootCollection, creating a new sub-collection\n const parent = resolveParentCollection(undefined, rootCollection);\n expect(parent).toBe(rootCollection);\n });\n });\n\n describe('when editing an existing collection', () => {\n it('should NOT pass parentCollection when editing the current collection', () => {\n // Inside rootCollection, editing rootCollection itself\n // Before fix: parentCollection = rootCollection (the collection being edited!)\n // After fix: parentCollection = undefined\n const parent = resolveParentCollection(rootCollection, rootCollection);\n expect(parent).toBeUndefined();\n });\n\n it('should NOT pass parentCollection when editing a child collection from the list', () => {\n // Inside rootCollection, editing childCollection from the grid\n const parent = resolveParentCollection(childCollection, rootCollection);\n expect(parent).toBeUndefined();\n });\n\n it('should NOT pass parentCollection when editing at root level', () => {\n // At root level, editing rootCollection\n const parent = resolveParentCollection(rootCollection, null);\n expect(parent).toBeUndefined();\n });\n });\n});\n\n/**\n * Reproduces the form-modal save logic for ParentID:\n *\n * if (!this.collection) {\n * // creating new — set ParentID from parentCollection\n * } else if (this.parentCollection) {\n * collection.ParentID = this.parentCollection.ID;\n * }\n */\nfunction simulateSave(\n existingCollection: MockCollection | undefined,\n parentCollection: MockCollection | undefined\n): { parentIdOverwritten: boolean; newParentId: string | null } {\n if (!existingCollection) {\n // Creating new collection — parentCollection sets ParentID (expected)\n return {\n parentIdOverwritten: !!parentCollection,\n newParentId: parentCollection?.ID ?? null\n };\n } else if (parentCollection) {\n // Editing existing — parentCollection would overwrite ParentID\n return {\n parentIdOverwritten: true,\n newParentId: parentCollection.ID\n };\n }\n // Editing existing, no parentCollection — ParentID unchanged\n return {\n parentIdOverwritten: false,\n newParentId: existingCollection.ParentID\n };\n}\n\ndescribe('Bug 1: form-modal save logic for ParentID', () => {\n const collection: MockCollection = {\n ID: 'col-1',\n Name: 'My Collection',\n ParentID: 'parent-1'\n };\n\n it('should not overwrite ParentID when editing with no parentCollection (the fix)', () => {\n // After fix: parentCollection is undefined when editing\n const result = simulateSave(collection, undefined);\n expect(result.parentIdOverwritten).toBe(false);\n expect(result.newParentId).toBe('parent-1'); // Preserved\n });\n\n it('would overwrite ParentID if parentCollection were passed during edit (the bug)', () => {\n // Before fix: parentCollection = the collection itself\n const result = simulateSave(collection, collection);\n expect(result.parentIdOverwritten).toBe(true);\n expect(result.newParentId).toBe('col-1'); // Self-referencing — the bug!\n });\n\n it('should set ParentID when creating a new child collection', () => {\n const parent: MockCollection = { ID: 'parent-1', Name: 'Parent', ParentID: null };\n const result = simulateSave(undefined, parent);\n expect(result.parentIdOverwritten).toBe(true);\n expect(result.newParentId).toBe('parent-1');\n });\n\n it('should leave ParentID null when creating a new root collection', () => {\n const result = simulateSave(undefined, undefined);\n expect(result.parentIdOverwritten).toBe(false);\n expect(result.newParentId).toBeNull();\n });\n});\n\n// ============================================================\n// Bug 2: Item counts always showing \"Empty\"\n// ============================================================\n\n/**\n * Reproduces the getItemCountText display logic\n */\nfunction getItemCountText(itemCount?: number): string {\n if (itemCount !== undefined) {\n if (itemCount === 0) return 'Empty';\n if (itemCount === 1) return '1 item';\n return `${itemCount} items`;\n }\n return '';\n}\n\n/**\n * Reproduces the item count calculation from loadItemCounts:\n * counts child collections + collection artifacts per parent collection\n */\nfunction buildItemCountMap(\n childCollections: Array<{ ParentID: string }>,\n collectionArtifacts: Array<{ CollectionID: string }>\n): Map<string, number> {\n const map = new Map<string, number>();\n\n for (const child of childCollections) {\n map.set(child.ParentID, (map.get(child.ParentID) || 0) + 1);\n }\n\n for (const ca of collectionArtifacts) {\n map.set(ca.CollectionID, (map.get(ca.CollectionID) || 0) + 1);\n }\n\n return map;\n}\n\ndescribe('Bug 2: item count display', () => {\n describe('getItemCountText', () => {\n it('should return \"Empty\" for count 0', () => {\n expect(getItemCountText(0)).toBe('Empty');\n });\n\n it('should return \"1 item\" for count 1', () => {\n expect(getItemCountText(1)).toBe('1 item');\n });\n\n it('should return \"N items\" for count > 1', () => {\n expect(getItemCountText(5)).toBe('5 items');\n });\n\n it('should return empty string for undefined', () => {\n expect(getItemCountText(undefined)).toBe('');\n });\n });\n\n describe('buildItemCountMap', () => {\n it('should count child collections per parent', () => {\n const children = [\n { ParentID: 'col-1' },\n { ParentID: 'col-1' },\n { ParentID: 'col-2' }\n ];\n const map = buildItemCountMap(children, []);\n\n expect(map.get('col-1')).toBe(2);\n expect(map.get('col-2')).toBe(1);\n });\n\n it('should count artifacts per collection', () => {\n const artifacts = [\n { CollectionID: 'col-1' },\n { CollectionID: 'col-1' },\n { CollectionID: 'col-1' }\n ];\n const map = buildItemCountMap([], artifacts);\n\n expect(map.get('col-1')).toBe(3);\n });\n\n it('should sum child collections and artifacts together', () => {\n const children = [\n { ParentID: 'col-1' },\n { ParentID: 'col-1' }\n ];\n const artifacts = [\n { CollectionID: 'col-1' },\n { CollectionID: 'col-1' },\n { CollectionID: 'col-1' }\n ];\n const map = buildItemCountMap(children, artifacts);\n\n // 2 children + 3 artifacts = 5 items\n expect(map.get('col-1')).toBe(5);\n });\n\n it('should return 0 (via map miss) for collections with no items', () => {\n const map = buildItemCountMap([], []);\n expect(map.get('col-1') || 0).toBe(0);\n });\n\n it('should handle multiple collections independently', () => {\n const children = [\n { ParentID: 'col-1' },\n { ParentID: 'col-2' },\n { ParentID: 'col-2' }\n ];\n const artifacts = [\n { CollectionID: 'col-1' },\n { CollectionID: 'col-3' }\n ];\n const map = buildItemCountMap(children, artifacts);\n\n expect(map.get('col-1')).toBe(2); // 1 child + 1 artifact\n expect(map.get('col-2')).toBe(2); // 2 children\n expect(map.get('col-3')).toBe(1); // 1 artifact\n });\n });\n\n describe('end-to-end: count map feeds display text', () => {\n it('should show correct text from calculated counts', () => {\n const children = [{ ParentID: 'col-1' }];\n const artifacts = [\n { CollectionID: 'col-1' },\n { CollectionID: 'col-2' }\n ];\n const map = buildItemCountMap(children, artifacts);\n\n expect(getItemCountText(map.get('col-1') || 0)).toBe('2 items');\n expect(getItemCountText(map.get('col-2') || 0)).toBe('1 item');\n expect(getItemCountText(map.get('col-3') || 0)).toBe('Empty');\n });\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=conversation-cache.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"conversation-cache.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/conversation-cache.test.ts"],"names":[],"mappings":""}
@@ -1,233 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- /**
3
- * Extracts the cache management logic from ConversationChatAreaComponent
4
- * for isolated testing without Angular dependencies.
5
- */
6
- class TestableConversationCache {
7
- cache = new Map();
8
- has(conversationId) {
9
- return this.cache.has(conversationId);
10
- }
11
- get(conversationId) {
12
- return this.cache.get(conversationId);
13
- }
14
- /** Store raw data from server (first visit) */
15
- setRaw(conversationId, raw) {
16
- this.cache.set(conversationId, { raw, entities: null });
17
- }
18
- /** Store hydrated entities after conversion */
19
- setEntities(conversationId, entities) {
20
- const entry = this.cache.get(conversationId);
21
- if (entry) {
22
- entry.entities = entities;
23
- }
24
- }
25
- /** Invalidate both raw and entities */
26
- invalidate(conversationId) {
27
- this.cache.delete(conversationId);
28
- }
29
- /** Patch raw data in-place (e.g., after pin toggle) */
30
- patchRaw(conversationId, messageId, patch) {
31
- const entry = this.cache.get(conversationId);
32
- if (entry) {
33
- const row = entry.raw.find(r => r.ID === messageId);
34
- if (row) {
35
- Object.assign(row, patch);
36
- }
37
- }
38
- }
39
- /** Update raw data with fresh server data (invalidates entities) */
40
- refreshRaw(conversationId, raw) {
41
- this.cache.set(conversationId, { raw, entities: null });
42
- }
43
- get size() {
44
- return this.cache.size;
45
- }
46
- }
47
- /** Simulate the 3-path loadMessages logic */
48
- function resolveLoadPath(cache, conversationId) {
49
- const entry = cache.get(conversationId);
50
- if (entry?.entities)
51
- return 'cached-entities';
52
- if (entry)
53
- return 'cached-raw';
54
- return 'server-fetch';
55
- }
56
- // ─── Test data ───────────────────────────────────────────────────────────
57
- function createRawRows(conversationId, count) {
58
- return Array.from({ length: count }, (_, i) => ({
59
- ID: `detail-${i}`,
60
- ConversationID: conversationId,
61
- Message: `Message ${i}`,
62
- Role: i % 2 === 0 ? 'user' : 'AI',
63
- Status: 'Completed',
64
- IsPinned: false,
65
- }));
66
- }
67
- function createEntities(rawRows) {
68
- return rawRows.map(r => ({
69
- ID: r.ID,
70
- Message: r.Message,
71
- Status: r.Status,
72
- IsPinned: r.IsPinned,
73
- }));
74
- }
75
- // ─── Tests ───────────────────────────────────────────────────────────────
76
- describe('Conversation Compound Cache', () => {
77
- let cache;
78
- const convA = 'conv-aaa';
79
- const convB = 'conv-bbb';
80
- beforeEach(() => {
81
- cache = new TestableConversationCache();
82
- });
83
- describe('Cache structure', () => {
84
- it('should start empty', () => {
85
- expect(cache.size).toBe(0);
86
- expect(cache.has(convA)).toBe(false);
87
- });
88
- it('should store raw data with null entities on first visit', () => {
89
- const raw = createRawRows(convA, 5);
90
- cache.setRaw(convA, raw);
91
- const entry = cache.get(convA);
92
- expect(entry).toBeDefined();
93
- expect(entry.raw).toBe(raw);
94
- expect(entry.entities).toBeNull();
95
- });
96
- it('should store entities alongside raw data after conversion', () => {
97
- const raw = createRawRows(convA, 5);
98
- cache.setRaw(convA, raw);
99
- const entities = createEntities(raw);
100
- cache.setEntities(convA, entities);
101
- const entry = cache.get(convA);
102
- expect(entry.raw).toBe(raw);
103
- expect(entry.entities).toBe(entities);
104
- expect(entry.entities).toHaveLength(5);
105
- });
106
- });
107
- describe('Load path resolution', () => {
108
- it('should resolve to server-fetch when cache is empty', () => {
109
- expect(resolveLoadPath(cache, convA)).toBe('server-fetch');
110
- });
111
- it('should resolve to cached-raw when only raw data exists', () => {
112
- cache.setRaw(convA, createRawRows(convA, 3));
113
- expect(resolveLoadPath(cache, convA)).toBe('cached-raw');
114
- });
115
- it('should resolve to cached-entities when entities are populated', () => {
116
- const raw = createRawRows(convA, 3);
117
- cache.setRaw(convA, raw);
118
- cache.setEntities(convA, createEntities(raw));
119
- expect(resolveLoadPath(cache, convA)).toBe('cached-entities');
120
- });
121
- it('should handle multiple conversations independently', () => {
122
- const rawA = createRawRows(convA, 3);
123
- cache.setRaw(convA, rawA);
124
- cache.setEntities(convA, createEntities(rawA));
125
- cache.setRaw(convB, createRawRows(convB, 2));
126
- expect(resolveLoadPath(cache, convA)).toBe('cached-entities');
127
- expect(resolveLoadPath(cache, convB)).toBe('cached-raw');
128
- });
129
- });
130
- describe('Invalidation', () => {
131
- it('should remove both raw and entities on invalidate', () => {
132
- const raw = createRawRows(convA, 3);
133
- cache.setRaw(convA, raw);
134
- cache.setEntities(convA, createEntities(raw));
135
- cache.invalidate(convA);
136
- expect(cache.has(convA)).toBe(false);
137
- expect(cache.get(convA)).toBeUndefined();
138
- expect(resolveLoadPath(cache, convA)).toBe('server-fetch');
139
- });
140
- it('should not affect other conversations when invalidating one', () => {
141
- cache.setRaw(convA, createRawRows(convA, 3));
142
- cache.setRaw(convB, createRawRows(convB, 2));
143
- cache.invalidate(convA);
144
- expect(cache.has(convA)).toBe(false);
145
- expect(cache.has(convB)).toBe(true);
146
- });
147
- });
148
- describe('Raw data refresh', () => {
149
- it('should replace raw data and clear entities on refresh', () => {
150
- const raw = createRawRows(convA, 3);
151
- cache.setRaw(convA, raw);
152
- cache.setEntities(convA, createEntities(raw));
153
- const freshRaw = createRawRows(convA, 5);
154
- cache.refreshRaw(convA, freshRaw);
155
- const entry = cache.get(convA);
156
- expect(entry.raw).toBe(freshRaw);
157
- expect(entry.raw).toHaveLength(5);
158
- expect(entry.entities).toBeNull(); // entities cleared
159
- expect(resolveLoadPath(cache, convA)).toBe('cached-raw');
160
- });
161
- });
162
- describe('In-place raw patching', () => {
163
- it('should patch a specific row in raw data', () => {
164
- const raw = createRawRows(convA, 3);
165
- cache.setRaw(convA, raw);
166
- cache.patchRaw(convA, 'detail-1', { IsPinned: true });
167
- const entry = cache.get(convA);
168
- expect(entry.raw[1].IsPinned).toBe(true);
169
- // Other rows unaffected
170
- expect(entry.raw[0].IsPinned).toBe(false);
171
- expect(entry.raw[2].IsPinned).toBe(false);
172
- });
173
- it('should not affect entities when patching raw data', () => {
174
- const raw = createRawRows(convA, 3);
175
- cache.setRaw(convA, raw);
176
- const entities = createEntities(raw);
177
- cache.setEntities(convA, entities);
178
- cache.patchRaw(convA, 'detail-1', { IsPinned: true });
179
- // Raw is patched
180
- expect(cache.get(convA).raw[1].IsPinned).toBe(true);
181
- // Entity objects are separate — not patched by raw patch
182
- // (In the real component, the entity is already mutated by .Save())
183
- expect(cache.get(convA).entities[1].IsPinned).toBe(false);
184
- });
185
- it('should be a no-op for non-existent conversation', () => {
186
- cache.patchRaw('nonexistent', 'detail-0', { IsPinned: true });
187
- expect(cache.has('nonexistent')).toBe(false);
188
- });
189
- it('should be a no-op for non-existent message ID', () => {
190
- const raw = createRawRows(convA, 2);
191
- cache.setRaw(convA, raw);
192
- cache.patchRaw(convA, 'nonexistent-detail', { IsPinned: true });
193
- // Nothing changed
194
- expect(raw.every(r => r.IsPinned === false)).toBe(true);
195
- });
196
- });
197
- describe('Conversation switching simulation', () => {
198
- it('should provide instant switch when entities are cached', () => {
199
- // Visit conversation A — full load
200
- const rawA = createRawRows(convA, 10);
201
- cache.setRaw(convA, rawA);
202
- cache.setEntities(convA, createEntities(rawA));
203
- // Visit conversation B — full load
204
- const rawB = createRawRows(convB, 5);
205
- cache.setRaw(convB, rawB);
206
- cache.setEntities(convB, createEntities(rawB));
207
- // Switch back to A — should be instant (cached-entities path)
208
- expect(resolveLoadPath(cache, convA)).toBe('cached-entities');
209
- const entryA = cache.get(convA);
210
- expect(entryA.entities).toHaveLength(10);
211
- // Switch to B — also instant
212
- expect(resolveLoadPath(cache, convB)).toBe('cached-entities');
213
- const entryB = cache.get(convB);
214
- expect(entryB.entities).toHaveLength(5);
215
- });
216
- it('should fall back to raw conversion after invalidation', () => {
217
- const raw = createRawRows(convA, 3);
218
- cache.setRaw(convA, raw);
219
- cache.setEntities(convA, createEntities(raw));
220
- // New message arrives — cache invalidated
221
- cache.invalidate(convA);
222
- // Re-fetch from server, store new raw
223
- const freshRaw = createRawRows(convA, 4);
224
- cache.setRaw(convA, freshRaw);
225
- // Should need conversion (cached-raw path, not cached-entities)
226
- expect(resolveLoadPath(cache, convA)).toBe('cached-raw');
227
- // After conversion
228
- cache.setEntities(convA, createEntities(freshRaw));
229
- expect(resolveLoadPath(cache, convA)).toBe('cached-entities');
230
- });
231
- });
232
- });
233
- //# sourceMappingURL=conversation-cache.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"conversation-cache.test.js","sourceRoot":"","sources":["../../src/__tests__/conversation-cache.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach } from 'vitest';\n\n/**\n * Tests for the compound conversation data cache used by ConversationChatAreaComponent.\n *\n * The cache stores both raw query data and hydrated entity objects in a single Map entry.\n * This test exercises the cache logic in isolation (no Angular, no real entities) to verify:\n * - Compound cache structure (raw + nullable entities)\n * - Cache hit paths: entities present vs only raw present vs miss\n * - Invalidation clears both raw and entities\n * - In-place patching of raw data preserves entity references\n */\n\n/** Minimal stand-in for ConversationDetailComplete (raw query row) */\ninterface MockRawRow {\n ID: string;\n ConversationID: string;\n Message: string;\n Role: string;\n Status: string;\n IsPinned: boolean;\n}\n\n/** Minimal stand-in for a hydrated entity object */\ninterface MockEntity {\n ID: string;\n Message: string;\n Status: string;\n IsPinned: boolean;\n}\n\n/** The compound cache entry shape matching the component's implementation */\ninterface CacheEntry {\n raw: MockRawRow[];\n entities: MockEntity[] | null;\n}\n\n/**\n * Extracts the cache management logic from ConversationChatAreaComponent\n * for isolated testing without Angular dependencies.\n */\nclass TestableConversationCache {\n private cache = new Map<string, CacheEntry>();\n\n has(conversationId: string): boolean {\n return this.cache.has(conversationId);\n }\n\n get(conversationId: string): CacheEntry | undefined {\n return this.cache.get(conversationId);\n }\n\n /** Store raw data from server (first visit) */\n setRaw(conversationId: string, raw: MockRawRow[]): void {\n this.cache.set(conversationId, { raw, entities: null });\n }\n\n /** Store hydrated entities after conversion */\n setEntities(conversationId: string, entities: MockEntity[]): void {\n const entry = this.cache.get(conversationId);\n if (entry) {\n entry.entities = entities;\n }\n }\n\n /** Invalidate both raw and entities */\n invalidate(conversationId: string): void {\n this.cache.delete(conversationId);\n }\n\n /** Patch raw data in-place (e.g., after pin toggle) */\n patchRaw(conversationId: string, messageId: string, patch: Partial<MockRawRow>): void {\n const entry = this.cache.get(conversationId);\n if (entry) {\n const row = entry.raw.find(r => r.ID === messageId);\n if (row) {\n Object.assign(row, patch);\n }\n }\n }\n\n /** Update raw data with fresh server data (invalidates entities) */\n refreshRaw(conversationId: string, raw: MockRawRow[]): void {\n this.cache.set(conversationId, { raw, entities: null });\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n\n/** Simulate the 3-path loadMessages logic */\nfunction resolveLoadPath(cache: TestableConversationCache, conversationId: string): 'cached-entities' | 'cached-raw' | 'server-fetch' {\n const entry = cache.get(conversationId);\n if (entry?.entities) return 'cached-entities';\n if (entry) return 'cached-raw';\n return 'server-fetch';\n}\n\n// ─── Test data ───────────────────────────────────────────────────────────\n\nfunction createRawRows(conversationId: string, count: number): MockRawRow[] {\n return Array.from({ length: count }, (_, i) => ({\n ID: `detail-${i}`,\n ConversationID: conversationId,\n Message: `Message ${i}`,\n Role: i % 2 === 0 ? 'user' : 'AI',\n Status: 'Completed',\n IsPinned: false,\n }));\n}\n\nfunction createEntities(rawRows: MockRawRow[]): MockEntity[] {\n return rawRows.map(r => ({\n ID: r.ID,\n Message: r.Message,\n Status: r.Status,\n IsPinned: r.IsPinned,\n }));\n}\n\n// ─── Tests ───────────────────────────────────────────────────────────────\n\ndescribe('Conversation Compound Cache', () => {\n let cache: TestableConversationCache;\n const convA = 'conv-aaa';\n const convB = 'conv-bbb';\n\n beforeEach(() => {\n cache = new TestableConversationCache();\n });\n\n describe('Cache structure', () => {\n it('should start empty', () => {\n expect(cache.size).toBe(0);\n expect(cache.has(convA)).toBe(false);\n });\n\n it('should store raw data with null entities on first visit', () => {\n const raw = createRawRows(convA, 5);\n cache.setRaw(convA, raw);\n\n const entry = cache.get(convA);\n expect(entry).toBeDefined();\n expect(entry!.raw).toBe(raw);\n expect(entry!.entities).toBeNull();\n });\n\n it('should store entities alongside raw data after conversion', () => {\n const raw = createRawRows(convA, 5);\n cache.setRaw(convA, raw);\n\n const entities = createEntities(raw);\n cache.setEntities(convA, entities);\n\n const entry = cache.get(convA);\n expect(entry!.raw).toBe(raw);\n expect(entry!.entities).toBe(entities);\n expect(entry!.entities).toHaveLength(5);\n });\n });\n\n describe('Load path resolution', () => {\n it('should resolve to server-fetch when cache is empty', () => {\n expect(resolveLoadPath(cache, convA)).toBe('server-fetch');\n });\n\n it('should resolve to cached-raw when only raw data exists', () => {\n cache.setRaw(convA, createRawRows(convA, 3));\n expect(resolveLoadPath(cache, convA)).toBe('cached-raw');\n });\n\n it('should resolve to cached-entities when entities are populated', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n cache.setEntities(convA, createEntities(raw));\n expect(resolveLoadPath(cache, convA)).toBe('cached-entities');\n });\n\n it('should handle multiple conversations independently', () => {\n const rawA = createRawRows(convA, 3);\n cache.setRaw(convA, rawA);\n cache.setEntities(convA, createEntities(rawA));\n\n cache.setRaw(convB, createRawRows(convB, 2));\n\n expect(resolveLoadPath(cache, convA)).toBe('cached-entities');\n expect(resolveLoadPath(cache, convB)).toBe('cached-raw');\n });\n });\n\n describe('Invalidation', () => {\n it('should remove both raw and entities on invalidate', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n cache.setEntities(convA, createEntities(raw));\n\n cache.invalidate(convA);\n\n expect(cache.has(convA)).toBe(false);\n expect(cache.get(convA)).toBeUndefined();\n expect(resolveLoadPath(cache, convA)).toBe('server-fetch');\n });\n\n it('should not affect other conversations when invalidating one', () => {\n cache.setRaw(convA, createRawRows(convA, 3));\n cache.setRaw(convB, createRawRows(convB, 2));\n\n cache.invalidate(convA);\n\n expect(cache.has(convA)).toBe(false);\n expect(cache.has(convB)).toBe(true);\n });\n });\n\n describe('Raw data refresh', () => {\n it('should replace raw data and clear entities on refresh', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n cache.setEntities(convA, createEntities(raw));\n\n const freshRaw = createRawRows(convA, 5);\n cache.refreshRaw(convA, freshRaw);\n\n const entry = cache.get(convA);\n expect(entry!.raw).toBe(freshRaw);\n expect(entry!.raw).toHaveLength(5);\n expect(entry!.entities).toBeNull(); // entities cleared\n expect(resolveLoadPath(cache, convA)).toBe('cached-raw');\n });\n });\n\n describe('In-place raw patching', () => {\n it('should patch a specific row in raw data', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n\n cache.patchRaw(convA, 'detail-1', { IsPinned: true });\n\n const entry = cache.get(convA);\n expect(entry!.raw[1].IsPinned).toBe(true);\n // Other rows unaffected\n expect(entry!.raw[0].IsPinned).toBe(false);\n expect(entry!.raw[2].IsPinned).toBe(false);\n });\n\n it('should not affect entities when patching raw data', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n const entities = createEntities(raw);\n cache.setEntities(convA, entities);\n\n cache.patchRaw(convA, 'detail-1', { IsPinned: true });\n\n // Raw is patched\n expect(cache.get(convA)!.raw[1].IsPinned).toBe(true);\n // Entity objects are separate — not patched by raw patch\n // (In the real component, the entity is already mutated by .Save())\n expect(cache.get(convA)!.entities![1].IsPinned).toBe(false);\n });\n\n it('should be a no-op for non-existent conversation', () => {\n cache.patchRaw('nonexistent', 'detail-0', { IsPinned: true });\n expect(cache.has('nonexistent')).toBe(false);\n });\n\n it('should be a no-op for non-existent message ID', () => {\n const raw = createRawRows(convA, 2);\n cache.setRaw(convA, raw);\n\n cache.patchRaw(convA, 'nonexistent-detail', { IsPinned: true });\n\n // Nothing changed\n expect(raw.every(r => r.IsPinned === false)).toBe(true);\n });\n });\n\n describe('Conversation switching simulation', () => {\n it('should provide instant switch when entities are cached', () => {\n // Visit conversation A — full load\n const rawA = createRawRows(convA, 10);\n cache.setRaw(convA, rawA);\n cache.setEntities(convA, createEntities(rawA));\n\n // Visit conversation B — full load\n const rawB = createRawRows(convB, 5);\n cache.setRaw(convB, rawB);\n cache.setEntities(convB, createEntities(rawB));\n\n // Switch back to A — should be instant (cached-entities path)\n expect(resolveLoadPath(cache, convA)).toBe('cached-entities');\n const entryA = cache.get(convA)!;\n expect(entryA.entities).toHaveLength(10);\n\n // Switch to B — also instant\n expect(resolveLoadPath(cache, convB)).toBe('cached-entities');\n const entryB = cache.get(convB)!;\n expect(entryB.entities).toHaveLength(5);\n });\n\n it('should fall back to raw conversion after invalidation', () => {\n const raw = createRawRows(convA, 3);\n cache.setRaw(convA, raw);\n cache.setEntities(convA, createEntities(raw));\n\n // New message arrives — cache invalidated\n cache.invalidate(convA);\n\n // Re-fetch from server, store new raw\n const freshRaw = createRawRows(convA, 4);\n cache.setRaw(convA, freshRaw);\n\n // Should need conversion (cached-raw path, not cached-entities)\n expect(resolveLoadPath(cache, convA)).toBe('cached-raw');\n\n // After conversion\n cache.setEntities(convA, createEntities(freshRaw));\n expect(resolveLoadPath(cache, convA)).toBe('cached-entities');\n });\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=conversation-naming.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"conversation-naming.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/conversation-naming.test.ts"],"names":[],"mappings":""}