@assistant-ui/react 0.15.22 → 0.15.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +44 -23
  3. package/dist/assistant-transport.js.map +1 -1
  4. package/dist/cloud-renderer/CloudRendererHost.js.map +1 -1
  5. package/dist/context/providers/MessageProvider.js.map +1 -1
  6. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  7. package/dist/hooks/useToolCallElapsed.js.map +1 -1
  8. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  9. package/dist/mcp-apps/app-frame.js.map +1 -1
  10. package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
  11. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  12. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  13. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  14. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  15. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  16. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  17. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  18. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  19. package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
  20. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  21. package/dist/primitives/actionBar/useActionBarFloatStatus.js.map +1 -1
  22. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
  23. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
  24. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
  25. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
  26. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
  27. package/dist/primitives/actionBarMore/scope.js.map +1 -1
  28. package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
  29. package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
  30. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  31. package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
  32. package/dist/primitives/assistantModal/popoverRenderPrimitives.js.map +1 -1
  33. package/dist/primitives/assistantModal/scope.js.map +1 -1
  34. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  35. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  36. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  37. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  38. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  39. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  40. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  41. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  42. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  43. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  44. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  45. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  46. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  47. package/dist/primitives/composer/ComposerDictate.js.map +1 -1
  48. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  49. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  50. package/dist/primitives/composer/ComposerInput.js +3 -2
  51. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  52. package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
  53. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  54. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  55. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  56. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  57. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  58. package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
  59. package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
  60. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
  61. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
  62. package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
  63. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  64. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
  65. package/dist/primitives/composer/trigger/index.js.map +1 -1
  66. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  67. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  68. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  69. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  70. package/dist/primitives/composer/useComposerInputState.js.map +1 -1
  71. package/dist/primitives/dropdownMenuRenderPrimitives.js.map +1 -1
  72. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  73. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  74. package/dist/primitives/message/MessageIf.d.ts.map +1 -1
  75. package/dist/primitives/message/MessageIf.js +6 -3
  76. package/dist/primitives/message/MessageIf.js.map +1 -1
  77. package/dist/primitives/message/MessageParts.js.map +1 -1
  78. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  79. package/dist/primitives/message/MessagePartsGrouped.js +42 -17
  80. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  81. package/dist/primitives/message/MessageRoot.js.map +1 -1
  82. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  83. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  84. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  85. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  86. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  87. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  88. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  89. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  90. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  91. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  92. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  93. package/dist/primitives/thread/ThreadRoot.d.ts +3 -2
  94. package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
  95. package/dist/primitives/thread/ThreadRoot.js +49 -27
  96. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  97. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  98. package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
  99. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  100. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  101. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  102. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -1
  103. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  104. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  105. package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
  106. package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
  107. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts.map +1 -1
  108. package/dist/primitives/threadListItem/ThreadListItemRoot.js +1 -0
  109. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  110. package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
  111. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  112. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.d.ts.map +1 -1
  113. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +1 -0
  114. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
  115. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
  116. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
  117. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
  118. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.d.ts.map +1 -1
  119. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +1 -0
  120. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
  121. package/dist/primitives/threadListItemMore/scope.js.map +1 -1
  122. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  123. package/dist/unstable/useModelContextSnapshot.js.map +1 -1
  124. package/dist/unstable/webmcp/WebMcpRegistrationResource.d.ts +1 -0
  125. package/dist/unstable/webmcp/WebMcpRegistrationResource.d.ts.map +1 -1
  126. package/dist/unstable/webmcp/WebMcpRegistrationResource.js +27 -39
  127. package/dist/unstable/webmcp/WebMcpRegistrationResource.js.map +1 -1
  128. package/dist/unstable/webmcp/useWebMcpProvider.d.ts.map +1 -1
  129. package/dist/unstable/webmcp/useWebMcpProvider.js +22 -13
  130. package/dist/unstable/webmcp/useWebMcpProvider.js.map +1 -1
  131. package/dist/utils/Primitive.js.map +1 -1
  132. package/dist/utils/createActionButton.js.map +1 -1
  133. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  134. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  135. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  136. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  137. package/dist/utils/hooks/useSizeHandle.js.map +1 -1
  138. package/dist/utils/isCompositionKey.d.ts +2 -0
  139. package/dist/utils/isCompositionKey.d.ts.map +1 -0
  140. package/dist/utils/isCompositionKey.js +6 -0
  141. package/dist/utils/isCompositionKey.js.map +1 -0
  142. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  143. package/package.json +15 -12
  144. package/src/primitives/composer/ComposerInput.test.tsx +33 -1
  145. package/src/primitives/composer/ComposerInput.tsx +3 -2
  146. package/src/primitives/message/MessageIf.test.tsx +72 -0
  147. package/src/primitives/message/MessageIf.ts +8 -3
  148. package/src/primitives/message/MessagePartsGrouped.test.tsx +271 -1
  149. package/src/primitives/message/MessagePartsGrouped.tsx +14 -6
  150. package/src/primitives/thread/ThreadRoot.test.tsx +163 -0
  151. package/src/primitives/thread/ThreadRoot.tsx +33 -3
  152. package/src/primitives/threadListItem/ThreadListItemRoot.tsx +2 -0
  153. package/src/primitives/threadListItem/ThreadListKeyboardNav.test.tsx +65 -0
  154. package/src/primitives/threadListItemMore/ThreadListItemMoreContent.tsx +7 -0
  155. package/src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx +2 -0
  156. package/src/tests/RemoteThreadListRuntime.reloadMainThread.test.tsx +8 -13
  157. package/src/tests/remote-thread-list-test-helpers.ts +15 -0
  158. package/src/tests/threadListItemIsRunning.test.tsx +10 -7
  159. package/src/unstable/webmcp/WebMcpRegistrationResource.ts +9 -8
  160. package/src/unstable/webmcp/useWebMcpProvider.test.tsx +36 -2
  161. package/src/unstable/webmcp/useWebMcpProvider.ts +40 -13
  162. package/src/utils/isCompositionKey.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadListItemMoreTrigger.js","names":["c","_c","ComponentRef","forwardRef","Direction","DropdownMenu","DropdownMenuPrimitive","useComposedRefs","composeEventHandlers","WithRenderPropProps","DropdownMenuRenderTrigger","useThreadListItemFocus","useThreadListItemMoreSharedFocusGroup","useThreadListItemMoreSetOpen","ScopedProps","useDropdownMenuScope","ThreadListItemMorePrimitiveTrigger","Element","Trigger","Props","t0","ref","$","__scopeThreadListItemMore","rest","scope","focus","setOpen","sharedFocusGroup","composedRef","moreRef","direction","useDirection","openKey","T0","t1","event","key","preventDefault","t2","onKeyDown","t3","displayName"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport {\n Direction,\n type DropdownMenu as DropdownMenuPrimitive,\n} from \"radix-ui\";\nimport { useComposedRefs } from \"radix-ui/internal\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderTrigger } from \"../dropdownMenuRenderPrimitives\";\nimport { useThreadListItemFocus } from \"../threadListFocusGroup\";\nimport {\n useThreadListItemMoreSharedFocusGroup,\n useThreadListItemMoreSetOpen,\n} from \"./ThreadListItemMoreRoot\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveTrigger {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Trigger>;\n export type Props = WithRenderPropProps<typeof DropdownMenuPrimitive.Trigger>;\n}\n\nexport const ThreadListItemMorePrimitiveTrigger = forwardRef<\n ThreadListItemMorePrimitiveTrigger.Element,\n ThreadListItemMorePrimitiveTrigger.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveTrigger.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n const focus = useThreadListItemFocus();\n const setOpen = useThreadListItemMoreSetOpen();\n const sharedFocusGroup = useThreadListItemMoreSharedFocusGroup();\n const composedRef = useComposedRefs(ref, focus?.moreRef);\n const direction = Direction.useDirection();\n const openKey = direction === \"rtl\" ? \"ArrowLeft\" : \"ArrowRight\";\n\n return (\n <DropdownMenuRenderTrigger\n {...scope}\n {...rest}\n onKeyDown={composeEventHandlers(rest.onKeyDown, (event) => {\n if (!sharedFocusGroup || event.key !== openKey) return;\n event.preventDefault();\n setOpen(true);\n })}\n ref={composedRef}\n />\n );\n },\n);\n\nThreadListItemMorePrimitiveTrigger.displayName =\n \"ThreadListItemMorePrimitive.Trigger\";\n"],"mappings":";;;;;;;;;;;AAuBA,MAAagB,qCAAqCb,YAIhDiB,IAAAC,QAAA;CAAA,MAAAC,IAAArB,EAAA,EAAA;CACE,MAAA,EAAAsB,2BAAA,GAAAC,SAAAJ;CAMA,MAAAK,QAAcV,qBAAqBQ,yBAAyB;CAC5D,MAAAG,QAAcf,uBAAuB;CACrC,MAAAgB,UAAgBd,6BAA6B;CAC7C,MAAAe,mBAAyBhB,sCAAsC;CAC/D,MAAAiB,cAAoBtB,gBAAgBc,KAAKK,OAAKI,OAAS;CAEvD,MAAAG,UADkB7B,UAAS4B,aACXD,MAAc,QAAd,cAAA;CAGb,MAAAG,KAAAxB;CAAyB,IAAAyB;CAAA,IAAAb,EAAA,OAAAW,WAAAX,EAAA,OAAAK,WAAAL,EAAA,OAAAM,kBAAA;EAGwBO,MAAAC,UAAA;GAC9C,IAAI,CAACR,oBAAoBQ,MAAKC,QAASJ,SAAO;GAC9CG,MAAKE,eAAgB;GACrBX,QAAQ,IAAI;EAAC;EACdL,EAAA,KAAAW;EAAAX,EAAA,KAAAK;EAAAL,EAAA,KAAAM;EAAAN,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAJU,MAAAiB,KAAA/B,qBAAqBgB,KAAIgB,WAAYL,EAI/C;CAAC,IAAAM;CAAA,IAAAnB,EAAA,OAAAY,MAAAZ,EAAA,OAAAO,eAAAP,EAAA,OAAAE,QAAAF,EAAA,OAAAG,SAAAH,EAAA,OAAAiB,IAAA;EAPJE,KAAA,oBAAC,IAAD;GAA0B,GACpBhB;GAAK,GACLD;GACO,WAAAe;GAKNV,KAAAA;EAAW,CAAA;EAChBP,EAAA,KAAAY;EAAAZ,EAAA,KAAAO;EAAAP,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAiB;EAAAjB,EAAA,KAAAmB;CAAA,OAAAA,KAAAnB,EAAA;CAAA,OATFmB;AASE,CAGR;AAEAzB,mCAAmC0B,cACjC"}
