@melony/react 0.1.31 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React11 = require('react');
4
+ var melony = require('melony');
4
5
  var react = require('nuqs/adapters/react');
5
6
  var reactQuery = require('@tanstack/react-query');
6
7
  var jsxRuntime = require('react/jsx-runtime');
@@ -12,7 +13,6 @@ var classVarianceAuthority = require('class-variance-authority');
12
13
  var ICONS = require('@tabler/icons-react');
13
14
  var menu = require('@base-ui/react/menu');
14
15
  var separator = require('@base-ui/react/separator');
15
- var client = require('melony/client');
16
16
  var nuqs = require('nuqs');
17
17
  var mergeProps = require('@base-ui/react/merge-props');
18
18
  var useRender = require('@base-ui/react/use-render');
@@ -43,31 +43,6 @@ var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
43
43
  var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
44
44
 
45
45
  // src/providers/melony-provider.tsx
46
-
47
- // src/lib/group-events-to-messages.ts
48
- function groupEventsToMessages(events) {
49
- if (events.length === 0) return [];
50
- const messages = [];
51
- let currentMessage = null;
52
- for (const event of events) {
53
- const role = event.role || "assistant";
54
- const runId = event.runId;
55
- if (!currentMessage || currentMessage.role !== role || runId && currentMessage.runId && runId !== currentMessage.runId) {
56
- currentMessage = {
57
- role,
58
- content: [event],
59
- runId
60
- };
61
- messages.push(currentMessage);
62
- } else {
63
- currentMessage.content.push(event);
64
- if (!currentMessage.runId && runId) {
65
- currentMessage.runId = runId;
66
- }
67
- }
68
- }
69
- return messages;
70
- }
71
46
  var MelonyContext = React11.createContext(
72
47
  void 0
73
48
  );
