chat 1.0.8 â 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-ACQNDPTB.js +356 -0
- package/dist/chunk-ACQNDPTB.js.map +1 -0
- package/dist/index.d.ts +1312 -0
- package/dist/index.js +1433 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-runtime-D7zHSnXe.d.ts +349 -0
- package/dist/jsx-runtime.d.ts +1 -0
- package/dist/jsx-runtime.js +17 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/package.json +61 -97
- package/lib/module/ChatContext/index.js +0 -2
- package/lib/module/ChatContext/index.js.map +0 -1
- package/lib/module/ChatContext/types.js +0 -2
- package/lib/module/ChatContext/types.js.map +0 -1
- package/lib/module/classes/Chat/index.js +0 -2
- package/lib/module/classes/Chat/index.js.map +0 -1
- package/lib/module/classes/Chat/types.js +0 -2
- package/lib/module/classes/Chat/types.js.map +0 -1
- package/lib/module/classes/Inbox/index.js +0 -2
- package/lib/module/classes/Inbox/index.js.map +0 -1
- package/lib/module/classes/Inbox/types.js +0 -2
- package/lib/module/classes/Inbox/types.js.map +0 -1
- package/lib/module/classes/Message/index.js +0 -2
- package/lib/module/classes/Message/index.js.map +0 -1
- package/lib/module/classes/Message/types.js +0 -2
- package/lib/module/classes/Message/types.js.map +0 -1
- package/lib/module/classes/Reaction/index.js +0 -2
- package/lib/module/classes/Reaction/index.js.map +0 -1
- package/lib/module/classes/Reaction/types.js +0 -2
- package/lib/module/classes/Reaction/types.js.map +0 -1
- package/lib/module/classes/Room/index.js +0 -2
- package/lib/module/classes/Room/index.js.map +0 -1
- package/lib/module/classes/Room/types.js +0 -2
- package/lib/module/classes/Room/types.js.map +0 -1
- package/lib/module/classes/index.js +0 -2
- package/lib/module/classes/index.js.map +0 -1
- package/lib/module/components/Avatar/index.js +0 -2
- package/lib/module/components/Avatar/index.js.map +0 -1
- package/lib/module/components/Chat/Bubble/index.js +0 -2
- package/lib/module/components/Chat/Bubble/index.js.map +0 -1
- package/lib/module/components/Chat/Composer/Input/index.js +0 -2
- package/lib/module/components/Chat/Composer/Input/index.js.map +0 -1
- package/lib/module/components/Chat/Composer/Send/index.js +0 -2
- package/lib/module/components/Chat/Composer/Send/index.js.map +0 -1
- package/lib/module/components/Chat/Composer/index.js +0 -2
- package/lib/module/components/Chat/Composer/index.js.map +0 -1
- package/lib/module/components/Chat/Media/Image/index.js +0 -2
- package/lib/module/components/Chat/Media/Image/index.js.map +0 -1
- package/lib/module/components/Chat/Media/index.js +0 -2
- package/lib/module/components/Chat/Media/index.js.map +0 -1
- package/lib/module/components/Chat/Message/Swiper/Action/index.js +0 -2
- package/lib/module/components/Chat/Message/Swiper/Action/index.js.map +0 -1
- package/lib/module/components/Chat/Message/Swiper/index.js +0 -2
- package/lib/module/components/Chat/Message/Swiper/index.js.map +0 -1
- package/lib/module/components/Chat/Message/Touchable/index.js +0 -2
- package/lib/module/components/Chat/Message/Touchable/index.js.map +0 -1
- package/lib/module/components/Chat/Message/index.js +0 -2
- package/lib/module/components/Chat/Message/index.js.map +0 -1
- package/lib/module/components/Chat/SystemMessage/index.js +0 -2
- package/lib/module/components/Chat/SystemMessage/index.js.map +0 -1
- package/lib/module/components/Chat/TypingFooter/index.js +0 -2
- package/lib/module/components/Chat/TypingFooter/index.js.map +0 -1
- package/lib/module/components/Chat/index.js +0 -2
- package/lib/module/components/Chat/index.js.map +0 -1
- package/lib/module/components/Chat/types.js +0 -2
- package/lib/module/components/Chat/types.js.map +0 -1
- package/lib/module/components/Chat-Old/Bubble/index.js +0 -2
- package/lib/module/components/Chat-Old/Bubble/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Composer/Input/index.js +0 -2
- package/lib/module/components/Chat-Old/Composer/Input/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Composer/Send/index.js +0 -2
- package/lib/module/components/Chat-Old/Composer/Send/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Composer/index.js +0 -2
- package/lib/module/components/Chat-Old/Composer/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Message/index.js +0 -2
- package/lib/module/components/Chat-Old/Message/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Swiper/Action/index.js +0 -2
- package/lib/module/components/Chat-Old/Swiper/Action/index.js.map +0 -1
- package/lib/module/components/Chat-Old/Swiper/index.js +0 -2
- package/lib/module/components/Chat-Old/Swiper/index.js.map +0 -1
- package/lib/module/components/Chat-Old/SystemMessage/index.js +0 -2
- package/lib/module/components/Chat-Old/SystemMessage/index.js.map +0 -1
- package/lib/module/components/Chat-Old/index.js +0 -2
- package/lib/module/components/Chat-Old/index.js.map +0 -1
- package/lib/module/components/Chat-Old/types.js +0 -2
- package/lib/module/components/Chat-Old/types.js.map +0 -1
- package/lib/module/components/ChatProvider/index.js +0 -2
- package/lib/module/components/ChatProvider/index.js.map +0 -1
- package/lib/module/components/ChatProvider/types.js +0 -2
- package/lib/module/components/ChatProvider/types.js.map +0 -1
- package/lib/module/components/Inbox/Item/Circle/index.js +0 -2
- package/lib/module/components/Inbox/Item/Circle/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/Circle/types.js +0 -2
- package/lib/module/components/Inbox/Item/Circle/types.js.map +0 -1
- package/lib/module/components/Inbox/Item/Initials/index.js +0 -2
- package/lib/module/components/Inbox/Item/Initials/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/ItemDate/index.js +0 -2
- package/lib/module/components/Inbox/Item/ItemDate/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/Separator/index.js +0 -2
- package/lib/module/components/Inbox/Item/Separator/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/Subtitle/index.js +0 -2
- package/lib/module/components/Inbox/Item/Subtitle/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/Swipeable/index.js +0 -2
- package/lib/module/components/Inbox/Item/Swipeable/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/Title/index.js +0 -2
- package/lib/module/components/Inbox/Item/Title/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/UnreadIndicator/index.js +0 -2
- package/lib/module/components/Inbox/Item/UnreadIndicator/index.js.map +0 -1
- package/lib/module/components/Inbox/Item/index.js +0 -2
- package/lib/module/components/Inbox/Item/index.js.map +0 -1
- package/lib/module/components/Inbox/index.js +0 -2
- package/lib/module/components/Inbox/index.js.map +0 -1
- package/lib/module/components/Inbox/question.md +0 -21
- package/lib/module/components/Inbox/readme.md +0 -21
- package/lib/module/components/Inbox/types.js +0 -2
- package/lib/module/components/Inbox/types.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/Footer/Button/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/Footer/Button/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/Footer/Input/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/Footer/Input/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/Footer/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/Footer/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/Item/Icon/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/Item/Icon/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/Item/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/Item/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Content/index.js +0 -2
- package/lib/module/components/RoomCreator/Content/index.js.map +0 -1
- package/lib/module/components/RoomCreator/Header/index.js +0 -2
- package/lib/module/components/RoomCreator/Header/index.js.map +0 -1
- package/lib/module/components/RoomCreator/index.js +0 -2
- package/lib/module/components/RoomCreator/index.js.map +0 -1
- package/lib/module/components/RoomCreator/types.js +0 -2
- package/lib/module/components/RoomCreator/types.js.map +0 -1
- package/lib/module/components/TypingIndicator/index.js +0 -2
- package/lib/module/components/TypingIndicator/index.js.map +0 -1
- package/lib/module/components/index.js +0 -2
- package/lib/module/components/index.js.map +0 -1
- package/lib/module/helpers/getInitials.js +0 -2
- package/lib/module/helpers/getInitials.js.map +0 -1
- package/lib/module/helpers/sortByAvatar.js +0 -2
- package/lib/module/helpers/sortByAvatar.js.map +0 -1
- package/lib/module/hooks/index.js +0 -2
- package/lib/module/hooks/index.js.map +0 -1
- package/lib/module/hooks/useCreateRoom/index.js +0 -2
- package/lib/module/hooks/useCreateRoom/index.js.map +0 -1
- package/lib/module/hooks/useCreator/index.js +0 -2
- package/lib/module/hooks/useCreator/index.js.map +0 -1
- package/lib/module/hooks/useInbox/index.js +0 -2
- package/lib/module/hooks/useInbox/index.js.map +0 -1
- package/lib/module/hooks/useInbox/types.js +0 -2
- package/lib/module/hooks/useInbox/types.js.map +0 -1
- package/lib/module/hooks/useMessages/index.js +0 -2
- package/lib/module/hooks/useMessages/index.js.map +0 -1
- package/lib/module/hooks/useMessages/types.js +0 -2
- package/lib/module/hooks/useMessages/types.js.map +0 -1
- package/lib/module/hooks/useRoom/index.js +0 -2
- package/lib/module/hooks/useRoom/index.js.map +0 -1
- package/lib/module/hooks/useRoom/types.js +0 -2
- package/lib/module/hooks/useRoom/types.js.map +0 -1
- package/lib/module/hooks/useSend/useSendToGroup/index.js +0 -2
- package/lib/module/hooks/useSend/useSendToGroup/index.js.map +0 -1
- package/lib/module/hooks/useSend/useSendToPeople/index.js +0 -2
- package/lib/module/hooks/useSend/useSendToPeople/index.js.map +0 -1
- package/lib/module/hooks/useTyping/index.js +0 -2
- package/lib/module/hooks/useTyping/index.js.map +0 -1
- package/lib/module/hooks/useTypingOLD/index.js +0 -2
- package/lib/module/hooks/useTypingOLD/index.js.map +0 -1
- package/lib/module/hooks/useTypingOLD/types.js +0 -2
- package/lib/module/hooks/useTypingOLD/types.js.map +0 -1
- package/lib/module/hooks/useViewMessages/index.js +0 -2
- package/lib/module/hooks/useViewMessages/index.js.map +0 -1
- package/lib/module/hooks/useViewMessages/types.js +0 -2
- package/lib/module/hooks/useViewMessages/types.js.map +0 -1
- package/lib/module/hooks/useViewMessagesOld/index.js +0 -2
- package/lib/module/hooks/useViewMessagesOld/index.js.map +0 -1
- package/lib/module/index.js +0 -2
- package/lib/module/index.js.map +0 -1
- package/lib/typescript/ChatContext/index.d.ts +0 -2
- package/lib/typescript/ChatContext/types.d.ts +0 -4
- package/lib/typescript/classes/Chat/index.d.ts +0 -14
- package/lib/typescript/classes/Chat/types.d.ts +0 -21
- package/lib/typescript/classes/Inbox/types.d.ts +0 -2
- package/lib/typescript/classes/Message/index.d.ts +0 -47
- package/lib/typescript/classes/Message/types.d.ts +0 -66
- package/lib/typescript/classes/Reaction/index.d.ts +0 -17
- package/lib/typescript/classes/Reaction/types.d.ts +0 -33
- package/lib/typescript/classes/Room/index.d.ts +0 -42
- package/lib/typescript/classes/Room/types.d.ts +0 -112
- package/lib/typescript/classes/index.d.ts +0 -4
- package/lib/typescript/components/Avatar/index.d.ts +0 -4
- package/lib/typescript/components/Chat/Bubble/index.d.ts +0 -4
- package/lib/typescript/components/Chat/Composer/Input/index.d.ts +0 -7
- package/lib/typescript/components/Chat/Composer/Send/index.d.ts +0 -4
- package/lib/typescript/components/Chat/Composer/index.d.ts +0 -8
- package/lib/typescript/components/Chat/Media/Image/index.d.ts +0 -7
- package/lib/typescript/components/Chat/Media/index.d.ts +0 -4
- package/lib/typescript/components/Chat/Message/Touchable/index.d.ts +0 -4
- package/lib/typescript/components/Chat/Message/index.d.ts +0 -8
- package/lib/typescript/components/Chat/SystemMessage/index.d.ts +0 -4
- package/lib/typescript/components/Chat/TypingFooter/index.d.ts +0 -4
- package/lib/typescript/components/Chat/index.d.ts +0 -8
- package/lib/typescript/components/Chat/types.d.ts +0 -843
- package/lib/typescript/components/ChatProvider/index.d.ts +0 -10
- package/lib/typescript/components/ChatProvider/types.d.ts +0 -7
- package/lib/typescript/components/Inbox/Item/Initials/index.d.ts +0 -4
- package/lib/typescript/components/Inbox/Item/ItemDate/index.d.ts +0 -4
- package/lib/typescript/components/Inbox/Item/Separator/index.d.ts +0 -6
- package/lib/typescript/components/Inbox/Item/Subtitle/index.d.ts +0 -3
- package/lib/typescript/components/Inbox/Item/Swipeable/index.d.ts +0 -4
- package/lib/typescript/components/Inbox/Item/Title/index.d.ts +0 -3
- package/lib/typescript/components/Inbox/Item/UnreadIndicator/index.d.ts +0 -4
- package/lib/typescript/components/Inbox/Item/index.d.ts +0 -6
- package/lib/typescript/components/Inbox/index.d.ts +0 -4
- package/lib/typescript/components/Inbox/types.d.ts +0 -304
- package/lib/typescript/components/RoomCreator/Content/Footer/Button/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/Content/Footer/Input/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/Content/Footer/index.d.ts +0 -3
- package/lib/typescript/components/RoomCreator/Content/Item/Icon/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/Content/Item/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/Content/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/Header/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/index.d.ts +0 -4
- package/lib/typescript/components/RoomCreator/types.d.ts +0 -208
- package/lib/typescript/components/TypingIndicator/index.d.ts +0 -9
- package/lib/typescript/components/index.d.ts +0 -12
- package/lib/typescript/helpers/getInitials.d.ts +0 -1
- package/lib/typescript/hooks/index.d.ts +0 -8
- package/lib/typescript/hooks/useCreator/index.d.ts +0 -27
- package/lib/typescript/hooks/useInbox/index.d.ts +0 -29
- package/lib/typescript/hooks/useInbox/types.d.ts +0 -5
- package/lib/typescript/hooks/useMessages/index.d.ts +0 -24
- package/lib/typescript/hooks/useMessages/types.d.ts +0 -5
- package/lib/typescript/hooks/useRoom/index.d.ts +0 -26
- package/lib/typescript/hooks/useRoom/types.d.ts +0 -5
- package/lib/typescript/hooks/useSend/useSendToGroup/index.d.ts +0 -6
- package/lib/typescript/hooks/useSend/useSendToPeople/index.d.ts +0 -6
- package/lib/typescript/hooks/useTyping/index.d.ts +0 -36
- package/lib/typescript/hooks/useViewMessages/index.d.ts +0 -18
- package/lib/typescript/hooks/useViewMessages/types.d.ts +0 -20
- package/lib/typescript/index.d.ts +0 -11
- package/readme.md +0 -201
- package/src/ChatContext/index.tsx +0 -9
- package/src/ChatContext/types.ts +0 -4
- package/src/classes/Chat/index.ts +0 -46
- package/src/classes/Chat/types.ts +0 -23
- package/src/classes/Inbox/index.ts +0 -12
- package/src/classes/Inbox/types.ts +0 -3
- package/src/classes/Message/index.ts +0 -310
- package/src/classes/Message/types.ts +0 -118
- package/src/classes/Reaction/index.ts +0 -108
- package/src/classes/Reaction/types.ts +0 -37
- package/src/classes/Room/index.ts +0 -323
- package/src/classes/Room/types.ts +0 -161
- package/src/classes/index.ts +0 -4
- package/src/components/Avatar/index.tsx +0 -25
- package/src/components/Chat/Bubble/index.tsx +0 -139
- package/src/components/Chat/Composer/Input/index.tsx +0 -45
- package/src/components/Chat/Composer/Send/index.tsx +0 -51
- package/src/components/Chat/Composer/index.tsx +0 -187
- package/src/components/Chat/Media/Image/index.tsx +0 -26
- package/src/components/Chat/Media/index.tsx +0 -11
- package/src/components/Chat/Message/Swiper/Action/index.tsx +0 -7
- package/src/components/Chat/Message/Swiper/index.tsx +0 -32
- package/src/components/Chat/Message/Touchable/index.tsx +0 -60
- package/src/components/Chat/Message/index.tsx +0 -328
- package/src/components/Chat/SystemMessage/index.tsx +0 -44
- package/src/components/Chat/TypingFooter/index.tsx +0 -48
- package/src/components/Chat/index.tsx +0 -596
- package/src/components/Chat/types.ts +0 -913
- package/src/components/Chat-Old/Bubble/index.tsx +0 -58
- package/src/components/Chat-Old/Composer/Input/index.tsx +0 -34
- package/src/components/Chat-Old/Composer/Send/index.tsx +0 -37
- package/src/components/Chat-Old/Composer/index.tsx +0 -131
- package/src/components/Chat-Old/Message/index.tsx +0 -160
- package/src/components/Chat-Old/Swiper/Action/index.tsx +0 -7
- package/src/components/Chat-Old/Swiper/index.tsx +0 -30
- package/src/components/Chat-Old/SystemMessage/index.tsx +0 -44
- package/src/components/Chat-Old/index.tsx +0 -356
- package/src/components/Chat-Old/types.ts +0 -752
- package/src/components/ChatProvider/index.tsx +0 -31
- package/src/components/ChatProvider/types.ts +0 -8
- package/src/components/Inbox/Item/Circle/index.tsx +0 -47
- package/src/components/Inbox/Item/Circle/types.ts +0 -8
- package/src/components/Inbox/Item/Initials/index.tsx +0 -41
- package/src/components/Inbox/Item/ItemDate/index.tsx +0 -26
- package/src/components/Inbox/Item/Separator/index.tsx +0 -13
- package/src/components/Inbox/Item/Subtitle/index.tsx +0 -23
- package/src/components/Inbox/Item/Swipeable/index.tsx +0 -143
- package/src/components/Inbox/Item/Title/index.tsx +0 -23
- package/src/components/Inbox/Item/UnreadIndicator/index.tsx +0 -84
- package/src/components/Inbox/Item/index.tsx +0 -307
- package/src/components/Inbox/index.tsx +0 -315
- package/src/components/Inbox/question.md +0 -21
- package/src/components/Inbox/readme.md +0 -21
- package/src/components/Inbox/types.ts +0 -371
- package/src/components/RoomCreator/Content/Footer/Button/index.tsx +0 -55
- package/src/components/RoomCreator/Content/Footer/Input/index.tsx +0 -27
- package/src/components/RoomCreator/Content/Footer/index.tsx +0 -72
- package/src/components/RoomCreator/Content/Item/Icon/index.tsx +0 -16
- package/src/components/RoomCreator/Content/Item/index.tsx +0 -87
- package/src/components/RoomCreator/Content/index.tsx +0 -75
- package/src/components/RoomCreator/Header/index.tsx +0 -74
- package/src/components/RoomCreator/index.tsx +0 -177
- package/src/components/RoomCreator/types.ts +0 -233
- package/src/components/TypingIndicator/index.tsx +0 -169
- package/src/components/index.ts +0 -18
- package/src/helpers/getInitials.ts +0 -11
- package/src/helpers/sortByAvatar.ts +0 -1
- package/src/hooks/index.ts +0 -8
- package/src/hooks/useCreateRoom/index.ts +0 -34
- package/src/hooks/useCreator/index.ts +0 -33
- package/src/hooks/useInbox/index.ts +0 -76
- package/src/hooks/useInbox/types.ts +0 -6
- package/src/hooks/useMessages/index.ts +0 -109
- package/src/hooks/useMessages/types.ts +0 -6
- package/src/hooks/useRoom/index.ts +0 -82
- package/src/hooks/useRoom/types.ts +0 -6
- package/src/hooks/useSend/useSendToGroup/index.ts +0 -38
- package/src/hooks/useSend/useSendToPeople/index.ts +0 -38
- package/src/hooks/useTyping/index.ts +0 -154
- package/src/hooks/useTypingOLD/index.ts +0 -67
- package/src/hooks/useTypingOLD/types.ts +0 -7
- package/src/hooks/useViewMessages/index.ts +0 -61
- package/src/hooks/useViewMessages/types.ts +0 -22
- package/src/hooks/useViewMessagesOld/index.ts +0 -39
- package/src/index.ts +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/markdown.ts","../src/thread.ts","../src/types.ts","../src/chat.ts","../src/emoji.ts","../src/index.ts"],"sourcesContent":["/**\n * Markdown parsing and conversion utilities using unified/remark.\n */\n\nimport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Text,\n} from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkParse from \"remark-parse\";\nimport remarkStringify from \"remark-stringify\";\nimport { unified } from \"unified\";\nimport type { CardChild, CardElement } from \"./cards\";\n\n// Re-export types for adapters\nexport type {\n Root,\n Content,\n Text,\n Strong,\n Emphasis,\n Delete,\n InlineCode,\n Code,\n Link,\n Blockquote,\n List,\n ListItem,\n Paragraph,\n};\n\n/**\n * Parse markdown string into an AST.\n * Supports GFM (GitHub Flavored Markdown) for strikethrough, tables, etc.\n */\nexport function parseMarkdown(markdown: string): Root {\n const processor = unified().use(remarkParse).use(remarkGfm);\n return processor.parse(markdown);\n}\n\n/**\n * Stringify an AST back to markdown.\n */\nexport function stringifyMarkdown(ast: Root): string {\n const processor = unified().use(remarkStringify).use(remarkGfm);\n return processor.stringify(ast);\n}\n\n/**\n * Extract plain text from an AST (strips all formatting).\n */\nexport function toPlainText(ast: Root): string {\n return toString(ast);\n}\n\n/**\n * Extract plain text from a markdown string.\n */\nexport function markdownToPlainText(markdown: string): string {\n const ast = parseMarkdown(markdown);\n return toString(ast);\n}\n\n/**\n * Walk the AST and transform nodes.\n */\nexport function walkAst<T extends Content | Root>(\n node: T,\n visitor: (node: Content) => Content | null,\n): T {\n if (\"children\" in node && Array.isArray(node.children)) {\n node.children = node.children\n .map((child) => {\n const result = visitor(child as Content);\n if (result === null) return null;\n return walkAst(result, visitor);\n })\n .filter((n): n is Content => n !== null);\n }\n return node;\n}\n\n/**\n * Create a text node.\n */\nexport function text(value: string): Text {\n return { type: \"text\", value };\n}\n\n/**\n * Create a strong (bold) node.\n */\nexport function strong(children: Content[]): Strong {\n return { type: \"strong\", children: children as Strong[\"children\"] };\n}\n\n/**\n * Create an emphasis (italic) node.\n */\nexport function emphasis(children: Content[]): Emphasis {\n return { type: \"emphasis\", children: children as Emphasis[\"children\"] };\n}\n\n/**\n * Create a delete (strikethrough) node.\n */\nexport function strikethrough(children: Content[]): Delete {\n return { type: \"delete\", children: children as Delete[\"children\"] };\n}\n\n/**\n * Create an inline code node.\n */\nexport function inlineCode(value: string): InlineCode {\n return { type: \"inlineCode\", value };\n}\n\n/**\n * Create a code block node.\n */\nexport function codeBlock(value: string, lang?: string): Code {\n return { type: \"code\", value, lang };\n}\n\n/**\n * Create a link node.\n */\nexport function link(url: string, children: Content[], title?: string): Link {\n return { type: \"link\", url, children: children as Link[\"children\"], title };\n}\n\n/**\n * Create a blockquote node.\n */\nexport function blockquote(children: Content[]): Blockquote {\n return { type: \"blockquote\", children: children as Blockquote[\"children\"] };\n}\n\n/**\n * Create a paragraph node.\n */\nexport function paragraph(children: Content[]): Paragraph {\n return { type: \"paragraph\", children: children as Paragraph[\"children\"] };\n}\n\n/**\n * Create a root node (top-level AST container).\n */\nexport function root(children: Content[]): Root {\n return { type: \"root\", children: children as Root[\"children\"] };\n}\n\n/**\n * Interface for platform-specific format converters.\n *\n * The AST (mdast Root) is the canonical representation.\n * All conversions go through the AST:\n *\n * Platform Format <-> AST <-> Markdown String\n *\n * Adapters implement this interface to convert between\n * their platform-specific format and the standard AST.\n */\nexport interface FormatConverter {\n /**\n * Render an AST to the platform's native format.\n * This is the primary method used when sending messages.\n */\n fromAst(ast: Root): string;\n\n /**\n * Parse platform's native format into an AST.\n * This is the primary method used when receiving messages.\n */\n toAst(platformText: string): Root;\n\n /**\n * Extract plain text from platform format.\n * Convenience method - default implementation uses toAst + toPlainText.\n */\n extractPlainText(platformText: string): string;\n}\n\n/**\n * @deprecated Use FormatConverter instead\n */\nexport interface MarkdownConverter extends FormatConverter {\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string;\n toMarkdown(platformText: string): string;\n toPlainText(platformText: string): string;\n}\n\n/**\n * Base class for format converters with default implementations.\n */\nexport abstract class BaseFormatConverter implements FormatConverter {\n abstract fromAst(ast: Root): string;\n abstract toAst(platformText: string): Root;\n\n extractPlainText(platformText: string): string {\n return toPlainText(this.toAst(platformText));\n }\n\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string {\n return this.fromAst(parseMarkdown(markdown));\n }\n\n toMarkdown(platformText: string): string {\n return stringifyMarkdown(this.toAst(platformText));\n }\n\n /** @deprecated Use extractPlainText instead */\n toPlainText(platformText: string): string {\n return this.extractPlainText(platformText);\n }\n\n /**\n * Convert a PostableMessage to platform format (text only).\n * - string: passed through as raw text (no conversion)\n * - { raw: string }: passed through as raw text (no conversion)\n * - { markdown: string }: converted from markdown to platform format\n * - { ast: Root }: converted from AST to platform format\n * - { card: CardElement }: returns fallback text (cards should be handled by adapter)\n * - CardElement: returns fallback text (cards should be handled by adapter)\n *\n * Note: For cards, adapters should check for card content first and render\n * them using platform-specific card APIs, using this method only for fallback.\n */\n renderPostable(message: PostableMessageInput): string {\n if (typeof message === \"string\") {\n return message;\n }\n if (\"raw\" in message) {\n return message.raw;\n }\n if (\"markdown\" in message) {\n return this.fromMarkdown(message.markdown);\n }\n if (\"ast\" in message) {\n return this.fromAst(message.ast);\n }\n if (\"card\" in message) {\n // Card with fallback text or generate from card content\n return message.fallbackText || this.cardToFallbackText(message.card);\n }\n if (\"type\" in message && message.type === \"card\") {\n // Direct CardElement\n return this.cardToFallbackText(message);\n }\n // Should never reach here with proper typing\n throw new Error(\"Invalid PostableMessage format\");\n }\n\n /**\n * Generate fallback text from a card element.\n * Override in subclasses for platform-specific formatting.\n */\n protected cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(`**${card.title}**`);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = this.cardChildToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Convert card child element to fallback text.\n */\n protected cardChildToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"fields\":\n return child.children\n .map((f) => `**${f.label}**: ${f.value}`)\n .join(\"\\n\");\n case \"actions\":\n return `[${child.children.map((b) => b.label).join(\"] [\")}]`;\n case \"section\":\n return child.children\n .map((c) => this.cardChildToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n }\n}\n\n/**\n * Type for PostableMessage input (for rendering to text)\n */\ntype PostableMessageInput =\n | string\n | { raw: string }\n | { markdown: string }\n | { ast: Root }\n | { card: CardElement; fallbackText?: string }\n | CardElement;\n","import type { Root } from \"mdast\";\nimport { cardToFallbackText } from \"./cards\";\nimport { type CardJSXElement, isJSX, toCardElement } from \"./jsx-runtime\";\nimport {\n paragraph,\n parseMarkdown,\n root,\n text as textNode,\n toPlainText,\n} from \"./markdown\";\nimport type {\n Adapter,\n Attachment,\n Message,\n PostableMessage,\n SentMessage,\n StateAdapter,\n Thread,\n} from \"./types\";\n\ninterface ThreadImplConfig {\n id: string;\n adapter: Adapter;\n channelId: string;\n state: StateAdapter;\n initialMessage?: Message;\n /** If true, thread is known to be subscribed (for short-circuit optimization) */\n isSubscribedContext?: boolean;\n /** Whether this is a direct message conversation */\n isDM?: boolean;\n}\n\nexport class ThreadImpl implements Thread {\n readonly id: string;\n readonly adapter: Adapter;\n readonly channelId: string;\n readonly isDM: boolean;\n\n private state: StateAdapter;\n private _recentMessages: Message[] = [];\n private _isSubscribedContext: boolean;\n\n constructor(config: ThreadImplConfig) {\n this.id = config.id;\n this.adapter = config.adapter;\n this.channelId = config.channelId;\n this.isDM = config.isDM ?? false;\n this.state = config.state;\n this._isSubscribedContext = config.isSubscribedContext ?? false;\n\n if (config.initialMessage) {\n this._recentMessages = [config.initialMessage];\n }\n }\n\n get recentMessages(): Message[] {\n return this._recentMessages;\n }\n\n set recentMessages(messages: Message[]) {\n this._recentMessages = messages;\n }\n\n get allMessages(): AsyncIterable<Message> {\n const adapter = this.adapter;\n const threadId = this.id;\n\n return {\n async *[Symbol.asyncIterator]() {\n let before: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const messages = await adapter.fetchMessages(threadId, {\n limit: 100,\n before,\n });\n\n if (messages.length === 0) {\n hasMore = false;\n break;\n }\n\n for (const message of messages) {\n yield message;\n }\n\n before = messages[messages.length - 1]?.id;\n\n // If we got fewer than requested, we've reached the end\n if (messages.length < 100) {\n hasMore = false;\n }\n }\n },\n };\n }\n\n async isSubscribed(): Promise<boolean> {\n // Short-circuit if we know we're in a subscribed context\n if (this._isSubscribedContext) {\n return true;\n }\n return this.state.isSubscribed(this.id);\n }\n\n async subscribe(): Promise<void> {\n await this.state.subscribe(this.id);\n // Allow adapters to set up platform-specific subscriptions\n if (this.adapter.onThreadSubscribe) {\n await this.adapter.onThreadSubscribe(this.id);\n }\n }\n\n async unsubscribe(): Promise<void> {\n await this.state.unsubscribe(this.id);\n }\n\n async post(\n message: string | PostableMessage | CardJSXElement,\n ): Promise<SentMessage> {\n // Auto-convert JSX elements to CardElement\n let postable: string | PostableMessage = message as\n | string\n | PostableMessage;\n if (isJSX(message)) {\n const card = toCardElement(message);\n if (!card) {\n throw new Error(\"Invalid JSX element: must be a Card element\");\n }\n postable = card;\n }\n\n const rawMessage = await this.adapter.postMessage(this.id, postable);\n\n // Create a SentMessage with edit/delete capabilities\n return this.createSentMessage(rawMessage.id, postable);\n }\n\n async startTyping(): Promise<void> {\n await this.adapter.startTyping(this.id);\n }\n\n async refresh(): Promise<void> {\n const messages = await this.adapter.fetchMessages(this.id, { limit: 50 });\n this._recentMessages = messages;\n }\n\n mentionUser(userId: string): string {\n return `<@${userId}>`;\n }\n\n private createSentMessage(\n messageId: string,\n postable: PostableMessage,\n ): SentMessage {\n const adapter = this.adapter;\n const threadId = this.id;\n const self = this;\n\n // Extract text and AST from the PostableMessage\n const { plainText, formatted, attachments } =\n extractMessageContent(postable);\n\n const sentMessage: SentMessage = {\n id: messageId,\n threadId,\n text: plainText,\n formatted,\n raw: null, // Will be populated if needed\n author: {\n userId: \"self\",\n userName: adapter.userName,\n fullName: adapter.userName,\n isBot: true,\n isMe: true,\n },\n metadata: {\n dateSent: new Date(),\n edited: false,\n },\n attachments,\n\n async edit(\n newContent: string | PostableMessage | CardJSXElement,\n ): Promise<SentMessage> {\n // Auto-convert JSX elements to CardElement\n let postable: string | PostableMessage = newContent as\n | string\n | PostableMessage;\n if (isJSX(newContent)) {\n const card = toCardElement(newContent);\n if (!card) {\n throw new Error(\"Invalid JSX element: must be a Card element\");\n }\n postable = card;\n }\n await adapter.editMessage(threadId, messageId, postable);\n return self.createSentMessage(messageId, postable);\n },\n\n async delete(): Promise<void> {\n await adapter.deleteMessage(threadId, messageId);\n },\n\n async addReaction(emoji: string): Promise<void> {\n await adapter.addReaction(threadId, messageId, emoji);\n },\n\n async removeReaction(emoji: string): Promise<void> {\n await adapter.removeReaction(threadId, messageId, emoji);\n },\n };\n\n return sentMessage;\n }\n}\n\n/**\n * Extract plain text, AST, and attachments from a PostableMessage.\n */\nfunction extractMessageContent(message: PostableMessage): {\n plainText: string;\n formatted: Root;\n attachments: Attachment[];\n} {\n if (typeof message === \"string\") {\n // Raw string - create simple AST\n return {\n plainText: message,\n formatted: root([paragraph([textNode(message)])]),\n attachments: [],\n };\n }\n\n if (\"raw\" in message) {\n // Raw text - create simple AST\n return {\n plainText: message.raw,\n formatted: root([paragraph([textNode(message.raw)])]),\n attachments: message.attachments || [],\n };\n }\n\n if (\"markdown\" in message) {\n // Markdown - parse to AST\n const ast = parseMarkdown(message.markdown);\n return {\n plainText: toPlainText(ast),\n formatted: ast,\n attachments: message.attachments || [],\n };\n }\n\n if (\"ast\" in message) {\n // AST provided directly\n return {\n plainText: toPlainText(message.ast),\n formatted: message.ast,\n attachments: message.attachments || [],\n };\n }\n\n if (\"card\" in message) {\n // PostableCard - generate fallback text from card\n const fallbackText =\n message.fallbackText || cardToFallbackText(message.card);\n return {\n plainText: fallbackText,\n formatted: root([paragraph([textNode(fallbackText)])]),\n attachments: [],\n };\n }\n\n if (\"type\" in message && message.type === \"card\") {\n // Direct CardElement\n const fallbackText = cardToFallbackText(message);\n return {\n plainText: fallbackText,\n formatted: root([paragraph([textNode(fallbackText)])]),\n attachments: [],\n };\n }\n\n // Should never reach here with proper typing\n throw new Error(\"Invalid PostableMessage format\");\n}\n","/**\n * Core types for chat-sdk\n */\n\nimport type { Root } from \"mdast\";\nimport type { CardElement } from \"./cards\";\nimport type { CardJSXElement } from \"./jsx-runtime\";\n\n// =============================================================================\n// Logging\n// =============================================================================\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n /** Create a sub-logger with a prefix */\n child(prefix: string): Logger;\n}\n\n/**\n * Default console logger implementation.\n */\nexport class ConsoleLogger implements Logger {\n private prefix: string;\n\n constructor(\n private level: LogLevel = \"info\",\n prefix = \"chat-sdk\",\n ) {\n this.prefix = prefix;\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels: LogLevel[] = [\"debug\", \"info\", \"warn\", \"error\", \"silent\"];\n return levels.indexOf(level) >= levels.indexOf(this.level);\n }\n\n child(prefix: string): Logger {\n return new ConsoleLogger(this.level, `${this.prefix}:${prefix}`);\n }\n\n // eslint-disable-next-line no-console\n debug(message: string, ...args: unknown[]): void {\n if (this.shouldLog(\"debug\"))\n console.debug(`[${this.prefix}] ${message}`, ...args);\n }\n\n // eslint-disable-next-line no-console\n info(message: string, ...args: unknown[]): void {\n if (this.shouldLog(\"info\"))\n console.info(`[${this.prefix}] ${message}`, ...args);\n }\n\n // eslint-disable-next-line no-console\n warn(message: string, ...args: unknown[]): void {\n if (this.shouldLog(\"warn\"))\n console.warn(`[${this.prefix}] ${message}`, ...args);\n }\n\n // eslint-disable-next-line no-console\n error(message: string, ...args: unknown[]): void {\n if (this.shouldLog(\"error\"))\n console.error(`[${this.prefix}] ${message}`, ...args);\n }\n}\n\n// =============================================================================\n// Configuration\n// =============================================================================\n\n/**\n * Chat configuration with type-safe adapter inference.\n * @template TAdapters - Record of adapter name to adapter instance\n */\nexport interface ChatConfig<\n TAdapters extends Record<string, Adapter> = Record<string, Adapter>,\n> {\n /** Default bot username across all adapters */\n userName: string;\n /** Map of adapter name to adapter instance */\n adapters: TAdapters;\n /** State adapter for subscriptions and locking */\n state: StateAdapter;\n /**\n * Logger instance or log level. Defaults to \"info\".\n * Pass \"silent\" to disable all logging.\n */\n logger?: Logger | LogLevel;\n}\n\n/**\n * Options for webhook handling.\n */\nexport interface WebhookOptions {\n /**\n * Function to run message handling in the background.\n * Use this to ensure fast webhook responses while processing continues.\n *\n * @example\n * // Next.js App Router\n * import { after } from \"next/server\";\n * chat.webhooks.slack(request, { waitUntil: (p) => after(() => p) });\n *\n * @example\n * // Vercel Functions\n * import { waitUntil } from \"@vercel/functions\";\n * chat.webhooks.slack(request, { waitUntil });\n */\n waitUntil?: (task: Promise<unknown>) => void;\n}\n\n// =============================================================================\n// Adapter Interface\n// =============================================================================\n\n/**\n * Adapter interface with generics for platform-specific types.\n * @template TThreadId - Platform-specific thread ID data type\n * @template TRawMessage - Platform-specific raw message type\n */\nexport interface Adapter<TThreadId = unknown, TRawMessage = unknown> {\n /** Unique name for this adapter (e.g., \"slack\", \"teams\") */\n readonly name: string;\n /** Bot username (can override global userName) */\n readonly userName: string;\n /** Bot user ID for platforms that use IDs in mentions (e.g., Slack's <@U123>) */\n readonly botUserId?: string;\n\n /** Called when Chat instance is created (internal use) */\n initialize(chat: ChatInstance): Promise<void>;\n\n /** Handle incoming webhook request */\n handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;\n\n /** Post a message to a thread */\n postMessage(\n threadId: string,\n message: PostableMessage,\n ): Promise<RawMessage<TRawMessage>>;\n\n /** Edit an existing message */\n editMessage(\n threadId: string,\n messageId: string,\n message: PostableMessage,\n ): Promise<RawMessage<TRawMessage>>;\n\n /** Delete a message */\n deleteMessage(threadId: string, messageId: string): Promise<void>;\n\n /** Add a reaction to a message */\n addReaction(\n threadId: string,\n messageId: string,\n emoji: EmojiValue | string,\n ): Promise<void>;\n\n /** Remove a reaction from a message */\n removeReaction(\n threadId: string,\n messageId: string,\n emoji: EmojiValue | string,\n ): Promise<void>;\n\n /** Show typing indicator */\n startTyping(threadId: string): Promise<void>;\n\n /** Fetch messages from a thread */\n fetchMessages(\n threadId: string,\n options?: FetchOptions,\n ): Promise<Message<TRawMessage>[]>;\n\n /** Fetch thread metadata */\n fetchThread(threadId: string): Promise<ThreadInfo>;\n\n /** Encode platform-specific data into a thread ID string */\n encodeThreadId(platformData: TThreadId): string;\n\n /** Decode thread ID string back to platform-specific data */\n decodeThreadId(threadId: string): TThreadId;\n\n /** Parse platform message format to normalized format */\n parseMessage(raw: TRawMessage): Message<TRawMessage>;\n\n /** Render formatted content to platform-specific string */\n renderFormatted(content: FormattedContent): string;\n\n /**\n * Optional hook called when a thread is subscribed to.\n * Adapters can use this to set up platform-specific subscriptions\n * (e.g., Google Chat Workspace Events).\n */\n onThreadSubscribe?(threadId: string): Promise<void>;\n\n /**\n * Open a direct message conversation with a user.\n *\n * @param userId - The platform-specific user ID\n * @returns The thread ID for the DM conversation\n *\n * @example\n * ```typescript\n * const dmThreadId = await adapter.openDM(\"U123456\");\n * await adapter.postMessage(dmThreadId, \"Hello!\");\n * ```\n */\n openDM?(userId: string): Promise<string>;\n\n /**\n * Check if a thread is a direct message conversation.\n *\n * @param threadId - The thread ID to check\n * @returns True if the thread is a DM, false otherwise\n */\n isDM?(threadId: string): boolean;\n}\n\n/** Internal interface for Chat instance passed to adapters */\nexport interface ChatInstance {\n /**\n * Process an incoming message from an adapter.\n * Handles waitUntil registration and error catching internally.\n *\n * @param adapter - The adapter that received the message\n * @param threadId - The thread ID\n * @param message - Either a parsed message, or a factory function for lazy async parsing\n * @param options - Webhook options including waitUntil\n */\n processMessage(\n adapter: Adapter,\n threadId: string,\n message: Message | (() => Promise<Message>),\n options?: WebhookOptions,\n ): void;\n\n /**\n * @deprecated Use processMessage instead. This method is for internal use.\n */\n handleIncomingMessage(\n adapter: Adapter,\n threadId: string,\n message: Message,\n ): Promise<void>;\n\n /**\n * Process an incoming reaction event from an adapter.\n * Handles waitUntil registration and error catching internally.\n *\n * @param event - The reaction event (without adapter field, will be added)\n * @param options - Webhook options including waitUntil\n */\n processReaction(\n event: Omit<ReactionEvent, \"adapter\" | \"thread\"> & { adapter?: Adapter },\n options?: WebhookOptions,\n ): void;\n\n /**\n * Process an incoming action event (button click) from an adapter.\n * Handles waitUntil registration and error catching internally.\n *\n * @param event - The action event (without thread field, will be added)\n * @param options - Webhook options including waitUntil\n */\n processAction(\n event: Omit<ActionEvent, \"thread\"> & { adapter: Adapter },\n options?: WebhookOptions,\n ): void;\n\n getState(): StateAdapter;\n getUserName(): string;\n /** Get the configured logger, optionally with a child prefix */\n getLogger(prefix?: string): Logger;\n}\n\n// =============================================================================\n// State Adapter Interface\n// =============================================================================\n\nexport interface StateAdapter {\n /** Connect to the state backend */\n connect(): Promise<void>;\n\n /** Disconnect from the state backend */\n disconnect(): Promise<void>;\n\n /** Subscribe to a thread (persists across restarts) */\n subscribe(threadId: string): Promise<void>;\n\n /** Unsubscribe from a thread */\n unsubscribe(threadId: string): Promise<void>;\n\n /** Check if subscribed to a thread */\n isSubscribed(threadId: string): Promise<boolean>;\n\n /** List all subscriptions, optionally filtered by adapter */\n listSubscriptions(adapterName?: string): AsyncIterable<string>;\n\n /** Acquire a lock on a thread (returns null if already locked) */\n acquireLock(threadId: string, ttlMs: number): Promise<Lock | null>;\n\n /** Release a lock */\n releaseLock(lock: Lock): Promise<void>;\n\n /** Extend a lock's TTL */\n extendLock(lock: Lock, ttlMs: number): Promise<boolean>;\n\n /** Get a cached value by key */\n get<T = unknown>(key: string): Promise<T | null>;\n\n /** Set a cached value with optional TTL in milliseconds */\n set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;\n\n /** Delete a cached value */\n delete(key: string): Promise<void>;\n}\n\nexport interface Lock {\n threadId: string;\n token: string;\n expiresAt: number;\n}\n\n// =============================================================================\n// Thread\n// =============================================================================\n\nexport interface Thread<TRawMessage = unknown> {\n /** Unique thread ID (format: \"adapter:channel:thread\") */\n readonly id: string;\n /** The adapter this thread belongs to */\n readonly adapter: Adapter;\n /** Channel/conversation ID */\n readonly channelId: string;\n /** Whether this is a direct message conversation */\n readonly isDM: boolean;\n\n /** Recently fetched messages (cached) */\n recentMessages: Message<TRawMessage>[];\n\n /** Async iterator for all messages in the thread */\n allMessages: AsyncIterable<Message<TRawMessage>>;\n\n /**\n * Check if this thread is currently subscribed.\n *\n * In subscribed message handlers, this is optimized to return true immediately\n * without a state lookup, since we already know we're in a subscribed context.\n *\n * @returns Promise resolving to true if subscribed, false otherwise\n */\n isSubscribed(): Promise<boolean>;\n\n /**\n * Subscribe to future messages in this thread.\n *\n * Once subscribed, all messages in this thread will trigger `onSubscribedMessage` handlers.\n * The initial message that triggered subscription will NOT fire the handler.\n *\n * @example\n * ```typescript\n * chat.onNewMention(async (thread, message) => {\n * await thread.subscribe(); // Subscribe to follow-up messages\n * await thread.post(\"I'm now watching this thread!\");\n * });\n * ```\n */\n subscribe(): Promise<void>;\n\n /**\n * Unsubscribe from this thread.\n *\n * Future messages will no longer trigger `onSubscribedMessage` handlers.\n */\n unsubscribe(): Promise<void>;\n\n /**\n * Post a message to this thread.\n *\n * @param message - String, PostableMessage, or JSX Card element to send\n * @returns A SentMessage with methods to edit, delete, or add reactions\n *\n * @example\n * ```typescript\n * // Simple string\n * await thread.post(\"Hello!\");\n *\n * // Markdown\n * await thread.post({ markdown: \"**Bold** and _italic_\" });\n *\n * // With emoji\n * await thread.post(`${emoji.thumbs_up} Great job!`);\n *\n * // JSX Card (with @jsxImportSource chat-sdk)\n * await thread.post(\n * <Card title=\"Welcome!\">\n * <Text>Hello world</Text>\n * </Card>\n * );\n * ```\n */\n post(\n message: string | PostableMessage | CardJSXElement,\n ): Promise<SentMessage<TRawMessage>>;\n\n /**\n * Show typing indicator in the thread.\n *\n * Some platforms support persistent typing indicators, others just send once.\n */\n startTyping(): Promise<void>;\n\n /**\n * Refresh `recentMessages` from the API.\n *\n * Fetches the latest 50 messages and updates `recentMessages`.\n */\n refresh(): Promise<void>;\n\n /**\n * Get a platform-specific mention string for a user.\n * Use this to @-mention a user in a message.\n * @example\n * await thread.post(`Hey ${thread.mentionUser(userId)}, check this out!`);\n */\n mentionUser(userId: string): string;\n}\n\nexport interface ThreadInfo {\n id: string;\n channelId: string;\n channelName?: string;\n /** Whether this is a direct message conversation */\n isDM?: boolean;\n /** Platform-specific metadata */\n metadata: Record<string, unknown>;\n}\n\nexport interface FetchOptions {\n /** Maximum number of messages to fetch */\n limit?: number;\n /** Fetch messages before this message ID */\n before?: string;\n /** Fetch messages after this message ID */\n after?: string;\n}\n\n// =============================================================================\n// Message\n// =============================================================================\n\n/**\n * Formatted content using mdast AST.\n * This is the canonical representation of message formatting.\n */\nexport type FormattedContent = Root;\n\nexport interface Message<TRawMessage = unknown> {\n /** Unique message ID */\n readonly id: string;\n /** Thread this message belongs to */\n readonly threadId: string;\n\n /** Plain text content (all formatting stripped) */\n text: string;\n /**\n * Structured formatting as an AST (mdast Root).\n * This is the canonical representation - use this for processing.\n * Use `stringifyMarkdown(message.formatted)` to get markdown string.\n */\n formatted: FormattedContent;\n /** Platform-specific raw payload (escape hatch) */\n raw: TRawMessage;\n\n /** Message author */\n author: Author;\n /** Message metadata */\n metadata: MessageMetadata;\n /** Attachments */\n attachments: Attachment[];\n\n /**\n * Whether the bot is @-mentioned in this message.\n *\n * This is set by the Chat SDK before passing the message to handlers.\n * It checks for `@username` in the message text using the adapter's\n * configured `userName` and optional `botUserId`.\n *\n * @example\n * ```typescript\n * chat.onSubscribedMessage(async (thread, message) => {\n * if (message.isMention) {\n * await thread.post(\"You mentioned me!\");\n * }\n * });\n * ```\n */\n isMention?: boolean;\n}\n\n/** Raw message returned from adapter (before wrapping as SentMessage) */\nexport interface RawMessage<TRawMessage = unknown> {\n id: string;\n threadId: string;\n raw: TRawMessage;\n}\n\nexport interface Author {\n /** Unique user ID */\n userId: string;\n /** Username/handle for @-mentions */\n userName: string;\n /** Display name */\n fullName: string;\n /** Whether the author is a bot */\n isBot: boolean | \"unknown\";\n /** Whether the author is this bot */\n isMe: boolean;\n}\n\nexport interface MessageMetadata {\n /** When the message was sent */\n dateSent: Date;\n /** Whether the message has been edited */\n edited: boolean;\n /** When the message was last edited */\n editedAt?: Date;\n}\n\n// =============================================================================\n// Sent Message (returned from thread.post())\n// =============================================================================\n\nexport interface SentMessage<TRawMessage = unknown>\n extends Message<TRawMessage> {\n /** Edit this message with text, a PostableMessage, or a JSX Card element */\n edit(\n newContent: string | PostableMessage | CardJSXElement,\n ): Promise<SentMessage<TRawMessage>>;\n /** Delete this message */\n delete(): Promise<void>;\n /** Add a reaction to this message */\n addReaction(emoji: EmojiValue | string): Promise<void>;\n /** Remove a reaction from this message */\n removeReaction(emoji: EmojiValue | string): Promise<void>;\n}\n\n// =============================================================================\n// Postable Message\n// =============================================================================\n\n/**\n * A message that can be posted to a thread.\n *\n * - `string` - Raw text, passed through as-is to the platform\n * - `{ raw: string }` - Explicit raw text, passed through as-is\n * - `{ markdown: string }` - Markdown text, converted to platform format\n * - `{ ast: Root }` - mdast AST, converted to platform format\n * - `{ card: CardElement }` - Rich card with buttons (Block Kit / Adaptive Cards / GChat Cards)\n * - `CardElement` - Direct card element\n */\nexport type PostableMessage =\n | string\n | PostableRaw\n | PostableMarkdown\n | PostableAst\n | PostableCard\n | CardElement;\n\nexport interface PostableRaw {\n /** Raw text passed through as-is to the platform */\n raw: string;\n /** File/image attachments */\n attachments?: Attachment[];\n /** Files to upload */\n files?: FileUpload[];\n}\n\nexport interface PostableMarkdown {\n /** Markdown text, converted to platform format */\n markdown: string;\n /** File/image attachments */\n attachments?: Attachment[];\n /** Files to upload */\n files?: FileUpload[];\n}\n\nexport interface PostableAst {\n /** mdast AST, converted to platform format */\n ast: Root;\n /** File/image attachments */\n attachments?: Attachment[];\n /** Files to upload */\n files?: FileUpload[];\n}\n\nexport interface PostableCard {\n /** Rich card element */\n card: CardElement;\n /** Fallback text for platforms/clients that can't render cards */\n fallbackText?: string;\n /** Files to upload */\n files?: FileUpload[];\n}\n\nexport interface Attachment {\n /** Type of attachment */\n type: \"image\" | \"file\" | \"video\" | \"audio\";\n /** URL to the file (for linking/downloading) */\n url?: string;\n /** Binary data (for uploading or if already fetched) */\n data?: Buffer | Blob;\n /** Filename */\n name?: string;\n /** MIME type */\n mimeType?: string;\n /** File size in bytes */\n size?: number;\n /** Image/video width (if applicable) */\n width?: number;\n /** Image/video height (if applicable) */\n height?: number;\n /**\n * Fetch the attachment data.\n * For platforms that require authentication (like Slack private URLs),\n * this method handles the auth automatically.\n */\n fetchData?: () => Promise<Buffer>;\n}\n\n/**\n * File to upload with a message.\n */\nexport interface FileUpload {\n /** Binary data */\n data: Buffer | Blob | ArrayBuffer;\n /** Filename */\n filename: string;\n /** MIME type (optional, will be inferred from filename if not provided) */\n mimeType?: string;\n}\n\n// =============================================================================\n// Event Handlers\n// =============================================================================\n\n/**\n * Handler for new @-mentions of the bot.\n *\n * **Important**: This handler is ONLY called for mentions in **unsubscribed** threads.\n * Once a thread is subscribed (via `thread.subscribe()`), subsequent messages\n * including @-mentions go to `onSubscribedMessage` handlers instead.\n *\n * To detect mentions in subscribed threads, check `message.isMention`:\n *\n * @example\n * ```typescript\n * // Handle new mentions (unsubscribed threads only)\n * chat.onNewMention(async (thread, message) => {\n * await thread.subscribe(); // Subscribe to follow-up messages\n * await thread.post(\"Hello! I'll be watching this thread.\");\n * });\n *\n * // Handle all messages in subscribed threads\n * chat.onSubscribedMessage(async (thread, message) => {\n * if (message.isMention) {\n * // User @-mentioned us in a thread we're already watching\n * await thread.post(\"You mentioned me again!\");\n * }\n * });\n * ```\n */\nexport type MentionHandler = (\n thread: Thread,\n message: Message,\n) => Promise<void>;\n\n/**\n * Handler for messages matching a regex pattern.\n *\n * Registered via `chat.onNewMessage(pattern, handler)`. Called when a message\n * matches the pattern in an unsubscribed thread.\n */\nexport type MessageHandler = (\n thread: Thread,\n message: Message,\n) => Promise<void>;\n\n/**\n * Handler for messages in subscribed threads.\n *\n * Called for all messages in threads that have been subscribed via `thread.subscribe()`.\n * This includes:\n * - Follow-up messages from users\n * - Messages that @-mention the bot (check `message.isMention`)\n *\n * Does NOT fire for:\n * - The message that triggered the subscription (e.g., the initial @mention)\n * - Messages sent by the bot itself\n *\n * @example\n * ```typescript\n * chat.onSubscribedMessage(async (thread, message) => {\n * // Handle all follow-up messages\n * if (message.isMention) {\n * // User @-mentioned us in a subscribed thread\n * }\n * await thread.post(`Got your message: ${message.text}`);\n * });\n * ```\n */\nexport type SubscribedMessageHandler = (\n thread: Thread,\n message: Message,\n) => Promise<void>;\n\n// =============================================================================\n// Reactions / Emoji\n// =============================================================================\n\n/**\n * Well-known emoji that work across platforms (Slack and Google Chat).\n * These are normalized to a common format regardless of platform.\n */\nexport type WellKnownEmoji =\n // Reactions & Gestures\n | \"thumbs_up\"\n | \"thumbs_down\"\n | \"clap\"\n | \"wave\"\n | \"pray\"\n | \"muscle\"\n | \"ok_hand\"\n | \"point_up\"\n | \"point_down\"\n | \"point_left\"\n | \"point_right\"\n | \"raised_hands\"\n | \"shrug\"\n | \"facepalm\"\n // Emotions & Faces\n | \"heart\"\n | \"smile\"\n | \"laugh\"\n | \"thinking\"\n | \"sad\"\n | \"cry\"\n | \"angry\"\n | \"love_eyes\"\n | \"cool\"\n | \"wink\"\n | \"surprised\"\n | \"worried\"\n | \"confused\"\n | \"neutral\"\n | \"sleeping\"\n | \"sick\"\n | \"mind_blown\"\n | \"relieved\"\n | \"grimace\"\n | \"rolling_eyes\"\n | \"hug\"\n | \"zany\"\n // Status & Symbols\n | \"check\"\n | \"x\"\n | \"question\"\n | \"exclamation\"\n | \"warning\"\n | \"stop\"\n | \"info\"\n | \"100\"\n | \"fire\"\n | \"star\"\n | \"sparkles\"\n | \"lightning\"\n | \"boom\"\n | \"eyes\"\n // Status Indicators\n | \"green_circle\"\n | \"yellow_circle\"\n | \"red_circle\"\n | \"blue_circle\"\n | \"white_circle\"\n | \"black_circle\"\n // Objects & Tools\n | \"rocket\"\n | \"party\"\n | \"confetti\"\n | \"balloon\"\n | \"gift\"\n | \"trophy\"\n | \"medal\"\n | \"lightbulb\"\n | \"gear\"\n | \"wrench\"\n | \"hammer\"\n | \"bug\"\n | \"link\"\n | \"lock\"\n | \"unlock\"\n | \"key\"\n | \"pin\"\n | \"memo\"\n | \"clipboard\"\n | \"calendar\"\n | \"clock\"\n | \"hourglass\"\n | \"bell\"\n | \"megaphone\"\n | \"speech_bubble\"\n | \"email\"\n | \"inbox\"\n | \"outbox\"\n | \"package\"\n | \"folder\"\n | \"file\"\n | \"chart_up\"\n | \"chart_down\"\n | \"coffee\"\n | \"pizza\"\n | \"beer\"\n // Arrows & Directions\n | \"arrow_up\"\n | \"arrow_down\"\n | \"arrow_left\"\n | \"arrow_right\"\n | \"refresh\"\n // Nature & Weather\n | \"sun\"\n | \"cloud\"\n | \"rain\"\n | \"snow\"\n | \"rainbow\";\n\n/**\n * Platform-specific emoji formats for a single emoji.\n */\nexport interface EmojiFormats {\n /** Slack emoji name (without colons), e.g., \"+1\", \"heart\" */\n slack: string | string[];\n /** Google Chat unicode emoji, e.g., \"ð\", \"âĪïļ\" */\n gchat: string | string[];\n}\n\n/**\n * Emoji map type - can be extended by users to add custom emoji.\n *\n * @example\n * ```typescript\n * // Extend with custom emoji\n * declare module \"chat\" {\n * interface CustomEmojiMap {\n * \"custom_emoji\": EmojiFormats;\n * }\n * }\n *\n * const myEmojiMap: EmojiMapConfig = {\n * custom_emoji: { slack: \"custom\", gchat: \"ðŊ\" },\n * };\n * ```\n */\n// biome-ignore lint/suspicious/noEmptyInterface: Required for TypeScript module augmentation\nexport interface CustomEmojiMap {}\n\n/**\n * Full emoji type including well-known and custom emoji.\n */\nexport type Emoji = WellKnownEmoji | keyof CustomEmojiMap;\n\n/**\n * Configuration for emoji mapping.\n */\nexport type EmojiMapConfig = Partial<Record<Emoji, EmojiFormats>>;\n\n/**\n * Immutable emoji value object with object identity.\n *\n * These objects are singletons - the same emoji name always returns\n * the same frozen object instance, enabling `===` comparison.\n *\n * @example\n * ```typescript\n * // Object identity comparison works\n * if (event.emoji === emoji.thumbs_up) {\n * console.log(\"User gave a thumbs up!\");\n * }\n *\n * // Works in template strings via toString()\n * await thread.post(`${emoji.thumbs_up} Great job!`);\n * ```\n */\nexport interface EmojiValue {\n /** The normalized emoji name (e.g., \"thumbs_up\") */\n readonly name: string;\n /** Returns the placeholder string for message formatting */\n toString(): string;\n /** Returns the placeholder string (for JSON.stringify) */\n toJSON(): string;\n}\n\n/**\n * Reaction event fired when a user adds or removes a reaction.\n */\nexport interface ReactionEvent<TRawMessage = unknown> {\n /** The normalized emoji as an EmojiValue singleton (enables `===` comparison) */\n emoji: EmojiValue;\n /** The raw platform-specific emoji (e.g., \"+1\" for Slack, \"ð\" for GChat) */\n rawEmoji: string;\n /** Whether the reaction was added (true) or removed (false) */\n added: boolean;\n /** The user who added/removed the reaction */\n user: Author;\n /** The message that was reacted to (if available) */\n message?: Message<TRawMessage>;\n /** The message ID that was reacted to */\n messageId: string;\n /** The thread ID */\n threadId: string;\n /**\n * The thread where the reaction occurred.\n * Use this to post replies or check subscription status.\n *\n * @example\n * ```typescript\n * chat.onReaction([emoji.thumbs_up], async (event) => {\n * await event.thread.post(`Thanks for the ${event.emoji}!`);\n * });\n * ```\n */\n thread: Thread<TRawMessage>;\n /** The adapter that received the event */\n adapter: Adapter;\n /** Platform-specific raw event data */\n raw: unknown;\n}\n\n/**\n * Handler for reaction events.\n *\n * @example\n * ```typescript\n * // Handle specific emoji\n * chat.onReaction([\"thumbs_up\", \"heart\"], async (event) => {\n * console.log(`${event.user.userName} ${event.added ? \"added\" : \"removed\"} ${event.emoji}`);\n * });\n *\n * // Handle all reactions\n * chat.onReaction(async (event) => {\n * // ...\n * });\n * ```\n */\nexport type ReactionHandler = (event: ReactionEvent) => Promise<void>;\n\n// =============================================================================\n// Action Events (Button Clicks)\n// =============================================================================\n\n/**\n * Action event fired when a user clicks a button in a card.\n *\n * @example\n * ```typescript\n * chat.onAction(\"approve\", async (event) => {\n * await event.thread.post(`Order ${event.value} approved by ${event.user.userName}`);\n * });\n * ```\n */\nexport interface ActionEvent<TRawMessage = unknown> {\n /** The action ID from the button (matches Button's `id` prop) */\n actionId: string;\n /** Optional value/payload from the button */\n value?: string;\n /** User who clicked the button */\n user: Author;\n /** The thread where the action occurred */\n thread: Thread<TRawMessage>;\n /** The message ID containing the card */\n messageId: string;\n /** The thread ID */\n threadId: string;\n /** The adapter that received the event */\n adapter: Adapter;\n /** Platform-specific raw event data */\n raw: unknown;\n}\n\n/**\n * Handler for action events (button clicks in cards).\n *\n * @example\n * ```typescript\n * // Handle specific action\n * chat.onAction(\"approve\", async (event) => {\n * await event.thread.post(\"Approved!\");\n * });\n *\n * // Handle multiple actions\n * chat.onAction([\"approve\", \"reject\"], async (event) => {\n * if (event.actionId === \"approve\") {\n * // ...\n * }\n * });\n *\n * // Handle all actions (catch-all)\n * chat.onAction(async (event) => {\n * console.log(`Action: ${event.actionId}`);\n * });\n * ```\n */\nexport type ActionHandler = (event: ActionEvent) => Promise<void>;\n\n// =============================================================================\n// Errors\n// =============================================================================\n\nexport class ChatError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"ChatError\";\n }\n}\n\nexport class RateLimitError extends ChatError {\n constructor(\n message: string,\n public readonly retryAfterMs?: number,\n cause?: unknown,\n ) {\n super(message, \"RATE_LIMITED\", cause);\n this.name = \"RateLimitError\";\n }\n}\n\nexport class LockError extends ChatError {\n constructor(message: string, cause?: unknown) {\n super(message, \"LOCK_FAILED\", cause);\n this.name = \"LockError\";\n }\n}\n\nexport class NotImplementedError extends ChatError {\n constructor(\n message: string,\n public readonly feature?: string,\n cause?: unknown,\n ) {\n super(message, \"NOT_IMPLEMENTED\", cause);\n this.name = \"NotImplementedError\";\n }\n}\n","import { ThreadImpl } from \"./thread\";\nimport type {\n ActionEvent,\n ActionHandler,\n Adapter,\n Author,\n ChatConfig,\n ChatInstance,\n EmojiValue,\n Logger,\n LogLevel,\n MentionHandler,\n Message,\n MessageHandler,\n ReactionEvent,\n ReactionHandler,\n StateAdapter,\n SubscribedMessageHandler,\n Thread,\n WebhookOptions,\n} from \"./types\";\nimport { ChatError, ConsoleLogger, LockError } from \"./types\";\n\nconst DEFAULT_LOCK_TTL_MS = 30_000; // 30 seconds\n/** TTL for message deduplication entries */\nconst DEDUPE_TTL_MS = 60_000; // 60 seconds\n\ninterface MessagePattern {\n pattern: RegExp;\n handler: MessageHandler;\n}\n\n/** Filter can be EmojiValue objects, emoji names, or raw emoji formats */\ntype EmojiFilter = EmojiValue | string;\n\ninterface ReactionPattern {\n /** If specified, only these emoji trigger the handler. Empty means all emoji. */\n emoji: EmojiFilter[];\n handler: ReactionHandler;\n}\n\ninterface ActionPattern {\n /** If specified, only these action IDs trigger the handler. Empty means all actions. */\n actionIds: string[];\n handler: ActionHandler;\n}\n\n/**\n * Type-safe webhook handler that is available for each adapter.\n */\ntype WebhookHandler = (\n request: Request,\n options?: WebhookOptions,\n) => Promise<Response>;\n\n/**\n * Creates a type-safe webhooks object based on the adapter names.\n */\ntype Webhooks<TAdapters extends Record<string, Adapter>> = {\n [K in keyof TAdapters]: WebhookHandler;\n};\n\n/**\n * Main Chat class with type-safe adapter inference.\n *\n * @example\n * const chat = new Chat({\n * userName: \"mybot\",\n * adapters: {\n * slack: createSlackAdapter({ ... }),\n * teams: createTeamsAdapter({ ... }),\n * },\n * state: createMemoryState(),\n * });\n *\n * // Type-safe: only 'slack' and 'teams' are valid\n * chat.webhooks.slack(request, { waitUntil });\n */\nexport class Chat<\n TAdapters extends Record<string, Adapter> = Record<string, Adapter>,\n> implements ChatInstance\n{\n private adapters: Map<string, Adapter>;\n private state: StateAdapter;\n private userName: string;\n private logger: Logger;\n\n private mentionHandlers: MentionHandler[] = [];\n private messagePatterns: MessagePattern[] = [];\n private subscribedMessageHandlers: SubscribedMessageHandler[] = [];\n private reactionHandlers: ReactionPattern[] = [];\n private actionHandlers: ActionPattern[] = [];\n\n /** Initialization state */\n private initPromise: Promise<void> | null = null;\n private initialized = false;\n\n /**\n * Type-safe webhook handlers keyed by adapter name.\n * @example\n * chat.webhooks.slack(request, { backgroundTask: waitUntil });\n */\n public readonly webhooks: Webhooks<TAdapters>;\n\n constructor(config: ChatConfig<TAdapters>) {\n this.userName = config.userName;\n this.state = config.state;\n this.adapters = new Map();\n\n // Initialize logger\n if (!config.logger) {\n this.logger = new ConsoleLogger(\"info\");\n } else if (typeof config.logger === \"string\") {\n this.logger = new ConsoleLogger(config.logger as LogLevel);\n } else {\n this.logger = config.logger;\n }\n\n // Register adapters and create webhook handlers\n const webhooks = {} as Record<string, WebhookHandler>;\n for (const [name, adapter] of Object.entries(config.adapters)) {\n this.adapters.set(name, adapter);\n // Create webhook handler for each adapter\n webhooks[name] = (request: Request, options?: WebhookOptions) =>\n this.handleWebhook(name, request, options);\n }\n this.webhooks = webhooks as Webhooks<TAdapters>;\n\n this.logger.debug(\"Chat instance created\", {\n adapters: Object.keys(config.adapters),\n });\n }\n\n /**\n * Handle a webhook request for a specific adapter.\n * Automatically initializes adapters on first call.\n */\n private async handleWebhook(\n adapterName: string,\n request: Request,\n options?: WebhookOptions,\n ): Promise<Response> {\n // Ensure initialization\n await this.ensureInitialized();\n\n const adapter = this.adapters.get(adapterName);\n if (!adapter) {\n return new Response(`Unknown adapter: ${adapterName}`, { status: 404 });\n }\n\n return adapter.handleWebhook(request, options);\n }\n\n /**\n * Ensure the chat instance is initialized.\n * This is called automatically before handling webhooks.\n */\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Avoid concurrent initialization\n if (!this.initPromise) {\n this.initPromise = this.doInitialize();\n }\n\n await this.initPromise;\n }\n\n private async doInitialize(): Promise<void> {\n this.logger.info(\"Initializing chat instance...\");\n await this.state.connect();\n this.logger.debug(\"State connected\");\n\n const initPromises = Array.from(this.adapters.values()).map(\n async (adapter) => {\n this.logger.debug(\"Initializing adapter\", adapter.name);\n const result = await adapter.initialize(this);\n this.logger.debug(\"Adapter initialized\", adapter.name);\n return result;\n },\n );\n await Promise.all(initPromises);\n\n this.initialized = true;\n this.logger.info(\"Chat instance initialized\", {\n adapters: Array.from(this.adapters.keys()),\n });\n }\n\n /**\n * Gracefully shut down the chat instance.\n */\n async shutdown(): Promise<void> {\n this.logger.info(\"Shutting down chat instance...\");\n await this.state.disconnect();\n this.initialized = false;\n this.initPromise = null;\n this.logger.info(\"Chat instance shut down\");\n }\n\n /**\n * Register a handler for new @-mentions of the bot.\n *\n * **Important**: This handler is ONLY called for mentions in **unsubscribed** threads.\n * Once a thread is subscribed (via `thread.subscribe()`), subsequent messages\n * including @-mentions go to `onSubscribedMessage` handlers instead.\n *\n * To detect mentions in subscribed threads, check `message.isMention`:\n *\n * @example\n * ```typescript\n * // Handle new mentions (unsubscribed threads only)\n * chat.onNewMention(async (thread, message) => {\n * await thread.subscribe(); // Subscribe to follow-up messages\n * await thread.post(\"Hello! I'll be watching this thread.\");\n * });\n *\n * // Handle all messages in subscribed threads\n * chat.onSubscribedMessage(async (thread, message) => {\n * if (message.isMention) {\n * // User @-mentioned us in a thread we're already watching\n * await thread.post(\"You mentioned me again!\");\n * }\n * });\n * ```\n */\n onNewMention(handler: MentionHandler): void {\n this.mentionHandlers.push(handler);\n this.logger.debug(\"Registered mention handler\");\n }\n\n /**\n * Register a handler for messages matching a regex pattern.\n *\n * @param pattern - Regular expression to match against message text\n * @param handler - Handler called when pattern matches\n *\n * @example\n * ```typescript\n * // Match messages starting with \"!help\"\n * chat.onNewMessage(/^!help/, async (thread, message) => {\n * await thread.post(\"Available commands: !help, !status, !ping\");\n * });\n * ```\n */\n onNewMessage(pattern: RegExp, handler: MessageHandler): void {\n this.messagePatterns.push({ pattern, handler });\n this.logger.debug(\"Registered message pattern handler\", {\n pattern: pattern.toString(),\n });\n }\n\n /**\n * Register a handler for messages in subscribed threads.\n *\n * Called for all messages in threads that have been subscribed via `thread.subscribe()`.\n * This includes:\n * - Follow-up messages from users\n * - Messages that @-mention the bot (check `message.isMention`)\n *\n * Does NOT fire for:\n * - The message that triggered the subscription (e.g., the initial @mention)\n * - Messages sent by the bot itself\n *\n * @example\n * ```typescript\n * chat.onSubscribedMessage(async (thread, message) => {\n * // Handle all follow-up messages\n * if (message.isMention) {\n * // User @-mentioned us in a subscribed thread\n * }\n * await thread.post(`Got your message: ${message.text}`);\n * });\n * ```\n */\n onSubscribedMessage(handler: SubscribedMessageHandler): void {\n this.subscribedMessageHandlers.push(handler);\n this.logger.debug(\"Registered subscribed message handler\");\n }\n\n /**\n * Register a handler for reaction events.\n *\n * @example\n * ```typescript\n * // Handle specific emoji using EmojiValue objects (recommended)\n * chat.onReaction([emoji.thumbs_up, emoji.heart], async (event) => {\n * if (event.emoji === emoji.thumbs_up) {\n * console.log(\"Thumbs up!\");\n * }\n * });\n *\n * // Handle all reactions\n * chat.onReaction(async (event) => {\n * console.log(`${event.added ? \"Added\" : \"Removed\"} ${event.emoji.name}`);\n * });\n * ```\n *\n * @param emojiOrHandler - Either an array of emoji to filter (EmojiValue or string), or the handler\n * @param handler - The handler (if emoji filter is provided)\n */\n onReaction(handler: ReactionHandler): void;\n onReaction(emoji: EmojiFilter[], handler: ReactionHandler): void;\n onReaction(\n emojiOrHandler: EmojiFilter[] | ReactionHandler,\n handler?: ReactionHandler,\n ): void {\n if (typeof emojiOrHandler === \"function\") {\n // No emoji filter - handle all reactions\n this.reactionHandlers.push({ emoji: [], handler: emojiOrHandler });\n this.logger.debug(\"Registered reaction handler for all emoji\");\n } else if (handler) {\n // Specific emoji filter\n this.reactionHandlers.push({ emoji: emojiOrHandler, handler });\n this.logger.debug(\"Registered reaction handler\", {\n emoji: emojiOrHandler.map((e) => (typeof e === \"string\" ? e : e.name)),\n });\n }\n }\n\n /**\n * Register a handler for action events (button clicks in cards).\n *\n * @example\n * ```typescript\n * // Handle specific action\n * chat.onAction(\"approve\", async (event) => {\n * await event.thread.post(\"Approved!\");\n * });\n *\n * // Handle multiple actions\n * chat.onAction([\"approve\", \"reject\"], async (event) => {\n * if (event.actionId === \"approve\") {\n * await event.thread.post(\"Approved!\");\n * } else {\n * await event.thread.post(\"Rejected!\");\n * }\n * });\n *\n * // Handle all actions (catch-all)\n * chat.onAction(async (event) => {\n * console.log(`Action: ${event.actionId}`);\n * });\n * ```\n *\n * @param actionIdOrHandler - Either an action ID, array of action IDs, or the handler\n * @param handler - The handler (if action ID filter is provided)\n */\n onAction(handler: ActionHandler): void;\n onAction(actionId: string, handler: ActionHandler): void;\n onAction(actionIds: string[], handler: ActionHandler): void;\n onAction(\n actionIdOrHandler: string | string[] | ActionHandler,\n handler?: ActionHandler,\n ): void {\n if (typeof actionIdOrHandler === \"function\") {\n // No action filter - handle all actions\n this.actionHandlers.push({ actionIds: [], handler: actionIdOrHandler });\n this.logger.debug(\"Registered action handler for all actions\");\n } else if (handler) {\n // Specific action ID(s) filter\n const actionIds = Array.isArray(actionIdOrHandler)\n ? actionIdOrHandler\n : [actionIdOrHandler];\n this.actionHandlers.push({ actionIds, handler });\n this.logger.debug(\"Registered action handler\", { actionIds });\n }\n }\n\n /**\n * Get an adapter by name with type safety.\n */\n getAdapter<K extends keyof TAdapters>(name: K): TAdapters[K] {\n return this.adapters.get(name as string) as TAdapters[K];\n }\n\n // ChatInstance interface implementations\n\n /**\n * Process an incoming message from an adapter.\n * Handles waitUntil registration and error catching internally.\n * Adapters should call this instead of handleIncomingMessage directly.\n */\n processMessage(\n adapter: Adapter,\n threadId: string,\n messageOrFactory: Message | (() => Promise<Message>),\n options?: WebhookOptions,\n ): void {\n const task = (async () => {\n const message =\n typeof messageOrFactory === \"function\"\n ? await messageOrFactory()\n : messageOrFactory;\n await this.handleIncomingMessage(adapter, threadId, message);\n })().catch((err) => {\n this.logger.error(\"Message processing error\", { error: err, threadId });\n });\n\n if (options?.waitUntil) {\n options.waitUntil(task);\n }\n }\n\n /**\n * Process an incoming reaction event from an adapter.\n * Handles waitUntil registration and error catching internally.\n */\n processReaction(\n event: Omit<ReactionEvent, \"adapter\" | \"thread\"> & { adapter?: Adapter },\n options?: WebhookOptions,\n ): void {\n const task = this.handleReactionEvent(event).catch((err) => {\n this.logger.error(\"Reaction processing error\", {\n error: err,\n emoji: event.emoji,\n messageId: event.messageId,\n });\n });\n\n if (options?.waitUntil) {\n options.waitUntil(task);\n }\n }\n\n /**\n * Process an incoming action event (button click) from an adapter.\n * Handles waitUntil registration and error catching internally.\n */\n processAction(\n event: Omit<ActionEvent, \"thread\"> & { adapter: Adapter },\n options?: WebhookOptions,\n ): void {\n const task = this.handleActionEvent(event).catch((err) => {\n this.logger.error(\"Action processing error\", {\n error: err,\n actionId: event.actionId,\n messageId: event.messageId,\n });\n });\n\n if (options?.waitUntil) {\n options.waitUntil(task);\n }\n }\n\n /**\n * Handle an action event internally.\n */\n private async handleActionEvent(\n event: Omit<ActionEvent, \"thread\"> & { adapter: Adapter },\n ): Promise<void> {\n this.logger.debug(\"Incoming action\", {\n adapter: event.adapter.name,\n actionId: event.actionId,\n value: event.value,\n user: event.user.userName,\n messageId: event.messageId,\n threadId: event.threadId,\n });\n\n // Skip actions from self (shouldn't happen, but be safe)\n if (event.user.isMe) {\n this.logger.debug(\"Skipping action from self\", {\n actionId: event.actionId,\n });\n return;\n }\n\n // Create thread for the action event\n const isSubscribed = await this.state.isSubscribed(event.threadId);\n const thread = await this.createThread(\n event.adapter,\n event.threadId,\n {} as Message,\n isSubscribed,\n );\n\n // Build full event with thread\n const fullEvent: ActionEvent = {\n ...event,\n thread,\n };\n\n // Run matching handlers\n this.logger.debug(\"Checking action handlers\", {\n handlerCount: this.actionHandlers.length,\n actionId: event.actionId,\n });\n\n for (const { actionIds, handler } of this.actionHandlers) {\n // If no action ID filter, run handler for all actions\n if (actionIds.length === 0) {\n this.logger.debug(\"Running catch-all action handler\");\n await handler(fullEvent);\n continue;\n }\n\n // Check if the action matches any of the specified action IDs\n if (actionIds.includes(event.actionId)) {\n this.logger.debug(\"Running matched action handler\", {\n actionId: event.actionId,\n });\n await handler(fullEvent);\n }\n }\n }\n\n /**\n * Handle a reaction event internally.\n */\n private async handleReactionEvent(\n event: Omit<ReactionEvent, \"adapter\" | \"thread\"> & { adapter?: Adapter },\n ): Promise<void> {\n this.logger.debug(\"Incoming reaction\", {\n adapter: event.adapter?.name,\n emoji: event.emoji,\n rawEmoji: event.rawEmoji,\n added: event.added,\n user: event.user.userName,\n messageId: event.messageId,\n threadId: event.threadId,\n });\n\n // Skip reactions from self\n if (event.user.isMe) {\n this.logger.debug(\"Skipping reaction from self\", {\n emoji: event.emoji,\n });\n return;\n }\n\n // Adapter is required for thread creation\n if (!event.adapter) {\n this.logger.error(\"Reaction event missing adapter\");\n return;\n }\n\n // Create thread for the reaction event\n const isSubscribed = await this.state.isSubscribed(event.threadId);\n const thread = await this.createThread(\n event.adapter,\n event.threadId,\n event.message ?? ({} as Message),\n isSubscribed,\n );\n\n // Build full event with thread and adapter\n const fullEvent: ReactionEvent = {\n ...event,\n adapter: event.adapter,\n thread,\n };\n\n // Run matching handlers\n this.logger.debug(\"Checking reaction handlers\", {\n handlerCount: this.reactionHandlers.length,\n emoji: event.emoji.name,\n rawEmoji: event.rawEmoji,\n });\n\n for (const { emoji: emojiFilter, handler } of this.reactionHandlers) {\n // If no emoji filter, run handler for all reactions\n if (emojiFilter.length === 0) {\n this.logger.debug(\"Running catch-all reaction handler\");\n await handler(fullEvent);\n continue;\n }\n\n // Check if the reaction matches any of the specified emoji\n const matches = emojiFilter.some((filter) => {\n // EmojiValue object identity comparison (recommended)\n if (filter === fullEvent.emoji) return true;\n\n // String comparison: check against emoji name or rawEmoji\n const filterName = typeof filter === \"string\" ? filter : filter.name;\n return (\n filterName === fullEvent.emoji.name ||\n filterName === fullEvent.rawEmoji\n );\n });\n\n this.logger.debug(\"Reaction filter check\", {\n filterEmoji: emojiFilter.map((e) =>\n typeof e === \"string\" ? e : e.name,\n ),\n eventEmoji: fullEvent.emoji.name,\n matches,\n });\n\n if (matches) {\n this.logger.debug(\"Running matched reaction handler\");\n await handler(fullEvent);\n }\n }\n }\n\n getState(): StateAdapter {\n return this.state;\n }\n\n getUserName(): string {\n return this.userName;\n }\n\n getLogger(prefix?: string): Logger {\n if (prefix) {\n return this.logger.child(prefix);\n }\n return this.logger;\n }\n\n /**\n * Open a direct message conversation with a user.\n *\n * Accepts either a user ID string or an Author object (from message.author or event.user).\n *\n * The adapter is automatically inferred from the userId format:\n * - Slack: `U...` (e.g., \"U03STHCA1JM\")\n * - Teams: `29:...` (e.g., \"29:198PbJuw...\")\n * - Google Chat: `users/...` (e.g., \"users/117994873354375860089\")\n *\n * @param user - Platform-specific user ID string, or an Author object\n * @returns A Thread that can be used to post messages\n *\n * @example\n * ```ts\n * // Using user ID directly\n * const dmThread = await chat.openDM(\"U123456\");\n * await dmThread.post(\"Hello via DM!\");\n *\n * // Using Author object from a message\n * chat.onSubscribedMessage(async (thread, message) => {\n * const dmThread = await chat.openDM(message.author);\n * await dmThread.post(\"Hello via DM!\");\n * });\n * ```\n */\n async openDM(user: string | Author): Promise<Thread> {\n const userId = typeof user === \"string\" ? user : user.userId;\n const adapter = this.inferAdapterFromUserId(userId);\n if (!adapter.openDM) {\n throw new ChatError(\n `Adapter \"${adapter.name}\" does not support openDM`,\n \"NOT_SUPPORTED\",\n );\n }\n\n const threadId = await adapter.openDM(userId);\n return this.createThread(adapter, threadId, {} as Message, false);\n }\n\n /**\n * Infer which adapter to use based on the userId format.\n */\n private inferAdapterFromUserId(userId: string): Adapter {\n // Google Chat: users/123456789\n if (userId.startsWith(\"users/\")) {\n const adapter = this.adapters.get(\"gchat\");\n if (adapter) return adapter;\n }\n\n // Teams: 29:base64string...\n if (userId.startsWith(\"29:\")) {\n const adapter = this.adapters.get(\"teams\");\n if (adapter) return adapter;\n }\n\n // Slack: U followed by alphanumeric (e.g., U03STHCA1JM)\n if (/^U[A-Z0-9]+$/i.test(userId)) {\n const adapter = this.adapters.get(\"slack\");\n if (adapter) return adapter;\n }\n\n throw new ChatError(\n `Cannot infer adapter from userId \"${userId}\". Expected format: Slack (U...), Teams (29:...), or Google Chat (users/...).`,\n \"UNKNOWN_USER_ID_FORMAT\",\n );\n }\n\n /**\n * Handle an incoming message from an adapter.\n * This is called by adapters when they receive a webhook.\n *\n * The Chat class handles common concerns centrally:\n * - Deduplication: Same message may arrive multiple times (e.g., Slack sends\n * both `message` and `app_mention` events, GChat sends direct webhook + Pub/Sub)\n * - Bot filtering: Messages from the bot itself are skipped\n * - Locking: Only one instance processes a thread at a time\n */\n async handleIncomingMessage(\n adapter: Adapter,\n threadId: string,\n message: Message,\n ): Promise<void> {\n this.logger.debug(\"Incoming message\", {\n adapter: adapter.name,\n threadId,\n messageId: message.id,\n text: message.text,\n author: message.author.userName,\n authorUserId: message.author.userId,\n isBot: message.author.isBot,\n isMe: message.author.isMe,\n });\n\n // Skip messages from self (bot's own messages)\n if (message.author.isMe) {\n this.logger.debug(\"Skipping message from self (isMe=true)\", {\n adapter: adapter.name,\n threadId,\n author: message.author.userName,\n });\n return;\n }\n\n // Deduplicate messages - same message can arrive via multiple paths\n // (e.g., Slack message + app_mention events, GChat direct webhook + Pub/Sub)\n const dedupeKey = `dedupe:${adapter.name}:${message.id}`;\n const alreadyProcessed = await this.state.get<boolean>(dedupeKey);\n if (alreadyProcessed) {\n this.logger.debug(\"Skipping duplicate message\", {\n adapter: adapter.name,\n messageId: message.id,\n });\n return;\n }\n await this.state.set(dedupeKey, true, DEDUPE_TTL_MS);\n\n // Try to acquire lock on thread\n const lock = await this.state.acquireLock(threadId, DEFAULT_LOCK_TTL_MS);\n if (!lock) {\n this.logger.warn(\"Could not acquire lock on thread\", { threadId });\n throw new LockError(\n `Could not acquire lock on thread ${threadId}. Another instance may be processing.`,\n );\n }\n\n this.logger.debug(\"Lock acquired\", { threadId, token: lock.token });\n\n try {\n // Set isMention on the message for handler access\n message.isMention = this.detectMention(adapter, message);\n\n // Check if this is a subscribed thread first\n const isSubscribed = await this.state.isSubscribed(threadId);\n this.logger.debug(\"Subscription check\", {\n threadId,\n isSubscribed,\n subscribedHandlerCount: this.subscribedMessageHandlers.length,\n });\n\n // Create thread object (with subscription context for optimization)\n const thread = await this.createThread(\n adapter,\n threadId,\n message,\n isSubscribed,\n );\n\n if (isSubscribed) {\n this.logger.debug(\"Message in subscribed thread - calling handlers\", {\n threadId,\n handlerCount: this.subscribedMessageHandlers.length,\n });\n await this.runHandlers(this.subscribedMessageHandlers, thread, message);\n return;\n }\n\n // Check for @-mention of bot\n if (message.isMention) {\n this.logger.debug(\"Bot mentioned\", {\n threadId,\n text: message.text.slice(0, 100),\n });\n await this.runHandlers(this.mentionHandlers, thread, message);\n return;\n }\n\n // Check message patterns\n this.logger.debug(\"Checking message patterns\", {\n patternCount: this.messagePatterns.length,\n patterns: this.messagePatterns.map((p) => p.pattern.toString()),\n messageText: message.text,\n });\n let matchedPattern = false;\n for (const { pattern, handler } of this.messagePatterns) {\n const matches = pattern.test(message.text);\n this.logger.debug(\"Pattern test\", {\n pattern: pattern.toString(),\n text: message.text,\n matches,\n });\n if (matches) {\n this.logger.debug(\"Message matched pattern - calling handler\", {\n pattern: pattern.toString(),\n });\n matchedPattern = true;\n await handler(thread, message);\n }\n }\n\n // Log if no handlers matched\n if (!matchedPattern) {\n this.logger.debug(\"No handlers matched message\", {\n threadId,\n text: message.text.slice(0, 100),\n });\n }\n } finally {\n await this.state.releaseLock(lock);\n this.logger.debug(\"Lock released\", { threadId });\n }\n }\n\n private async createThread(\n adapter: Adapter,\n threadId: string,\n initialMessage: Message,\n isSubscribedContext = false,\n ): Promise<Thread> {\n // Parse thread ID to get channel info\n // Format: \"adapter:channel:thread\"\n const parts = threadId.split(\":\");\n const channelId = parts[1] || \"\";\n\n // Check if this is a DM\n const isDM = adapter.isDM?.(threadId) ?? false;\n\n return new ThreadImpl({\n id: threadId,\n adapter,\n channelId,\n state: this.state,\n initialMessage,\n isSubscribedContext,\n isDM,\n });\n }\n\n /**\n * Detect if the bot was mentioned in the message.\n * All adapters normalize mentions to @name format, so we just check for @username.\n */\n private detectMention(adapter: Adapter, message: Message): boolean {\n const botUserName = adapter.userName || this.userName;\n const botUserId = adapter.botUserId;\n\n // Primary check: @username format (normalized by all adapters)\n const usernamePattern = new RegExp(\n `@${this.escapeRegex(botUserName)}\\\\b`,\n \"i\",\n );\n if (usernamePattern.test(message.text)) {\n return true;\n }\n\n // Fallback: check for user ID mention if available (e.g., @U_BOT_123)\n if (botUserId) {\n const userIdPattern = new RegExp(\n `@${this.escapeRegex(botUserId)}\\\\b`,\n \"i\",\n );\n if (userIdPattern.test(message.text)) {\n return true;\n }\n }\n\n return false;\n }\n\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n\n private async runHandlers(\n handlers: Array<(thread: Thread, message: Message) => Promise<void>>,\n thread: Thread,\n message: Message,\n ): Promise<void> {\n for (const handler of handlers) {\n await handler(thread, message);\n }\n }\n}\n","import type {\n CustomEmojiMap,\n EmojiFormats,\n EmojiMapConfig,\n EmojiValue,\n WellKnownEmoji,\n} from \"./types\";\n\n// Re-export EmojiValue for convenience\nexport type { EmojiValue } from \"./types\";\n\n// =============================================================================\n// EmojiValue - Immutable singleton emoji objects with object identity\n// =============================================================================\n\n/** Internal emoji registry for singleton instances */\nconst emojiRegistry = new Map<string, EmojiValue>();\n\n/**\n * Get or create an immutable singleton EmojiValue.\n *\n * Always returns the same frozen object for the same name,\n * enabling `===` comparison for emoji identity.\n *\n * @example\n * ```typescript\n * const e1 = getEmoji(\"thumbs_up\");\n * const e2 = getEmoji(\"thumbs_up\");\n * console.log(e1 === e2); // true - same object\n * ```\n */\nexport function getEmoji(name: string): EmojiValue {\n let emojiValue = emojiRegistry.get(name);\n if (!emojiValue) {\n emojiValue = Object.freeze({\n name,\n toString: () => `{{emoji:${name}}}`,\n toJSON: () => `{{emoji:${name}}}`,\n });\n emojiRegistry.set(name, emojiValue);\n }\n return emojiValue;\n}\n\n// =============================================================================\n// Emoji Map - Platform-specific formats\n// =============================================================================\n\n/**\n * Default emoji map for well-known emoji.\n * Maps normalized emoji names to platform-specific formats.\n */\nexport const DEFAULT_EMOJI_MAP: Record<string, EmojiFormats> = {\n // Reactions & Gestures\n thumbs_up: { slack: [\"+1\", \"thumbsup\"], gchat: \"ð\" },\n thumbs_down: { slack: [\"-1\", \"thumbsdown\"], gchat: \"ð\" },\n clap: { slack: \"clap\", gchat: \"ð\" },\n wave: { slack: \"wave\", gchat: \"ð\" },\n pray: { slack: \"pray\", gchat: \"ð\" },\n muscle: { slack: \"muscle\", gchat: \"ðŠ\" },\n ok_hand: { slack: \"ok_hand\", gchat: \"ð\" },\n point_up: { slack: \"point_up\", gchat: \"ð\" },\n point_down: { slack: \"point_down\", gchat: \"ð\" },\n point_left: { slack: \"point_left\", gchat: \"ð\" },\n point_right: { slack: \"point_right\", gchat: \"ð\" },\n raised_hands: { slack: \"raised_hands\", gchat: \"ð\" },\n shrug: { slack: \"shrug\", gchat: \"ðĪ·\" },\n facepalm: { slack: \"facepalm\", gchat: \"ðĪĶ\" },\n\n // Emotions & Faces\n heart: { slack: \"heart\", gchat: [\"âĪïļ\", \"âĪ\"] },\n smile: { slack: [\"smile\", \"slightly_smiling_face\"], gchat: \"ð\" },\n laugh: { slack: [\"laughing\", \"satisfied\", \"joy\"], gchat: [\"ð\", \"ð\"] },\n thinking: { slack: \"thinking_face\", gchat: \"ðĪ\" },\n sad: { slack: [\"cry\", \"sad\", \"white_frowning_face\"], gchat: \"ðĒ\" },\n cry: { slack: \"sob\", gchat: \"ð\" },\n angry: { slack: \"angry\", gchat: \"ð \" },\n love_eyes: { slack: \"heart_eyes\", gchat: \"ð\" },\n cool: { slack: \"sunglasses\", gchat: \"ð\" },\n wink: { slack: \"wink\", gchat: \"ð\" },\n surprised: { slack: \"open_mouth\", gchat: \"ðŪ\" },\n worried: { slack: \"worried\", gchat: \"ð\" },\n confused: { slack: \"confused\", gchat: \"ð\" },\n neutral: { slack: \"neutral_face\", gchat: \"ð\" },\n sleeping: { slack: \"sleeping\", gchat: \"ðī\" },\n sick: { slack: \"nauseated_face\", gchat: \"ðĪĒ\" },\n mind_blown: { slack: \"exploding_head\", gchat: \"ðĪŊ\" },\n relieved: { slack: \"relieved\", gchat: \"ð\" },\n grimace: { slack: \"grimacing\", gchat: \"ðŽ\" },\n rolling_eyes: { slack: \"rolling_eyes\", gchat: \"ð\" },\n hug: { slack: \"hugging_face\", gchat: \"ðĪ\" },\n zany: { slack: \"zany_face\", gchat: \"ðĪŠ\" },\n\n // Status & Symbols\n check: {\n slack: [\"white_check_mark\", \"heavy_check_mark\"],\n gchat: [\"â
\", \"âïļ\"],\n },\n x: { slack: [\"x\", \"heavy_multiplication_x\"], gchat: [\"â\", \"âïļ\"] },\n question: { slack: \"question\", gchat: [\"â\", \"?\"] },\n exclamation: { slack: \"exclamation\", gchat: \"â\" },\n warning: { slack: \"warning\", gchat: \"â ïļ\" },\n stop: { slack: \"octagonal_sign\", gchat: \"ð\" },\n info: { slack: \"information_source\", gchat: \"âđïļ\" },\n \"100\": { slack: \"100\", gchat: \"ðŊ\" },\n fire: { slack: \"fire\", gchat: \"ðĨ\" },\n star: { slack: \"star\", gchat: \"â\" },\n sparkles: { slack: \"sparkles\", gchat: \"âĻ\" },\n lightning: { slack: \"zap\", gchat: \"âĄ\" },\n boom: { slack: \"boom\", gchat: \"ðĨ\" },\n eyes: { slack: \"eyes\", gchat: \"ð\" },\n\n // Status Indicators (colored circles)\n green_circle: { slack: \"large_green_circle\", gchat: \"ðĒ\" },\n yellow_circle: { slack: \"large_yellow_circle\", gchat: \"ðĄ\" },\n red_circle: { slack: \"red_circle\", gchat: \"ðī\" },\n blue_circle: { slack: \"large_blue_circle\", gchat: \"ðĩ\" },\n white_circle: { slack: \"white_circle\", gchat: \"âŠ\" },\n black_circle: { slack: \"black_circle\", gchat: \"âŦ\" },\n\n // Objects & Tools\n rocket: { slack: \"rocket\", gchat: \"ð\" },\n party: { slack: [\"tada\", \"partying_face\"], gchat: [\"ð\", \"ðĨģ\"] },\n confetti: { slack: \"confetti_ball\", gchat: \"ð\" },\n balloon: { slack: \"balloon\", gchat: \"ð\" },\n gift: { slack: \"gift\", gchat: \"ð\" },\n trophy: { slack: \"trophy\", gchat: \"ð\" },\n medal: { slack: \"first_place_medal\", gchat: \"ðĨ\" },\n lightbulb: { slack: \"bulb\", gchat: \"ðĄ\" },\n gear: { slack: \"gear\", gchat: \"âïļ\" },\n wrench: { slack: \"wrench\", gchat: \"ð§\" },\n hammer: { slack: \"hammer\", gchat: \"ðĻ\" },\n bug: { slack: \"bug\", gchat: \"ð\" },\n link: { slack: \"link\", gchat: \"ð\" },\n lock: { slack: \"lock\", gchat: \"ð\" },\n unlock: { slack: \"unlock\", gchat: \"ð\" },\n key: { slack: \"key\", gchat: \"ð\" },\n pin: { slack: \"pushpin\", gchat: \"ð\" },\n memo: { slack: \"memo\", gchat: \"ð\" },\n clipboard: { slack: \"clipboard\", gchat: \"ð\" },\n calendar: { slack: \"calendar\", gchat: \"ð
\" },\n clock: { slack: \"clock1\", gchat: \"ð\" },\n hourglass: { slack: \"hourglass\", gchat: \"âģ\" },\n bell: { slack: \"bell\", gchat: \"ð\" },\n megaphone: { slack: \"mega\", gchat: \"ðĒ\" },\n speech_bubble: { slack: \"speech_balloon\", gchat: \"ðŽ\" },\n email: { slack: \"email\", gchat: \"ð§\" },\n inbox: { slack: \"inbox_tray\", gchat: \"ðĨ\" },\n outbox: { slack: \"outbox_tray\", gchat: \"ðĪ\" },\n package: { slack: \"package\", gchat: \"ðĶ\" },\n folder: { slack: \"file_folder\", gchat: \"ð\" },\n file: { slack: \"page_facing_up\", gchat: \"ð\" },\n chart_up: { slack: \"chart_with_upwards_trend\", gchat: \"ð\" },\n chart_down: { slack: \"chart_with_downwards_trend\", gchat: \"ð\" },\n coffee: { slack: \"coffee\", gchat: \"â\" },\n pizza: { slack: \"pizza\", gchat: \"ð\" },\n beer: { slack: \"beer\", gchat: \"ðš\" },\n\n // Arrows & Directions\n arrow_up: { slack: \"arrow_up\", gchat: \"âŽïļ\" },\n arrow_down: { slack: \"arrow_down\", gchat: \"âŽïļ\" },\n arrow_left: { slack: \"arrow_left\", gchat: \"âŽ
ïļ\" },\n arrow_right: { slack: \"arrow_right\", gchat: \"âĄïļ\" },\n refresh: { slack: \"arrows_counterclockwise\", gchat: \"ð\" },\n\n // Nature & Weather\n sun: { slack: \"sunny\", gchat: \"âïļ\" },\n cloud: { slack: \"cloud\", gchat: \"âïļ\" },\n rain: { slack: \"rain_cloud\", gchat: \"ð§ïļ\" },\n snow: { slack: \"snowflake\", gchat: \"âïļ\" },\n rainbow: { slack: \"rainbow\", gchat: \"ð\" },\n};\n\n/**\n * Emoji resolver that handles conversion between platform formats and normalized names.\n */\nexport class EmojiResolver {\n private emojiMap: Record<string, EmojiFormats>;\n private slackToNormalized: Map<string, string>;\n private gchatToNormalized: Map<string, string>;\n\n constructor(customMap?: EmojiMapConfig) {\n this.emojiMap = { ...DEFAULT_EMOJI_MAP, ...customMap };\n this.slackToNormalized = new Map();\n this.gchatToNormalized = new Map();\n this.buildReverseMaps();\n }\n\n private buildReverseMaps(): void {\n for (const [normalized, formats] of Object.entries(this.emojiMap)) {\n // Build Slack reverse map\n const slackFormats = Array.isArray(formats.slack)\n ? formats.slack\n : [formats.slack];\n for (const slack of slackFormats) {\n this.slackToNormalized.set(slack.toLowerCase(), normalized);\n }\n\n // Build GChat reverse map\n const gchatFormats = Array.isArray(formats.gchat)\n ? formats.gchat\n : [formats.gchat];\n for (const gchat of gchatFormats) {\n this.gchatToNormalized.set(gchat, normalized);\n }\n }\n }\n\n /**\n * Convert a Slack emoji name to normalized EmojiValue.\n * Returns an EmojiValue for the raw emoji if no mapping exists.\n */\n fromSlack(slackEmoji: string): EmojiValue {\n // Remove colons if present (e.g., \":+1:\" -> \"+1\")\n const cleaned = slackEmoji.replace(/^:|:$/g, \"\").toLowerCase();\n const normalized = this.slackToNormalized.get(cleaned) ?? slackEmoji;\n return getEmoji(normalized);\n }\n\n /**\n * Convert a Google Chat unicode emoji to normalized EmojiValue.\n * Returns an EmojiValue for the raw emoji if no mapping exists.\n */\n fromGChat(gchatEmoji: string): EmojiValue {\n const normalized = this.gchatToNormalized.get(gchatEmoji) ?? gchatEmoji;\n return getEmoji(normalized);\n }\n\n /**\n * Convert a Teams reaction type to normalized EmojiValue.\n * Teams uses specific names: like, heart, laugh, surprised, sad, angry\n * Returns an EmojiValue for the raw reaction if no mapping exists.\n */\n fromTeams(teamsReaction: string): EmojiValue {\n const teamsMap: Record<string, string> = {\n like: \"thumbs_up\",\n heart: \"heart\",\n laugh: \"laugh\",\n surprised: \"surprised\",\n sad: \"sad\",\n angry: \"angry\",\n };\n const normalized = teamsMap[teamsReaction] ?? teamsReaction;\n return getEmoji(normalized);\n }\n\n /**\n * Convert a normalized emoji (or EmojiValue) to Slack format.\n * Returns the first Slack format if multiple exist.\n */\n toSlack(emoji: EmojiValue | string): string {\n const name = typeof emoji === \"string\" ? emoji : emoji.name;\n const formats = this.emojiMap[name];\n if (!formats) return name;\n return Array.isArray(formats.slack) ? formats.slack[0] : formats.slack;\n }\n\n /**\n * Convert a normalized emoji (or EmojiValue) to Google Chat format.\n * Returns the first GChat format if multiple exist.\n */\n toGChat(emoji: EmojiValue | string): string {\n const name = typeof emoji === \"string\" ? emoji : emoji.name;\n const formats = this.emojiMap[name];\n if (!formats) return name;\n return Array.isArray(formats.gchat) ? formats.gchat[0] : formats.gchat;\n }\n\n /**\n * Check if an emoji (in any format) matches a normalized emoji name or EmojiValue.\n */\n matches(rawEmoji: string, normalized: EmojiValue | string): boolean {\n const name = typeof normalized === \"string\" ? normalized : normalized.name;\n const formats = this.emojiMap[name];\n if (!formats) return rawEmoji === name;\n\n const slackFormats = Array.isArray(formats.slack)\n ? formats.slack\n : [formats.slack];\n const gchatFormats = Array.isArray(formats.gchat)\n ? formats.gchat\n : [formats.gchat];\n\n const cleanedRaw = rawEmoji.replace(/^:|:$/g, \"\").toLowerCase();\n\n return (\n slackFormats.some((s) => s.toLowerCase() === cleanedRaw) ||\n gchatFormats.includes(rawEmoji)\n );\n }\n\n /**\n * Add or override emoji mappings.\n */\n extend(customMap: EmojiMapConfig): void {\n Object.assign(this.emojiMap, customMap);\n this.buildReverseMaps();\n }\n}\n\n/**\n * Default emoji resolver instance.\n */\nexport const defaultEmojiResolver = new EmojiResolver();\n\n/** Placeholder pattern for emoji in text: {{emoji:name}} */\nconst EMOJI_PLACEHOLDER_REGEX = /\\{\\{emoji:([a-z0-9_]+)\\}\\}/gi;\n\n/**\n * Convert emoji placeholders in text to platform-specific format.\n *\n * @example\n * ```typescript\n * convertEmojiPlaceholders(\"Thanks! {{emoji:thumbs_up}}\", \"slack\");\n * // Returns: \"Thanks! :+1:\"\n *\n * convertEmojiPlaceholders(\"Thanks! {{emoji:thumbs_up}}\", \"gchat\");\n * // Returns: \"Thanks! ð\"\n * ```\n */\nexport function convertEmojiPlaceholders(\n text: string,\n platform: \"slack\" | \"gchat\" | \"teams\",\n resolver: EmojiResolver = defaultEmojiResolver,\n): string {\n return text.replace(EMOJI_PLACEHOLDER_REGEX, (_, emojiName: string) => {\n switch (platform) {\n case \"slack\":\n return `:${resolver.toSlack(emojiName)}:`;\n case \"gchat\":\n return resolver.toGChat(emojiName);\n case \"teams\":\n // Teams uses unicode emoji\n return resolver.toGChat(emojiName);\n default:\n return resolver.toGChat(emojiName);\n }\n });\n}\n\n// =============================================================================\n// Emoji Helper Types\n// =============================================================================\n\n/** Base emoji object with well-known emoji as EmojiValue singletons */\ntype BaseEmojiHelper = {\n [K in WellKnownEmoji]: EmojiValue;\n} & {\n /** Create an EmojiValue for a custom emoji name */\n custom: (name: string) => EmojiValue;\n};\n\n/** Extended emoji object including custom emoji from module augmentation */\ntype ExtendedEmojiHelper = BaseEmojiHelper & {\n [K in keyof CustomEmojiMap]: EmojiValue;\n};\n\n/**\n * Create a type-safe emoji helper with custom emoji.\n *\n * Returns immutable singleton EmojiValue objects that support:\n * - Object identity comparison (`event.emoji === emoji.thumbs_up`)\n * - Template string interpolation (`${emoji.thumbs_up}` â \"{{emoji:thumbs_up}}\")\n *\n * Custom emoji are automatically registered with the default resolver,\n * so placeholders will convert correctly in messages.\n *\n * @example\n * ```typescript\n * // First, extend the CustomEmojiMap type (usually in a .d.ts file)\n * declare module \"chat\" {\n * interface CustomEmojiMap {\n * unicorn: EmojiFormats;\n * company_logo: EmojiFormats;\n * }\n * }\n *\n * // Then create the emoji helper with your custom emoji\n * const emoji = createEmoji({\n * unicorn: { slack: \"unicorn_face\", gchat: \"ðĶ\" },\n * company_logo: { slack: \"company\", gchat: \"ðĒ\" },\n * });\n *\n * // Object identity works for comparisons\n * if (event.emoji === emoji.unicorn) { ... }\n *\n * // Template strings work for messages\n * await thread.post(`${emoji.unicorn} Magic!`);\n * // Slack: \":unicorn_face: Magic!\"\n * // GChat: \"ðĶ Magic!\"\n * ```\n */\nexport function createEmoji<\n T extends Record<\n string,\n { slack: string | string[]; gchat: string | string[] }\n >,\n>(customEmoji?: T): BaseEmojiHelper & { [K in keyof T]: EmojiValue } {\n // All well-known emoji names\n const wellKnownEmoji: WellKnownEmoji[] = [\n // Reactions & Gestures\n \"thumbs_up\",\n \"thumbs_down\",\n \"clap\",\n \"wave\",\n \"pray\",\n \"muscle\",\n \"ok_hand\",\n \"point_up\",\n \"point_down\",\n \"point_left\",\n \"point_right\",\n \"raised_hands\",\n \"shrug\",\n \"facepalm\",\n // Emotions & Faces\n \"heart\",\n \"smile\",\n \"laugh\",\n \"thinking\",\n \"sad\",\n \"cry\",\n \"angry\",\n \"love_eyes\",\n \"cool\",\n \"wink\",\n \"surprised\",\n \"worried\",\n \"confused\",\n \"neutral\",\n \"sleeping\",\n \"sick\",\n \"mind_blown\",\n \"relieved\",\n \"grimace\",\n \"rolling_eyes\",\n \"hug\",\n \"zany\",\n // Status & Symbols\n \"check\",\n \"x\",\n \"question\",\n \"exclamation\",\n \"warning\",\n \"stop\",\n \"info\",\n \"100\",\n \"fire\",\n \"star\",\n \"sparkles\",\n \"lightning\",\n \"boom\",\n \"eyes\",\n // Status Indicators\n \"green_circle\",\n \"yellow_circle\",\n \"red_circle\",\n \"blue_circle\",\n \"white_circle\",\n \"black_circle\",\n // Objects & Tools\n \"rocket\",\n \"party\",\n \"confetti\",\n \"balloon\",\n \"gift\",\n \"trophy\",\n \"medal\",\n \"lightbulb\",\n \"gear\",\n \"wrench\",\n \"hammer\",\n \"bug\",\n \"link\",\n \"lock\",\n \"unlock\",\n \"key\",\n \"pin\",\n \"memo\",\n \"clipboard\",\n \"calendar\",\n \"clock\",\n \"hourglass\",\n \"bell\",\n \"megaphone\",\n \"speech_bubble\",\n \"email\",\n \"inbox\",\n \"outbox\",\n \"package\",\n \"folder\",\n \"file\",\n \"chart_up\",\n \"chart_down\",\n \"coffee\",\n \"pizza\",\n \"beer\",\n // Arrows & Directions\n \"arrow_up\",\n \"arrow_down\",\n \"arrow_left\",\n \"arrow_right\",\n \"refresh\",\n // Nature & Weather\n \"sun\",\n \"cloud\",\n \"rain\",\n \"snow\",\n \"rainbow\",\n ];\n\n // Build the emoji helper object with EmojiValue singletons\n const helper: Record<string, EmojiValue | ((name: string) => EmojiValue)> = {\n custom: (name: string): EmojiValue => getEmoji(name),\n };\n\n // Add all well-known emoji\n for (const name of wellKnownEmoji) {\n helper[name] = getEmoji(name);\n }\n\n // Add custom emoji if provided\n if (customEmoji) {\n for (const key of Object.keys(customEmoji)) {\n helper[key] = getEmoji(key);\n }\n // Extend the default resolver so placeholders convert correctly\n defaultEmojiResolver.extend(customEmoji as EmojiMapConfig);\n }\n\n return helper as BaseEmojiHelper & {\n [K in keyof T]: EmojiValue;\n };\n}\n\n/**\n * Type-safe emoji helper for embedding emoji in messages.\n *\n * @example\n * ```typescript\n * import { emoji } from \"chat\";\n *\n * await thread.post(`Great job! ${emoji.thumbs_up} ${emoji.fire}`);\n * // Slack: \"Great job! :+1: :fire:\"\n * // GChat: \"Great job! ð ðĨ\"\n * ```\n *\n * For custom emoji, use `createEmoji()` with module augmentation:\n * @example\n * ```typescript\n * // types.d.ts\n * declare module \"chat\" {\n * interface CustomEmojiMap {\n * unicorn: EmojiFormats;\n * }\n * }\n *\n * // bot.ts\n * const emoji = createEmoji({ unicorn: { slack: \"unicorn\", gchat: \"ðĶ\" } });\n * await thread.post(`${emoji.unicorn} Magic!`);\n * ```\n */\nexport const emoji: ExtendedEmojiHelper = createEmoji() as ExtendedEmojiHelper;\n","// Main exports\nexport { Chat } from \"./chat\";\n\n// Card builders - import then re-export to ensure values are properly exported\nimport {\n Actions as _Actions,\n Button as _Button,\n Card as _Card,\n CardText as _CardText,\n Divider as _Divider,\n Field as _Field,\n Fields as _Fields,\n fromReactElement as _fromReactElement,\n Image as _Image,\n isCardElement as _isCardElement,\n Section as _Section,\n} from \"./cards\";\nimport {\n isJSX as _isJSX,\n toCardElement as _toCardElement,\n type CardJSXElement,\n} from \"./jsx-runtime\";\nexport const Actions = _Actions;\nexport const Button = _Button;\nexport const Card = _Card;\nexport const CardText = _CardText;\nexport const Divider = _Divider;\nexport const Field = _Field;\nexport const Fields = _Fields;\nexport const fromReactElement = _fromReactElement;\nexport const Image = _Image;\nexport const isCardElement = _isCardElement;\nexport const isJSX = _isJSX;\nexport const Section = _Section;\nexport const toCardElement = _toCardElement;\n// Card types\nexport type {\n ActionsElement,\n ButtonElement,\n ButtonOptions,\n ButtonStyle,\n CardChild,\n CardElement,\n CardOptions,\n DividerElement,\n FieldElement,\n FieldsElement,\n ImageElement,\n SectionElement,\n TextElement,\n TextStyle,\n} from \"./cards\";\n// JSX types\nexport type { CardJSXElement };\n// Emoji utilities\nexport {\n convertEmojiPlaceholders,\n createEmoji,\n DEFAULT_EMOJI_MAP,\n defaultEmojiResolver,\n EmojiResolver,\n type EmojiValue,\n emoji,\n getEmoji,\n} from \"./emoji\";\n// Re-export mdast types for adapters\nexport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Text,\n} from \"./markdown\";\n// Markdown/AST utilities\nexport {\n // Format converter base class\n BaseFormatConverter,\n blockquote,\n codeBlock,\n emphasis,\n // Types\n type FormatConverter,\n inlineCode,\n link,\n type MarkdownConverter,\n markdownToPlainText,\n paragraph,\n // Parsing and stringifying\n parseMarkdown,\n root,\n strikethrough,\n stringifyMarkdown,\n strong,\n // AST node builders\n text,\n toPlainText,\n walkAst,\n} from \"./markdown\";\n// Types\nexport type {\n ActionEvent,\n ActionHandler,\n Adapter,\n Attachment,\n Author,\n ChatConfig,\n ChatInstance,\n CustomEmojiMap,\n Emoji,\n EmojiFormats,\n EmojiMapConfig,\n FetchOptions,\n FileUpload,\n FormattedContent,\n Lock,\n Logger,\n LogLevel,\n MentionHandler,\n Message,\n MessageHandler,\n MessageMetadata,\n PostableAst,\n PostableCard,\n PostableMarkdown,\n PostableMessage,\n PostableRaw,\n RawMessage,\n ReactionEvent,\n ReactionHandler,\n SentMessage,\n StateAdapter,\n SubscribedMessageHandler,\n Thread,\n ThreadInfo,\n WebhookOptions,\n WellKnownEmoji,\n} from \"./types\";\n// Errors and Logger\nexport {\n ChatError,\n ConsoleLogger,\n LockError,\n NotImplementedError,\n RateLimitError,\n} from \"./types\";\n"],"mappings":"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","names":["text","postable","emoji","emoji","text","Actions","Button","Card","CardText","Divider","Field","Fields","fromReactElement","Image","isCardElement","isJSX","Section","toCardElement"]}
|