Skip to content

Commit

Permalink
Merge branch 'main' into chore/remove-webpack.config.js
Browse files Browse the repository at this point in the history
  • Loading branch information
afc163 authored Dec 4, 2024
2 parents 0f71645 + 4bfbd13 commit 8b2390e
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export default defineConfig({
define: {
antdReproduceVersion: version,
},
externals: {
// optimize build of GPT-Vis
'mapbox-gl': 'mapboxgl',
'maplibre-gl': 'maplibregl',
},
alias: {
'@ant-design/x/lib': path.join(__dirname, 'components'),
'@ant-design/x/es': path.join(__dirname, 'components'),
Expand Down
Binary file modified bun.lockb
Binary file not shown.
5 changes: 4 additions & 1 deletion components/bubble/__tests__/demo-extend.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { extendTest } from '../../../tests/shared/demoTest';

extendTest('bubble');
extendTest('bubble', {
// Ignore gpt-vis demo, need browser env not jsdom
skip: ['gpt-vis'],
});
5 changes: 4 additions & 1 deletion components/bubble/__tests__/demo.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import demoTest from '../../../tests/shared/demoTest';

demoTest('bubble');
demoTest('bubble', {
// Ignore gpt-vis demo, need browser env not jsdom
skip: ['gpt-vis'],
});
7 changes: 7 additions & 0 deletions components/bubble/demo/gpt-vis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## zh-CN

配合 `@antv/GPT-Vis` 实现大模型输出的图表渲染,支持模型流式输出。

## en-US

Cooperate with `@antv/GPT-Vis` to achieve customized rendering chart of LLM stream output.
52 changes: 52 additions & 0 deletions components/bubble/demo/gpt-vis.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Bubble } from '@ant-design/x';
import type { BubbleProps } from '@ant-design/x';
import { GPTVis } from '@antv/gpt-vis';
import { Button, Flex } from 'antd';
/* eslint-disable react/no-danger */
import React from 'react';

const text = `
**GPT-Vis**, Components for GPTs, generative AI, and LLM projects. Not only UI Components. [more...](https://github.com/antvis/GPT-Vis) \n\n
Here’s a visualization of Haidilao's food delivery revenue from 2013 to 2022. You can see a steady increase over the years, with notable *growth* particularly in recent years.
\`\`\`vis-chart
{
"type": "line",
"data": [{"time":2013,"value":59.3},{"time":2014,"value":64.4},{"time":2015,"value":68.9},{"time":2016,"value":74.4},{"time":2017,"value":82.7},{"time":2018,"value":91.9},{"time":2019,"value":99.1},{"time":2020,"value":101.6},{"time":2021,"value":114.4},{"time":2022,"value":121}],
"axisXTitle": "year",
"axisYTitle": "sale"
}
\`\`\`
`;

const RenderMarkdown: BubbleProps['messageRender'] = (content) => <GPTVis>{content}</GPTVis>;

const App = () => {
const [rerenderKey, setRerenderKey] = React.useState(0);

return (
<Flex vertical gap="small" key={rerenderKey}>
<Button
style={{ alignSelf: 'flex-end' }}
onClick={() => {
setRerenderKey((prev) => prev + 1);
}}
>
Re-Render
</Button>

<Bubble
typing={{ step: 20, interval: 150 }}
content={text}
messageRender={RenderMarkdown}
avatar={{
src: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*2Q5LRJ3LFPUAAAAAAAAAAAAADmJ7AQ/fmt.webp',
}}
variant="outlined"
/>
</Flex>
);
};

export default App;
1 change: 1 addition & 0 deletions components/bubble/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Often used when chatting.
<code src="./demo/list.tsx">Bubble List</code>
<code src="./demo/bubble-custom.tsx">Semantic Custom</code>
<code src="./demo/list-custom.tsx">Custom List Content</code>
<code src="./demo/gpt-vis.tsx">Using GPT-Vis to render charts</code>

## API

Expand Down
1 change: 1 addition & 0 deletions components/bubble/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ demo:
<code src="./demo/list.tsx">气泡列表</code>
<code src="./demo/bubble-custom.tsx">语义化自定义</code>
<code src="./demo/list-custom.tsx">自定义列表内容</code>
<code src="./demo/gpt-vis.tsx">使用 GPT-Vis 渲染图表</code>

## API

Expand Down
4 changes: 2 additions & 2 deletions components/useXChat/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('useXChat', () => {
expect(requestNeverEnd).toHaveBeenCalledWith(
expect.objectContaining({
message: 'little',
messages: [],
messages: ['little'],
}),
expect.anything(),
);
Expand All @@ -104,7 +104,7 @@ describe('useXChat', () => {
expect(requestNeverEnd).toHaveBeenCalledWith(
expect.objectContaining({
message: 'little',
messages: [],
messages: ['little'],
}),
expect.anything(),
);
Expand Down
77 changes: 77 additions & 0 deletions components/useXChat/__tests__/useSyncState.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { act, renderHook } from '../../../tests/utils';
import useSyncState from '../useSyncState';

describe('useSyncState', () => {
it('should initialize state with default value', () => {
const { result } = renderHook(() => useSyncState(0));

const [state] = result.current!;

expect(state).toBe(0);
});

it('should initialize state with default value by getter', () => {
const { result } = renderHook(() => useSyncState(() => 0));

const [state] = result.current!;

expect(state).toBe(0);
});

it('should update state using setState', () => {
const { result } = renderHook(() => useSyncState(0));
const [, setState] = result.current!;

act(() => {
setState(10);
});

const [state] = result.current!;
expect(state).toBe(10);
});

it('should update state using setState by setter', () => {
const { result } = renderHook(() => useSyncState(0));
const [, setState] = result.current!;

act(() => {
setState((prev) => prev + 1);
});

const [state] = result.current!;
expect(state).toBe(1);
});

it('should get the current state by getState', () => {
const { result } = renderHook(() => useSyncState(0));
const [, setState, getState] = result.current!;

act(() => {
setState(5);
});

expect(getState()).toBe(5);

act(() => {
setState((prev) => prev + 5);
});

expect(getState()).toBe(10);
});

it('should trigger re-renders when state update', () => {
const { result } = renderHook(() => useSyncState(0));

const [, setState] = result.current!;

const prevState = result?.current?.[0];

act(() => {
setState(20);
});

const nextState = result?.current?.[0];
expect(nextState).not.toBe(prevState);
expect(nextState).toBe(20);
});
});
23 changes: 17 additions & 6 deletions components/useXChat/useSyncState.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import React from 'react';

export default function useSyncState<T>(defaultValue: T | (() => T)) {
const [state, setState] = React.useState(defaultValue);
type Getter<T> = () => T;
type Setter<T> = (pre: T) => T;

const stateRef = React.useRef(state);
stateRef.current = state;
export default function useSyncState<T>(defaultValue: T | Getter<T>) {
const [, forceUpdate] = React.useState(0);

const getState = React.useCallback(() => stateRef.current, []);
const stateRef = React.useRef<T>(
typeof defaultValue === 'function' ? (defaultValue as Getter<T>)() : defaultValue,
);

return [state, setState, getState] as const;
const setState = React.useCallback((action: React.SetStateAction<T>) => {
stateRef.current =
typeof action === 'function' ? (action as Setter<T>)(stateRef.current) : action;

forceUpdate((prev) => prev + 1);
}, []);

const getState: Getter<T> = React.useCallback(() => stateRef.current, []);

return [stateRef.current, setState, getState] as const;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
},
"devDependencies": {
"@ant-design/tools": "^18.0.2",
"@antv/gpt-vis": "^0.3.0",
"@biomejs/biome": "^1.9.0",
"@codecov/webpack-plugin": "^1.4.0",
"@codesandbox/sandpack-react": "^2.19.8",
Expand Down

0 comments on commit 8b2390e

Please sign in to comment.