1
+ {"version":3,"file":"ThreadListItemMoreTrigger.js","names":["c","_c","ComponentRef","forwardRef","Direction","DropdownMenu","DropdownMenuPrimitive","useComposedRefs","composeEventHandlers","WithRenderPropProps","DropdownMenuRenderTrigger","useThreadListItemFocus","useThreadListItemMoreSharedFocusGroup","useThreadListItemMoreSetOpen","ScopedProps","useDropdownMenuScope","ThreadListItemMorePrimitiveTrigger","Element","Trigger","Props","t0","ref","$","__scopeThreadListItemMore","rest","scope","focus","setOpen","sharedFocusGroup","composedRef","moreRef","direction","useDirection","openKey","T0","t1","event","key","altKey","ctrlKey","metaKey","shiftKey","preventDefault","t2","onKeyDown","t3","displayName","_c"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport {\n Direction,\n type DropdownMenu as DropdownMenuPrimitive,\n} from \"radix-ui\";\nimport { useComposedRefs } from \"radix-ui/internal\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderTrigger } from \"../dropdownMenuRenderPrimitives\";\nimport { useThreadListItemFocus } from \"../threadListFocusGroup\";\nimport {\n useThreadListItemMoreSharedFocusGroup,\n useThreadListItemMoreSetOpen,\n} from \"./ThreadListItemMoreRoot\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveTrigger {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Trigger>;\n export type Props = WithRenderPropProps<typeof DropdownMenuPrimitive.Trigger>;\n}\n\nexport const ThreadListItemMorePrimitiveTrigger = forwardRef<\n ThreadListItemMorePrimitiveTrigger.Element,\n ThreadListItemMorePrimitiveTrigger.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveTrigger.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n const focus = useThreadListItemFocus();\n const setOpen = useThreadListItemMoreSetOpen();\n const sharedFocusGroup = useThreadListItemMoreSharedFocusGroup();\n const composedRef = useComposedRefs(ref, focus?.moreRef);\n const direction = Direction.useDirection();\n const openKey = direction === \"rtl\" ? \"ArrowLeft\" : \"ArrowRight\";\n\n return (\n <DropdownMenuRenderTrigger\n {...scope}\n {...rest}\n onKeyDown={composeEventHandlers(rest.onKeyDown, (event) => {\n if (!sharedFocusGroup || event.key !== openKey) return;\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)\n return;\n event.preventDefault();\n setOpen(true);\n })}\n ref={composedRef}\n />\n );\n },\n);\n\nThreadListItemMorePrimitiveTrigger.displayName =\n \"ThreadListItemMorePrimitive.Trigger\";\n"],"mappings":";;;;;;;;;;;AAuBA,MAAagB,qCAAqCb,YAIhDiB,IAAAC,QAAA;CAAA,MAAAC,IAAArB,EAAA,EAAA;CACE,MAAA,EAAAsB,2BAAA,GAAAC,SAAAJ;CAMA,MAAAK,QAAcV,qBAAqBQ,yBAAyB;CAC5D,MAAAG,QAAcf,uBAAuB;CACrC,MAAAgB,UAAgBd,6BAA6B;CAC7C,MAAAe,mBAAyBhB,sCAAsC;CAC/D,MAAAiB,cAAoBtB,gBAAgBc,KAAKK,OAAKI,OAAS;CAEvD,MAAAG,UADkB7B,UAAS4B,aACXD,MAAc,QAAd,cAAA;CAGb,MAAAG,KAAAxB;CAAyB,IAAAyB;CAAA,IAAAb,EAAA,OAAAW,WAAAX,EAAA,OAAAK,WAAAL,EAAA,OAAAM,kBAAA;EAGwBO,MAAAC,UAAA;GAC9C,IAAI,CAACR,oBAAoBQ,MAAKC,QAASJ,SAAO;GAC9C,IAAIG,MAAKE,UAAWF,MAAKG,WAAYH,MAAKI,WAAYJ,MAAKK,UAAS;GAEpEL,MAAKM,eAAgB;GACrBf,QAAQ,IAAI;EAAC;EACdL,EAAA,KAAAW;EAAAX,EAAA,KAAAK;EAAAL,EAAA,KAAAM;EAAAN,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CANU,MAAAqB,KAAAnC,qBAAqBgB,KAAIoB,WAAYT,EAM/C;CAAC,IAAAU;CAAA,IAAAvB,EAAA,OAAAY,MAAAZ,EAAA,OAAAO,eAAAP,EAAA,OAAAE,QAAAF,EAAA,OAAAG,SAAAH,EAAA,OAAAqB,IAAA;EATJE,KAAA,oBAAC,IAAD;GAA0B,GACpBpB;GAAK,GACLD;GACO,WAAAmB;GAONd,KAAAA;EAAW,CAAA;EAChBP,EAAA,KAAAY;EAAAZ,EAAA,KAAAO;EAAAP,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAqB;EAAArB,EAAA,KAAAuB;CAAA,OAAAA,KAAAvB,EAAA;CAAA,OAXFuB;AAWE,CAGR;AAEA7B,mCAAmC8B,cACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","names":["DropdownMenu","DropdownMenuPrimitive","Context","useDropdownMenuScope","ReturnType","createDropdownMenuScope","ScopedProps","P","__scopeThreadListItemMore","Scope"],"sources":["../../../src/primitives/threadListItemMore/scope.ts"],"sourcesContent":["import { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { Context } from \"radix-ui/internal\";\n\nexport const useDropdownMenuScope: ReturnType<\n typeof DropdownMenuPrimitive.createDropdownMenuScope\n> = DropdownMenuPrimitive.createDropdownMenuScope();\n\nexport type ScopedProps<P> = P & { __scopeThreadListItemMore?: Context.Scope };\n"],"mappings":";;AAGA,MAAaG,uBAETF,aAAsBI,wBAAwB"}
1
+ {"version":3,"file":"scope.js","names":["DropdownMenu","DropdownMenuPrimitive","Context","useDropdownMenuScope","ReturnType","createDropdownMenuScope","ScopedProps","P","__scopeThreadListItemMore","Scope","DropdownMenuPrimitive"],"sources":["../../../src/primitives/threadListItemMore/scope.ts"],"sourcesContent":["import { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { Context } from \"radix-ui/internal\";\n\nexport const useDropdownMenuScope: ReturnType<\n typeof DropdownMenuPrimitive.createDropdownMenuScope\n> = DropdownMenuPrimitive.createDropdownMenuScope();\n\nexport type ScopedProps<P> = P & { __scopeThreadListItemMore?: Context.Scope };\n"],"mappings":";;AAGA,MAAaG,uBAETF,aAAsBI,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"SandboxHost.js","names":["c","_c","CSSProperties","useEffect","useLayoutEffect","useRef","useState","isShimLoadError","RenderedFrame","SafeContentFrame","SandboxOption","invokeUserCallback","DEFAULT_PRODUCT","DEFAULT_MAX_HEIGHT","LOAD_TIMEOUT_MS","SandboxHostConfig","sandbox","useShadowDom","enableBrowserCaching","salt","product","className","style","unsafeDocumentWrite","SandboxHostFrame","Pick","SandboxHostApi","setHeight","height","SandboxBridge","onMessage","event","MessageEvent","dispose","SandboxContent","html","SandboxHostProps","content","contentKey","maxHeight","createBridge","frame","host","onError","error","Error","containerProps","Record","isSandboxFrameMessage","iframe","HTMLIFrameElement","origin","source","contentWindow","LiveSnapshot","SandboxHost","t0","$","t1","undefined","containerRef","contentHeight","setContentHeight","t2","liveRef","t3","t4","current","t5","Symbol","for","container","cancelled","bridge","liveContent","sb","reportError","err","String","bind","scf","renderOpts","renderHtml","then","rendered","hostApi","Number","isFinite","sendMessage","window","addEventListener","fullyLoadedPromiseWithTimeout","catch","err_0","code","err_1","cleanupFailed","cleanupError","runCleanup","cleanup","t6","console","listener","removeEventListener","bridgeToDispose","frameToDispose","resolvedHeight","Math","min","t7","mergedStyle","t8","t9"],"sources":["../../src/sandbox-host/SandboxHost.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n isShimLoadError,\n type RenderedFrame,\n SafeContentFrame,\n type SandboxOption,\n} from \"safe-content-frame\";\nimport { invokeUserCallback } from \"@assistant-ui/core/internal\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-sandbox\";\nconst DEFAULT_MAX_HEIGHT = 800;\nconst LOAD_TIMEOUT_MS = 10_000;\n\nexport type SandboxHostConfig = {\n sandbox?: SandboxOption[];\n useShadowDom?: boolean;\n enableBrowserCaching?: boolean;\n salt?: string;\n product?: string;\n className?: string;\n style?: CSSProperties;\n unsafeDocumentWrite?: boolean;\n};\n\nexport type SandboxHostFrame = Pick<\n RenderedFrame,\n \"iframe\" | \"origin\" | \"sendMessage\"\n>;\n\nexport type SandboxHostApi = {\n setHeight: (height: number) => void;\n};\n\nexport type SandboxBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n};\n\nexport type SandboxContent = { html: string };\n\nexport type SandboxHostProps = {\n content: SandboxContent;\n contentKey: string;\n sandbox?: SandboxHostConfig | undefined;\n maxHeight?: number | undefined;\n createBridge: (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ) => SandboxBridge;\n onError?: ((error: Error) => void) | undefined;\n containerProps?: Record<string, string | undefined> | undefined;\n};\n\nexport function isSandboxFrameMessage(\n event: MessageEvent,\n frame: { iframe: HTMLIFrameElement; origin: string },\n): boolean {\n return (\n event.source === frame.iframe.contentWindow && event.origin === frame.origin\n );\n}\n\ntype LiveSnapshot = {\n content: SandboxContent;\n sandbox: SandboxHostConfig | undefined;\n createBridge: SandboxHostProps[\"createBridge\"];\n onError: SandboxHostProps[\"onError\"];\n};\n\nexport function SandboxHost({\n content,\n contentKey,\n sandbox,\n maxHeight = DEFAULT_MAX_HEIGHT,\n createBridge,\n onError,\n containerProps,\n}: SandboxHostProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [contentHeight, setContentHeight] = useState<number | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>({\n content,\n sandbox,\n createBridge,\n onError,\n });\n useLayoutEffect(() => {\n liveRef.current = { content, sandbox, createBridge, onError };\n }, [content, sandbox, createBridge, onError]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n let frame: RenderedFrame | null = null;\n let bridge: SandboxBridge | null = null;\n let onMessage: ((event: MessageEvent) => void) | null = null;\n\n const { content: liveContent, sandbox: sb } = liveRef.current;\n\n const reportError = (err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n invokeUserCallback(\n \"assistant-ui\",\n \"SandboxHost onError\",\n liveRef.current.onError?.bind(liveRef.current),\n error,\n );\n };\n\n const scf = new SafeContentFrame(sb?.product ?? DEFAULT_PRODUCT, {\n ...(sb?.sandbox !== undefined && { sandbox: sb.sandbox }),\n ...(sb?.useShadowDom !== undefined && { useShadowDom: sb.useShadowDom }),\n ...(sb?.enableBrowserCaching !== undefined && {\n enableBrowserCaching: sb.enableBrowserCaching,\n }),\n ...(sb?.salt !== undefined && { salt: sb.salt }),\n });\n\n const renderOpts =\n sb?.unsafeDocumentWrite !== undefined\n ? { unsafeDocumentWrite: sb.unsafeDocumentWrite }\n : undefined;\n\n scf\n .renderHtml(liveContent.html, container, renderOpts)\n .then((rendered) => {\n if (cancelled) {\n rendered.dispose();\n return;\n }\n frame = rendered;\n\n const hostApi: SandboxHostApi = {\n setHeight: (height) => {\n if (\n typeof height === \"number\" &&\n Number.isFinite(height) &&\n height > 0\n ) {\n setContentHeight(height);\n }\n },\n };\n\n bridge = liveRef.current.createBridge(\n {\n iframe: rendered.iframe,\n origin: rendered.origin,\n sendMessage: rendered.sendMessage,\n },\n hostApi,\n );\n\n // Single owner of the window listener; the cross-origin guard runs\n // here so the bridge only sees frame-validated messages.\n onMessage = (event) => {\n if (!isSandboxFrameMessage(event, rendered)) return;\n bridge?.onMessage(event);\n };\n window.addEventListener(\"message\", onMessage);\n\n // renderHtml resolves at iframe load, which a shim that was never\n // served also reaches, so a completed render is only known once the\n // frame says so. render-timeout is excluded because the shim is\n // running and the guest may still paint, and reporting it would leave\n // a host that renders an error state showing one over a frame that\n // recovers.\n rendered.fullyLoadedPromiseWithTimeout(LOAD_TIMEOUT_MS).catch((err) => {\n if (cancelled) return;\n if (isShimLoadError(err) && err.code === \"render-timeout\") return;\n reportError(err);\n });\n })\n .catch((err) => {\n if (cancelled) return;\n frame?.dispose();\n frame = null;\n reportError(err);\n });\n\n return () => {\n cancelled = true;\n let cleanupFailed = false;\n let cleanupError: unknown;\n const runCleanup = (cleanup: () => void) => {\n try {\n cleanup();\n } catch (error) {\n if (cleanupFailed) {\n console.error(error);\n } else {\n cleanupFailed = true;\n cleanupError = error;\n }\n }\n };\n\n if (onMessage) {\n const listener = onMessage;\n onMessage = null;\n runCleanup(() => window.removeEventListener(\"message\", listener));\n }\n const bridgeToDispose = bridge;\n bridge = null;\n if (bridgeToDispose) runCleanup(() => bridgeToDispose.dispose());\n const frameToDispose = frame;\n frame = null;\n if (frameToDispose) runCleanup(() => frameToDispose.dispose());\n runCleanup(() => setContentHeight(undefined));\n\n if (cleanupFailed) throw cleanupError;\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-init only on contentKey change; live values flow through liveRef\n }, [contentKey]);\n\n const resolvedHeight =\n contentHeight != null ? Math.min(contentHeight, maxHeight) : undefined;\n const mergedStyle =\n resolvedHeight != null\n ? { ...sandbox?.style, height: resolvedHeight }\n : sandbox?.style;\n\n return (\n <div\n {...containerProps}\n ref={containerRef}\n className={sandbox?.className}\n style={mergedStyle}\n />\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SandboxHost.js","names":["c","_c","CSSProperties","useEffect","useLayoutEffect","useRef","useState","isShimLoadError","RenderedFrame","SafeContentFrame","SandboxOption","invokeUserCallback","DEFAULT_PRODUCT","DEFAULT_MAX_HEIGHT","LOAD_TIMEOUT_MS","SandboxHostConfig","sandbox","useShadowDom","enableBrowserCaching","salt","product","className","style","unsafeDocumentWrite","SandboxHostFrame","Pick","SandboxHostApi","setHeight","height","SandboxBridge","onMessage","event","MessageEvent","dispose","SandboxContent","html","SandboxHostProps","content","contentKey","maxHeight","createBridge","frame","host","onError","error","Error","containerProps","Record","isSandboxFrameMessage","iframe","HTMLIFrameElement","origin","source","contentWindow","LiveSnapshot","SandboxHost","t0","$","t1","undefined","containerRef","contentHeight","setContentHeight","t2","liveRef","t3","t4","current","t5","Symbol","for","container","cancelled","bridge","liveContent","sb","reportError","err","String","bind","scf","renderOpts","renderHtml","then","rendered","hostApi","Number","isFinite","sendMessage","window","addEventListener","fullyLoadedPromiseWithTimeout","catch","err_0","code","err_1","cleanupFailed","cleanupError","runCleanup","cleanup","t6","console","listener","removeEventListener","bridgeToDispose","frameToDispose","resolvedHeight","Math","min","t7","mergedStyle","t8","t9","_c"],"sources":["../../src/sandbox-host/SandboxHost.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type CSSProperties,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n isShimLoadError,\n type RenderedFrame,\n SafeContentFrame,\n type SandboxOption,\n} from \"safe-content-frame\";\nimport { invokeUserCallback } from \"@assistant-ui/core/internal\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-sandbox\";\nconst DEFAULT_MAX_HEIGHT = 800;\nconst LOAD_TIMEOUT_MS = 10_000;\n\nexport type SandboxHostConfig = {\n sandbox?: SandboxOption[];\n useShadowDom?: boolean;\n enableBrowserCaching?: boolean;\n salt?: string;\n product?: string;\n className?: string;\n style?: CSSProperties;\n unsafeDocumentWrite?: boolean;\n};\n\nexport type SandboxHostFrame = Pick<\n RenderedFrame,\n \"iframe\" | \"origin\" | \"sendMessage\"\n>;\n\nexport type SandboxHostApi = {\n setHeight: (height: number) => void;\n};\n\nexport type SandboxBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n};\n\nexport type SandboxContent = { html: string };\n\nexport type SandboxHostProps = {\n content: SandboxContent;\n contentKey: string;\n sandbox?: SandboxHostConfig | undefined;\n maxHeight?: number | undefined;\n createBridge: (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ) => SandboxBridge;\n onError?: ((error: Error) => void) | undefined;\n containerProps?: Record<string, string | undefined> | undefined;\n};\n\nexport function isSandboxFrameMessage(\n event: MessageEvent,\n frame: { iframe: HTMLIFrameElement; origin: string },\n): boolean {\n return (\n event.source === frame.iframe.contentWindow && event.origin === frame.origin\n );\n}\n\ntype LiveSnapshot = {\n content: SandboxContent;\n sandbox: SandboxHostConfig | undefined;\n createBridge: SandboxHostProps[\"createBridge\"];\n onError: SandboxHostProps[\"onError\"];\n};\n\nexport function SandboxHost({\n content,\n contentKey,\n sandbox,\n maxHeight = DEFAULT_MAX_HEIGHT,\n createBridge,\n onError,\n containerProps,\n}: SandboxHostProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [contentHeight, setContentHeight] = useState<number | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>({\n content,\n sandbox,\n createBridge,\n onError,\n });\n useLayoutEffect(() => {\n liveRef.current = { content, sandbox, createBridge, onError };\n }, [content, sandbox, createBridge, onError]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n let frame: RenderedFrame | null = null;\n let bridge: SandboxBridge | null = null;\n let onMessage: ((event: MessageEvent) => void) | null = null;\n\n const { content: liveContent, sandbox: sb } = liveRef.current;\n\n const reportError = (err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n invokeUserCallback(\n \"assistant-ui\",\n \"SandboxHost onError\",\n liveRef.current.onError?.bind(liveRef.current),\n error,\n );\n };\n\n const scf = new SafeContentFrame(sb?.product ?? DEFAULT_PRODUCT, {\n ...(sb?.sandbox !== undefined && { sandbox: sb.sandbox }),\n ...(sb?.useShadowDom !== undefined && { useShadowDom: sb.useShadowDom }),\n ...(sb?.enableBrowserCaching !== undefined && {\n enableBrowserCaching: sb.enableBrowserCaching,\n }),\n ...(sb?.salt !== undefined && { salt: sb.salt }),\n });\n\n const renderOpts =\n sb?.unsafeDocumentWrite !== undefined\n ? { unsafeDocumentWrite: sb.unsafeDocumentWrite }\n : undefined;\n\n scf\n .renderHtml(liveContent.html, container, renderOpts)\n .then((rendered) => {\n if (cancelled) {\n rendered.dispose();\n return;\n }\n frame = rendered;\n\n const hostApi: SandboxHostApi = {\n setHeight: (height) => {\n if (\n typeof height === \"number\" &&\n Number.isFinite(height) &&\n height > 0\n ) {\n setContentHeight(height);\n }\n },\n };\n\n bridge = liveRef.current.createBridge(\n {\n iframe: rendered.iframe,\n origin: rendered.origin,\n sendMessage: rendered.sendMessage,\n },\n hostApi,\n );\n\n // Single owner of the window listener; the cross-origin guard runs\n // here so the bridge only sees frame-validated messages.\n onMessage = (event) => {\n if (!isSandboxFrameMessage(event, rendered)) return;\n bridge?.onMessage(event);\n };\n window.addEventListener(\"message\", onMessage);\n\n // renderHtml resolves at iframe load, which a shim that was never\n // served also reaches, so a completed render is only known once the\n // frame says so. render-timeout is excluded because the shim is\n // running and the guest may still paint, and reporting it would leave\n // a host that renders an error state showing one over a frame that\n // recovers.\n rendered.fullyLoadedPromiseWithTimeout(LOAD_TIMEOUT_MS).catch((err) => {\n if (cancelled) return;\n if (isShimLoadError(err) && err.code === \"render-timeout\") return;\n reportError(err);\n });\n })\n .catch((err) => {\n if (cancelled) return;\n frame?.dispose();\n frame = null;\n reportError(err);\n });\n\n return () => {\n cancelled = true;\n let cleanupFailed = false;\n let cleanupError: unknown;\n const runCleanup = (cleanup: () => void) => {\n try {\n cleanup();\n } catch (error) {\n if (cleanupFailed) {\n console.error(error);\n } else {\n cleanupFailed = true;\n cleanupError = error;\n }\n }\n };\n\n if (onMessage) {\n const listener = onMessage;\n onMessage = null;\n runCleanup(() => window.removeEventListener(\"message\", listener));\n }\n const bridgeToDispose = bridge;\n bridge = null;\n if (bridgeToDispose) runCleanup(() => bridgeToDispose.dispose());\n const frameToDispose = frame;\n frame = null;\n if (frameToDispose) runCleanup(() => frameToDispose.dispose());\n runCleanup(() => setContentHeight(undefined));\n\n if (cleanupFailed) throw cleanupError;\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-init only on contentKey change; live values flow through liveRef\n }, [contentKey]);\n\n const resolvedHeight =\n contentHeight != null ? Math.min(contentHeight, maxHeight) : undefined;\n const mergedStyle =\n resolvedHeight != null\n ? { ...sandbox?.style, height: resolvedHeight }\n : sandbox?.style;\n\n return (\n <div\n {...containerProps}\n ref={containerRef}\n className={sandbox?.className}\n style={mergedStyle}\n />\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useModelContextSnapshot.js","names":["c","_c","useEffect","useState","AssistantClient","Unsubscribe","ModelContextSnapshotSource","empty","T","read","aui","subscribe","onChange","isEqual","previous","next","useModelContextSnapshot","enabled","source","$","t0","snapshot","setSnapshot","t1","t2","shallowEqualRecords","Readonly","Record","keys","Object","length","every","key","hasOwn"],"sources":["../../src/unstable/useModelContextSnapshot.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { AssistantClient } from \"@assistant-ui/store\";\nimport type { Unsubscribe } from \"@assistant-ui/core\";\n\n/**\n * Where a snapshot comes from and what counts as a change to it. Declared once\n * per consumer at module scope: the subscription effect keys on this object, so\n * an inline source without an `isEqual` re-reads itself into a render loop.\n */\nexport type ModelContextSnapshotSource<T> = {\n /** Seeds the snapshot when it starts disabled. */\n readonly empty: T;\n /** Projects the fields the consumer observes out of the live model context. */\n read(aui: AssistantClient): T;\n subscribe(aui: AssistantClient, onChange: () => void): Unsubscribe;\n /**\n * An equal pair keeps the previous reference. Omitted by a consumer that\n * re-derives on every notification, where a caller republishing an unchanged\n * tool set is how it asks to be re-run.\n */\n isEqual?(previous: T, next: T): boolean;\n};\n\n/**\n * `getModelContext()` rebuilds its result on every call, so a projection of the\n * fields a consumer observes is held in state and refreshed on notification\n * rather than read during render. Keeping the previous reference for an equal\n * projection is what stops a notification carrying no observable change from\n * invalidating everything derived from it.\n */\nexport const useModelContextSnapshot = <T>(\n aui: AssistantClient,\n enabled: boolean,\n source: ModelContextSnapshotSource<T>,\n): T => {\n const [snapshot, setSnapshot] = useState(() =>\n enabled ? source.read(aui) : source.empty,\n );\n\n useEffect(() => {\n if (!enabled) return undefined;\n const read = () => {\n const next = source.read(aui);\n setSnapshot((previous) =>\n source.isEqual?.(previous, next) ? previous : next,\n );\n };\n read();\n return source.subscribe(aui, read);\n }, [aui, enabled, source]);\n\n return snapshot;\n};\n\n/** Shallow own-key comparison, for a projection whose values are records. */\nexport const shallowEqualRecords = (\n previous: Readonly<Record<string, unknown>>,\n next: Readonly<Record<string, unknown>>,\n): boolean => {\n const keys = Object.keys(previous);\n if (keys.length !== Object.keys(next).length) return false;\n return keys.every(\n (key) => Object.hasOwn(next, key) && previous[key] === next[key],\n );\n};\n"],"mappings":";;;;;;;;;;;AAgCA,MAAagB,2BAA0BN,KAAAO,SAAAC,WAAA;CAAA,MAAAC,IAAAlB,EAAA,CAAA;CAAA,IAAAmB;CAAA,IAAAD,EAAA,OAAAT,OAAAS,EAAA,OAAAF,WAAAE,EAAA,OAAAD,QAAA;EAKIE,WACvCH,UAAUC,OAAMT,KAAMC,GAAkB,IAAXQ,OAAMX;EAAMY,EAAA,KAAAT;EAAAS,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAD3C,MAAA,CAAAE,UAAAC,eAAgCnB,SAASiB,EAEzC;CAAE,IAAAG;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAT,OAAAS,EAAA,OAAAF,WAAAE,EAAA,OAAAD,QAAA;EAEQK,WAAA;GACR,IAAI,CAACN,SAAO;GACZ,MAAAR,aAAa;IACX,MAAAM,OAAaG,OAAMT,KAAMC,GAAG;IAC5BY,aAAYR,aACVI,OAAML,UAAWC,UAAUC,IAAsB,IAAjDD,WAAAC,IACF;GAAC;GAEHN,KAAK;GAAC,OACCS,OAAMP,UAAWD,KAAKD,IAAI;EAAC;EACjCe,KAAA;GAACd;GAAKO;GAASC;EAAM;EAACC,EAAA,KAAAT;EAAAS,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAVzBjB,UAAUqB,IAUPC,EAAsB;CAAC,OAEnBH;AAAQ;;AAIjB,MAAaI,uBACXX,UACAC,SACY;CACZ,MAAMa,OAAOC,OAAOD,KAAKd,QAAQ;CACjC,IAAIc,KAAKE,WAAWD,OAAOD,KAAKb,IAAI,CAAC,CAACe,QAAQ,OAAO;CACrD,OAAOF,KAAKG,OACTC,QAAQH,OAAOI,OAAOlB,MAAMiB,GAAG,KAAKlB,SAASkB,SAASjB,KAAKiB,IAC9D;AACF"}
1
+ {"version":3,"file":"useModelContextSnapshot.js","names":["c","_c","useEffect","useState","AssistantClient","Unsubscribe","ModelContextSnapshotSource","empty","T","read","aui","subscribe","onChange","isEqual","previous","next","useModelContextSnapshot","enabled","source","$","t0","snapshot","setSnapshot","t1","t2","shallowEqualRecords","Readonly","Record","keys","Object","length","every","key","hasOwn","_c"],"sources":["../../src/unstable/useModelContextSnapshot.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { AssistantClient } from \"@assistant-ui/store\";\nimport type { Unsubscribe } from \"@assistant-ui/core\";\n\n/**\n * Where a snapshot comes from and what counts as a change to it. Declared once\n * per consumer at module scope: the subscription effect keys on this object, so\n * an inline source without an `isEqual` re-reads itself into a render loop.\n */\nexport type ModelContextSnapshotSource<T> = {\n /** Seeds the snapshot when it starts disabled. */\n readonly empty: T;\n /** Projects the fields the consumer observes out of the live model context. */\n read(aui: AssistantClient): T;\n subscribe(aui: AssistantClient, onChange: () => void): Unsubscribe;\n /**\n * An equal pair keeps the previous reference. Omitted by a consumer that\n * re-derives on every notification, where a caller republishing an unchanged\n * tool set is how it asks to be re-run.\n */\n isEqual?(previous: T, next: T): boolean;\n};\n\n/**\n * `getModelContext()` rebuilds its result on every call, so a projection of the\n * fields a consumer observes is held in state and refreshed on notification\n * rather than read during render. Keeping the previous reference for an equal\n * projection is what stops a notification carrying no observable change from\n * invalidating everything derived from it.\n */\nexport const useModelContextSnapshot = <T>(\n aui: AssistantClient,\n enabled: boolean,\n source: ModelContextSnapshotSource<T>,\n): T => {\n const [snapshot, setSnapshot] = useState(() =>\n enabled ? source.read(aui) : source.empty,\n );\n\n useEffect(() => {\n if (!enabled) return undefined;\n const read = () => {\n const next = source.read(aui);\n setSnapshot((previous) =>\n source.isEqual?.(previous, next) ? previous : next,\n );\n };\n read();\n return source.subscribe(aui, read);\n }, [aui, enabled, source]);\n\n return snapshot;\n};\n\n/** Shallow own-key comparison, for a projection whose values are records. */\nexport const shallowEqualRecords = (\n previous: Readonly<Record<string, unknown>>,\n next: Readonly<Record<string, unknown>>,\n): boolean => {\n const keys = Object.keys(previous);\n if (keys.length !== Object.keys(next).length) return false;\n return keys.every(\n (key) => Object.hasOwn(next, key) && previous[key] === next[key],\n );\n};\n"],"mappings":";;;;;;;;;;;AAgCA,MAAagB,2BAA0BN,KAAAO,SAAAC,WAAA;CAAA,MAAAC,IAAAlB,EAAA,CAAA;CAAA,IAAAmB;CAAA,IAAAD,EAAA,OAAAT,OAAAS,EAAA,OAAAF,WAAAE,EAAA,OAAAD,QAAA;EAKIE,WACvCH,UAAUC,OAAMT,KAAMC,GAAkB,IAAXQ,OAAMX;EAAMY,EAAA,KAAAT;EAAAS,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAD3C,MAAA,CAAAE,UAAAC,eAAgCnB,SAASiB,EAEzC;CAAE,IAAAG;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAT,OAAAS,EAAA,OAAAF,WAAAE,EAAA,OAAAD,QAAA;EAEQK,WAAA;GACR,IAAI,CAACN,SAAO;GACZ,MAAAR,aAAa;IACX,MAAAM,OAAaG,OAAMT,KAAMC,GAAG;IAC5BY,aAAYR,aACVI,OAAML,UAAWC,UAAUC,IAAsB,IAAjDD,WAAAC,IACF;GAAC;GAEHN,KAAK;GAAC,OACCS,OAAMP,UAAWD,KAAKD,IAAI;EAAC;EACjCe,KAAA;GAACd;GAAKO;GAASC;EAAM;EAACC,EAAA,KAAAT;EAAAS,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAVzBjB,UAAUqB,IAUPC,EAAsB;CAAC,OAEnBH;AAAQ;;AAIjB,MAAaI,uBACXX,UACAC,SACY;CACZ,MAAMa,OAAOC,OAAOD,KAAKd,QAAQ;CACjC,IAAIc,KAAKE,WAAWD,OAAOD,KAAKb,IAAI,CAAC,CAACe,QAAQ,OAAO;CACrD,OAAOF,KAAKG,OACTC,QAAQH,OAAOI,OAAOlB,MAAMiB,GAAG,KAAKlB,SAASkB,SAASjB,KAAKiB,IAC9D;AACF"}
@@ -6,6 +6,7 @@ export type WebMcpRegistrationProps = {
6
6
  /** Re-registers when it changes; an execute-only edit reads through instead. */
7
7
  signature: string;
8
8
  tool: Tool<any, any>;
9
+ getCurrentTool: (name: string) => Tool<any, any> | undefined;
9
10
  };
