@melony/react 0.1.29 → 0.1.38

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.d.cts CHANGED
@@ -59,10 +59,7 @@ interface ThreadService {
59
59
 
60
60
  interface MelonyContextValue extends ClientState {
61
61
  messages: Message[];
62
- sendEvent: (event: Event, options?: {
63
- runId?: string;
64
- state?: Record<string, any>;
65
- }) => Promise<void>;
62
+ sendEvent: (event: Event) => Promise<void>;
66
63
  reset: (events?: Event[]) => void;
67
64
  client: MelonyClient;
68
65
  config?: Config;
@@ -114,7 +111,7 @@ interface ThreadContextValue {
114
111
  isLoading: boolean;
115
112
  error: Error | null;
116
113
  selectThread: (threadId: string) => void;
117
- createThread: () => Promise<string>;
114
+ createThread: () => Promise<string | null>;
118
115
  deleteThread: (threadId: string) => Promise<void>;
119
116
  refreshThreads: () => Promise<void>;
120
117
  threadEvents: Event[];
package/dist/index.d.ts CHANGED
@@ -59,10 +59,7 @@ interface ThreadService {
59
59
 
60
60
  interface MelonyContextValue extends ClientState {
61
61
  messages: Message[];
62
- sendEvent: (event: Event, options?: {
63
- runId?: string;
64
- state?: Record<string, any>;
65
- }) => Promise<void>;
62
+ sendEvent: (event: Event) => Promise<void>;
66
63
  reset: (events?: Event[]) => void;
67
64
  client: MelonyClient;
68
65
  config?: Config;
@@ -114,7 +111,7 @@ interface ThreadContextValue {
114
111
  isLoading: boolean;
115
112
  error: Error | null;
116
113
  selectThread: (threadId: string) => void;
117
- createThread: () => Promise<string>;
114
+ createThread: () => Promise<string | null>;
118
115
  deleteThread: (threadId: string) => Promise<void>;
119
116
  refreshThreads: () => Promise<void>;
120
117
  threadEvents: Event[];
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React11 from 'react';
2
- import React11__default, { createContext, useState, useContext, useCallback, useMemo, useEffect, useRef } from 'react';
2
+ import React11__default, { createContext, useState, useContext, useCallback, useEffect, useMemo, useRef } from 'react';
3
3
  import { NuqsAdapter } from 'nuqs/adapters/react';
4
4
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -12,7 +12,6 @@ import * as ICONS from '@tabler/icons-react';
12
12
  import { IconUser, IconLogout, IconX, IconBrandGoogle, IconFileText, IconFile, IconPaperclip, IconChevronDown, IconLoader2, IconArrowUp, IconDotsVertical, IconTrash, IconHistory, IconPlus, IconArrowLeft, IconMessage, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
13
13
  import { Menu } from '@base-ui/react/menu';
14
14
  import { Separator as Separator$1 } from '@base-ui/react/separator';
15
- import { generateId } from 'melony/client';
16
15
  import { useQueryState, parseAsString } from 'nuqs';
17
16
  import { mergeProps } from '@base-ui/react/merge-props';
18
17
  import { useRender } from '@base-ui/react/use-render';
@@ -65,6 +64,7 @@ var MelonyContextProviderInner = ({
65
64
  setContextValue
66
65
  }) => {
67
66
  const [state, setState] = useState(client.getState());
67
+ const queryClient = useQueryClient();
68
68
  const { data: config } = useQuery({
69
69
  queryKey: ["melony-config", client.url],
70
70
  queryFn: () => client.getConfig(),
@@ -116,17 +116,24 @@ var MelonyContextProviderInner = ({
116
116
  reset([]);
117
117
  return true;
118
118
  }
119
+ case "client:invalidate-query": {
120
+ const { queryKey } = event.data || {};
121
+ if (queryKey) {
122
+ await queryClient.invalidateQueries({ queryKey });
123
+ }
124
+ return true;
125
+ }
119
126
  default:
120
127
  return false;
121
128
  }
122
129
  },
123
- [client, reset]
130
+ [client, reset, queryClient]
124
131
  );
125
132
  const sendEvent = useCallback(
126
- async (event, options) => {
133
+ async (event) => {
127
134
  const handled = await dispatchClientAction(event);
128
135
  if (handled) return;
129
- const generator = client.sendEvent(event, options);
136
+ const generator = client.sendEvent(event);
130
137
  for await (const incomingEvent of generator) {
131
138
  await dispatchClientAction(incomingEvent);
132
139
  }
@@ -773,12 +780,15 @@ var ThreadProvider = ({
773
780
  initialThreadId: providedInitialThreadId
774
781
  }) => {
775
782
  const queryClient = useQueryClient();
776
- const defaultInitialThreadId = useMemo(() => generateId(), []);
777
- const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
778
783
  const [activeThreadId, setActiveThreadId] = useQueryState(
779
784
  "threadId",
780
- parseAsString.withDefault(initialThreadId)
785
+ parseAsString
781
786
  );
787
+ useEffect(() => {
788
+ if (!activeThreadId && providedInitialThreadId) {
789
+ setActiveThreadId(providedInitialThreadId);
790
+ }
791
+ }, [activeThreadId, providedInitialThreadId, setActiveThreadId]);
782
792
  const {
783
793
  data: threads = [],
784
794
  isLoading,
@@ -795,12 +805,11 @@ var ThreadProvider = ({
795
805
  });
796
806
  const createMutation = useMutation({
797
807
  mutationFn: async () => {
798
- const newId = service.createThread ? await service.createThread() : generateId();
799
- return newId;
808
+ return null;
800
809
  },
801
- onSuccess: async (newId) => {
810
+ onSuccess: async () => {
802
811
  await queryClient.invalidateQueries({ queryKey: ["threads"] });
803
- await setActiveThreadId(newId);
812
+ await setActiveThreadId(null);
804
813
  }
805
814
  });
806
815
  const deleteMutation = useMutation({
@@ -2770,24 +2779,33 @@ function UIRenderer({ node }) {
2770
2779
  return /* @__PURE__ */ jsx(Component, { ...componentProps, children: renderedChildren });
2771
2780
  }
2772
2781
  function MessageContent({ events }) {
2782
+ const firstSlotIndexes = /* @__PURE__ */ new Map();
2773
2783
  const latestSlotIndexes = /* @__PURE__ */ new Map();
2774
2784
  events.forEach((event, index) => {
2775
2785
  if (event.slot) {
2786
+ if (!firstSlotIndexes.has(event.slot)) {
2787
+ firstSlotIndexes.set(event.slot, index);
2788
+ }
2776
2789
  latestSlotIndexes.set(event.slot, index);
2777
2790
  }
2778
2791
  });
2779
2792
  return /* @__PURE__ */ jsx(Fragment, { children: events.map((event, index) => {
2780
- if (event.slot && latestSlotIndexes.get(event.slot) !== index) {
2781
- return null;
2793
+ let displayEvent = event;
2794
+ if (event.slot) {
2795
+ if (firstSlotIndexes.get(event.slot) !== index) {
2796
+ return null;
2797
+ }
2798
+ const latestIndex = latestSlotIndexes.get(event.slot);
2799
+ displayEvent = events[latestIndex];
2782
2800
  }
2783
- if (event.type === "text-delta") {
2784
- return /* @__PURE__ */ jsx("span", { children: event.data?.delta }, index);
2801
+ if (displayEvent.type === "text-delta") {
2802
+ return /* @__PURE__ */ jsx("span", { children: displayEvent.data?.delta }, index);
2785
2803
  }
2786
- if (event.type === "text") {
2787
- return /* @__PURE__ */ jsx("p", { children: event.data?.content || event.data?.text }, index);
2804
+ if (displayEvent.type === "text") {
2805
+ return /* @__PURE__ */ jsx("p", { children: displayEvent.data?.content || displayEvent.data?.text }, index);
2788
2806
  }
2789
- if (event.ui) {
2790
- return /* @__PURE__ */ jsx(UIRenderer, { node: event.ui }, index);
2807
+ if (displayEvent.ui) {
2808
+ return /* @__PURE__ */ jsx(UIRenderer, { node: displayEvent.ui }, index);
2791
2809
  }
2792
2810
  return null;
2793
2811
  }) });
@@ -2899,9 +2917,7 @@ function Thread({
2899
2917
  {
2900
2918
  type: "text",
2901
2919
  role: "user",
2902
- data: { content: text || "" }
2903
- },
2904
- {
2920
+ data: { content: text || "" },
2905
2921
  state: {
2906
2922
  ...state,
2907
2923
  threadId: activeThreadId ?? void 0
@@ -3035,7 +3051,7 @@ var Dropdown = ({
3035
3051
  ] });
3036
3052
  };
3037
3053
  var ThreadList = ({ className }) => {
3038
- const { threads, activeThreadId, selectThread, deleteThread, isLoading } = useThreads();
3054
+ const { threads, activeThreadId, deleteThread } = useThreads();
3039
3055
  const sortedThreads = React11.useMemo(() => {
3040
3056
  return [...threads].sort((a, b) => {
3041
3057
  const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
@@ -3511,7 +3527,6 @@ var CreateThreadButton = ({
3511
3527
  className,
3512
3528
  variant = "ghost",
3513
3529
  size = "default",
3514
- children,
3515
3530
  onThreadCreated
3516
3531
  }) => {
3517
3532
  const { createThread } = useThreads();
@@ -3521,7 +3536,9 @@ var CreateThreadButton = ({
3521
3536
  try {
3522
3537
  setIsCreating(true);
3523
3538
  const threadId = await createThread();
3524
- onThreadCreated?.(threadId);
3539
+ if (threadId) {
3540
+ onThreadCreated?.(threadId);
3541
+ }
3525
3542
  } catch (error) {
3526
3543
  console.error("Failed to create thread:", error);
3527
3544
  } finally {
@@ -3626,7 +3643,7 @@ var CreateThreadNavItem = ({
3626
3643
  onClickAction: {
3627
3644
  type: "client:navigate",
3628
3645
  data: {
3629
- url: `?threadId=${generateId()}`
3646
+ url: "?"
3630
3647
  }
3631
3648
  },
3632
3649
  className: cn(className),