Skip to content

Commit

Permalink
✨ feat: 提供 render 相关方法
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Sep 3, 2023
1 parent 31edf40 commit 8a73d88
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 2 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
"typescript": "^5",
"vitest": "latest"
},
"peerDependencies": {
"react": "^18"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
Expand Down
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './error';
export * from './manifest';
export * from './market';
export * from './render';
export * from './request';
export * from './schema/manifest';
export * from './schema/market';
export * from './types';
5 changes: 5 additions & 0 deletions src/render/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum PluginChannel {
fetchPluginMessage = 'lobe-chat:fetch-plugin-message',
pluginReadyForRender = 'lobe-chat:pluginReadyForRender',
renderPlugin = 'lobe-chat:render-plugin',
}
44 changes: 44 additions & 0 deletions src/render/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useEffect, useState } from 'react';

import { PluginRenderProps } from '@/types';

import { PluginChannel } from './const';
import { onPluginReady, onReceiveData } from './utils';

export const useWatchPluginMessage = <T = any>() => {
const [result, setData] = useState<{ data: T; loading: boolean }>({
data: undefined as T,
loading: true,
});

const receiverData = (e: MessageEvent) => {
onReceiveData(e, (data: PluginRenderProps<T>) => {
setData({ data: data.content, loading: false });
});
};

useEffect(() => {
window.addEventListener('message', receiverData);

top?.postMessage({ type: PluginChannel.pluginReadyForRender }, '*');

return () => {
window.removeEventListener('message', receiverData);
};
}, []);

return result;
};

export const useOnPluginReady = (onReady: () => void) => {
useEffect(() => {
const fn = (e: MessageEvent) => {
onPluginReady(e, onReady);
};

window.addEventListener('message', fn);
return () => {
window.removeEventListener('message', fn);
};
}, []);
};
3 changes: 3 additions & 0 deletions src/render/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './const';
export * from './hooks';
export { fetchPluginMessage, sendMessageToPlugin } from './message';
20 changes: 20 additions & 0 deletions src/render/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PluginChannel } from './const';
import { onReceiveData } from './utils';

export const sendMessageToPlugin = (window: Window, props: any) => {
window.postMessage({ props, type: PluginChannel.renderPlugin }, '*');
};

export const fetchPluginMessage = () =>
new Promise<any>((resolve) => {
const receiverData = (e: MessageEvent) => {
onReceiveData(e, (data) => {
resolve(data.content);
window.removeEventListener('message', receiverData);
});
};

window.addEventListener('message', receiverData);

top?.postMessage({ type: PluginChannel.fetchPluginMessage }, '*');
});
25 changes: 25 additions & 0 deletions src/render/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PluginChannel } from '@/render/const';
import { PluginRenderProps } from '@/types';

export const onPluginReady = (e: MessageEvent, onReady: () => void) => {
if (e.data.type === PluginChannel.pluginReadyForRender) {
onReady();
}
};

export const onPluginFetchMessage = (e: MessageEvent, onRequest: (data: any) => void) => {
if (e.data.type === PluginChannel.fetchPluginMessage) {
onRequest(e.data);
}
};

export const sendMessageToPlugin = (window: Window, props: any) => {
window.postMessage({ props, type: PluginChannel.renderPlugin }, '*');
};

export const onReceiveData = <T>(e: MessageEvent, onData: (data: PluginRenderProps<T>) => void) => {
if (e.data.type === PluginChannel.renderPlugin) {
const props = e.data.props as PluginRenderProps<T>;
onData(props);
}
};
File renamed without changes.
File renamed without changes.

0 comments on commit 8a73d88

Please sign in to comment.