@@ -86,6 +61,7 @@ var MelonyContextProviderInner = ({
86
61
  setContextValue
87
62
  }) => {
88
63
  const [state, setState] = React11.useState(client.getState());
64
+ const queryClient = reactQuery.useQueryClient();
89
65
  const { data: config } = reactQuery.useQuery({
90
66
  queryKey: ["melony-config", client.url],
91
67
  queryFn: () => client.getConfig(),
@@ -137,11 +113,18 @@ var MelonyContextProviderInner = ({
137
113
  reset([]);
138
114
  return true;
139
115
  }
116
+ case "client:invalidate-query": {
117
+ const { queryKey } = event.data || {};
118
+ if (queryKey) {
119
+ await queryClient.invalidateQueries({ queryKey });
120
+ }
121
+ return true;
122
+ }
140
123
  default:
141
124
  return false;
142
125
  }
143
126
  },
144
- [client, reset]
127
+ [client, reset, queryClient]
145
128
  );
146
129
  const sendEvent = React11.useCallback(
147
130
  async (event) => {
@@ -157,7 +140,7 @@ var MelonyContextProviderInner = ({
157
140
  const value = React11.useMemo(
158
141
  () => ({
159
142
  ...state,
160
- messages: groupEventsToMessages(state.events),
143
+ messages: melony.convertEventsToMessages(state.events),
161
144
  sendEvent,
162
145
  reset,
163
146
  client,
@@ -794,12 +777,15 @@ var ThreadProvider = ({
794
777
  initialThreadId: providedInitialThreadId
795
778
  }) => {
796
779
  const queryClient = reactQuery.useQueryClient();
797
- const defaultInitialThreadId = React11.useMemo(() => client.generateId(), []);
798
- const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
799
780
  const [activeThreadId, setActiveThreadId] = nuqs.useQueryState(
800
781
  "threadId",
801
- nuqs.parseAsString.withDefault(initialThreadId)
782
+ nuqs.parseAsString
802
783
  );
784
+ React11.useEffect(() => {
785
+ if (!activeThreadId && providedInitialThreadId) {
786
+ setActiveThreadId(providedInitialThreadId);
787
+ }
788
+ }, [activeThreadId, providedInitialThreadId, setActiveThreadId]);
803
789
  const {
804
790
  data: threads = [],
805
791
  isLoading,
@@ -816,12 +802,11 @@ var ThreadProvider = ({
816
802
  });
817
803
  const createMutation = reactQuery.useMutation({
818
804
  mutationFn: async () => {
819
- const newId = service.createThread ? await service.createThread() : client.generateId();
820
- return newId;
805
+ return null;
821
806
  },
822
- onSuccess: async (newId) => {
807
+ onSuccess: async () => {
823
808
  await queryClient.invalidateQueries({ queryKey: ["threads"] });
824
- await setActiveThreadId(newId);
809
+ await setActiveThreadId(null);
825
810
  }
826
811
  });
827
812
  const deleteMutation = reactQuery.useMutation({
@@ -2791,49 +2776,49 @@ function UIRenderer({ node }) {
2791
2776
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentProps, children: renderedChildren });
2792
2777
  }
2793
2778
  function MessageContent({ events }) {
2779
+ const firstSlotIndexes = /* @__PURE__ */ new Map();
2794
2780
  const latestSlotIndexes = /* @__PURE__ */ new Map();
2795
2781
  events.forEach((event, index) => {
2796
2782
  if (event.slot) {
2783
+ if (!firstSlotIndexes.has(event.slot)) {
2784
+ firstSlotIndexes.set(event.slot, index);
2785
+ }
2797
2786
  latestSlotIndexes.set(event.slot, index);
2798
2787
  }
2799
2788
  });
2800
2789
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: events.map((event, index) => {
2801
- if (event.slot && latestSlotIndexes.get(event.slot) !== index) {
2802
- return null;
2790
+ let displayEvent = event;
2791
+ if (event.slot) {
2792
+ if (firstSlotIndexes.get(event.slot) !== index) {
2793
+ return null;
2794
+ }
2795
+ const latestIndex = latestSlotIndexes.get(event.slot);
2796
+ displayEvent = events[latestIndex];
2803
2797
  }
2804
- if (event.type === "text-delta") {
2805
- return /* @__PURE__ */ jsxRuntime.jsx("span", { children: event.data?.delta }, index);
2798
+ if (displayEvent.type === "text-delta") {
2799
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayEvent.data?.delta }, index);
2806
2800
  }
2807
- if (event.type === "text") {
2808
- return /* @__PURE__ */ jsxRuntime.jsx("p", { children: event.data?.content || event.data?.text }, index);
2801
+ if (displayEvent.type === "text") {
2802
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { children: displayEvent.data?.content || displayEvent.data?.text }, index);
2809
2803
  }
2810
- if (event.ui) {
2811
- return /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, index);
2804
+ if (displayEvent.ui) {
2805
+ return /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: displayEvent.ui }, index);
2812
2806
  }
2813
2807
  return null;
2814
2808
  }) });
2815
2809
  }
2816
2810
  function MessageBubble({ message }) {
2817
2811
  const isUser = message.role === "user";
2818
- return /* @__PURE__ */ jsxRuntime.jsx(
2812
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col", isUser ? "items-end" : "items-start"), children: /* @__PURE__ */ jsxRuntime.jsx(
2819
2813
  "div",
2820
2814
  {
2821
2815
  className: cn(
2822
- "flex flex-col",
2823
- isUser ? "items-end" : "items-start"
2816
+ "flex flex-col items-start max-w-[85%] rounded-2xl px-4 py-2 space-y-4 whitespace-pre-wrap",
2817
+ isUser ? "bg-primary text-primary-foreground" : "px-0 py-0 text-foreground"
2824
2818
  ),
2825
- children: /* @__PURE__ */ jsxRuntime.jsx(
2826
- "div",
2827
- {
2828
- className: cn(
2829
- "flex flex-col items-start max-w-[85%] rounded-2xl px-4 py-2 space-y-4 whitespace-pre-wrap",
2830
- isUser ? "bg-primary text-primary-foreground" : "px-0 py-0 text-foreground"
2831
- ),
2832
- children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { events: message.content })
2833
- }
2834
- )
2819
+ children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { events: message.content })
2835
2820
  }
2836
- );
2821
+ ) });
2837
2822
  }
2838
2823
  function LoadingIndicator({ status }) {
2839
2824
  const [isExpanded, setIsExpanded] = React11.useState(false);
@@ -2916,17 +2901,15 @@ function Thread({
2916
2901
  const hasOptions = state && Object.keys(state).filter((k) => k !== "threadId").length > 0;
2917
2902
  if (!text && !hasFiles && !hasOptions || isLoading) return;
2918
2903
  if (!overrideInput) setInput("");
2919
- await sendEvent(
2920
- {
2921
- type: "text",
2922
- role: "user",
2923
- data: { content: text || "" },
2924
- state: {
2925
- ...state,
2926
- threadId: activeThreadId ?? void 0
2927
- }
2904
+ await sendEvent({
2905
+ type: "text",
2906
+ role: "user",
2907
+ data: { content: text || "" },
2908
+ state: {
2909
+ ...state,
2910
+ threadId: activeThreadId ?? void 0
2928
2911
  }
2929
- );
2912
+ });
2930
2913
  };
2931
2914
  const handleStarterPromptClick = (prompt) => {
2932
2915
  if (onStarterPromptClick) {
@@ -3054,7 +3037,7 @@ var Dropdown = ({
3054
3037
  ] });
3055
3038
  };
3056
3039
  var ThreadList = ({ className }) => {
3057
- const { threads, activeThreadId, selectThread, deleteThread, isLoading } = useThreads();
3040
+ const { threads, activeThreadId, deleteThread } = useThreads();
3058
3041
  const sortedThreads = React11__namespace.useMemo(() => {
3059
3042
  return [...threads].sort((a, b) => {
3060
3043
  const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
@@ -3530,7 +3513,6 @@ var CreateThreadButton = ({
3530
3513
  className,
3531
3514
  variant = "ghost",
3532
3515
  size = "default",
3533
- children,
3534
3516
  onThreadCreated
3535
3517
  }) => {
3536
3518
  const { createThread } = useThreads();
@@ -3540,7 +3522,9 @@ var CreateThreadButton = ({
3540
3522
  try {
3541
3523
  setIsCreating(true);
3542
3524
  const threadId = await createThread();
3543
- onThreadCreated?.(threadId);
3525
+ if (threadId) {
3526
+ onThreadCreated?.(threadId);
3527
+ }
3544
3528
  } catch (error) {
3545
3529
  console.error("Failed to create thread:", error);
3546
3530
  } finally {
@@ -3645,7 +3629,7 @@ var CreateThreadNavItem = ({
3645
3629
  onClickAction: {
3646
3630
  type: "client:navigate",
3647
3631
  data: {
3648
- url: `?threadId=${client.generateId()}`
3632
+ url: "?"
3649
3633
  }
3650
3634
  },
3651
3635
  className: cn(className),
@@ -3703,7 +3687,6 @@ exports.ThreadPopover = ThreadPopover;
3703
3687
  exports.ThreadProvider = ThreadProvider;
3704
3688
  exports.UIRenderer = UIRenderer;
3705
3689
  exports.WelcomeScreen = WelcomeScreen;
3706
- exports.groupEventsToMessages = groupEventsToMessages;
3707
3690
  exports.useAuth = useAuth;
3708
3691
  exports.useMelony = useMelony;
3709
3692
  exports.useScreenSize = useScreenSize;