diff --git a/packages/react/src/api/ThreadListItemRuntime.ts b/packages/react/src/api/ThreadListItemRuntime.ts index 56b3e7cf35..669b336aa3 100644 --- a/packages/react/src/api/ThreadListItemRuntime.ts +++ b/packages/react/src/api/ThreadListItemRuntime.ts @@ -8,7 +8,13 @@ export type ThreadListItemEventType = "switched-to" | "switched-away"; export type ThreadListItemState = { readonly isMain: boolean; + readonly id: string; + + /** + * @deprecated This field was renamed to `id`. This field will be removed in 0.8.0. + */ readonly threadId: string; + readonly state: "archived" | "regular" | "new" | "deleted"; readonly title?: string | undefined; }; @@ -52,40 +58,42 @@ export class ThreadListItemRuntimeImpl implements ThreadListItemRuntime { public switchTo(): Promise { const state = this._core.getState(); - return this._threadListBinding.switchToThread(state.threadId); + return this._threadListBinding.switchToThread(state.id); } public rename(newTitle: string): Promise { const state = this._core.getState(); - return this._threadListBinding.rename(state.threadId, newTitle); + return this._threadListBinding.rename(state.id, newTitle); } public archive(): Promise { const state = this._core.getState(); - return this._threadListBinding.archive(state.threadId); + return this._threadListBinding.archive(state.id); } public unarchive(): Promise { const state = this._core.getState(); - return this._threadListBinding.unarchive(state.threadId); + return this._threadListBinding.unarchive(state.id); } public delete(): Promise { const state = this._core.getState(); - return this._threadListBinding.delete(state.threadId); + return this._threadListBinding.delete(state.id); } public unstable_on(event: ThreadListItemEventType, callback: () => void) { - const isMain = this._core.getState().isMain; + let prevIsMain = this._core.getState().isMain; return this.subscribe(() => { const newIsMain = this._core.getState().isMain; - if (isMain === newIsMain) return; - if (event === "switched-to" && newIsMain) return; - if (event === "switched-away" && !newIsMain) return; + if (prevIsMain === newIsMain) return; + prevIsMain = newIsMain; + + if (event === "switched-to" && !newIsMain) return; + if (event === "switched-away" && newIsMain) return; callback(); }); } diff --git a/packages/react/src/api/ThreadListRuntime.ts b/packages/react/src/api/ThreadListRuntime.ts index 91b7019ea4..e2020b92a1 100644 --- a/packages/react/src/api/ThreadListRuntime.ts +++ b/packages/react/src/api/ThreadListRuntime.ts @@ -47,7 +47,8 @@ const getThreadListItemState = ( const threadData = threadList.getItemById(threadId); if (!threadData) return SKIP_UPDATE; return { - threadId: threadData.threadId, + id: threadData.threadId, + threadId: threadData.threadId, // TODO remove in 0.8.0 title: threadData.title, state: threadData.state, isMain: threadData.threadId === threadList.mainThreadId, diff --git a/packages/react/src/api/ThreadRuntime.ts b/packages/react/src/api/ThreadRuntime.ts index 586de2a1aa..0c07764409 100644 --- a/packages/react/src/api/ThreadRuntime.ts +++ b/packages/react/src/api/ThreadRuntime.ts @@ -86,7 +86,7 @@ export type ThreadListItemRuntimeBinding = SubscribableWithState< export type ThreadState = { /** * The thread ID. - * @deprecated This field is deprecated and will be removed in 0.8.0. Use `metadata.threadId` instead. + * @deprecated This field is deprecated and will be removed in 0.8.0. Use `useThreadListItem().id` instead. */ readonly threadId: string; @@ -139,7 +139,7 @@ export const getThreadState = ( ): ThreadState => { const lastMessage = runtime.messages.at(-1); return Object.freeze({ - threadId: threadListItemState.threadId, + threadId: threadListItemState.id, metadata: threadListItemState, capabilities: runtime.capabilities, isDisabled: runtime.isDisabled, diff --git a/packages/react/src/runtimes/core/ThreadListRuntimeCore.tsx b/packages/react/src/runtimes/core/ThreadListRuntimeCore.tsx index 8f2d6c20fe..573c19d014 100644 --- a/packages/react/src/runtimes/core/ThreadListRuntimeCore.tsx +++ b/packages/react/src/runtimes/core/ThreadListRuntimeCore.tsx @@ -24,7 +24,7 @@ export type ThreadListRuntimeCore = { // getLoadThreadsPromise(): Promise; // getLoadArchivedThreadsPromise(): Promise; - // create(): Promise; + rename(threadId: string, newTitle: string): Promise; archive(threadId: string): Promise; unarchive(threadId: string): Promise; diff --git a/packages/react/src/runtimes/local/LocalThreadListRuntimeCore.tsx b/packages/react/src/runtimes/local/LocalThreadListRuntimeCore.tsx index f33e110918..297054c6ef 100644 --- a/packages/react/src/runtimes/local/LocalThreadListRuntimeCore.tsx +++ b/packages/react/src/runtimes/local/LocalThreadListRuntimeCore.tsx @@ -123,9 +123,10 @@ export class LocalThreadListRuntimeCore implements ThreadListRuntimeCore { ); break; - default: + default: { const _exhaustiveCheck: never = lastState; throw new Error(`Unsupported state: ${_exhaustiveCheck}`); + } } // newState @@ -143,9 +144,10 @@ export class LocalThreadListRuntimeCore implements ThreadListRuntimeCore { data.dispose(); break; - default: + default: { const _exhaustiveCheck: never = newState; throw new Error(`Unsupported state: ${_exhaustiveCheck}`); + } } if (newState !== "deleted") { diff --git a/packages/react/src/runtimes/local/LocalThreadRuntimeCore.tsx b/packages/react/src/runtimes/local/LocalThreadRuntimeCore.tsx index c60a9f5418..3a5d6ada43 100644 --- a/packages/react/src/runtimes/local/LocalThreadRuntimeCore.tsx +++ b/packages/react/src/runtimes/local/LocalThreadRuntimeCore.tsx @@ -83,11 +83,15 @@ export class LocalThreadRuntimeCore if (hasUpdates) this._notifySubscribers(); } - public async append(message: AppendMessage): Promise { + private _ensureInitialized() { if (!this._isInitialized) { this._isInitialized = true; this._notifyEventSubscribers("initialize"); } + } + + public async append(message: AppendMessage): Promise { + this._ensureInitialized(); const newMessage = fromCoreMessage(message, { attachments: message.attachments, @@ -104,10 +108,7 @@ export class LocalThreadRuntimeCore } public async startRun(parentId: string | null): Promise { - if (!this._isInitialized) { - this._isInitialized = true; - this._notifyEventSubscribers("initialize"); - } + this._ensureInitialized(); this.repository.resetHead(parentId);