chat 4.13.4 → 4.15.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/README.md CHANGED
@@ -27,6 +27,7 @@ const bot = new Chat({
27
27
  }),
28
28
  },
29
29
  state: createRedisState({ url: process.env.REDIS_URL! }),
30
+ dedupeTtlMs: 600_000, // 10 minutes (default: 5 min)
30
31
  });
31
32
 
32
33
  bot.onNewMention(async (thread) => {
@@ -39,6 +40,17 @@ bot.onSubscribedMessage(async (thread, message) => {
39
40
  });
40
41
  ```
41
42
 
43
+ ## Configuration
44
+
45
+ | Option | Type | Default | Description |
46
+ |--------|------|---------|-------------|
47
+ | `userName` | `string` | **required** | Default bot username across all adapters |
48
+ | `adapters` | `Record<string, Adapter>` | **required** | Map of adapter name to adapter instance |
49
+ | `state` | `StateAdapter` | **required** | State adapter for subscriptions, locking, and dedup |
50
+ | `logger` | `Logger \| LogLevel` | `"info"` | Logger instance or log level (`"silent"` to disable) |
51
+ | `streamingUpdateIntervalMs` | `number` | `500` | Update interval for fallback streaming (post + edit) in ms |
52
+ | `dedupeTtlMs` | `number` | `300000` | TTL for message deduplication entries in ms. Increase if webhook cold starts cause platform retries (e.g., Slack's `http_timeout` retry) that arrive after the default window |
53
+
42
54
  ## AI coding agent support
43
55
 
44
56
  If you use an AI coding agent like [Claude Code](https://docs.anthropic.com/en/docs/claude-code), you can teach it about Chat SDK:
@@ -71,6 +71,13 @@ function Fields(children) {
71
71
  children
72
72
  };
73
73
  }
74
+ function CardLink(options) {
75
+ return {
76
+ type: "link",
77
+ url: options.url,
78
+ label: options.label
79
+ };
80
+ }
74
81
  function isReactElement(value) {
75
82
  if (typeof value !== "object" || value === null) {
76
83
  return false;
@@ -91,6 +98,7 @@ var componentMap = /* @__PURE__ */ new Map([
91
98
  [Actions, "Actions"],
92
99
  [Button, "Button"],
93
100
  [LinkButton, "LinkButton"],
101
+ [CardLink, "CardLink"],
94
102
  [Field, "Field"],
95
103
  [Fields, "Fields"]
96
104
  ]);
@@ -163,6 +171,13 @@ function fromReactElement(element) {
163
171
  style: props.style
164
172
  });
165
173
  }
174
+ case "CardLink": {
175
+ const label = extractTextContent(props.children);
176
+ return CardLink({
177
+ url: props.url,
178
+ label: props.label ?? label
179
+ });
180
+ }
166
181
  case "Field":
167
182
  return Field({
168
183
  label: props.label,
@@ -224,6 +239,8 @@ function childToFallbackText(child) {
224
239
  switch (child.type) {
225
240
  case "text":
226
241
  return child.content;
242
+ case "link":
243
+ return `${child.label} (${child.url})`;
227
244
  case "fields":
228
245
  return child.children.map((f) => `${f.label}: ${f.value}`).join("\n");
229
246
  case "actions":
@@ -459,6 +476,9 @@ function isButtonProps(props) {
459
476
  function isLinkButtonProps(props) {
460
477
  return "url" in props && typeof props.url === "string" && !("id" in props);
461
478
  }
479
+ function isCardLinkProps(props) {
480
+ return "url" in props && typeof props.url === "string" && !("id" in props) && !("alt" in props) && !("style" in props);
481
+ }
462
482
  function isImageProps(props) {
463
483
  return "url" in props && typeof props.url === "string";
464
484
  }
@@ -522,6 +542,16 @@ function resolveJSXElement(element) {
522
542
  style: props.style
523
543
  });
524
544
  }
545
+ if (type === CardLink) {
546
+ if (!isCardLinkProps(props)) {
547
+ throw new Error("CardLink requires a 'url' prop");
548
+ }
549
+ const label = processedChildren.length > 0 ? processedChildren.map(String).join("") : props.label ?? "";
550
+ return CardLink({
551
+ url: props.url,
552
+ label
553
+ });
554
+ }
525
555
  if (type === Image) {
526
556
  if (!isImageProps(props)) {
527
557
  throw new Error("Image requires a 'url' prop");
@@ -688,6 +718,7 @@ export {
688
718
  LinkButton,
689
719
  Field,
690
720
  Fields,
721
+ CardLink,
691
722
  fromReactElement,
692
723
  cardToFallbackText,
693
724
  isModalElement,
@@ -697,6 +728,7 @@ export {
697
728
  SelectOption,
698
729
  RadioSelect,
699
730
  fromReactModalElement,
731
+ isCardLinkProps,
700
732
  jsx,
701
733
  jsxs,
702
734
  jsxDEV,
@@ -705,4 +737,4 @@ export {
705
737
  toModalElement,
706
738
  isJSX
707
739
  };
708
- //# sourceMappingURL=chunk-THM4ACIE.js.map
740
+ //# sourceMappingURL=chunk-VGF42GJ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cards.ts","../src/modals.ts","../src/jsx-runtime.ts"],"sourcesContent":["/**\n * Card elements for cross-platform rich messaging.\n *\n * Provides a builder API for creating rich cards that automatically\n * convert to platform-specific formats:\n * - Slack: Block Kit\n * - Teams: Adaptive Cards\n * - Google Chat: Card v2\n *\n * Supports both function-call and JSX syntax:\n *\n * @example Function API\n * ```ts\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * Card({\n * title: \"Order #1234\",\n * children: [\n * Text(\"Total: $50.00\"),\n * Actions([\n * Button({ id: \"approve\", label: \"Approve\", style: \"primary\" }),\n * Button({ id: \"reject\", label: \"Reject\", style: \"danger\" }),\n * ]),\n * ],\n * })\n * );\n * ```\n *\n * @example JSX API (requires jsxImportSource: \"chat\" in tsconfig)\n * ```tsx\n * /** @jsxImportSource chat *\\/\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * <Card title=\"Order #1234\">\n * <Text>Total: $50.00</Text>\n * <Actions>\n * <Button id=\"approve\" style=\"primary\">Approve</Button>\n * <Button id=\"reject\" style=\"danger\">Reject</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport type { RadioSelectElement, SelectElement } from \"./modals\";\n\n// ============================================================================\n// Card Element Types\n// ============================================================================\n\n/** Button style options */\nexport type ButtonStyle = \"primary\" | \"danger\" | \"default\";\n\n/** Text style options */\nexport type TextStyle = \"plain\" | \"bold\" | \"muted\";\n\n/** Button element for interactive actions */\nexport interface ButtonElement {\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"button\";\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/** Link button element that opens a URL */\nexport interface LinkButtonElement {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"link-button\";\n /** URL to open when clicked */\n url: string;\n}\n\n/** Text content element */\nexport interface TextElement {\n /** Text content (supports markdown in some platforms) */\n content: string;\n /** Text style */\n style?: TextStyle;\n type: \"text\";\n}\n\n/** Image element */\nexport interface ImageElement {\n /** Alt text for accessibility */\n alt?: string;\n type: \"image\";\n /** Image URL */\n url: string;\n}\n\n/** Visual divider/separator */\nexport interface DividerElement {\n type: \"divider\";\n}\n\n/** Container for action buttons and selects */\nexport interface ActionsElement {\n /** Button, link button, select, and radio select elements */\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[];\n type: \"actions\";\n}\n\n/** Section container for grouping elements */\nexport interface SectionElement {\n /** Section children */\n children: CardChild[];\n type: \"section\";\n}\n\n/** Inline hyperlink element */\nexport interface LinkElement {\n /** Link label text */\n label: string;\n type: \"link\";\n /** URL to link to */\n url: string;\n}\n\n/** Field for key-value display */\nexport interface FieldElement {\n /** Field label */\n label: string;\n type: \"field\";\n /** Field value */\n value: string;\n}\n\n/** Fields container for multi-column layout */\nexport interface FieldsElement {\n /** Field elements */\n children: FieldElement[];\n type: \"fields\";\n}\n\n/** Union of all card child element types */\nexport type CardChild =\n | TextElement\n | ImageElement\n | DividerElement\n | ActionsElement\n | SectionElement\n | FieldsElement\n | LinkElement;\n\n/** Union of all element types (including nested children) */\ntype AnyCardElement =\n | CardChild\n | CardElement\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | RadioSelectElement;\n\n/** Root card element */\nexport interface CardElement {\n /** Card content */\n children: CardChild[];\n /** Header image URL */\n imageUrl?: string;\n /** Card subtitle */\n subtitle?: string;\n /** Card title */\n title?: string;\n type: \"card\";\n}\n\n/** Type guard for CardElement */\nexport function isCardElement(value: unknown): value is CardElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as CardElement).type === \"card\"\n );\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\n/** Options for Card */\nexport interface CardOptions {\n children?: CardChild[];\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/**\n * Create a Card element.\n *\n * @example\n * ```ts\n * Card({\n * title: \"Welcome\",\n * children: [Text(\"Hello!\")],\n * })\n * ```\n */\nexport function Card(options: CardOptions = {}): CardElement {\n return {\n type: \"card\",\n title: options.title,\n subtitle: options.subtitle,\n imageUrl: options.imageUrl,\n children: options.children ?? [],\n };\n}\n\n/**\n * Create a Text element.\n *\n * @example\n * ```ts\n * Text(\"Hello, world!\")\n * Text(\"Important\", { style: \"bold\" })\n * ```\n */\nexport function Text(\n content: string,\n options: { style?: TextStyle } = {}\n): TextElement {\n return {\n type: \"text\",\n content,\n style: options.style,\n };\n}\n\n/**\n * Alias for Text that avoids conflicts with DOM's global Text constructor.\n * Use this when importing in environments where `Text` would conflict.\n *\n * @example\n * ```ts\n * import { CardText } from \"chat\";\n * CardText(\"Hello, world!\")\n * ```\n */\nexport const CardText = Text;\n\n/**\n * Create an Image element.\n *\n * @example\n * ```ts\n * Image({ url: \"https://example.com/image.png\", alt: \"Description\" })\n * ```\n */\nexport function Image(options: { url: string; alt?: string }): ImageElement {\n return {\n type: \"image\",\n url: options.url,\n alt: options.alt,\n };\n}\n\n/**\n * Create a Divider element.\n *\n * @example\n * ```ts\n * Divider()\n * ```\n */\nexport function Divider(): DividerElement {\n return { type: \"divider\" };\n}\n\n/**\n * Create a Section container.\n *\n * @example\n * ```ts\n * Section([\n * Text(\"Grouped content\"),\n * Image({ url: \"...\" }),\n * ])\n * ```\n */\nexport function Section(children: CardChild[]): SectionElement {\n return {\n type: \"section\",\n children,\n };\n}\n\n/**\n * Create an Actions container for buttons and selects.\n *\n * @example\n * ```ts\n * Actions([\n * Button({ id: \"ok\", label: \"OK\" }),\n * Button({ id: \"cancel\", label: \"Cancel\" }),\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\" }),\n * Select({ id: \"priority\", label: \"Priority\", options: [...] }),\n * RadioSelect({ id: \"status\", label: \"Status\", options: [...] }),\n * ])\n * ```\n */\nexport function Actions(\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n): ActionsElement {\n return {\n type: \"actions\",\n children,\n };\n}\n\n/** Options for Button */\nexport interface ButtonOptions {\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/**\n * Create a Button element.\n *\n * @example\n * ```ts\n * Button({ id: \"submit\", label: \"Submit\", style: \"primary\" })\n * Button({ id: \"delete\", label: \"Delete\", style: \"danger\", value: \"item-123\" })\n * ```\n */\nexport function Button(options: ButtonOptions): ButtonElement {\n return {\n type: \"button\",\n id: options.id,\n label: options.label,\n style: options.style,\n value: options.value,\n };\n}\n\n/** Options for LinkButton */\nexport interface LinkButtonOptions {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** URL to open when clicked */\n url: string;\n}\n\n/**\n * Create a LinkButton element that opens a URL when clicked.\n *\n * @example\n * ```ts\n * LinkButton({ url: \"https://example.com\", label: \"View Docs\" })\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\", style: \"primary\" })\n * ```\n */\nexport function LinkButton(options: LinkButtonOptions): LinkButtonElement {\n return {\n type: \"link-button\",\n url: options.url,\n label: options.label,\n style: options.style,\n };\n}\n\n/**\n * Create a Field element for key-value display.\n *\n * @example\n * ```ts\n * Field({ label: \"Status\", value: \"Active\" })\n * ```\n */\nexport function Field(options: { label: string; value: string }): FieldElement {\n return {\n type: \"field\",\n label: options.label,\n value: options.value,\n };\n}\n\n/**\n * Create a Fields container for multi-column layout.\n *\n * @example\n * ```ts\n * Fields([\n * Field({ label: \"Name\", value: \"John\" }),\n * Field({ label: \"Email\", value: \"john@example.com\" }),\n * ])\n * ```\n */\nexport function Fields(children: FieldElement[]): FieldsElement {\n return {\n type: \"fields\",\n children,\n };\n}\n\n/**\n * Create a CardLink element for inline hyperlinks.\n *\n * @example\n * ```ts\n * CardLink({ url: \"https://example.com\", label: \"Visit Site\" })\n * ```\n */\nexport function CardLink(options: { url: string; label: string }): LinkElement {\n return {\n type: \"link\",\n url: options.url,\n label: options.label,\n };\n}\n\n// ============================================================================\n// React Element Support\n// ============================================================================\n\n/** React element shape (minimal typing to avoid React dependency) */\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\n/**\n * Check if a value is a React element.\n */\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\n/**\n * Map of component functions to their names for React element conversion.\n */\nconst componentMap = new Map<unknown, string>([\n [Card, \"Card\"],\n [Text, \"Text\"],\n [Image, \"Image\"],\n [Divider, \"Divider\"],\n [Section, \"Section\"],\n [Actions, \"Actions\"],\n [Button, \"Button\"],\n [LinkButton, \"LinkButton\"],\n [CardLink, \"CardLink\"],\n [Field, \"Field\"],\n [Fields, \"Fields\"],\n]);\n\n/**\n * Convert a React element tree to a CardElement tree.\n * This allows using React's JSX with our card components.\n *\n * @example\n * ```tsx\n * import React from \"react\";\n * import { Card, Text, fromReactElement } from \"chat\";\n *\n * const element = (\n * <Card title=\"Hello\">\n * <Text>World</Text>\n * </Card>\n * );\n *\n * const card = fromReactElement(element);\n * await thread.post(card);\n * ```\n */\nexport function fromReactElement(element: unknown): AnyCardElement | null {\n if (!isReactElement(element)) {\n // Already a card element or primitive\n if (isCardElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as CardChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = componentMap.get(type);\n\n if (!componentName) {\n // Check if it's an HTML element (string type like \"div\", \"a\", \"span\")\n if (typeof type === \"string\") {\n throw new Error(\n `HTML element <${type}> is not supported in card elements. ` +\n \"Use Card, Text, Section, Actions, Button, Fields, Field, Image, or Divider components instead.\"\n );\n }\n\n // Unknown custom component - try to extract children\n if (props.children) {\n return convertChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n // Convert children recursively\n const convertedChildren = props.children\n ? convertChildren(props.children)\n : [];\n\n // Helper to filter for CardChild elements\n const isCardChild = (el: AnyCardElement): el is CardChild =>\n el.type !== \"card\" &&\n el.type !== \"button\" &&\n el.type !== \"link-button\" &&\n el.type !== \"field\" &&\n el.type !== \"select\" &&\n el.type !== \"radio_select\";\n\n // Call the appropriate builder function based on component type\n switch (componentName) {\n case \"Card\":\n return Card({\n title: props.title as string | undefined,\n subtitle: props.subtitle as string | undefined,\n imageUrl: props.imageUrl as string | undefined,\n children: convertedChildren.filter(isCardChild),\n });\n\n case \"Text\": {\n // JSX: <Text style=\"bold\">content</Text>\n const content = extractTextContent(props.children);\n return Text(content, { style: props.style as TextStyle | undefined });\n }\n\n case \"Image\":\n return Image({\n url: props.url as string,\n alt: props.alt as string | undefined,\n });\n\n case \"Divider\":\n return Divider();\n\n case \"Section\":\n return Section(convertedChildren.filter(isCardChild));\n\n case \"Actions\":\n return Actions(\n convertedChildren.filter(\n (\n c\n ): c is\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement =>\n c.type === \"button\" ||\n c.type === \"link-button\" ||\n c.type === \"select\" ||\n c.type === \"radio_select\"\n )\n );\n\n case \"Button\": {\n // JSX: <Button id=\"x\" style=\"primary\">Label</Button>\n const label = extractTextContent(props.children);\n return Button({\n id: props.id as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n value: props.value as string | undefined,\n });\n }\n\n case \"LinkButton\": {\n // JSX: <LinkButton url=\"https://...\" style=\"primary\">Label</LinkButton>\n const label = extractTextContent(props.children);\n return LinkButton({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n });\n }\n\n case \"CardLink\": {\n const label = extractTextContent(props.children);\n return CardLink({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n });\n }\n\n case \"Field\":\n return Field({\n label: props.label as string,\n value: props.value as string,\n });\n\n case \"Fields\":\n return Fields(\n convertedChildren.filter((c): c is FieldElement => c.type === \"field\")\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Convert React children to card elements.\n */\nfunction convertChildren(children: unknown): AnyCardElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertChildren);\n }\n\n const converted = fromReactElement(children);\n if (converted && typeof converted === \"object\" && \"type\" in converted) {\n // If it's a card, extract its children\n if (converted.type === \"card\") {\n return (converted as CardElement).children;\n }\n return [converted];\n }\n\n return [];\n}\n\n/**\n * Extract text content from React children.\n */\nfunction extractTextContent(children: unknown): string {\n if (typeof children === \"string\") {\n return children;\n }\n if (typeof children === \"number\") {\n return String(children);\n }\n if (Array.isArray(children)) {\n return children.map(extractTextContent).join(\"\");\n }\n return \"\";\n}\n\n// ============================================================================\n// Fallback Text Generation\n// ============================================================================\n\n/**\n * Generate plain text fallback from a CardElement.\n * Used for platforms/clients that can't render rich cards,\n * and for the SentMessage.text property.\n */\nexport function 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 = childToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n}\n\n/**\n * Generate fallback text from a card child element.\n */\nfunction childToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"link\":\n return `${child.label} (${child.url})`;\n case \"fields\":\n return child.children.map((f) => `${f.label}: ${f.value}`).join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"section\":\n return child.children\n .map((c) => childToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n}\n","/**\n * Modal elements for form dialogs.\n */\n\nimport type { FieldsElement, TextElement } from \"./cards\";\n\n// ============================================================================\n// Modal Element Types\n// ============================================================================\n\nexport const VALID_MODAL_CHILD_TYPES = [\n \"text_input\",\n \"select\",\n \"radio_select\",\n \"text\",\n \"fields\",\n] as const;\n\nexport type ModalChild =\n | TextInputElement\n | SelectElement\n | RadioSelectElement\n | TextElement\n | FieldsElement;\n\nexport interface ModalElement {\n callbackId: string;\n children: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n type: \"modal\";\n}\n\nexport interface TextInputElement {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n type: \"text_input\";\n}\n\nexport interface SelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n type: \"select\";\n}\n\nexport interface SelectOptionElement {\n description?: string;\n label: string;\n value: string;\n}\n\nexport interface RadioSelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n type: \"radio_select\";\n}\n\nexport function isModalElement(value: unknown): value is ModalElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as ModalElement).type === \"modal\"\n );\n}\n\nexport function filterModalChildren(children: unknown[]): ModalChild[] {\n const validChildren = children.filter(\n (c): c is ModalChild =>\n typeof c === \"object\" &&\n c !== null &&\n \"type\" in c &&\n VALID_MODAL_CHILD_TYPES.includes(\n (c as { type: string }).type as (typeof VALID_MODAL_CHILD_TYPES)[number]\n )\n );\n if (validChildren.length < children.length) {\n console.warn(\n \"[chat] Modal contains unsupported child elements that were ignored\"\n );\n }\n return validChildren;\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\nexport interface ModalOptions {\n callbackId: string;\n children?: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\nexport function Modal(options: ModalOptions): ModalElement {\n return {\n type: \"modal\",\n callbackId: options.callbackId,\n title: options.title,\n submitLabel: options.submitLabel,\n closeLabel: options.closeLabel,\n notifyOnClose: options.notifyOnClose,\n privateMetadata: options.privateMetadata,\n children: options.children ?? [],\n };\n}\n\nexport interface TextInputOptions {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\nexport function TextInput(options: TextInputOptions): TextInputElement {\n return {\n type: \"text_input\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n initialValue: options.initialValue,\n multiline: options.multiline,\n optional: options.optional,\n maxLength: options.maxLength,\n };\n}\n\nexport interface SelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n}\n\nexport function Select(options: SelectOptions): SelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"Select requires at least one option\");\n }\n return {\n type: \"select\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\nexport function SelectOption(options: {\n label: string;\n value: string;\n description?: string;\n}): SelectOptionElement {\n return {\n label: options.label,\n value: options.value,\n description: options.description,\n };\n}\n\nexport interface RadioSelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n}\n\nexport function RadioSelect(options: RadioSelectOptions): RadioSelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"RadioSelect requires at least one option\");\n }\n return {\n type: \"radio_select\",\n id: options.id,\n label: options.label,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\n// ============================================================================\n// JSX Support\n// ============================================================================\n\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\ntype AnyModalElement = ModalElement | ModalChild | SelectOptionElement;\n\nconst modalComponentMap = new Map<unknown, string>([\n [Modal, \"Modal\"],\n [TextInput, \"TextInput\"],\n [Select, \"Select\"],\n [RadioSelect, \"RadioSelect\"],\n [SelectOption, \"SelectOption\"],\n]);\n\nexport function fromReactModalElement(\n element: unknown\n): AnyModalElement | null {\n if (!isReactElement(element)) {\n if (isModalElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as ModalChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = modalComponentMap.get(type);\n\n if (!componentName) {\n if (props.children) {\n return convertModalChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n const convertedChildren = props.children\n ? convertModalChildren(props.children)\n : [];\n\n switch (componentName) {\n case \"Modal\":\n return Modal({\n callbackId: props.callbackId as string,\n title: props.title as string,\n submitLabel: props.submitLabel as string | undefined,\n closeLabel: props.closeLabel as string | undefined,\n notifyOnClose: props.notifyOnClose as boolean | undefined,\n privateMetadata: props.privateMetadata as string | undefined,\n children: filterModalChildren(convertedChildren),\n });\n\n case \"TextInput\":\n return TextInput({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n initialValue: props.initialValue as string | undefined,\n multiline: props.multiline as boolean | undefined,\n optional: props.optional as boolean | undefined,\n maxLength: props.maxLength as number | undefined,\n });\n\n case \"Select\":\n return Select({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"RadioSelect\":\n return RadioSelect({\n id: props.id as string,\n label: props.label as string,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"SelectOption\":\n return SelectOption({\n label: props.label as string,\n value: props.value as string,\n description: props.description as string | undefined,\n });\n\n default:\n return null;\n }\n}\n\nfunction convertModalChildren(children: unknown): AnyModalElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertModalChildren);\n }\n\n const converted = fromReactModalElement(children);\n if (converted) {\n if (isModalElement(converted)) {\n return converted.children;\n }\n return [converted];\n }\n\n return [];\n}\n","/**\n * Custom JSX runtime for chat cards.\n *\n * This allows using JSX syntax without React. Configure your bundler:\n *\n * tsconfig.json:\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"chat\"\n * }\n * }\n *\n * Or per-file:\n * /** @jsxImportSource chat *\\/\n *\n * Usage:\n * ```tsx\n * import { Card, Text, Button, Actions } from \"chat\";\n *\n * const card = (\n * <Card title=\"Order #1234\">\n * <Text>Your order is ready!</Text>\n * <Actions>\n * <Button id=\"pickup\" style=\"primary\">Schedule Pickup</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport {\n Actions,\n Button,\n type ButtonElement,\n type ButtonStyle,\n Card,\n type CardChild,\n type CardElement,\n CardLink,\n Divider,\n Field,\n type FieldElement,\n Fields,\n Image,\n LinkButton,\n type LinkButtonElement,\n type LinkElement,\n Section,\n Text,\n type TextStyle,\n} from \"./cards\";\n\nimport {\n filterModalChildren,\n isModalElement,\n Modal,\n type ModalChild,\n type ModalElement,\n RadioSelect,\n type RadioSelectElement,\n Select,\n type SelectElement,\n SelectOption,\n type SelectOptionElement,\n TextInput,\n} from \"./modals\";\n\n// Symbol to identify our JSX elements before they're processed\nconst JSX_ELEMENT = Symbol.for(\"chat.jsx.element\");\n\n// ============================================================================\n// JSX Props Types - Strongly typed props for each component\n// ============================================================================\n\n/** Props for Card component in JSX */\nexport interface CardProps {\n children?: unknown;\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/** Props for Text component in JSX */\nexport interface TextProps {\n children?: string | number;\n style?: TextStyle;\n}\n\n/** Props for Button component in JSX */\nexport interface ButtonProps {\n children?: string | number;\n id: string;\n label?: string;\n style?: ButtonStyle;\n value?: string;\n}\n\n/** Props for LinkButton component in JSX */\nexport interface LinkButtonProps {\n children?: string | number;\n label?: string;\n style?: ButtonStyle;\n url: string;\n}\n\n/** Props for CardLink component in JSX */\nexport interface CardLinkProps {\n children?: string | number;\n label?: string;\n url: string;\n}\n\n/** Props for Image component in JSX */\nexport interface ImageProps {\n alt?: string;\n url: string;\n}\n\n/** Props for Field component in JSX */\nexport interface FieldProps {\n label: string;\n value: string;\n}\n\n/** Props for container components (Section, Actions, Fields) */\nexport interface ContainerProps {\n children?: unknown;\n}\n\n/** Props for Divider component (no props) */\nexport type DividerProps = Record<string, never>;\n\n/** Props for Modal component in JSX */\nexport interface ModalProps {\n callbackId: string;\n children?: unknown;\n closeLabel?: string;\n notifyOnClose?: boolean;\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\n/** Props for TextInput component in JSX */\nexport interface TextInputProps {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for Select component in JSX */\nexport interface SelectProps {\n children?: unknown;\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for SelectOption component in JSX */\nexport interface SelectOptionProps {\n description?: string;\n label: string;\n value: string;\n}\n\n/** Union of all valid JSX props */\nexport type CardJSXProps =\n | CardProps\n | TextProps\n | ButtonProps\n | LinkButtonProps\n | CardLinkProps\n | ImageProps\n | FieldProps\n | ContainerProps\n | DividerProps\n | ModalProps\n | TextInputProps\n | SelectProps\n | SelectOptionProps;\n\n/** Component function type with proper overloads */\ntype CardComponentFunction =\n | typeof Card\n | typeof Text\n | typeof Button\n | typeof LinkButton\n | typeof CardLink\n | typeof Image\n | typeof Field\n | typeof Divider\n | typeof Section\n | typeof Actions\n | typeof Fields\n | typeof Modal\n | typeof TextInput\n | typeof Select\n | typeof RadioSelect\n | typeof SelectOption;\n\n/**\n * Represents a JSX element from the chat JSX runtime.\n * This is the type returned when using JSX syntax with chat components.\n */\nexport interface CardJSXElement<P extends CardJSXProps = CardJSXProps> {\n $$typeof: typeof JSX_ELEMENT;\n children: unknown[];\n props: P;\n type: CardComponentFunction;\n}\n\n// Internal alias for backwards compatibility\ntype JSXElement = CardJSXElement;\n\n/**\n * Check if a value is a JSX element from our runtime.\n */\nfunction isJSXElement(value: unknown): value is JSXElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as JSXElement).$$typeof === JSX_ELEMENT\n );\n}\n\n/** Non-null card element for children arrays */\ntype CardChildOrNested =\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | SelectOptionElement\n | RadioSelectElement;\n\n/**\n * Process children, converting JSX elements to card elements.\n */\nfunction processChildren(children: unknown): CardChildOrNested[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(processChildren);\n }\n\n // If it's a JSX element, resolve it\n if (isJSXElement(children)) {\n const resolved = resolveJSXElement(children);\n if (resolved) {\n return [resolved as CardChildOrNested];\n }\n return [];\n }\n\n // If it's already a card element, return it\n if (typeof children === \"object\" && \"type\" in children) {\n return [children as CardChildOrNested];\n }\n\n // If it's a string or number, it might be text content for a Button or Text\n if (typeof children === \"string\" || typeof children === \"number\") {\n // Return as string, the component will handle it\n return [String(children) as unknown as CardChildOrNested];\n }\n\n return [];\n}\n\n/** Any card element type that can be created */\ntype AnyCardElement =\n | CardElement\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | ModalElement\n | ModalChild\n | SelectOptionElement\n | null;\n\n/**\n * Type guard to check if props match TextProps\n */\nfunction isTextProps(props: CardJSXProps): props is TextProps {\n return !(\"id\" in props || \"url\" in props || \"label\" in props);\n}\n\n/**\n * Type guard to check if props match ButtonProps\n */\nfunction isButtonProps(props: CardJSXProps): props is ButtonProps {\n return \"id\" in props && typeof props.id === \"string\" && !(\"url\" in props);\n}\n\n/**\n * Type guard to check if props match LinkButtonProps\n */\nfunction isLinkButtonProps(props: CardJSXProps): props is LinkButtonProps {\n return \"url\" in props && typeof props.url === \"string\" && !(\"id\" in props);\n}\n\n/**\n * Type guard to check if props match CardLinkProps\n */\nexport function isCardLinkProps(props: CardJSXProps): props is CardLinkProps {\n return (\n \"url\" in props &&\n typeof props.url === \"string\" &&\n !(\"id\" in props) &&\n !(\"alt\" in props) &&\n !(\"style\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ImageProps\n */\nfunction isImageProps(props: CardJSXProps): props is ImageProps {\n return \"url\" in props && typeof props.url === \"string\";\n}\n\n/**\n * Type guard to check if props match FieldProps\n */\nfunction isFieldProps(props: CardJSXProps): props is FieldProps {\n return (\n \"label\" in props &&\n \"value\" in props &&\n typeof props.label === \"string\" &&\n typeof props.value === \"string\"\n );\n}\n\n/**\n * Type guard to check if props match CardProps\n */\nfunction isCardProps(props: CardJSXProps): props is CardProps {\n return (\n !(\"id\" in props || \"url\" in props || \"callbackId\" in props) &&\n (\"title\" in props || \"subtitle\" in props || \"imageUrl\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ModalProps\n */\nfunction isModalProps(props: CardJSXProps): props is ModalProps {\n return \"callbackId\" in props && \"title\" in props;\n}\n\n/**\n * Type guard to check if props match TextInputProps\n */\nfunction isTextInputProps(props: CardJSXProps): props is TextInputProps {\n return (\n \"id\" in props &&\n \"label\" in props &&\n !(\"options\" in props) &&\n !(\"value\" in props)\n );\n}\n\n/**\n * Type guard to check if props match SelectProps\n */\nfunction isSelectProps(props: CardJSXProps): props is SelectProps {\n return \"id\" in props && \"label\" in props && !(\"value\" in props);\n}\n\n/**\n * Type guard to check if props match SelectOptionProps\n */\nfunction isSelectOptionProps(props: CardJSXProps): props is SelectOptionProps {\n return \"label\" in props && \"value\" in props && !(\"id\" in props);\n}\n\n/**\n * Resolve a JSX element by calling its component function.\n * Transforms JSX props into the format each builder function expects.\n */\nfunction resolveJSXElement(element: JSXElement): AnyCardElement {\n const { type, props, children } = element;\n\n // Process children first\n const processedChildren = processChildren(children);\n\n // Use identity comparison to determine which builder function this is\n // This is necessary because function names get minified in production builds\n if (type === Text) {\n // Text(content: string, options?: { style })\n // JSX children become the content string\n const textProps = isTextProps(props) ? props : { style: undefined };\n const content =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : String(textProps.children ?? \"\");\n return Text(content, { style: textProps.style });\n }\n\n if (type === Section) {\n // Section takes array as first argument\n return Section(processedChildren as CardChild[]);\n }\n\n if (type === Actions) {\n // Actions takes array of ButtonElements, LinkButtonElements, SelectElements, and RadioSelectElements\n return Actions(\n processedChildren as (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n );\n }\n\n if (type === Fields) {\n // Fields takes array of FieldElements\n return Fields(processedChildren as FieldElement[]);\n }\n\n if (type === Button) {\n // Button({ id, label, style, value })\n // JSX children become the label\n if (!isButtonProps(props)) {\n throw new Error(\"Button requires an 'id' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return Button({\n id: props.id,\n label,\n style: props.style,\n value: props.value,\n });\n }\n\n if (type === LinkButton) {\n // LinkButton({ url, label, style })\n // JSX children become the label\n if (!isLinkButtonProps(props)) {\n throw new Error(\"LinkButton requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return LinkButton({\n url: props.url,\n label,\n style: props.style,\n });\n }\n\n if (type === CardLink) {\n // CardLink({ url, label })\n // JSX children become the label\n if (!isCardLinkProps(props)) {\n throw new Error(\"CardLink requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return CardLink({\n url: props.url,\n label,\n });\n }\n\n if (type === Image) {\n // Image({ url, alt })\n if (!isImageProps(props)) {\n throw new Error(\"Image requires a 'url' prop\");\n }\n return Image({ url: props.url, alt: props.alt });\n }\n\n if (type === Field) {\n // Field({ label, value })\n if (!isFieldProps(props)) {\n throw new Error(\"Field requires 'label' and 'value' props\");\n }\n return Field({\n label: props.label,\n value: props.value,\n });\n }\n\n if (type === Divider) {\n // Divider() - no args\n return Divider();\n }\n\n // Modal components\n if (type === Modal) {\n if (!isModalProps(props)) {\n throw new Error(\"Modal requires 'callbackId' and 'title' props\");\n }\n return Modal({\n callbackId: props.callbackId,\n title: props.title,\n submitLabel: props.submitLabel,\n closeLabel: props.closeLabel,\n notifyOnClose: props.notifyOnClose,\n privateMetadata: props.privateMetadata,\n children: filterModalChildren(processedChildren),\n });\n }\n\n if (type === TextInput) {\n if (!isTextInputProps(props)) {\n throw new Error(\"TextInput requires 'id' and 'label' props\");\n }\n return TextInput({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialValue: props.initialValue,\n multiline: props.multiline,\n optional: props.optional,\n maxLength: props.maxLength,\n });\n }\n\n if (type === Select) {\n if (!isSelectProps(props)) {\n throw new Error(\"Select requires 'id' and 'label' props\");\n }\n return Select({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === RadioSelect) {\n if (!isSelectProps(props)) {\n throw new Error(\"RadioSelect requires 'id' and 'label' props\");\n }\n return RadioSelect({\n id: props.id,\n label: props.label,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === SelectOption) {\n if (!isSelectOptionProps(props)) {\n throw new Error(\"SelectOption requires 'label' and 'value' props\");\n }\n return SelectOption({\n label: props.label,\n value: props.value,\n description: props.description,\n });\n }\n\n // Default: Card({ title, subtitle, imageUrl, children })\n const cardProps = isCardProps(props) ? props : {};\n return Card({\n title: cardProps.title,\n subtitle: cardProps.subtitle,\n imageUrl: cardProps.imageUrl,\n children: processedChildren as CardChild[],\n });\n}\n\n/**\n * JSX factory function (used by the JSX transform).\n * Creates a lazy JSX element that will be resolved when needed.\n */\nexport function jsx<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: children != null ? [children] : [],\n };\n}\n\n/**\n * JSX factory for elements with multiple children.\n */\nexport function jsxs<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n let resolvedChildren: unknown[];\n if (Array.isArray(children)) {\n resolvedChildren = children;\n } else if (children != null) {\n resolvedChildren = [children];\n } else {\n resolvedChildren = [];\n }\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: resolvedChildren,\n };\n}\n\n/**\n * Development JSX factory (same as jsx, but called in dev mode).\n */\nexport const jsxDEV = jsx;\n\n/**\n * Fragment support (flattens children).\n */\nexport function Fragment(props: { children?: unknown }): CardChild[] {\n return processChildren(props.children) as CardChild[];\n}\n\n/**\n * Convert a JSX element tree to a CardElement.\n * Call this on the root JSX element to get a usable CardElement.\n */\nexport function toCardElement(jsxElement: unknown): CardElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"card\"\n ) {\n return resolved as CardElement;\n }\n }\n\n // Already a CardElement\n if (\n typeof jsxElement === \"object\" &&\n jsxElement !== null &&\n \"type\" in jsxElement &&\n (jsxElement as CardElement).type === \"card\"\n ) {\n return jsxElement as CardElement;\n }\n\n return null;\n}\n\nexport function toModalElement(jsxElement: unknown): ModalElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"modal\"\n ) {\n return resolved as ModalElement;\n }\n }\n if (isModalElement(jsxElement)) {\n return jsxElement;\n }\n return null;\n}\n\n/**\n * Check if a value is a JSX element (from our runtime or React).\n */\nexport function isJSX(value: unknown): boolean {\n if (isJSXElement(value)) {\n return true;\n }\n // Check for React elements\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"$$typeof\" in value &&\n typeof (value as { $$typeof: unknown }).$$typeof === \"symbol\"\n ) {\n const symbolStr = (value as { $$typeof: symbol }).$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n }\n return false;\n}\n\n// biome-ignore lint/style/noNamespace: JSX namespace required by TypeScript JSX transform\nexport namespace JSX {\n export interface Element extends JSXElement {}\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX namespace\n export type IntrinsicElements = {};\n export interface ElementChildrenAttribute {\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX children attribute\n children: {};\n }\n}\n"],"mappings":"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","names":["isReactElement"]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CardElement, M as ModalElement, a as CardJSXElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, T as Text$1, D as Divider$1, F as Field$1, d as Fields$1, f as fromReactElement$1, I as Image$1, i as isCardElement$1, e as isJSX$1, L as LinkButton$1, S as Section$1, t as toCardElement$1, g as toModalElement$1, h as fromReactModalElement$1, j as isModalElement$1, k as Modal$1, R as RadioSelect$1, l as Select$1, m as SelectOption$1, n as TextInput$1 } from './jsx-runtime-Bdt1Dwzf.js';
2
- export { o as ActionsElement, p as ButtonElement, q as ButtonOptions, J as ButtonProps, r as ButtonStyle, K as CardJSXProps, s as CardOptions, N as CardProps, O as ContainerProps, u as DividerElement, P as DividerProps, v as FieldElement, Q as FieldProps, w as FieldsElement, x as ImageElement, U as ImageProps, y as LinkButtonElement, z as LinkButtonOptions, V as LinkButtonProps, X as ModalChild, Y as ModalOptions, Z as RadioSelectElement, _ as RadioSelectOptions, E as SectionElement, $ as SelectElement, a0 as SelectOptionElement, a1 as SelectOptions, G as TextElement, a2 as TextInputElement, a3 as TextInputOptions, W as TextProps, H as TextStyle } from './jsx-runtime-Bdt1Dwzf.js';
1
+ import { C as CardElement, M as ModalElement, a as CardJSXElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, d as CardLink$1, T as Text$1, D as Divider$1, F as Field$1, e as Fields$1, f as fromReactElement$1, I as Image$1, i as isCardElement$1, g as isJSX$1, L as LinkButton$1, S as Section$1, t as toCardElement$1, h as toModalElement$1, j as fromReactModalElement$1, k as isModalElement$1, l as Modal$1, R as RadioSelect$1, m as Select$1, n as SelectOption$1, o as TextInput$1 } from './jsx-runtime-Wowykq7Z.js';
2
+ export { p as ActionsElement, q as ButtonElement, r as ButtonOptions, N as ButtonProps, s as ButtonStyle, O as CardJSXProps, P as CardLinkProps, u as CardOptions, Q as CardProps, U as ContainerProps, v as DividerElement, V as DividerProps, w as FieldElement, W as FieldProps, x as FieldsElement, y as ImageElement, X as ImageProps, z as LinkButtonElement, E as LinkButtonOptions, Y as LinkButtonProps, G as LinkElement, _ as ModalChild, $ as ModalOptions, a0 as RadioSelectElement, a1 as RadioSelectOptions, H as SectionElement, a2 as SelectElement, a3 as SelectOptionElement, a4 as SelectOptions, J as TextElement, a5 as TextInputElement, a6 as TextInputOptions, Z as TextProps, K as TextStyle } from './jsx-runtime-Wowykq7Z.js';
3
3
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
4
4
  import { Root, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, List, Paragraph, Strong, Text } from 'mdast';
5
5
  export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Paragraph, Root, Strong, Text } from 'mdast';
@@ -58,6 +58,12 @@ declare class NotImplementedError extends ChatError {
58
58
  interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string, Adapter>> {
59
59
  /** Map of adapter name to adapter instance */
60
60
  adapters: TAdapters;
61
+ /**
62
+ * TTL for message deduplication entries in milliseconds.
63
+ * Defaults to 300000 (5 minutes). Increase if your webhook cold starts
64
+ * cause platform retries that arrive after the default TTL expires.
65
+ */
66
+ dedupeTtlMs?: number;
61
67
  /**
62
68
  * Logger instance or log level.
63
69
  * Pass "silent" to disable all logging.
@@ -242,7 +248,7 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
242
248
  /** Render formatted content to platform-specific string */
243
249
  renderFormatted(content: FormattedContent): string;
244
250
  /** Show typing indicator */
245
- startTyping(threadId: string): Promise<void>;
251
+ startTyping(threadId: string, status?: string): Promise<void>;
246
252
  /**
247
253
  * Stream a message using platform-native streaming APIs.
248
254
  *
@@ -410,7 +416,7 @@ interface Postable<TState = Record<string, unknown>, TRawMessage = unknown> {
410
416
  replace?: boolean;
411
417
  }): Promise<void>;
412
418
  /** Show typing indicator */
413
- startTyping(): Promise<void>;
419
+ startTyping(status?: string): Promise<void>;
414
420
  /**
415
421
  * Get the current state.
416
422
  * Returns null if no state has been set.
@@ -589,8 +595,9 @@ interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extend
589
595
  * Show typing indicator in the thread.
590
596
  *
591
597
  * Some platforms support persistent typing indicators, others just send once.
598
+ * Optional status (e.g. "Typing...", "Searching documents...") is shown where supported.
592
599
  */
593
- startTyping(): Promise<void>;
600
+ startTyping(status?: string): Promise<void>;
594
601
  /**
595
602
  * Subscribe to future messages in this thread.
596
603
  *
@@ -1499,7 +1506,7 @@ declare class ChannelImpl<TState = Record<string, unknown>> implements Channel<T
1499
1506
  post(message: string | PostableMessage | CardJSXElement): Promise<SentMessage>;
1500
1507
  private postSingleMessage;
1501
1508
  postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
1502
- startTyping(): Promise<void>;
1509
+ startTyping(status?: string): Promise<void>;
1503
1510
  mentionUser(userId: string): string;
1504
1511
  toJSON(): SerializedChannel;
1505
1512
  static fromJSON<TState = Record<string, unknown>>(json: SerializedChannel, adapter?: Adapter): ChannelImpl<TState>;
@@ -1583,6 +1590,7 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
1583
1590
  private readonly userName;
1584
1591
  private readonly logger;
1585
1592
  private readonly _streamingUpdateIntervalMs;
1593
+ private readonly _dedupeTtlMs;
1586
1594
  private readonly mentionHandlers;
1587
1595
  private readonly messagePatterns;
1588
1596
  private readonly subscribedMessageHandlers;
@@ -2055,7 +2063,7 @@ declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TSt
2055
2063
  * Uses adapter's native streaming if available, otherwise falls back to post+edit.
2056
2064
  */
2057
2065
  private handleStream;
2058
- startTyping(): Promise<void>;
2066
+ startTyping(status?: string): Promise<void>;
2059
2067
  /**
2060
2068
  * Fallback streaming implementation using post + edit.
2061
2069
  * Used when adapter doesn't support native streaming.
@@ -2481,6 +2489,7 @@ declare abstract class BaseFormatConverter implements FormatConverter {
2481
2489
  declare const Actions: typeof Actions$1;
2482
2490
  declare const Button: typeof Button$1;
2483
2491
  declare const Card: typeof Card$1;
2492
+ declare const CardLink: typeof CardLink$1;
2484
2493
  declare const CardText: typeof Text$1;
2485
2494
  declare const Divider: typeof Divider$1;
2486
2495
  declare const Field: typeof Field$1;
@@ -2502,4 +2511,4 @@ declare const Select: typeof Select$1;
2502
2511
  declare const SelectOption: typeof SelectOption$1;
2503
2512
  declare const TextInput: typeof TextInput$1;
2504
2513
 
2505
- export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, TextInput, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, text, toCardElement, toModalElement, toPlainText, walkAst };
2514
+ export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardLink, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, TextInput, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, text, toCardElement, toModalElement, toPlainText, walkAst };
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Actions,
3
3
  Button,
4
4
  Card,
5
+ CardLink,
5
6
  CardText,
6
7
  Divider,
7
8
  Field,
@@ -22,7 +23,7 @@ import {
22
23
  isModalElement,
23
24
  toCardElement,
24
25
  toModalElement
25
- } from "./chunk-THM4ACIE.js";
26
+ } from "./chunk-VGF42GJ2.js";
26
27
 
27
28
  // src/channel.ts
28
29
  import { WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE2, WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE2 } from "@workflow/serde";
@@ -646,8 +647,8 @@ var ChannelImpl = class _ChannelImpl {
646
647
  }
647
648
  return null;
648
649
  }
649
- async startTyping() {
650
- await this.adapter.startTyping(this.id);
650
+ async startTyping(status) {
651
+ await this.adapter.startTyping(this.id, status);
651
652
  }
652
653
  mentionUser(userId) {
653
654
  return `<@${userId}>`;
@@ -1054,8 +1055,8 @@ var ThreadImpl = class _ThreadImpl {
1054
1055
  }
1055
1056
  return this.fallbackStream(textStream, options);
1056
1057
  }
1057
- async startTyping() {
1058
- await this.adapter.startTyping(this.id);
1058
+ async startTyping(status) {
1059
+ await this.adapter.startTyping(this.id, status);
1059
1060
  }
1060
1061
  /**
1061
1062
  * Fallback streaming implementation using post + edit.
@@ -1330,7 +1331,7 @@ function extractMessageContent2(message) {
1330
1331
  var DEFAULT_LOCK_TTL_MS = 3e4;
1331
1332
  var SLACK_USER_ID_REGEX = /^U[A-Z0-9]+$/i;
1332
1333
  var DISCORD_SNOWFLAKE_REGEX = /^\d{17,19}$/;
1333
- var DEDUPE_TTL_MS = 6e4;
1334
+ var DEDUPE_TTL_MS = 5 * 60 * 1e3;
1334
1335
  var MODAL_CONTEXT_TTL_MS = 24 * 60 * 60 * 1e3;
1335
1336
  var Chat = class {
1336
1337
  /**
@@ -1368,6 +1369,7 @@ var Chat = class {
1368
1369
  userName;
1369
1370
  logger;
1370
1371
  _streamingUpdateIntervalMs;
1372
+ _dedupeTtlMs;
1371
1373
  mentionHandlers = [];
1372
1374
  messagePatterns = [];
1373
1375
  subscribedMessageHandlers = [];
@@ -1393,6 +1395,7 @@ var Chat = class {
1393
1395
  this._stateAdapter = config.state;
1394
1396
  this.adapters = /* @__PURE__ */ new Map();
1395
1397
  this._streamingUpdateIntervalMs = config.streamingUpdateIntervalMs ?? 500;
1398
+ this._dedupeTtlMs = config.dedupeTtlMs ?? DEDUPE_TTL_MS;
1396
1399
  if (typeof config.logger === "string") {
1397
1400
  this.logger = new ConsoleLogger(config.logger);
1398
1401
  } else {
@@ -2299,7 +2302,7 @@ var Chat = class {
2299
2302
  });
2300
2303
  return;
2301
2304
  }
2302
- await this._stateAdapter.set(dedupeKey, true, DEDUPE_TTL_MS);
2305
+ await this._stateAdapter.set(dedupeKey, true, this._dedupeTtlMs);
2303
2306
  const lock = await this._stateAdapter.acquireLock(
2304
2307
  threadId,
2305
2308
  DEFAULT_LOCK_TTL_MS
@@ -2822,6 +2825,7 @@ var emoji = createEmoji();
2822
2825
  var Actions2 = Actions;
2823
2826
  var Button2 = Button;
2824
2827
  var Card2 = Card;
2828
+ var CardLink2 = CardLink;
2825
2829
  var CardText2 = CardText;
2826
2830
  var Divider2 = Divider;
2827
2831
  var Field2 = Field;
@@ -2846,6 +2850,7 @@ export {
2846
2850
  BaseFormatConverter,
2847
2851
  Button2 as Button,
2848
2852
  Card2 as Card,
2853
+ CardLink2 as CardLink,
2849
2854
  CardText2 as CardText,
2850
2855
  ChannelImpl,
2851
2856
  Chat,