10
11
  export declare const WebMcpRegistrationResource: import("@assistant-ui/tap").Resource<string | null, [WebMcpRegistrationProps]>;
11
12
  //# sourceMappingURL=WebMcpRegistrationResource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WebMcpRegistrationResource.d.ts","sourceRoot":"","sources":["../../../src/unstable/webmcp/WebMcpRegistrationResource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,yBAAsB;AAEhD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;CACtB,CAAC;AA+EF,eAAO,MAAM,0BAA0B,gFAAkC,CAAC"}
1
+ {"version":3,"file":"WebMcpRegistrationResource.d.ts","sourceRoot":"","sources":["../../../src/unstable/webmcp/WebMcpRegistrationResource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,yBAAsB;AAEhD,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;CAC9D,CAAC;AA+EF,eAAO,MAAM,0BAA0B,gFAAkC,CAAC"}
@@ -6,28 +6,13 @@ import { resource } from "@assistant-ui/tap";
6
6
  const notPermitted = (error) => error?.name === "NotAllowedError";
7
7
  const notPermittedMessage = (name) => `[assistant-ui] WebMCP registration for tool "${name}" was not permitted; the page's tools permission is disabled.`;
8
8
  const useWebMcpRegistration = (t0) => {
9
- const $ = c(12);
10
- const { host, name, signature, tool } = t0;
9
+ const $ = c(11);
10
+ const { host, name, signature, tool, getCurrentTool } = t0;
11
11
  const [refused, setRefused] = useState(false);
12
- const toolRef = useRef(tool);
12
+ const fallbackToolRef = useRef(tool);
13
13
  let t1;
14
- let t2;
15
- if ($[0] !== tool) {
14
+ if ($[0] !== getCurrentTool || $[1] !== host || $[2] !== name || $[3] !== refused) {
16
15
  t1 = () => {
17
- toolRef.current = tool;
18
- };
19
- t2 = [tool];
20
- $[0] = tool;
21
- $[1] = t1;
22
- $[2] = t2;
23
- } else {
24
- t1 = $[1];
25
- t2 = $[2];
26
- }
27
- useEffect(t1, t2);
28
- let t3;
29
- if ($[3] !== host || $[4] !== name || $[5] !== refused) {
30
- t3 = () => {
31
16
  if (refused) return;
32
17
  const lifecycle = new AbortController();
33
18
  let live = true;
@@ -39,9 +24,9 @@ const useWebMcpRegistration = (t0) => {
39
24
  console.warn(message, error);
40
25
  };
41
26
  try {
42
- dispose = host.registerTool(toWebMcpTool(name, () => toolRef.current, lifecycle.signal), (error_1) => refuse(notPermitted(error_1) ? notPermittedMessage(name) : `[assistant-ui] WebMCP registration for tool "${name}" failed (name may already be registered).`, error_1));
43
- } catch (t4) {
44
- const error_0 = t4;
27
+ dispose = host.registerTool(toWebMcpTool(name, () => getCurrentTool(name) ?? fallbackToolRef.current, lifecycle.signal), (error_1) => refuse(notPermitted(error_1) ? notPermittedMessage(name) : `[assistant-ui] WebMCP registration for tool "${name}" failed (name may already be registered).`, error_1));
28
+ } catch (t2) {
29
+ const error_0 = t2;
45
30
  refuse(notPermitted(error_0) ? notPermittedMessage(name) : `[assistant-ui] Skipping WebMCP registration for tool "${name}": registerTool failed (name may already be registered).`, error_0);
46
31
  return;
47
32
  }
@@ -50,32 +35,35 @@ const useWebMcpRegistration = (t0) => {
50
35
  lifecycle.abort();
51
36
  try {
52
37
  dispose();
53
- } catch (t5) {
54
- const error_2 = t5;
38
+ } catch (t3) {
39
+ const error_2 = t3;
55
40
  console.warn(`[assistant-ui] Unregistering WebMCP tool "${name}" failed.`, error_2);
56
41
  }
57
42
  };
58
43
  };
59
- $[3] = host;
60
- $[4] = name;
61
- $[5] = refused;
62
- $[6] = t3;
63
- } else t3 = $[6];
64
- let t4;
65
- if ($[7] !== host || $[8] !== name || $[9] !== refused || $[10] !== signature) {
66
- t4 = [
44
+ $[0] = getCurrentTool;
45
+ $[1] = host;
46
+ $[2] = name;
47
+ $[3] = refused;
48
+ $[4] = t1;
49
+ } else t1 = $[4];
50
+ let t2;
51
+ if ($[5] !== getCurrentTool || $[6] !== host || $[7] !== name || $[8] !== refused || $[9] !== signature) {
52
+ t2 = [
53
+ getCurrentTool,
67
54
  host,
68
55
  name,
69
56
  signature,
70
57
  refused
71
58
  ];
72
- $[7] = host;
73
- $[8] = name;
74
- $[9] = refused;
75
- $[10] = signature;
76
- $[11] = t4;
77
- } else t4 = $[11];
78
- useEffect(t3, t4);
59
+ $[5] = getCurrentTool;
60
+ $[6] = host;
61
+ $[7] = name;
62
+ $[8] = refused;
63
+ $[9] = signature;
64
+ $[10] = t2;
65
+ } else t2 = $[10];
66
+ useEffect(t1, t2);
79
67
  return refused ? null : name;
80
68
  };
81
69
  const WebMcpRegistrationResource = resource(useWebMcpRegistration);
@@ -1 +1 @@
1
- {"version":3,"file":"WebMcpRegistrationResource.js","names":["useEffect","useRef","useState","resource","Tool","toWebMcpTool","WebMcpHost","WebMcpRegistrationProps","host","name","signature","tool","notPermitted","error","notPermittedMessage","useWebMcpRegistration","t0","$","_c","refused","setRefused","toolRef","t1","t2","current","t3","lifecycle","AbortController","live","dispose","refuse","message","console","warn","registerTool","signal","error_1","t4","abort","t5","WebMcpRegistrationResource"],"sources":["../../../src/unstable/webmcp/WebMcpRegistrationResource.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { Tool } from \"assistant-stream\";\nimport { toWebMcpTool } from \"./convertTools\";\nimport type { WebMcpHost } from \"./webmcp-host\";\n\nexport type WebMcpRegistrationProps = {\n host: WebMcpHost;\n name: string;\n /** Re-registers when it changes; an execute-only edit reads through instead. */\n signature: string;\n tool: Tool<any, any>;\n};\n\n// The explainer specifies NotAllowedError for a page whose tools permission is\n// off, which a cross-origin iframe without allow=\"tools\" reaches routinely. It\n// documents no rejection for a name already taken, so that stays a hedge.\nconst notPermitted = (error: unknown) =>\n (error as { name?: unknown } | null | undefined)?.name === \"NotAllowedError\";\n\nconst notPermittedMessage = (name: string) =>\n `[assistant-ui] WebMCP registration for tool \"${name}\" was not permitted; the page's tools permission is disabled.`;\n\nconst useWebMcpRegistration = ({\n host,\n name,\n signature,\n tool,\n}: WebMcpRegistrationProps): string | null => {\n // A refused name is remembered for as long as the tool stays in the model\n // context, so a permanent collision warns once rather than on every sync.\n const [refused, setRefused] = useState(false);\n const toolRef = useRef(tool);\n // Commit phase, so an abandoned render cannot hand the host a tool the tree\n // never committed.\n useEffect(() => {\n toolRef.current = tool;\n }, [tool]);\n\n useEffect(() => {\n if (refused) return undefined;\n\n const lifecycle = new AbortController();\n let live = true;\n let dispose: (() => void) | undefined;\n\n const refuse = (message: string, error: unknown) => {\n if (!live) return;\n live = false;\n setRefused(true);\n console.warn(message, error);\n };\n\n try {\n dispose = host.registerTool(\n toWebMcpTool(name, () => toolRef.current, lifecycle.signal),\n (error) =>\n refuse(\n notPermitted(error)\n ? notPermittedMessage(name)\n : `[assistant-ui] WebMCP registration for tool \"${name}\" failed (name may already be registered).`,\n error,\n ),\n );\n } catch (error) {\n refuse(\n notPermitted(error)\n ? notPermittedMessage(name)\n : `[assistant-ui] Skipping WebMCP registration for tool \"${name}\": registerTool failed (name may already be registered).`,\n error,\n );\n return undefined;\n }\n\n return () => {\n live = false;\n lifecycle.abort();\n try {\n dispose();\n } catch (error) {\n console.warn(\n `[assistant-ui] Unregistering WebMCP tool \"${name}\" failed.`,\n error,\n );\n }\n };\n }, [host, name, signature, refused]);\n\n return refused ? null : name;\n};\n\nexport const WebMcpRegistrationResource = resource(useWebMcpRegistration);\n"],"mappings":";;;;;AAiBA,MAAMY,gBAAgBC,UACnBA,OAAiDJ,SAAS;AAE7D,MAAMK,uBAAuBL,SAC3B,gDAAgDA,KAAI;AAEtD,MAAMM,yBAAwBC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAV,MAAAC,MAAAC,WAAAC,SAAAK;CAQ7B,MAAA,CAAAG,SAAAC,cAA8BlB,SAAS,KAAK;CAC5C,MAAAmB,UAAgBpB,OAAOU,IAAI;CAAE,IAAAW;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAN,MAAA;EAGnBW,WAAA;GACRD,QAAOG,UAAWb;EAAH;EACdY,KAAA,CAACZ,IAAI;EAACM,EAAA,KAAAN;EAAAM,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAD,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAFTjB,UAAUsB,IAEPC,EAAM;CAAC,IAAAE;CAAA,IAAAR,EAAA,OAAAT,QAAAS,EAAA,OAAAR,QAAAQ,EAAA,OAAAE,SAAA;EAEAM,WAAA;GACR,IAAIN,SAAO;GAEX,MAAAO,YAAkB,IAAIC,gBAAgB;GACtC,IAAAC,OAAW;GACPC,IAAAA;GAEJ,MAAAC,UAAeC,SAAAlB,UAAA;IACb,IAAI,CAACe,MAAI;IACTA,OAAOA;IACPR,WAAW,IAAI;IACfY,QAAOC,KAAMF,SAASlB,KAAK;GAAC;GAG9B,IAAA;IACEgB,UAAUrB,KAAI0B,aACZ7B,aAAaI,YAAYY,QAAOG,SAAUE,UAASS,MAAO,IAC1DC,YACEN,OACElB,aAAaC,OAEsF,IAD/FC,oBAAoBL,IAC2E,IAFnG,gDAEoDA,KAAI,6CACxDI,OACF,CACJ;GATO,SAAAwB,IAAA;IAUAxB,MAAAA,UAAAA;IACPiB,OACElB,aAAaC,OAE6G,IADtHC,oBAAoBL,IACkG,IAF1H,yDAE6DA,KAAI,2DACjEI,OACF;IAAC;GAAA;GAEF,aAEM;IACLe,OAAOA;IACPF,UAASY,MAAO;IAChB,IAAA;KACET,QAAQ;IAAC,SAAAU,IAAA;KACF1B,MAAAA,UAAAA;KACPmB,QAAOC,KACL,6CAA6CxB,KAAI,YACjDI,OACF;IAAC;GACF;EACF;EACFI,EAAA,KAAAT;EAAAS,EAAA,KAAAR;EAAAQ,EAAA,KAAAE;EAAAF,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,IAAAoB;CAAA,IAAApB,EAAA,OAAAT,QAAAS,EAAA,OAAAR,QAAAQ,EAAA,OAAAE,WAAAF,EAAA,QAAAP,WAAA;EAAE2B,KAAA;GAAC7B;GAAMC;GAAMC;GAAWS;EAAO;EAACF,EAAA,KAAAT;EAAAS,EAAA,KAAAR;EAAAQ,EAAA,KAAAE;EAAAF,EAAA,MAAAP;EAAAO,EAAA,MAAAoB;CAAA,OAAAA,KAAApB,EAAA;CA/CnCjB,UAAUyB,IA+CPY,EAAgC;CAAC,OAE7BlB,UAAA,OAAAV;AAAqB;AAG9B,MAAa+B,6BAA6BrC,SAASY,qBAAqB"}
1
+ {"version":3,"file":"WebMcpRegistrationResource.js","names":["useEffect","useRef","useState","resource","Tool","toWebMcpTool","WebMcpHost","WebMcpRegistrationProps","host","name","signature","tool","getCurrentTool","notPermitted","error","notPermittedMessage","useWebMcpRegistration","t0","$","_c","refused","setRefused","fallbackToolRef","t1","lifecycle","AbortController","live","dispose","refuse","message","console","warn","registerTool","current","signal","error_1","t2","abort","t3","WebMcpRegistrationResource","_c"],"sources":["../../../src/unstable/webmcp/WebMcpRegistrationResource.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { Tool } from \"assistant-stream\";\nimport { toWebMcpTool } from \"./convertTools\";\nimport type { WebMcpHost } from \"./webmcp-host\";\n\nexport type WebMcpRegistrationProps = {\n host: WebMcpHost;\n name: string;\n /** Re-registers when it changes; an execute-only edit reads through instead. */\n signature: string;\n tool: Tool<any, any>;\n getCurrentTool: (name: string) => Tool<any, any> | undefined;\n};\n\n// The explainer specifies NotAllowedError for a page whose tools permission is\n// off, which a cross-origin iframe without allow=\"tools\" reaches routinely. It\n// documents no rejection for a name already taken, so that stays a hedge.\nconst notPermitted = (error: unknown) =>\n (error as { name?: unknown } | null | undefined)?.name === \"NotAllowedError\";\n\nconst notPermittedMessage = (name: string) =>\n `[assistant-ui] WebMCP registration for tool \"${name}\" was not permitted; the page's tools permission is disabled.`;\n\nconst useWebMcpRegistration = ({\n host,\n name,\n signature,\n tool,\n getCurrentTool,\n}: WebMcpRegistrationProps): string | null => {\n // A refused name is remembered for as long as the tool stays in the model\n // context, so a permanent collision warns once rather than on every sync.\n const [refused, setRefused] = useState(false);\n const fallbackToolRef = useRef(tool);\n\n useEffect(() => {\n if (refused) return undefined;\n\n const lifecycle = new AbortController();\n let live = true;\n let dispose: (() => void) | undefined;\n\n const refuse = (message: string, error: unknown) => {\n if (!live) return;\n live = false;\n setRefused(true);\n console.warn(message, error);\n };\n\n try {\n dispose = host.registerTool(\n toWebMcpTool(\n name,\n () => getCurrentTool(name) ?? fallbackToolRef.current,\n lifecycle.signal,\n ),\n (error) =>\n refuse(\n notPermitted(error)\n ? notPermittedMessage(name)\n : `[assistant-ui] WebMCP registration for tool \"${name}\" failed (name may already be registered).`,\n error,\n ),\n );\n } catch (error) {\n refuse(\n notPermitted(error)\n ? notPermittedMessage(name)\n : `[assistant-ui] Skipping WebMCP registration for tool \"${name}\": registerTool failed (name may already be registered).`,\n error,\n );\n return undefined;\n }\n\n return () => {\n live = false;\n lifecycle.abort();\n try {\n dispose();\n } catch (error) {\n console.warn(\n `[assistant-ui] Unregistering WebMCP tool \"${name}\" failed.`,\n error,\n );\n }\n };\n }, [getCurrentTool, host, name, signature, refused]);\n\n return refused ? null : name;\n};\n\nexport const WebMcpRegistrationResource = resource(useWebMcpRegistration);\n"],"mappings":";;;;;AAkBA,MAAMa,gBAAgBC,UACnBA,OAAiDL,SAAS;AAE7D,MAAMM,uBAAuBN,SAC3B,gDAAgDA,KAAI;AAEtD,MAAMO,yBAAwBC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAX,MAAAC,MAAAC,WAAAC,MAAAC,mBAAAK;CAS7B,MAAA,CAAAG,SAAAC,cAA8BnB,SAAS,KAAK;CAC5C,MAAAoB,kBAAwBrB,OAAOU,IAAI;CAAE,IAAAY;CAAA,IAAAL,EAAA,OAAAN,kBAAAM,EAAA,OAAAV,QAAAU,EAAA,OAAAT,QAAAS,EAAA,OAAAE,SAAA;EAE3BG,WAAA;GACR,IAAIH,SAAO;GAEX,MAAAI,YAAkB,IAAIC,gBAAgB;GACtC,IAAAC,OAAW;GACPC,IAAAA;GAEJ,MAAAC,UAAeC,SAAAf,UAAA;IACb,IAAI,CAACY,MAAI;IACTA,OAAOA;IACPL,WAAW,IAAI;IACfS,QAAOC,KAAMF,SAASf,KAAK;GAAC;GAG9B,IAAA;IACEa,UAAUnB,KAAIwB,aACZ3B,aACEI,YACMG,eAAeH,IAA+B,KAAtBa,gBAAeW,SAC7CT,UAASU,MACX,IACAC,YACEP,OACEf,aAAaC,OAEsF,IAD/FC,oBAAoBN,IAC2E,IAFnG,gDAEoDA,KAAI,6CACxDK,OACF,CACJ;GAbO,SAAAsB,IAAA;IAcAtB,MAAAA,UAAAA;IACPc,OACEf,aAAaC,OAE6G,IADtHC,oBAAoBN,IACkG,IAF1H,yDAE6DA,KAAI,2DACjEK,OACF;IAAC;GAAA;GAEF,aAEM;IACLY,OAAOA;IACPF,UAASa,MAAO;IAChB,IAAA;KACEV,QAAQ;IAAC,SAAAW,IAAA;KACFxB,MAAAA,UAAAA;KACPgB,QAAOC,KACL,6CAA6CtB,KAAI,YACjDK,OACF;IAAC;GACF;EACF;EACFI,EAAA,KAAAN;EAAAM,EAAA,KAAAV;EAAAU,EAAA,KAAAT;EAAAS,EAAA,KAAAE;EAAAF,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,IAAAkB;CAAA,IAAAlB,EAAA,OAAAN,kBAAAM,EAAA,OAAAV,QAAAU,EAAA,OAAAT,QAAAS,EAAA,OAAAE,WAAAF,EAAA,OAAAR,WAAA;EAAE0B,KAAA;GAACxB;GAAgBJ;GAAMC;GAAMC;GAAWU;EAAO;EAACF,EAAA,KAAAN;EAAAM,EAAA,KAAAV;EAAAU,EAAA,KAAAT;EAAAS,EAAA,KAAAE;EAAAF,EAAA,KAAAR;EAAAQ,EAAA,MAAAkB;CAAA,OAAAA,KAAAlB,EAAA;CAnDnDlB,UAAUuB,IAmDPa,EAAgD;CAAC,OAE7ChB,UAAA,OAAAX;AAAqB;AAG9B,MAAa8B,6BAA6BpC,SAASa,qBAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useWebMcpProvider.d.ts","sourceRoot":"","sources":["../../../src/unstable/webmcp/useWebMcpProvider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAU7C,MAAM,MAAM,8BAA8B,GAAG;IAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;IACjC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AA4FF;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAS,8BAAmC,KAC3C,6BAuBF,CAAC"}
1
+ {"version":3,"file":"useWebMcpProvider.d.ts","sourceRoot":"","sources":["../../../src/unstable/webmcp/useWebMcpProvider.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAU7C,MAAM,MAAM,8BAA8B,GAAG;IAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;IACjC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AA8FF;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAS,8BAAmC,KAC3C,6BAyCF,CAAC"}
@@ -4,7 +4,7 @@ import { getDefaultWebMcpHost } from "./webmcp-host.js";
4
4
  import { defaultWebMcpFilter, toWebMcpInputSchema } from "./convertTools.js";
5
5
  import { WebMcpRegistrationResource } from "./WebMcpRegistrationResource.js";
6
6
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
7
- import { useEffect, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
7
+ import { useCallback, useEffect, useInsertionEffect, useRef, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
8
8
  import { useAui } from "@assistant-ui/store";
9
9
  import { useResources, useTapRoot, withKey } from "@assistant-ui/tap";
10
10
  import { shallowEqual } from "@assistant-ui/store/internal";
@@ -38,11 +38,10 @@ const useStableNames = (names) => {
38
38
  return next;
39
39
  };
40
40
  const useWebMcpRegistry = (t0) => {
41
- const $ = c(4);
42
- const { aui, host, filter } = t0;
43
- const tools = useModelContextSnapshot(aui, host.available, modelContextToolSource);
41
+ const $ = c(5);
42
+ const { host, filter, tools, getCurrentTool } = t0;
44
43
  let elements;
45
- if ($[0] !== filter || $[1] !== host || $[2] !== tools) {
44
+ if ($[0] !== filter || $[1] !== getCurrentTool || $[2] !== host || $[3] !== tools) {
46
45
  elements = [];
47
46
  for (const [name, tool] of Object.entries(tools)) try {
48
47
  if (!filter(name, tool)) continue;
@@ -51,12 +50,14 @@ const useWebMcpRegistry = (t0) => {
51
50
  host,
52
51
  name,
53
52
  signature,
54
- tool
53
+ tool,
54
+ getCurrentTool
55
55
  }), [
56
56
  host,
57
57
  name,
58
58
  signature,
59
- tool
59
+ tool,
60
+ getCurrentTool
60
61
  ]));
61
62
  } catch (t1) {
62
63
  const error = t1;
@@ -65,10 +66,11 @@ const useWebMcpRegistry = (t0) => {
65
66
  console.warn(`[assistant-ui] Skipping WebMCP registration for tool "${name}": filter or schema conversion failed.`, error);
66
67
  }
67
68
  $[0] = filter;
68
- $[1] = host;
69
- $[2] = tools;
70
- $[3] = elements;
71
- } else elements = $[3];
69
+ $[1] = getCurrentTool;
70
+ $[2] = host;
71
+ $[3] = tools;
72
+ $[4] = elements;
73
+ } else elements = $[4];
72
74
  return useStableNames(useResources(elements));
73
75
  };
74
76
  /**
@@ -83,11 +85,18 @@ const unstable_useWebMcpProvider = (options = {}) => {
83
85
  const aui = useAui();
84
86
  const [host] = useState(getDefaultWebMcpHost);
85
87
  const filter = options.filter ?? defaultWebMcpFilter;
88
+ const tools = useModelContextSnapshot(aui, host.available, modelContextToolSource);
89
+ const currentToolsRef = useRef(tools);
90
+ useInsertionEffect(() => {
91
+ currentToolsRef.current = tools;
92
+ }, [tools]);
93
+ const getCurrentTool = useCallback((name) => currentToolsRef.current[name], []);
86
94
  const root = useTapRoot(function WebMcpProviderRoot() {
87
95
  return useWebMcpRegistry({
88
- aui,
89
96
  host,
90
- filter
97
+ filter,
98
+ tools,
99
+ getCurrentTool
91
100
  });
92
101
  });
93
102
  const registeredToolNames = useSyncExternalStore(root.subscribe, root.getValue, () => EMPTY_NAMES);
@@ -1 +1 @@
1
- {"version":3,"file":"useWebMcpProvider.js","names":["c","_c","useEffect","useState","useSyncExternalStore","useResources","useTapRoot","withKey","useAui","AssistantClient","Tool","getDefaultWebMcpHost","WebMcpHost","defaultWebMcpFilter","toWebMcpInputSchema","WebMcpRegistrationResource","shallowEqual","useModelContextSnapshot","ModelContextSnapshotSource","Unstable_WebMcpProviderOptions","filter","name","tool","Unstable_WebMcpProviderResult","status","registeredToolNames","EMPTY_NAMES","Object","freeze","EMPTY_TOOLS","Record","warned","WeakSet","signatures","WeakMap","description","signature","signatureOf","cached","get","JSON","stringify","set","NO_SUBSCRIPTION","modelContextToolSource","empty","read","aui","modelContext","getModelContext","tools","subscribe","onChange","useStableNames","names","cell","next","sort","previous","useWebMcpRegistry","t0","$","host","available","elements","entries","push","t1","error","has","add","console","warn","unstable_useWebMcpProvider","options","root","WebMcpProviderRoot","getValue","published","setPublished"],"sources":["../../../src/unstable/webmcp/useWebMcpProvider.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, useSyncExternalStore } from \"react\";\nimport { useResources, useTapRoot, withKey } from \"@assistant-ui/tap\";\nimport { useAui, type AssistantClient } from \"@assistant-ui/store\";\nimport type { Tool } from \"assistant-stream\";\nimport { getDefaultWebMcpHost, type WebMcpHost } from \"./webmcp-host\";\nimport { defaultWebMcpFilter, toWebMcpInputSchema } from \"./convertTools\";\nimport { WebMcpRegistrationResource } from \"./WebMcpRegistrationResource\";\nimport { shallowEqual } from \"@assistant-ui/store/internal\";\nimport {\n useModelContextSnapshot,\n type ModelContextSnapshotSource,\n} from \"../useModelContextSnapshot\";\n\nexport type Unstable_WebMcpProviderOptions = {\n filter?: (name: string, tool: Tool<any, any>) => boolean;\n};\n\nexport type Unstable_WebMcpProviderResult = {\n status: \"unsupported\" | \"active\";\n registeredToolNames: readonly string[];\n};\n\nconst EMPTY_NAMES: readonly string[] = Object.freeze([]);\nconst EMPTY_TOOLS: Record<string, Tool<any, any>> = Object.freeze({});\n\n// The description is re-read on every sync so mutating it in place is\n// observed; the schema is converted only when the tool object itself changes.\n// Keyed on the tool so a schema or filter that throws warns once instead of\n// on every model-context notify.\nconst warned = new WeakSet<Tool<any, any>>();\n\nconst signatures = new WeakMap<\n Tool<any, any>,\n { description: string | undefined; signature: string }\n>();\n\nconst signatureOf = (tool: Tool<any, any>) => {\n const cached = signatures.get(tool);\n if (cached && cached.description === tool.description)\n return cached.signature;\n const signature = `${tool.description ?? \"\"}\\u0000${JSON.stringify(\n toWebMcpInputSchema(tool),\n )}`;\n signatures.set(tool, { description: tool.description, signature });\n return signature;\n};\n\nconst NO_SUBSCRIPTION = () => {};\n\n// No `isEqual`: a caller republishing an unchanged tool set is how it asks for\n// a re-sync, which is what re-attempts a tool whose filter has stopped throwing\n// and what picks up a description edited in place on a stable tool object.\nconst modelContextToolSource: ModelContextSnapshotSource<\n Record<string, Tool<any, any>>\n> = {\n empty: EMPTY_TOOLS,\n read: (aui) => aui.modelContext.getModelContext().tools ?? EMPTY_TOOLS,\n subscribe: (aui, onChange) =>\n aui.modelContext.subscribe?.(onChange) ?? NO_SUBSCRIPTION,\n};\n\nconst useStableNames = (names: readonly (string | null)[]) => {\n const [cell] = useState(() => ({ names: EMPTY_NAMES }));\n const next = names.filter((name): name is string => name !== null).sort();\n const previous = cell.names;\n if (shallowEqual(previous, next)) {\n return previous;\n }\n cell.names = next;\n return next;\n};\n\nconst useWebMcpRegistry = ({\n aui,\n host,\n filter,\n}: {\n aui: AssistantClient;\n host: WebMcpHost;\n filter: (name: string, tool: Tool<any, any>) => boolean;\n}) => {\n const tools = useModelContextSnapshot(\n aui,\n host.available,\n modelContextToolSource,\n );\n\n const elements = [];\n for (const [name, tool] of Object.entries(tools)) {\n try {\n if (!filter(name, tool)) continue;\n const signature = signatureOf(tool);\n elements.push(\n withKey(\n name,\n WebMcpRegistrationResource({ host, name, signature, tool }),\n [host, name, signature, tool],\n ),\n );\n } catch (error) {\n if (warned.has(tool)) continue;\n warned.add(tool);\n console.warn(\n `[assistant-ui] Skipping WebMCP registration for tool \"${name}\": filter or schema conversion failed.`,\n error,\n );\n }\n }\n\n return useStableNames(useResources(elements));\n};\n\n/**\n * Publishes the frontend tools in the model context to a WebMCP-capable\n * browser, so the user's own browser agent can call them.\n *\n * Returns `status: \"unsupported\"` when the page exposes no\n * `document.modelContext` (or `navigator.modelContext`), and the sorted names\n * of the tools currently registered with the host.\n */\nexport const unstable_useWebMcpProvider = (\n options: Unstable_WebMcpProviderOptions = {},\n): Unstable_WebMcpProviderResult => {\n const aui = useAui();\n const [host] = useState(getDefaultWebMcpHost);\n const filter = options.filter ?? defaultWebMcpFilter;\n\n const root = useTapRoot(function WebMcpProviderRoot() {\n return useWebMcpRegistry({ aui, host, filter });\n });\n const registeredToolNames = useSyncExternalStore(\n root.subscribe,\n root.getValue,\n () => EMPTY_NAMES,\n );\n\n const [published, setPublished] = useState(false);\n useEffect(() => {\n if (host.available) setPublished(true);\n }, [host]);\n\n return {\n status: published ? \"active\" : \"unsupported\",\n registeredToolNames,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useWebMcpProvider.js","names":["c","_c","useCallback","useEffect","useInsertionEffect","useRef","useState","useSyncExternalStore","useResources","useTapRoot","withKey","useAui","Tool","getDefaultWebMcpHost","WebMcpHost","defaultWebMcpFilter","toWebMcpInputSchema","WebMcpRegistrationResource","shallowEqual","useModelContextSnapshot","ModelContextSnapshotSource","Unstable_WebMcpProviderOptions","filter","name","tool","Unstable_WebMcpProviderResult","status","registeredToolNames","EMPTY_NAMES","Object","freeze","EMPTY_TOOLS","Record","warned","WeakSet","signatures","WeakMap","description","signature","signatureOf","cached","get","JSON","stringify","set","NO_SUBSCRIPTION","modelContextToolSource","empty","read","aui","modelContext","getModelContext","tools","subscribe","onChange","useStableNames","names","cell","next","sort","previous","useWebMcpRegistry","t0","$","host","getCurrentTool","elements","entries","push","t1","error","has","add","console","warn","unstable_useWebMcpProvider","options","available","currentToolsRef","current","root","WebMcpProviderRoot","getValue","published","setPublished","_c"],"sources":["../../../src/unstable/webmcp/useWebMcpProvider.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useInsertionEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { useResources, useTapRoot, withKey } from \"@assistant-ui/tap\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { Tool } from \"assistant-stream\";\nimport { getDefaultWebMcpHost, type WebMcpHost } from \"./webmcp-host\";\nimport { defaultWebMcpFilter, toWebMcpInputSchema } from \"./convertTools\";\nimport { WebMcpRegistrationResource } from \"./WebMcpRegistrationResource\";\nimport { shallowEqual } from \"@assistant-ui/store/internal\";\nimport {\n useModelContextSnapshot,\n type ModelContextSnapshotSource,\n} from \"../useModelContextSnapshot\";\n\nexport type Unstable_WebMcpProviderOptions = {\n filter?: (name: string, tool: Tool<any, any>) => boolean;\n};\n\nexport type Unstable_WebMcpProviderResult = {\n status: \"unsupported\" | \"active\";\n registeredToolNames: readonly string[];\n};\n\nconst EMPTY_NAMES: readonly string[] = Object.freeze([]);\nconst EMPTY_TOOLS: Record<string, Tool<any, any>> = Object.freeze({});\n\n// The description is re-read on every sync so mutating it in place is\n// observed; the schema is converted only when the tool object itself changes.\n// Keyed on the tool so a schema or filter that throws warns once instead of\n// on every model-context notify.\nconst warned = new WeakSet<Tool<any, any>>();\n\nconst signatures = new WeakMap<\n Tool<any, any>,\n { description: string | undefined; signature: string }\n>();\n\nconst signatureOf = (tool: Tool<any, any>) => {\n const cached = signatures.get(tool);\n if (cached && cached.description === tool.description)\n return cached.signature;\n const signature = `${tool.description ?? \"\"}\\u0000${JSON.stringify(\n toWebMcpInputSchema(tool),\n )}`;\n signatures.set(tool, { description: tool.description, signature });\n return signature;\n};\n\nconst NO_SUBSCRIPTION = () => {};\n\n// No `isEqual`: a caller republishing an unchanged tool set is how it asks for\n// a re-sync, which is what re-attempts a tool whose filter has stopped throwing\n// and what picks up a description edited in place on a stable tool object.\nconst modelContextToolSource: ModelContextSnapshotSource<\n Record<string, Tool<any, any>>\n> = {\n empty: EMPTY_TOOLS,\n read: (aui) => aui.modelContext.getModelContext().tools ?? EMPTY_TOOLS,\n subscribe: (aui, onChange) =>\n aui.modelContext.subscribe?.(onChange) ?? NO_SUBSCRIPTION,\n};\n\nconst useStableNames = (names: readonly (string | null)[]) => {\n const [cell] = useState(() => ({ names: EMPTY_NAMES }));\n const next = names.filter((name): name is string => name !== null).sort();\n const previous = cell.names;\n if (shallowEqual(previous, next)) {\n return previous;\n }\n cell.names = next;\n return next;\n};\n\nconst useWebMcpRegistry = ({\n host,\n filter,\n tools,\n getCurrentTool,\n}: {\n host: WebMcpHost;\n filter: (name: string, tool: Tool<any, any>) => boolean;\n tools: Record<string, Tool<any, any>>;\n getCurrentTool: (name: string) => Tool<any, any> | undefined;\n}) => {\n const elements = [];\n for (const [name, tool] of Object.entries(tools)) {\n try {\n if (!filter(name, tool)) continue;\n const signature = signatureOf(tool);\n elements.push(\n withKey(\n name,\n WebMcpRegistrationResource({\n host,\n name,\n signature,\n tool,\n getCurrentTool,\n }),\n [host, name, signature, tool, getCurrentTool],\n ),\n );\n } catch (error) {\n if (warned.has(tool)) continue;\n warned.add(tool);\n console.warn(\n `[assistant-ui] Skipping WebMCP registration for tool \"${name}\": filter or schema conversion failed.`,\n error,\n );\n }\n }\n\n return useStableNames(useResources(elements));\n};\n\n/**\n * Publishes the frontend tools in the model context to a WebMCP-capable\n * browser, so the user's own browser agent can call them.\n *\n * Returns `status: \"unsupported\"` when the page exposes no\n * `document.modelContext` (or `navigator.modelContext`), and the sorted names\n * of the tools currently registered with the host.\n */\nexport const unstable_useWebMcpProvider = (\n options: Unstable_WebMcpProviderOptions = {},\n): Unstable_WebMcpProviderResult => {\n const aui = useAui();\n const [host] = useState(getDefaultWebMcpHost);\n const filter = options.filter ?? defaultWebMcpFilter;\n const tools = useModelContextSnapshot(\n aui,\n host.available,\n modelContextToolSource,\n );\n const currentToolsRef = useRef(tools);\n useInsertionEffect(() => {\n currentToolsRef.current = tools;\n }, [tools]);\n const getCurrentTool = useCallback(\n (name: string) => currentToolsRef.current[name],\n [],\n );\n\n const root = useTapRoot(function WebMcpProviderRoot() {\n return useWebMcpRegistry({\n host,\n filter,\n tools,\n getCurrentTool,\n });\n });\n const registeredToolNames = useSyncExternalStore(\n root.subscribe,\n root.getValue,\n () => EMPTY_NAMES,\n );\n\n const [published, setPublished] = useState(false);\n useEffect(() => {\n if (host.available) setPublished(true);\n }, [host]);\n\n return {\n status: published ? \"active\" : \"unsupported\",\n registeredToolNames,\n };\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Primitive.js","names":["ComponentProps","ComponentPropsWithoutRef","ComponentRef","ElementType","ForwardRefExoticComponent","PropsWithoutRef","ReactElement","ReactNode","RefAttributes","cloneElement","forwardRef","isValidElement","Primitive","RadixPrimitive","Slot","NODES","const","PrimitiveNode","WithRenderPropProps","T","render","PrimitiveProps","E","WithRenderPropRuntimeProps","asChild","children","PrimitiveRef","composeRenderElement","undefined","props","renderSlot","Root","withRenderProp","Component","Wrapped","t0","ref","$","_c","rest","Comp","t1","t2","t3","componentName","displayName","name","createPrimitive","node","RadixComp","reduce","acc","ReturnType","K"],"sources":["../../src/utils/Primitive.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ElementType,\n type ForwardRefExoticComponent,\n type PropsWithoutRef,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n} from \"react\";\nimport { Primitive as RadixPrimitive } from \"radix-ui/internal\";\nimport { Slot } from \"radix-ui\";\n\n/**\n * Thin wrapper around Radix `Primitive` that adds `render` prop support.\n *\n * When `render` is provided, it is converted to the equivalent `asChild` pattern:\n * render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>\n *\n * All prop merging, ref composition, and event handler chaining remain handled\n * by Radix's battle-tested Slot implementation — we add zero custom logic for that.\n */\n\n// Match @radix-ui/react-primitive's full element set\nconst NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\",\n] as const;\ntype PrimitiveNode = (typeof NODES)[number];\n\ntype WithRenderPropProps<T extends ElementType> =\n ComponentPropsWithoutRef<T> & {\n render?: ReactElement | undefined;\n };\n\ntype PrimitiveProps<E extends PrimitiveNode> = WithRenderPropProps<\n (typeof RadixPrimitive)[E]\n>;\n\ntype WithRenderPropRuntimeProps<T extends ElementType> =\n WithRenderPropProps<T> & {\n asChild?: boolean | undefined;\n children?: ReactNode | undefined;\n };\n\ntype PrimitiveRef<E extends PrimitiveNode> = ComponentRef<\n (typeof RadixPrimitive)[E]\n>;\n\n/**\n * Composes the children of a `render` element. Outer children win when supplied;\n * the render element's own children are the fallback.\n */\nfunction composeRenderElement(\n render: ReactElement,\n children: ReactNode,\n): ReactElement {\n return cloneElement(\n render,\n undefined,\n children !== undefined\n ? children\n : (render.props as { children?: ReactNode }).children,\n );\n}\n\n/**\n * Composes a `render` element at a call site that has already computed its props.\n *\n * `withRenderProp` wraps a component; this covers the case where the props are\n * already in hand and the composition happens inline.\n */\nfunction renderSlot(\n render: ReactElement,\n children: ReactNode,\n props: ComponentProps<typeof Slot.Root>,\n): ReactElement {\n return (\n <Slot.Root {...props}>{composeRenderElement(render, children)}</Slot.Root>\n );\n}\n\nfunction withRenderProp<T extends ElementType>(Component: T) {\n const Wrapped = forwardRef<ComponentRef<T>, WithRenderPropRuntimeProps<T>>(\n (\n {\n render,\n asChild,\n children,\n ...rest\n }: PropsWithoutRef<WithRenderPropRuntimeProps<T>>,\n ref,\n ) => {\n const Comp = Component as any;\n\n if (render && isValidElement(render)) {\n return (\n <Comp {...(rest as any)} asChild ref={ref}>\n {composeRenderElement(render, children)}\n </Comp>\n );\n }\n\n return (\n <Comp {...(rest as any)} asChild={asChild} ref={ref}>\n {children}\n </Comp>\n );\n },\n );\n\n const componentName =\n typeof Component === \"string\"\n ? Component\n : (Component.displayName ?? Component.name ?? \"Component\");\n Wrapped.displayName = componentName;\n\n return Wrapped as ForwardRefExoticComponent<\n WithRenderPropProps<T> & RefAttributes<ComponentRef<T>>\n >;\n}\n\nfunction createPrimitive<E extends PrimitiveNode>(node: E) {\n const RadixComp = RadixPrimitive[node];\n const Component = withRenderProp(RadixComp);\n\n Component.displayName = `Primitive.${node}`;\n return Component as ForwardRefExoticComponent<\n PrimitiveProps<E> & RefAttributes<PrimitiveRef<E>>\n >;\n}\n\nconst Primitive = NODES.reduce(\n (acc, node) => {\n acc[node] = createPrimitive(node);\n return acc;\n },\n {} as {\n [K in PrimitiveNode]: ReturnType<typeof createPrimitive<K>>;\n },\n);\n\nexport { Primitive, renderSlot, withRenderProp };\nexport type { PrimitiveProps, WithRenderPropProps };\n"],"mappings":";;;;;;;;;;;;;;;AA4BA,MAAMe,QAAQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAAI;;;;;AA2BN,SAASY,qBACPP,QACAK,UACc;CACd,OAAOhB,aACLW,QACAQ,KAAAA,GACAH,aAAaG,KAAAA,IACTH,WACCL,OAAOS,MAAmCJ,QACjD;AACF;;;;;;;AAQA,SAASK,WACPV,QACAK,UACAI,OACc;CACd,OACE,oBAAC,KAAK,MAAN;EAAW,GAAIA;EAAQF,UAAAA,qBAAqBP,QAAQK,QAAQ;CAAa,CAAA;AAE7E;AAEA,SAASO,eAAsCC,WAAc;CAC3D,MAAMC,UAAUxB,YACdyB,IAAAC,QAAA;EAAA,MAAAC,IAAAC,EAAA,EAAA;EAAA,IAAAd;EAAA,IAAAC;EAAA,IAAAL;EAAA,IAAAmB;EAAA,IAAAF,EAAA,OAAAF,IAAA;GACE,CAAA,CAAAf,QAAAI,SAAAC,UAAA,GAAAc,QAAAJ;GAKiDE,EAAA,KAAAF;GAAAE,EAAA,KAAAb;GAAAa,EAAA,KAAAZ;GAAAY,EAAA,KAAAjB;GAAAiB,EAAA,KAAAE;EAAA,OAAA;GAAAf,UAAAa,EAAA;GAAAZ,WAAAY,EAAA;GAAAjB,SAAAiB,EAAA;GAAAE,OAAAF,EAAA;EAAA;EAGjD,MAAAG,OAAaP;EAEb,IAAIb,UAAUT,eAAeS,MAAM,GAAC;GAErB,MAAAqB,KAAAF;GAAW,IAAAG;GAAA,IAAAL,EAAA,OAAAZ,YAAAY,EAAA,OAAAjB,QAAA;IACnBsB,KAAAf,qBAAqBP,QAAQK,QAAQ;IAACY,EAAA,KAAAZ;IAAAY,EAAA,KAAAjB;IAAAiB,EAAA,KAAAK;GAAA,OAAAA,KAAAL,EAAA;GAAA,IAAAM;GAAA,IAAAN,EAAA,OAAAD,OAAAC,EAAA,OAAAI,MAAAJ,EAAA,QAAAK,IAAA;IADzCC,KAAA,oBAAC,MAAD;KAAK,GAAMF;KAAc,SAAA;KAAaL;KACnCM,UAAAA;IADE,CAAA;IAEEL,EAAA,KAAAD;IAAAC,EAAA,KAAAI;IAAAJ,EAAA,MAAAK;IAAAL,EAAA,MAAAM;GAAA,OAAAA,KAAAN,EAAA;GAAA,OAFPM;EAEO;EAKE,MAAAF,KAAAF;EAAW,IAAAG;EAAA,IAAAL,EAAA,QAAAb,WAAAa,EAAA,QAAAZ,YAAAY,EAAA,QAAAD,OAAAC,EAAA,QAAAI,IAAA;GAAtBC,KAAA,oBAAC,MAAD;IAAK,GAAMD;IAAuBjB;IAAcY;IAC7CX;GADE,CAAA;GAEEY,EAAA,MAAAb;GAAAa,EAAA,MAAAZ;GAAAY,EAAA,MAAAD;GAAAC,EAAA,MAAAI;GAAAJ,EAAA,MAAAK;EAAA,OAAAA,KAAAL,EAAA;EAAA,OAFPK;CAEO,CAGb;CAMAR,QAAQW,cAHN,OAAOZ,cAAc,WACjBA,YACCA,UAAUY,eAAeZ,UAAUa,QAAQ;CAGlD,OAAOZ;AAGT;AAEA,SAASa,gBAAyCC,MAAS;CACzD,MAAMC,YAAYpC,YAAemC;CACjC,MAAMf,YAAYD,eAAeiB,SAAS;CAE1ChB,UAAUY,cAAc,aAAaG;CACrC,OAAOf;AAGT;AAEA,MAAMrB,YAAYG,MAAMmC,QACrBC,KAAKH,SAAS;CACbG,IAAIH,QAAQD,gBAAgBC,IAAI;CAChC,OAAOG;AACT,GACA,CAAC,CAGH"}
1
+ {"version":3,"file":"Primitive.js","names":["ComponentProps","ComponentPropsWithoutRef","ComponentRef","ElementType","ForwardRefExoticComponent","PropsWithoutRef","ReactElement","ReactNode","RefAttributes","cloneElement","forwardRef","isValidElement","Primitive","RadixPrimitive","Slot","NODES","const","PrimitiveNode","WithRenderPropProps","T","render","PrimitiveProps","E","WithRenderPropRuntimeProps","asChild","children","PrimitiveRef","composeRenderElement","undefined","props","renderSlot","Root","withRenderProp","Component","Wrapped","t0","ref","$","_c","rest","Comp","t1","t2","t3","componentName","displayName","name","createPrimitive","node","RadixComp","reduce","acc","ReturnType","K","_c","RadixPrimitive"],"sources":["../../src/utils/Primitive.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ElementType,\n type ForwardRefExoticComponent,\n type PropsWithoutRef,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n} from \"react\";\nimport { Primitive as RadixPrimitive } from \"radix-ui/internal\";\nimport { Slot } from \"radix-ui\";\n\n/**\n * Thin wrapper around Radix `Primitive` that adds `render` prop support.\n *\n * When `render` is provided, it is converted to the equivalent `asChild` pattern:\n * render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>\n *\n * All prop merging, ref composition, and event handler chaining remain handled\n * by Radix's battle-tested Slot implementation — we add zero custom logic for that.\n */\n\n// Match @radix-ui/react-primitive's full element set\nconst NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\",\n] as const;\ntype PrimitiveNode = (typeof NODES)[number];\n\ntype WithRenderPropProps<T extends ElementType> =\n ComponentPropsWithoutRef<T> & {\n render?: ReactElement | undefined;\n };\n\ntype PrimitiveProps<E extends PrimitiveNode> = WithRenderPropProps<\n (typeof RadixPrimitive)[E]\n>;\n\ntype WithRenderPropRuntimeProps<T extends ElementType> =\n WithRenderPropProps<T> & {\n asChild?: boolean | undefined;\n children?: ReactNode | undefined;\n };\n\ntype PrimitiveRef<E extends PrimitiveNode> = ComponentRef<\n (typeof RadixPrimitive)[E]\n>;\n\n/**\n * Composes the children of a `render` element. Outer children win when supplied;\n * the render element's own children are the fallback.\n */\nfunction composeRenderElement(\n render: ReactElement,\n children: ReactNode,\n): ReactElement {\n return cloneElement(\n render,\n undefined,\n children !== undefined\n ? children\n : (render.props as { children?: ReactNode }).children,\n );\n}\n\n/**\n * Composes a `render` element at a call site that has already computed its props.\n *\n * `withRenderProp` wraps a component; this covers the case where the props are\n * already in hand and the composition happens inline.\n */\nfunction renderSlot(\n render: ReactElement,\n children: ReactNode,\n props: ComponentProps<typeof Slot.Root>,\n): ReactElement {\n return (\n <Slot.Root {...props}>{composeRenderElement(render, children)}</Slot.Root>\n );\n}\n\nfunction withRenderProp<T extends ElementType>(Component: T) {\n const Wrapped = forwardRef<ComponentRef<T>, WithRenderPropRuntimeProps<T>>(\n (\n {\n render,\n asChild,\n children,\n ...rest\n }: PropsWithoutRef<WithRenderPropRuntimeProps<T>>,\n ref,\n ) => {\n const Comp = Component as any;\n\n if (render && isValidElement(render)) {\n return (\n <Comp {...(rest as any)} asChild ref={ref}>\n {composeRenderElement(render, children)}\n </Comp>\n );\n }\n\n return (\n <Comp {...(rest as any)} asChild={asChild} ref={ref}>\n {children}\n </Comp>\n );\n },\n );\n\n const componentName =\n typeof Component === \"string\"\n ? Component\n : (Component.displayName ?? Component.name ?? \"Component\");\n Wrapped.displayName = componentName;\n\n return Wrapped as ForwardRefExoticComponent<\n WithRenderPropProps<T> & RefAttributes<ComponentRef<T>>\n >;\n}\n\nfunction createPrimitive<E extends PrimitiveNode>(node: E) {\n const RadixComp = RadixPrimitive[node];\n const Component = withRenderProp(RadixComp);\n\n Component.displayName = `Primitive.${node}`;\n return Component as ForwardRefExoticComponent<\n PrimitiveProps<E> & RefAttributes<PrimitiveRef<E>>\n >;\n}\n\nconst Primitive = NODES.reduce(\n (acc, node) => {\n acc[node] = createPrimitive(node);\n return acc;\n },\n {} as {\n [K in PrimitiveNode]: ReturnType<typeof createPrimitive<K>>;\n },\n);\n\nexport { Primitive, renderSlot, withRenderProp };\nexport type { PrimitiveProps, WithRenderPropProps };\n"],"mappings":";;;;;;;;;;;;;;;AA4BA,MAAMe,QAAQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAAI;;;;;AA2BN,SAASY,qBACPP,QACAK,UACc;CACd,OAAOhB,aACLW,QACAQ,KAAAA,GACAH,aAAaG,KAAAA,IACTH,WACCL,OAAOS,MAAmCJ,QACjD;AACF;;;;;;;AAQA,SAASK,WACPV,QACAK,UACAI,OACc;CACd,OACE,oBAAC,KAAK,MAAN;EAAW,GAAIA;EAAQF,UAAAA,qBAAqBP,QAAQK,QAAQ;CAAa,CAAA;AAE7E;AAEA,SAASO,eAAsCC,WAAc;CAC3D,MAAMC,UAAUxB,YACdyB,IAAAC,QAAA;EAAA,MAAAC,IAAAC,EAAA,EAAA;EAAA,IAAAd;EAAA,IAAAC;EAAA,IAAAL;EAAA,IAAAmB;EAAA,IAAAF,EAAA,OAAAF,IAAA;GACE,CAAA,CAAAf,QAAAI,SAAAC,UAAA,GAAAc,QAAAJ;GAKiDE,EAAA,KAAAF;GAAAE,EAAA,KAAAb;GAAAa,EAAA,KAAAZ;GAAAY,EAAA,KAAAjB;GAAAiB,EAAA,KAAAE;EAAA,OAAA;GAAAf,UAAAa,EAAA;GAAAZ,WAAAY,EAAA;GAAAjB,SAAAiB,EAAA;GAAAE,OAAAF,EAAA;EAAA;EAGjD,MAAAG,OAAaP;EAEb,IAAIb,UAAUT,eAAeS,MAAM,GAAC;GAErB,MAAAqB,KAAAF;GAAW,IAAAG;GAAA,IAAAL,EAAA,OAAAZ,YAAAY,EAAA,OAAAjB,QAAA;IACnBsB,KAAAf,qBAAqBP,QAAQK,QAAQ;IAACY,EAAA,KAAAZ;IAAAY,EAAA,KAAAjB;IAAAiB,EAAA,KAAAK;GAAA,OAAAA,KAAAL,EAAA;GAAA,IAAAM;GAAA,IAAAN,EAAA,OAAAD,OAAAC,EAAA,OAAAI,MAAAJ,EAAA,QAAAK,IAAA;IADzCC,KAAA,oBAAC,MAAD;KAAK,GAAMF;KAAc,SAAA;KAAaL;KACnCM,UAAAA;IADE,CAAA;IAEEL,EAAA,KAAAD;IAAAC,EAAA,KAAAI;IAAAJ,EAAA,MAAAK;IAAAL,EAAA,MAAAM;GAAA,OAAAA,KAAAN,EAAA;GAAA,OAFPM;EAEO;EAKE,MAAAF,KAAAF;EAAW,IAAAG;EAAA,IAAAL,EAAA,QAAAb,WAAAa,EAAA,QAAAZ,YAAAY,EAAA,QAAAD,OAAAC,EAAA,QAAAI,IAAA;GAAtBC,KAAA,oBAAC,MAAD;IAAK,GAAMD;IAAuBjB;IAAcY;IAC7CX;GADE,CAAA;GAEEY,EAAA,MAAAb;GAAAa,EAAA,MAAAZ;GAAAY,EAAA,MAAAD;GAAAC,EAAA,MAAAI;GAAAJ,EAAA,MAAAK;EAAA,OAAAA,KAAAL,EAAA;EAAA,OAFPK;CAEO,CAGb;CAMAR,QAAQW,cAHN,OAAOZ,cAAc,WACjBA,YACCA,UAAUY,eAAeZ,UAAUa,QAAQ;CAGlD,OAAOZ;AAGT;AAEA,SAASa,gBAAyCC,MAAS;CACzD,MAAMC,YAAYpC,YAAemC;CACjC,MAAMf,YAAYD,eAAeiB,SAAS;CAE1ChB,UAAUY,cAAc,aAAaG;CACrC,OAAOf;AAGT;AAEA,MAAMrB,YAAYG,MAAMmC,QACrBC,KAAKH,SAAS;CACbG,IAAIH,QAAQD,gBAAgBC,IAAI;CAChC,OAAOG;AACT,GACA,CAAC,CAGH"}
@@ -1 +1 @@
1
- {"version":3,"file":"createActionButton.js","names":["ComponentRef","forwardRef","ComponentPropsWithoutRef","MouseEventHandler","Primitive","composeEventHandlers","ActionButtonCallback","props","TProps","HTMLButtonElement","PrimitiveButtonProps","button","ActionButtonProps","THook","ActionButtonElement","createActionButton","displayName","useActionButton","forwardProps","NonNullable","ActionButton","forwardedRef","$","_c","forwardedProps","primitiveProps","Object","keys","Array","forEach","key","includes","callback","undefined","t0","t1","t2","disabled","t3","onClick","t4"],"sources":["../../src/utils/createActionButton.tsx"],"sourcesContent":["import {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n type MouseEventHandler,\n} from \"react\";\nimport { Primitive } from \"./Primitive\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\n\ntype ActionButtonCallback<TProps> = (\n props: TProps,\n) => MouseEventHandler<HTMLButtonElement> | null;\n\ntype PrimitiveButtonProps = ComponentPropsWithoutRef<typeof Primitive.button>;\n\nexport type ActionButtonProps<THook> = PrimitiveButtonProps &\n (THook extends (props: infer TProps) => unknown ? TProps : never);\n\nexport type ActionButtonElement = ComponentRef<typeof Primitive.button>;\n\nexport const createActionButton = <TProps,>(\n displayName: string,\n useActionButton: ActionButtonCallback<TProps>,\n forwardProps: (keyof NonNullable<TProps>)[] = [],\n) => {\n const ActionButton = forwardRef<\n ActionButtonElement,\n PrimitiveButtonProps & TProps\n >((props, forwardedRef) => {\n const forwardedProps = {} as TProps;\n const primitiveProps = {} as PrimitiveButtonProps;\n\n (Object.keys(props) as Array<keyof typeof props>).forEach((key) => {\n if (forwardProps.includes(key as keyof TProps)) {\n (forwardedProps as any)[key] = props[key];\n } else {\n (primitiveProps as any)[key] = props[key];\n }\n });\n\n const callback = useActionButton(forwardedProps as TProps) ?? undefined;\n return (\n <Primitive.button\n type=\"button\"\n {...primitiveProps}\n ref={forwardedRef}\n disabled={primitiveProps.disabled || !callback}\n onClick={composeEventHandlers(primitiveProps.onClick, callback)}\n />\n );\n });\n\n ActionButton.displayName = displayName;\n\n return ActionButton;\n};\n"],"mappings":";;;;;;AAoBA,MAAae,sBACXC,aACAC,iBACAC,eAA8C,CAAA,MAC3C;CACH,MAAME,eAAenB,YAGnBM,OAAAc,iBAAA;EAAA,MAAAC,IAAAC,EAAA,CAAA;EACA,MAAAC,iBAAuB,CAAC;EACxB,MAAAC,iBAAuB,CAAC;EAExB,OAAOE,KAAMpB,KAAK,CAAC,CAA6BsB,SAAUC,QAAA;GACxD,IAAIZ,aAAYa,SAAUD,GAAmB,GAC3C,eAAwBA,OAAOvB,MAAMuB;QAErC,eAAwBA,OAAOvB,MAAMuB;EACtC,CACF;EAED,MAAAE,WAAiBf,gBAAgBO,cAAqC,KAArDS,KAAAA;EAEd,MAAAC,KAAA9B;EACM,MAAA+B,KAAA;EAGK,MAAAC,KAAAX,eAAcY,YAAd,CAA4BL;EAC7B,MAAAM,KAAAjC,qBAAqBoB,eAAcc,SAAUP,QAAQ;EAAC,IAAAQ;EAAA,IAAAlB,EAAA,OAAAD,gBAAAC,EAAA,OAAAG,kBAAAH,EAAA,OAAAY,GAAAvB,UAAAW,EAAA,OAAAc,MAAAd,EAAA,OAAAgB,IAAA;GALjEE,KAAA,oBAAA,GAAA,QAAA;IACO,MAAAL;IAAQ,GACTV;IACCJ,KAAAA;IACK,UAAAe;IACD,SAAAE;GAAsD,CAAA;GAC/DhB,EAAA,KAAAD;GAAAC,EAAA,KAAAG;GAAAH,EAAA,KAAAY,GAAAvB;GAAAW,EAAA,KAAAc;GAAAd,EAAA,KAAAgB;GAAAhB,EAAA,KAAAkB;EAAA,OAAAA,KAAAlB,EAAA;EAAA,OANFkB;CAME,CAEL;CAEDpB,aAAaJ,cAAcA;CAE3B,OAAOI;AACT"}
1
+ {"version":3,"file":"createActionButton.js","names":["ComponentRef","forwardRef","ComponentPropsWithoutRef","MouseEventHandler","Primitive","composeEventHandlers","ActionButtonCallback","props","TProps","HTMLButtonElement","PrimitiveButtonProps","button","ActionButtonProps","THook","ActionButtonElement","createActionButton","displayName","useActionButton","forwardProps","NonNullable","ActionButton","forwardedRef","$","_c","forwardedProps","primitiveProps","Object","keys","Array","forEach","key","includes","callback","undefined","t0","t1","t2","disabled","t3","onClick","t4","_c","Primitive"],"sources":["../../src/utils/createActionButton.tsx"],"sourcesContent":["import {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n type MouseEventHandler,\n} from \"react\";\nimport { Primitive } from \"./Primitive\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\n\ntype ActionButtonCallback<TProps> = (\n props: TProps,\n) => MouseEventHandler<HTMLButtonElement> | null;\n\ntype PrimitiveButtonProps = ComponentPropsWithoutRef<typeof Primitive.button>;\n\nexport type ActionButtonProps<THook> = PrimitiveButtonProps &\n (THook extends (props: infer TProps) => unknown ? TProps : never);\n\nexport type ActionButtonElement = ComponentRef<typeof Primitive.button>;\n\nexport const createActionButton = <TProps,>(\n displayName: string,\n useActionButton: ActionButtonCallback<TProps>,\n forwardProps: (keyof NonNullable<TProps>)[] = [],\n) => {\n const ActionButton = forwardRef<\n ActionButtonElement,\n PrimitiveButtonProps & TProps\n >((props, forwardedRef) => {\n const forwardedProps = {} as TProps;\n const primitiveProps = {} as PrimitiveButtonProps;\n\n (Object.keys(props) as Array<keyof typeof props>).forEach((key) => {\n if (forwardProps.includes(key as keyof TProps)) {\n (forwardedProps as any)[key] = props[key];\n } else {\n (primitiveProps as any)[key] = props[key];\n }\n });\n\n const callback = useActionButton(forwardedProps as TProps) ?? undefined;\n return (\n <Primitive.button\n type=\"button\"\n {...primitiveProps}\n ref={forwardedRef}\n disabled={primitiveProps.disabled || !callback}\n onClick={composeEventHandlers(primitiveProps.onClick, callback)}\n />\n );\n });\n\n ActionButton.displayName = displayName;\n\n return ActionButton;\n};\n"],"mappings":";;;;;;AAoBA,MAAae,sBACXC,aACAC,iBACAC,eAA8C,CAAA,MAC3C;CACH,MAAME,eAAenB,YAGnBM,OAAAc,iBAAA;EAAA,MAAAC,IAAAC,EAAA,CAAA;EACA,MAAAC,iBAAuB,CAAC;EACxB,MAAAC,iBAAuB,CAAC;EAExB,OAAOE,KAAMpB,KAAK,CAAC,CAA6BsB,SAAUC,QAAA;GACxD,IAAIZ,aAAYa,SAAUD,GAAmB,GAC3C,eAAwBA,OAAOvB,MAAMuB;QAErC,eAAwBA,OAAOvB,MAAMuB;EACtC,CACF;EAED,MAAAE,WAAiBf,gBAAgBO,cAAqC,KAArDS,KAAAA;EAEd,MAAAC,KAAA9B;EACM,MAAA+B,KAAA;EAGK,MAAAC,KAAAX,eAAcY,YAAd,CAA4BL;EAC7B,MAAAM,KAAAjC,qBAAqBoB,eAAcc,SAAUP,QAAQ;EAAC,IAAAQ;EAAA,IAAAlB,EAAA,OAAAD,gBAAAC,EAAA,OAAAG,kBAAAH,EAAA,OAAAY,GAAAvB,UAAAW,EAAA,OAAAc,MAAAd,EAAA,OAAAgB,IAAA;GALjEE,KAAA,oBAAA,GAAA,QAAA;IACO,MAAAL;IAAQ,GACTV;IACCJ,KAAAA;IACK,UAAAe;IACD,SAAAE;GAAsD,CAAA;GAC/DhB,EAAA,KAAAD;GAAAC,EAAA,KAAAG;GAAAH,EAAA,KAAAY,GAAAvB;GAAAW,EAAA,KAAAc;GAAAd,EAAA,KAAAgB;GAAAhB,EAAA,KAAAkB;EAAA,OAAAA,KAAAlB,EAAA;EAAA,OANFkB;CAME,CAEL;CAEDpB,aAAaJ,cAAcA;CAE3B,OAAOI;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"useManagedRef.js","names":["useCallback","useRef","useManagedRef","callback","$","_c","cleanupRef","undefined","t0","el","current","ref"],"sources":["../../../src/utils/hooks/useManagedRef.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\n\nexport const useManagedRef = <TNode>(\n callback: (node: TNode) => (() => void) | undefined,\n) => {\n const cleanupRef = useRef<(() => void) | undefined>(undefined);\n\n const ref = useCallback(\n (el: TNode | null) => {\n // Call the previous cleanup function\n if (cleanupRef.current) {\n cleanupRef.current();\n cleanupRef.current = undefined;\n }\n\n // Call the new callback and store its cleanup function\n if (el) {\n cleanupRef.current = callback(el);\n }\n },\n [callback],\n );\n\n return ref;\n};\n"],"mappings":";;;AAEA,MAAaE,iBAAgBC,aAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAG3B,MAAAC,aAAmBL,OAAiCM,KAAAA,CAAS;CAAE,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,UAAA;EAG7DK,MAAAC,OAAA;GAEE,IAAIH,WAAUI,SAAQ;IACpBJ,WAAUI,QAAS;IACnBJ,WAAUI,UAAWH,KAAAA;GAAH;GAIpB,IAAIE,IACFH,WAAUI,UAAWP,SAASM,EAAE;EACjC;EACFL,EAAA,KAAAD;EAAAC,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAED,OAEKO;AAAG"}
1
+ {"version":3,"file":"useManagedRef.js","names":["useCallback","useRef","useManagedRef","callback","$","_c","cleanupRef","undefined","t0","el","current","ref","_c","ref"],"sources":["../../../src/utils/hooks/useManagedRef.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\n\nexport const useManagedRef = <TNode>(\n callback: (node: TNode) => (() => void) | undefined,\n) => {\n const cleanupRef = useRef<(() => void) | undefined>(undefined);\n\n const ref = useCallback(\n (el: TNode | null) => {\n // Call the previous cleanup function\n if (cleanupRef.current) {\n cleanupRef.current();\n cleanupRef.current = undefined;\n }\n\n // Call the new callback and store its cleanup function\n if (el) {\n cleanupRef.current = callback(el);\n }\n },\n [callback],\n );\n\n return ref;\n};\n"],"mappings":";;;AAEA,MAAaE,iBAAgBC,aAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAG3B,MAAAC,aAAmBL,OAAiCM,KAAAA,CAAS;CAAE,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,UAAA;EAG7DK,MAAAC,OAAA;GAEE,IAAIH,WAAUI,SAAQ;IACpBJ,WAAUI,QAAS;IACnBJ,WAAUI,UAAWH,KAAAA;GAAH;GAIpB,IAAIE,IACFH,WAAUI,UAAWP,SAASM,EAAE;EACjC;EACFL,EAAA,KAAAD;EAAAC,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAED,OAEKO;AAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMediaQuery.js","names":["c","_c","useCallback","useSyncExternalStore","getServerSnapshot","noopUnsubscribe","useMediaQuery","query","$","t0","callback","window","matchMedia","mql","addEventListener","removeEventListener","subscribe","t1","matches","getSnapshot"],"sources":["../../../src/utils/hooks/useMediaQuery.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useSyncExternalStore } from \"react\";\n\nconst getServerSnapshot = () => false;\nconst noopUnsubscribe = () => {};\n\nexport const useMediaQuery = (query: string | null): boolean => {\n const subscribe = useCallback(\n (callback: () => void) => {\n if (typeof window === \"undefined\" || query === null || !window.matchMedia)\n return noopUnsubscribe;\n const mql = window.matchMedia(query);\n mql.addEventListener(\"change\", callback);\n return () => mql.removeEventListener(\"change\", callback);\n },\n [query],\n );\n\n const getSnapshot = useCallback(() => {\n if (typeof window === \"undefined\" || query === null || !window.matchMedia)\n return false;\n return window.matchMedia(query).matches;\n }, [query]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n"],"mappings":";;;;AAIA,MAAMI,0BAA0B;AAChC,MAAMC,wBAAwB,CAAC;AAE/B,MAAaC,iBAAgBC,UAAA;CAAA,MAAAC,IAAAP,EAAA,CAAA;CAAA,IAAAQ;CAAA,IAAAD,EAAA,OAAAD,OAAA;EAEzBE,MAAAC,aAAA;GACE,IAAI,OAAOC,WAAW,eAAeJ,UAAU,QAA3C,CAAoDI,OAAMC,YAAW,OAChEP;GACT,MAAAQ,MAAYF,OAAMC,WAAYL,KAAK;GACnCM,IAAGC,iBAAkB,UAAUJ,QAAQ;GAAC,aAC3BG,IAAGE,oBAAqB,UAAUL,QAAQ;EAAC;EACzDF,EAAA,KAAAD;EAAAC,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAPH,MAAAQ,YAAkBP;CAShB,IAAAQ;CAAA,IAAAT,EAAA,OAAAD,OAAA;EAE8BU,WAAA;GAC9B,IAAI,OAAON,WAAW,eAAeJ,UAAU,QAA3C,CAAoDI,OAAMC,YAAW,OAChE;GAAM,OACRD,OAAMC,WAAYL,KAAK,CAAC,CAAAW;EAAQ;EACxCV,EAAA,KAAAD;EAAAC,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAW,OAELL,qBAAqBa,WAAWG,IAAaf,iBAAiB;AAAC"}
1
+ {"version":3,"file":"useMediaQuery.js","names":["c","_c","useCallback","useSyncExternalStore","getServerSnapshot","noopUnsubscribe","useMediaQuery","query","$","t0","callback","window","matchMedia","mql","addEventListener","removeEventListener","subscribe","t1","matches","getSnapshot","_c","getSnapshot"],"sources":["../../../src/utils/hooks/useMediaQuery.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useSyncExternalStore } from \"react\";\n\nconst getServerSnapshot = () => false;\nconst noopUnsubscribe = () => {};\n\nexport const useMediaQuery = (query: string | null): boolean => {\n const subscribe = useCallback(\n (callback: () => void) => {\n if (typeof window === \"undefined\" || query === null || !window.matchMedia)\n return noopUnsubscribe;\n const mql = window.matchMedia(query);\n mql.addEventListener(\"change\", callback);\n return () => mql.removeEventListener(\"change\", callback);\n },\n [query],\n );\n\n const getSnapshot = useCallback(() => {\n if (typeof window === \"undefined\" || query === null || !window.matchMedia)\n return false;\n return window.matchMedia(query).matches;\n }, [query]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n"],"mappings":";;;;AAIA,MAAMI,0BAA0B;AAChC,MAAMC,wBAAwB,CAAC;AAE/B,MAAaC,iBAAgBC,UAAA;CAAA,MAAAC,IAAAP,EAAA,CAAA;CAAA,IAAAQ;CAAA,IAAAD,EAAA,OAAAD,OAAA;EAEzBE,MAAAC,aAAA;GACE,IAAI,OAAOC,WAAW,eAAeJ,UAAU,QAA3C,CAAoDI,OAAMC,YAAW,OAChEP;GACT,MAAAQ,MAAYF,OAAMC,WAAYL,KAAK;GACnCM,IAAGC,iBAAkB,UAAUJ,QAAQ;GAAC,aAC3BG,IAAGE,oBAAqB,UAAUL,QAAQ;EAAC;EACzDF,EAAA,KAAAD;EAAAC,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAPH,MAAAQ,YAAkBP;CAShB,IAAAQ;CAAA,IAAAT,EAAA,OAAAD,OAAA;EAE8BU,WAAA;GAC9B,IAAI,OAAON,WAAW,eAAeJ,UAAU,QAA3C,CAAoDI,OAAMC,YAAW,OAChE;GAAM,OACRD,OAAMC,WAAYL,KAAK,CAAC,CAAAW;EAAQ;EACxCV,EAAA,KAAAD;EAAAC,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAW,OAELL,qBAAqBa,WAAWG,IAAaf,iBAAiB;AAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useOnResizeContent.js","names":["useCallbackRef","useCallback","useManagedRef","useOnResizeContent","callback","$","_c","callbackRef","t0","el","resizeObserver","ResizeObserver","mutationObserver","MutationObserver","mutations","hasRelevantMutation","some","_temp","observe","childList","subtree","attributes","characterData","disconnect","refCallback","m","type","attributeName"],"sources":["../../../src/utils/hooks/useOnResizeContent.ts"],"sourcesContent":["import { useCallbackRef } from \"radix-ui/internal\";\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\n\nexport const useOnResizeContent = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n\n const refCallback = useCallback(\n (el: HTMLElement) => {\n const resizeObserver = new ResizeObserver(() => {\n callbackRef();\n });\n\n const mutationObserver = new MutationObserver((mutations) => {\n // Filter out style-only attribute mutations to prevent feedback loops\n // with code paths that write styles in response to viewport changes.\n const hasRelevantMutation = mutations.some(\n (m) => m.type !== \"attributes\" || m.attributeName !== \"style\",\n );\n if (hasRelevantMutation) {\n callbackRef();\n }\n });\n\n resizeObserver.observe(el);\n mutationObserver.observe(el, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n return () => {\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n },\n [callbackRef],\n );\n\n return useManagedRef(refCallback);\n};\n"],"mappings":";;;;;AAIA,MAAaG,sBAAqBC,aAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAChC,MAAAC,cAAoBP,eAAeI,QAAQ;CAAE,IAAAI;CAAA,IAAAH,EAAA,OAAAE,aAAA;EAG3CC,MAAAC,OAAA;GACE,MAAAC,iBAAuB,IAAIC,qBAAe;IACxCJ,YAAY;GAAC,CACd;GAED,MAAAK,mBAAyB,IAAIC,kBAAiBC,cAAA;IAM5C,IAH4BA,UAASE,KACnCC,KAEEF,GACFR,YAAY;GACb,CACF;GAEDG,eAAcQ,QAAST,EAAE;GACzBG,iBAAgBM,QAAST,IAAI;IAAAU,WAChB;IAAIC,SACN;IAAIC,YACD;IAAIC,eACD;GACjB,CAAC;GAAC,aAEK;IACLZ,eAAca,WAAY;IAC1BX,iBAAgBW,WAAY;GAAC;EAC9B;EACFlB,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAED,OAEKH,cAAcsB,EAAW;AAAC;AApCD,SAAAP,MAAAQ,GAAA;CAAA,OAajBA,EAACC,SAAU,gBAAgBD,EAACE,kBAAmB;AAAO"}
1
+ {"version":3,"file":"useOnResizeContent.js","names":["useCallbackRef","useCallback","useManagedRef","useOnResizeContent","callback","$","_c","callbackRef","t0","el","resizeObserver","ResizeObserver","mutationObserver","MutationObserver","mutations","hasRelevantMutation","some","_temp","observe","childList","subtree","attributes","characterData","disconnect","refCallback","m","type","attributeName","_c","refCallback"],"sources":["../../../src/utils/hooks/useOnResizeContent.ts"],"sourcesContent":["import { useCallbackRef } from \"radix-ui/internal\";\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\n\nexport const useOnResizeContent = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n\n const refCallback = useCallback(\n (el: HTMLElement) => {\n const resizeObserver = new ResizeObserver(() => {\n callbackRef();\n });\n\n const mutationObserver = new MutationObserver((mutations) => {\n // Filter out style-only attribute mutations to prevent feedback loops\n // with code paths that write styles in response to viewport changes.\n const hasRelevantMutation = mutations.some(\n (m) => m.type !== \"attributes\" || m.attributeName !== \"style\",\n );\n if (hasRelevantMutation) {\n callbackRef();\n }\n });\n\n resizeObserver.observe(el);\n mutationObserver.observe(el, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n return () => {\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n },\n [callbackRef],\n );\n\n return useManagedRef(refCallback);\n};\n"],"mappings":";;;;;AAIA,MAAaG,sBAAqBC,aAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAChC,MAAAC,cAAoBP,eAAeI,QAAQ;CAAE,IAAAI;CAAA,IAAAH,EAAA,OAAAE,aAAA;EAG3CC,MAAAC,OAAA;GACE,MAAAC,iBAAuB,IAAIC,qBAAe;IACxCJ,YAAY;GAAC,CACd;GAED,MAAAK,mBAAyB,IAAIC,kBAAiBC,cAAA;IAM5C,IAH4BA,UAASE,KACnCC,KAEEF,GACFR,YAAY;GACb,CACF;GAEDG,eAAcQ,QAAST,EAAE;GACzBG,iBAAgBM,QAAST,IAAI;IAAAU,WAChB;IAAIC,SACN;IAAIC,YACD;IAAIC,eACD;GACjB,CAAC;GAAC,aAEK;IACLZ,eAAca,WAAY;IAC1BX,iBAAgBW,WAAY;GAAC;EAC9B;EACFlB,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAED,OAEKH,cAAcsB,EAAW;AAAC;AApCD,SAAAP,MAAAQ,GAAA;CAAA,OAajBA,EAACC,SAAU,gBAAgBD,EAACE,kBAAmB;AAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"useOnScrollToBottom.js","names":["c","_c","useCallbackRef","useEffect","useThreadViewport","useOnScrollToBottom","callback","$","callbackRef","onScrollToBottom","_temp","t0","t1","vp"],"sources":["../../../src/utils/hooks/useOnScrollToBottom.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"radix-ui/internal\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (\n callback: (config: { behavior: ScrollBehavior }) => void,\n) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;;;;AAMA,MAAaK,uBAAsBC,aAAA;CAAA,MAAAC,IAAAN,EAAA,CAAA;CAGjC,MAAAO,cAAoBN,eAAeI,QAAQ;CAC3C,MAAAG,mBAAyBL,kBAAkBM,KAA2B;CAAE,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAC,eAAAD,EAAA,OAAAE,kBAAA;EAE9DE,WACDF,iBAAiBD,WAAW;EAClCI,KAAA,CAACH,kBAAkBD,WAAW;EAACD,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAFlCJ,UAAUQ,IAEPC,EAA+B;AAAC;AARF,SAAAF,MAAAG,IAAA;CAAA,OAIkBA,GAAEJ;AAAiB"}
1
+ {"version":3,"file":"useOnScrollToBottom.js","names":["c","_c","useCallbackRef","useEffect","useThreadViewport","useOnScrollToBottom","callback","$","callbackRef","onScrollToBottom","_temp","t0","t1","vp","_c"],"sources":["../../../src/utils/hooks/useOnScrollToBottom.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"radix-ui/internal\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (\n callback: (config: { behavior: ScrollBehavior }) => void,\n) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;;;;AAMA,MAAaK,uBAAsBC,aAAA;CAAA,MAAAC,IAAAN,EAAA,CAAA;CAGjC,MAAAO,cAAoBN,eAAeI,QAAQ;CAC3C,MAAAG,mBAAyBL,kBAAkBM,KAA2B;CAAE,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAC,eAAAD,EAAA,OAAAE,kBAAA;EAE9DE,WACDF,iBAAiBD,WAAW;EAClCI,KAAA,CAACH,kBAAkBD,WAAW;EAACD,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAFlCJ,UAAUQ,IAEPC,EAA+B;AAAC;AARF,SAAAF,MAAAG,IAAA;CAAA,OAIkBA,GAAEJ;AAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSizeHandle.js","names":["c","_c","useCallback","useManagedRef","SizeHandle","useSizeHandle","register","getHeight","$","t0","el","sizeHandle","updateHeight","height","offsetHeight","setHeight","ro","ResizeObserver","observe","disconnect","unregister","callbackRef"],"sources":["../../../src/utils/hooks/useSizeHandle.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\nimport type { SizeHandle } from \"../../context/stores/ThreadViewport\";\n\n/**\n * Hook that creates a ref for tracking element size via a SizeHandle.\n * Automatically sets up ResizeObserver and reports height changes.\n *\n * @param register - Function that returns a SizeHandle (e.g., registerContentInset)\n * @param getHeight - Optional function to compute height (defaults to el.offsetHeight)\n * @returns A ref callback to attach to the element\n */\nexport const useSizeHandle = (\n register: (() => SizeHandle) | null | undefined,\n getHeight?: (el: HTMLElement) => number,\n) => {\n const callbackRef = useCallback(\n (el: HTMLElement) => {\n if (!register) return;\n\n const sizeHandle = register();\n\n const updateHeight = () => {\n const height = getHeight ? getHeight(el) : el.offsetHeight;\n sizeHandle.setHeight(height);\n };\n\n const ro = new ResizeObserver(updateHeight);\n ro.observe(el);\n updateHeight();\n\n return () => {\n ro.disconnect();\n sizeHandle.unregister();\n };\n },\n [register, getHeight],\n );\n\n return useManagedRef(callbackRef);\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAaK,iBAAgBC,UAAAC,cAAA;CAAA,MAAAC,IAAAP,EAAA,CAAA;CAAA,IAAAQ;CAAA,IAAAD,EAAA,OAAAD,aAAAC,EAAA,OAAAF,UAAA;EAKzBG,MAAAC,OAAA;GACE,IAAI,CAACJ,UAAQ;GAEb,MAAAK,aAAmBL,SAAS;GAE5B,MAAAM,qBAAqB;IACnB,MAAAC,SAAeN,YAAYA,UAAUG,EAAoB,IAAdA,GAAEI;IAC7CH,WAAUI,UAAWF,MAAM;GAAC;GAG9B,MAAAG,KAAW,IAAIC,eAAeL,YAAY;GAC1CI,GAAEE,QAASR,EAAE;GACbE,aAAa;GAAC,aAEP;IACLI,GAAEG,WAAY;IACdR,WAAUS,WAAY;GAAC;EACxB;EACFZ,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAED,OAEKL,cAAckB,EAAW;AAAC"}
1
+ {"version":3,"file":"useSizeHandle.js","names":["c","_c","useCallback","useManagedRef","SizeHandle","useSizeHandle","register","getHeight","$","t0","el","sizeHandle","updateHeight","height","offsetHeight","setHeight","ro","ResizeObserver","observe","disconnect","unregister","callbackRef","_c","callbackRef"],"sources":["../../../src/utils/hooks/useSizeHandle.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\nimport type { SizeHandle } from \"../../context/stores/ThreadViewport\";\n\n/**\n * Hook that creates a ref for tracking element size via a SizeHandle.\n * Automatically sets up ResizeObserver and reports height changes.\n *\n * @param register - Function that returns a SizeHandle (e.g., registerContentInset)\n * @param getHeight - Optional function to compute height (defaults to el.offsetHeight)\n * @returns A ref callback to attach to the element\n */\nexport const useSizeHandle = (\n register: (() => SizeHandle) | null | undefined,\n getHeight?: (el: HTMLElement) => number,\n) => {\n const callbackRef = useCallback(\n (el: HTMLElement) => {\n if (!register) return;\n\n const sizeHandle = register();\n\n const updateHeight = () => {\n const height = getHeight ? getHeight(el) : el.offsetHeight;\n sizeHandle.setHeight(height);\n };\n\n const ro = new ResizeObserver(updateHeight);\n ro.observe(el);\n updateHeight();\n\n return () => {\n ro.disconnect();\n sizeHandle.unregister();\n };\n },\n [register, getHeight],\n );\n\n return useManagedRef(callbackRef);\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAaK,iBAAgBC,UAAAC,cAAA;CAAA,MAAAC,IAAAP,EAAA,CAAA;CAAA,IAAAQ;CAAA,IAAAD,EAAA,OAAAD,aAAAC,EAAA,OAAAF,UAAA;EAKzBG,MAAAC,OAAA;GACE,IAAI,CAACJ,UAAQ;GAEb,MAAAK,aAAmBL,SAAS;GAE5B,MAAAM,qBAAqB;IACnB,MAAAC,SAAeN,YAAYA,UAAUG,EAAoB,IAAdA,GAAEI;IAC7CH,WAAUI,UAAWF,MAAM;GAAC;GAG9B,MAAAG,KAAW,IAAIC,eAAeL,YAAY;GAC1CI,GAAEE,QAASR,EAAE;GACbE,aAAa;GAAC,aAEP;IACLI,GAAEG,WAAY;IACdR,WAAUS,WAAY;GAAC;EACxB;EACFZ,EAAA,KAAAD;EAAAC,EAAA,KAAAF;EAAAE,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAED,OAEKL,cAAckB,EAAW;AAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const isCompositionKey: (event: KeyboardEvent) => boolean;
2
+ //# sourceMappingURL=isCompositionKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isCompositionKey.d.ts","sourceRoot":"","sources":["../../src/utils/isCompositionKey.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,GAAI,OAAO,aAAa,YACT,CAAC"}
@@ -0,0 +1,6 @@
1
+ //#region src/utils/isCompositionKey.ts
2
+ const isCompositionKey = (event) => event.isComposing || event.keyCode === 229;
3
+ //#endregion
4
+ export { isCompositionKey };
5
+
6
+ //# sourceMappingURL=isCompositionKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isCompositionKey.js","names":["isCompositionKey","event","KeyboardEvent","isComposing","keyCode"],"sources":["../../src/utils/isCompositionKey.ts"],"sourcesContent":["// A keydown that ends an IME composition can arrive after compositionend with\n// isComposing false and keyCode 229, as the Enter that commits one does in\n// Safari.\nexport const isCompositionKey = (event: KeyboardEvent) =>\n event.isComposing || event.keyCode === 229;\n"],"mappings":";AAGA,MAAaA,oBAAoBC,UAC/BA,MAAME,eAAeF,MAAMG,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"SmoothContext.js","names":["c","_c","ComponentType","createContext","FC","forwardRef","PropsWithChildren","useContext","useState","ReadonlyStore","create","UseBoundStore","MessagePartStatus","ToolCallMessagePartStatus","useAui","createContextStoreHook","SmoothContextValue","useSmoothStatus","SmoothContext","makeSmoothContext","initialState","SmoothContextProvider","t0","$","children","t1","Symbol","for","optional","outer","useSmoothContext","aui","t2","part","getState","status","context","t3","withSmoothContextProvider","Component","C","Wrapped","props","ref","displayName","options","Error","useSmoothStatusStore"],"sources":["../../../src/utils/smooth/SmoothContext.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n createContext,\n type FC,\n forwardRef,\n type PropsWithChildren,\n useContext,\n useState,\n} from \"react\";\nimport type { ReadonlyStore } from \"../../context/ReadonlyStore\";\nimport { create, type UseBoundStore } from \"zustand\";\nimport type {\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { createContextStoreHook } from \"../../context/react/utils/createContextStoreHook\";\n\ntype SmoothContextValue = {\n useSmoothStatus: UseBoundStore<\n ReadonlyStore<MessagePartStatus | ToolCallMessagePartStatus>\n >;\n};\n\nconst SmoothContext = createContext<SmoothContextValue | null>(null);\n\nconst makeSmoothContext = (\n initialState: MessagePartStatus | ToolCallMessagePartStatus,\n) => {\n const useSmoothStatus = create(() => initialState);\n return { useSmoothStatus };\n};\n\nexport const SmoothContextProvider: FC<PropsWithChildren> = ({ children }) => {\n const outer = useSmoothContext({ optional: true });\n const aui = useAui();\n\n const [context] = useState(() =>\n makeSmoothContext(aui.part.getState().status),\n );\n\n // do not wrap if there is an outer SmoothContextProvider\n if (outer) return children;\n\n return (\n <SmoothContext.Provider value={context}>{children}</SmoothContext.Provider>\n );\n};\n\nexport const withSmoothContextProvider = <C extends ComponentType<any>>(\n Component: C,\n): C => {\n const Wrapped = forwardRef((props, ref) => {\n return (\n <SmoothContextProvider>\n <Component {...(props as any)} ref={ref} />\n </SmoothContextProvider>\n );\n });\n Wrapped.displayName = Component.displayName;\n return Wrapped as any;\n};\n\nfunction useSmoothContext(options?: {\n optional?: false | undefined;\n}): SmoothContextValue;\nfunction useSmoothContext(options?: {\n optional?: boolean | undefined;\n}): SmoothContextValue | null;\nfunction useSmoothContext(options?: { optional?: boolean | undefined }) {\n const context = useContext(SmoothContext);\n if (!options?.optional && !context)\n throw new Error(\n \"This component must be used within a SmoothContextProvider.\",\n );\n return context;\n}\n\nexport const { useSmoothStatus, useSmoothStatusStore } = createContextStoreHook(\n useSmoothContext,\n \"useSmoothStatus\",\n);\n"],"mappings":";;;;;;;;AA0BA,MAAMkB,gBAAgBf,cAAyC,IAAI;AAEnE,MAAMgB,qBACJC,iBACG;CAEH,OAAO,EAAEH,iBADeP,aAAaU,YAC5BH,EAAgB;AAC3B;AAEA,MAAaI,yBAA+CC,OAAA;CAAA,MAAAC,IAAAtB,EAAA,CAAA;CAAC,MAAA,EAAAuB,aAAAF;CAAY,IAAAG;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACxCF,KAAA,EAAAG,UAAY,KAAK;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAjD,MAAAM,QAAcC,iBAAiBL,EAAkB;CACjD,MAAAM,MAAYjB,OAAO;CAAE,IAAAkB;CAAA,IAAAT,EAAA,OAAAQ,IAAAE,MAAA;EAEMD,WACzBb,kBAAkBY,IAAGE,KAAKC,SAAU,CAAC,CAAAC,MAAO;EAACZ,EAAA,KAAAQ,IAAAE;EAAAV,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAD/C,MAAA,CAAAa,WAAkB5B,SAASwB,EAE3B;CAGA,IAAIH,OAAK,OAASL;CAAS,IAAAa;CAAA,IAAAd,EAAA,OAAAC,YAAAD,EAAA,OAAAa,SAAA;EAGzBC,KAAA,oBAAA,cAAA,UAAA;GAA+BD,OAAAA;GAAUZ;EAAS,CAAA;EAAyBD,EAAA,KAAAC;EAAAD,EAAA,KAAAa;EAAAb,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAA3Ec;AAA2E;AAI/E,MAAaC,6BACXC,cACM;CACN,MAAME,UAAUpC,YAAWqC,OAAAC,QAAA;EAAA,MAAApB,IAAAtB,EAAA,CAAA;EAGL,MAAAqB,KAAAoB;EAAY,IAAAjB;EAAA,IAAAF,EAAA,OAAAoB,OAAApB,EAAA,OAAAD,IAAA;GAD9BG,KAAA,oBAAC,uBAAD,EAAA,UACE,oBAAC,WAAD;IAAU,GAAMH;IAAoBqB;GAAG,CAAA,EADnB,CAAA;GAEEpB,EAAA,KAAAoB;GAAApB,EAAA,KAAAD;GAAAC,EAAA,KAAAE;EAAA,OAAAA,KAAAF,EAAA;EAAA,OAFxBE;CAEwB,CAE3B;CACDgB,QAAQG,cAAcL,UAAUK;CAChC,OAAOH;AACT;AAQA,SAAAX,iBAAAe,SAAA;CACE,MAAAT,UAAgB7B,WAAWW,aAAa;CACxC,IAAI,CAAC2B,SAAOjB,YAAR,CAAuBQ,SACzB,MAAM,IAAIU,MACR,6DACF;CAAE,OACGV;AAAO;AAGhB,MAAa,EAAEnB,iBAAiB8B,yBAAyBhC,uBACvDe,kBACA,iBACF"}
1
+ {"version":3,"file":"SmoothContext.js","names":["c","_c","ComponentType","createContext","FC","forwardRef","PropsWithChildren","useContext","useState","ReadonlyStore","create","UseBoundStore","MessagePartStatus","ToolCallMessagePartStatus","useAui","createContextStoreHook","SmoothContextValue","useSmoothStatus","SmoothContext","makeSmoothContext","initialState","SmoothContextProvider","t0","$","children","t1","Symbol","for","optional","outer","useSmoothContext","aui","t2","part","getState","status","context","t3","withSmoothContextProvider","Component","C","Wrapped","props","ref","displayName","options","Error","useSmoothStatusStore","_c"],"sources":["../../../src/utils/smooth/SmoothContext.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n createContext,\n type FC,\n forwardRef,\n type PropsWithChildren,\n useContext,\n useState,\n} from \"react\";\nimport type { ReadonlyStore } from \"../../context/ReadonlyStore\";\nimport { create, type UseBoundStore } from \"zustand\";\nimport type {\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"@assistant-ui/core\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { createContextStoreHook } from \"../../context/react/utils/createContextStoreHook\";\n\ntype SmoothContextValue = {\n useSmoothStatus: UseBoundStore<\n ReadonlyStore<MessagePartStatus | ToolCallMessagePartStatus>\n >;\n};\n\nconst SmoothContext = createContext<SmoothContextValue | null>(null);\n\nconst makeSmoothContext = (\n initialState: MessagePartStatus | ToolCallMessagePartStatus,\n) => {\n const useSmoothStatus = create(() => initialState);\n return { useSmoothStatus };\n};\n\nexport const SmoothContextProvider: FC<PropsWithChildren> = ({ children }) => {\n const outer = useSmoothContext({ optional: true });\n const aui = useAui();\n\n const [context] = useState(() =>\n makeSmoothContext(aui.part.getState().status),\n );\n\n // do not wrap if there is an outer SmoothContextProvider\n if (outer) return children;\n\n return (\n <SmoothContext.Provider value={context}>{children}</SmoothContext.Provider>\n );\n};\n\nexport const withSmoothContextProvider = <C extends ComponentType<any>>(\n Component: C,\n): C => {\n const Wrapped = forwardRef((props, ref) => {\n return (\n <SmoothContextProvider>\n <Component {...(props as any)} ref={ref} />\n </SmoothContextProvider>\n );\n });\n Wrapped.displayName = Component.displayName;\n return Wrapped as any;\n};\n\nfunction useSmoothContext(options?: {\n optional?: false | undefined;\n}): SmoothContextValue;\nfunction useSmoothContext(options?: {\n optional?: boolean | undefined;\n}): SmoothContextValue | null;\nfunction useSmoothContext(options?: { optional?: boolean | undefined }) {\n const context = useContext(SmoothContext);\n if (!options?.optional && !context)\n throw new Error(\n \"This component must be used within a SmoothContextProvider.\",\n );\n return context;\n}\n\nexport const { useSmoothStatus, useSmoothStatusStore } = createContextStoreHook(\n useSmoothContext,\n \"useSmoothStatus\",\n);\n"],"mappings":";;;;;;;;AA0BA,MAAMkB,gBAAgBf,cAAyC,IAAI;AAEnE,MAAMgB,qBACJC,iBACG;CAEH,OAAO,EAAEH,iBADeP,aAAaU,YAC5BH,EAAgB;AAC3B;AAEA,MAAaI,yBAA+CC,OAAA;CAAA,MAAAC,IAAAtB,EAAA,CAAA;CAAC,MAAA,EAAAuB,aAAAF;CAAY,IAAAG;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACxCF,KAAA,EAAAG,UAAY,KAAK;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAjD,MAAAM,QAAcC,iBAAiBL,EAAkB;CACjD,MAAAM,MAAYjB,OAAO;CAAE,IAAAkB;CAAA,IAAAT,EAAA,OAAAQ,IAAAE,MAAA;EAEMD,WACzBb,kBAAkBY,IAAGE,KAAKC,SAAU,CAAC,CAAAC,MAAO;EAACZ,EAAA,KAAAQ,IAAAE;EAAAV,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAD/C,MAAA,CAAAa,WAAkB5B,SAASwB,EAE3B;CAGA,IAAIH,OAAK,OAASL;CAAS,IAAAa;CAAA,IAAAd,EAAA,OAAAC,YAAAD,EAAA,OAAAa,SAAA;EAGzBC,KAAA,oBAAA,cAAA,UAAA;GAA+BD,OAAAA;GAAUZ;EAAS,CAAA;EAAyBD,EAAA,KAAAC;EAAAD,EAAA,KAAAa;EAAAb,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAA3Ec;AAA2E;AAI/E,MAAaC,6BACXC,cACM;CACN,MAAME,UAAUpC,YAAWqC,OAAAC,QAAA;EAAA,MAAApB,IAAAtB,EAAA,CAAA;EAGL,MAAAqB,KAAAoB;EAAY,IAAAjB;EAAA,IAAAF,EAAA,OAAAoB,OAAApB,EAAA,OAAAD,IAAA;GAD9BG,KAAA,oBAAC,uBAAD,EAAA,UACE,oBAAC,WAAD;IAAU,GAAMH;IAAoBqB;GAAG,CAAA,EADnB,CAAA;GAEEpB,EAAA,KAAAoB;GAAApB,EAAA,KAAAD;GAAAC,EAAA,KAAAE;EAAA,OAAAA,KAAAF,EAAA;EAAA,OAFxBE;CAEwB,CAE3B;CACDgB,QAAQG,cAAcL,UAAUK;CAChC,OAAOH;AACT;AAQA,SAAAX,iBAAAe,SAAA;CACE,MAAAT,UAAgB7B,WAAWW,aAAa;CACxC,IAAI,CAAC2B,SAAOjB,YAAR,CAAuBQ,SACzB,MAAM,IAAIU,MACR,6DACF;CAAE,OACGV;AAAO;AAGhB,MAAa,EAAEnB,iBAAiB8B,yBAAyBhC,uBACvDe,kBACA,iBACF"}