fix: resolve logical issues when generating multi-page data

This commit is contained in:
LIlGG
2025-10-10 18:48:40 +08:00
parent e96c2da9e5
commit 884f5186a6
6 changed files with 104 additions and 46 deletions

View File

@@ -34,6 +34,7 @@ export interface ParserCallbacks {
interface ElementFactoryProps {
messageId: string;
pageName: string;
}
type ElementFactory = (props: ElementFactoryProps) => string;
@@ -207,7 +208,7 @@ export class StreamingMessageParser {
const artifactFactory = this._options.artifactElement ?? createArtifactElement;
output += artifactFactory({ messageId });
output += artifactFactory({ messageId, pageName: artifactName });
i = openTagEnd + 1;
} else {

View File

@@ -18,8 +18,9 @@ export interface ArtifactState {
}
export type ArtifactUpdateState = Pick<ArtifactState, 'title' | 'closed'>;
type Artifacts = MapStore<Record<string, ArtifactState>>;
type ArtifactsByPageName = Map<string, ArtifactState>;
type ArtifactsByMessageId = Map<string, ArtifactsByPageName>;
type Artifacts = MapStore<ArtifactsByMessageId>;
export class ChatStore {
private globalExecutionQueue = Promise.resolve();
@@ -31,8 +32,8 @@ export class ChatStore {
currentDescription: WritableAtom<string | undefined> =
import.meta.hot?.data?.currentDescription ?? atom<string | undefined>(undefined);
artifacts: Artifacts = import.meta.hot?.data?.artifacts ?? map({});
artifactIdList: string[] = [];
artifacts: Artifacts = import.meta.hot?.data?.artifacts ?? map(new Map());
artifactIdList: { messageId: string; pageName: string }[] = [];
actionAlert: WritableAtom<ActionAlert | undefined> =
import.meta.hot?.data?.actionAlert ?? atom<ActionAlert | undefined>(undefined);
@@ -60,7 +61,12 @@ export class ChatStore {
}
get firstArtifact(): ArtifactState | undefined {
return this.getArtifact(this.artifactIdList[0]);
if (this.artifactIdList.length === 0) {
return undefined;
}
const { messageId, pageName } = this.artifactIdList[0];
return this.getArtifact(messageId, pageName);
}
get description() {
@@ -76,31 +82,30 @@ export class ChatStore {
}
abortAllActions() {
// TODO: what do we wanna do and how do we wanna recover from this?
const artifacts = this.artifacts.get();
Object.values(artifacts).forEach((artifact) => {
const actions = artifact.runner.actions.get();
Object.values(actions).forEach((action) => {
if (action.status === 'running' || action.status === 'pending') {
action.abort();
}
artifacts.values().forEach((artifactByPageNames) => {
artifactByPageNames.values().forEach((artifact) => {
const actions = artifact.runner.actions.get();
Object.values(actions).forEach((action) => {
if (action.status === 'running' || action.status === 'pending') {
action.abort();
}
});
});
});
}
addArtifact({ messageId, name, title, id }: ArtifactCallbackData) {
const artifact = this.getArtifact(messageId);
const artifact = this.getArtifact(messageId, name);
if (artifact) {
return;
}
if (!this.artifactIdList.includes(messageId)) {
this.artifactIdList.push(messageId);
if (!this.artifactIdList.includes({ messageId, pageName: name })) {
this.artifactIdList.push({ messageId, pageName: name });
}
this.artifacts.setKey(messageId, {
const newArtifact = {
id,
name,
title,
@@ -112,21 +117,56 @@ export class ChatStore {
this.actionAlert.set(alert);
}),
});
};
const artifactsByMessageId = this.artifacts.get();
let artifactsByPageName = artifactsByMessageId.get(messageId);
if (!artifactsByPageName) {
artifactsByPageName = new Map();
artifactsByMessageId.set(messageId, artifactsByPageName);
}
artifactsByPageName.set(name, newArtifact);
this.artifacts.set(artifactsByMessageId);
}
updateArtifact({ messageId }: ArtifactCallbackData, state: Partial<ArtifactUpdateState>) {
const artifact = this.getArtifact(messageId);
updateArtifact({ messageId, name }: ArtifactCallbackData, state: Partial<ArtifactUpdateState>) {
const artifact = this.getArtifact(messageId, name);
if (!artifact) {
return;
}
this.artifacts.setKey(messageId, { ...artifact, ...state });
const artifactsByMessageId = this.artifacts.get();
const artifactsByPageName = artifactsByMessageId.get(messageId);
if (!artifactsByPageName) {
return;
}
artifactsByPageName.set(name, { ...artifact, ...state });
artifactsByMessageId.set(messageId, artifactsByPageName);
this.artifacts.set(artifactsByMessageId);
}
private getArtifact(id: string) {
private getArtifact(messageId: string, pageName: string) {
const artifacts = this.artifacts.get();
return artifacts[id];
const artifactsByPageName = artifacts.get(messageId);
if (!artifactsByPageName) {
return undefined;
}
return artifactsByPageName.get(pageName);
}
private getArtifactByArtifactId(messageId: string, artifactId: string) {
const artifacts = this.artifacts.get();
const artifactsByPageName = artifacts.get(messageId);
if (!artifactsByPageName) {
return undefined;
}
return artifactsByPageName.values().find((artifact) => artifact.id === artifactId);
}
setReloadedMessages(messages: string[]) {
@@ -138,8 +178,8 @@ export class ChatStore {
}
private async _addAction(data: ActionCallbackData) {
const { messageId } = data;
const artifact = this.getArtifact(messageId);
const { messageId, artifactId } = data;
const artifact = this.getArtifactByArtifactId(messageId, artifactId);
if (!artifact) {
unreachable('Artifact not found');
@@ -157,9 +197,9 @@ export class ChatStore {
}
async _runAction(data: ActionCallbackData, isRunning: boolean = false) {
const { messageId } = data;
const { messageId, artifactId } = data;
const artifact = this.getArtifact(messageId);
const artifact = this.getArtifactByArtifactId(messageId, artifactId);
if (!artifact) {
unreachable('Artifact not found');
}

View File

@@ -77,6 +77,7 @@ export class WebBuilderStore {
// 找到第一个页面并选中
for (const [pageName] of Object.entries(pages)) {
this.setSelectedPage(pageName);
this.setActiveSectionByPageName(pageName);
break;
}
}
@@ -84,12 +85,12 @@ export class WebBuilderStore {
setSelectedPage(pageName: string | undefined) {
this.pagesStore.setActivePage(pageName);
}
if (pageName) {
const page = this.pagesStore.getPage(pageName);
if (page) {
this.setActiveSection(page.actionIds[page.actionIds.length - 1]);
}
setActiveSectionByPageName(pageName: string) {
const page = this.pagesStore.getPage(pageName);
if (page) {
this.setActiveSection(page.actionIds[page.actionIds.length - 1]);
}
}