Commit 9cb4443b authored by jaden's avatar jaden

feat: support any npm libary

parent a159bed1
...@@ -40,3 +40,5 @@ TOKEN.ts ...@@ -40,3 +40,5 @@ TOKEN.ts
.env .env
.vscode .vscode
public/service-worker.js
\ No newline at end of file
...@@ -232,6 +232,8 @@ i18n.use(LanguageDetector) ...@@ -232,6 +232,8 @@ i18n.use(LanguageDetector)
'No function description available': '暂无函数描述', 'No function description available': '暂无函数描述',
Run: '运行', Run: '运行',
'Execution successful': '执行成功', 'Execution successful': '执行成功',
'Loading dependencies': '正在加载依赖',
'Loading completed': '加载完成',
}, },
}, },
}, },
......
// const rewrites = () => { const withOffline = require('next-offline');
// return [ const path = require('path');
// {
// source: '/openai/:path*',
// destination: 'https://chat-query-backend.netlify.app/api/openai/:path*',
// },
// ,
// ];
// };
const rewrites = async () => { const rewrites = async () => {
const ret = [ const ret = [
...@@ -49,6 +42,21 @@ const nextConfig = { ...@@ -49,6 +42,21 @@ const nextConfig = {
typescript: { typescript: {
ignoreBuildErrors: true, ignoreBuildErrors: true,
}, },
generateSw: false,
// dontAutoRegisterSw: true,
generateInDevMode: true,
workboxOpts: {
swSrc: './serviceWorker.js',
mode: process.env.NODE_ENV,
swDest: path.resolve(__dirname, './public/service-worker.js'),
maximumFileSizeToCacheInBytes: 7 * 1024 * 1024,
include: [
_ => {
if (/^static\//.test(_.asset.name)) console.log(_.asset.name, '333');
return /^static\//.test(_.asset.name);
},
],
},
}; };
module.exports = nextConfig; module.exports = withOffline(nextConfig);
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev -p 4010",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint"
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
"acorn-walk": "^8.2.0", "acorn-walk": "^8.2.0",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"dayjs": "^1.11.9",
"dexie": "^3.2.2", "dexie": "^3.2.2",
"diff": "^5.1.0", "diff": "^5.1.0",
"echarts": "^5.4.2", "echarts": "^5.4.2",
...@@ -38,7 +37,7 @@ ...@@ -38,7 +37,7 @@
"markdown-it-highlightjs": "^4.0.1", "markdown-it-highlightjs": "^4.0.1",
"nanoid": "^4.0.0", "nanoid": "^4.0.0",
"next": "13.1.6", "next": "13.1.6",
"next-workbox-webpack-plugin": "^2.1.1", "next-offline": "^5.0.5",
"npm": "^9.6.0", "npm": "^9.6.0",
"postcss-flexbugs-fixes": "^5.0.2", "postcss-flexbugs-fixes": "^5.0.2",
"postcss-preset-env": "^8.0.1", "postcss-preset-env": "^8.0.1",
...@@ -60,6 +59,7 @@ ...@@ -60,6 +59,7 @@
"systemjs": "^6.14.1", "systemjs": "^6.14.1",
"tailwindcss": "^3.2.7", "tailwindcss": "^3.2.7",
"unstated-next": "^1.1.0", "unstated-next": "^1.1.0",
"workbox-precaching": "^7.0.0",
"workbox-window": "^7.0.0" "workbox-window": "^7.0.0"
}, },
"resolutions": { "resolutions": {
......
...@@ -6,6 +6,7 @@ import { ...@@ -6,6 +6,7 @@ import {
Input, Input,
Select, Select,
Spin, Spin,
Tag,
Tooltip, Tooltip,
} from '@arco-design/web-react'; } from '@arco-design/web-react';
import { import {
...@@ -50,7 +51,6 @@ const ReactJson = dynamic(() => import('react-json-view'), { ssr: false }); ...@@ -50,7 +51,6 @@ const ReactJson = dynamic(() => import('react-json-view'), { ssr: false });
import { Parser } from 'acorn'; import { Parser } from 'acorn';
import ConnectDb, { Query } from '@/client/api/connectDb'; import ConnectDb, { Query } from '@/client/api/connectDb';
import 'systemjs'; import 'systemjs';
import dayjs from 'dayjs';
import { simple } from 'acorn-walk'; import { simple } from 'acorn-walk';
import jsx from 'acorn-jsx'; import jsx from 'acorn-jsx';
import i18n from '@/next-i18next.config'; import i18n from '@/next-i18next.config';
...@@ -92,32 +92,44 @@ async function getUMDPath(packageName: string) { ...@@ -92,32 +92,44 @@ async function getUMDPath(packageName: string) {
} }
function loadUMDModule(packageName: string) { function loadUMDModule(packageName: string) {
window.React = React;
window.ReactDOM = ReactDOM;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
// const script = document.createElement('script'); const script = document.createElement('script');
// script.type = 'module'; script.type = 'module';
// const initFnName: any = [packageName + 'Init']; const initFnName: any = [packageName + 'Init'];
// window[initFnName] = mod => { window[initFnName] = mod => {
// resolve(mod); resolve(mod);
// delete window[initFnName]; delete window[initFnName];
// }; };
// const errHandler = e => { const errHandler = e => {
// resolve(loadUMDModuleBySystem(packageName));
// window.removeEventListener('error', errHandler);
// console.log('error: esm load err', e);
// };
// window.addEventListener('error', errHandler);
// script.textContent = `
// import * as module from "https://esm.run/${packageName}";
// console.log(module,"module")
// window["${initFnName}"] && window["${initFnName}"](module)
// `;
// document.head.append(script);
resolve(loadUMDModuleBySystem(packageName)); resolve(loadUMDModuleBySystem(packageName));
window.removeEventListener('error', errHandler);
console.log('error: esm load err', e);
};
window.addEventListener('error', errHandler);
script.textContent = `
import * as module from "https://cdn.jsdelivr.net/npm/${packageName}/+esm";
console.log(module,"module")
window["${initFnName}"] && window["${initFnName}"](module)
`;
document.head.append(script);
(async () => {
const umdPath = await getUMDPath(packageName);
for (const item of umdPath) {
if (item.type === 'css') {
System.import(item.url).then(function (module: any) {
const styleSheet = module.default; // A CSSStyleSheet object
console.log(styleSheet, "styleSheet")
document.adoptedStyleSheets = [...document.adoptedStyleSheets, styleSheet]; // now your css is available to be used.
});
}
}
})()
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
...@@ -129,7 +141,6 @@ async function loadUMDModuleBySystem(packageName: string) { ...@@ -129,7 +141,6 @@ async function loadUMDModuleBySystem(packageName: string) {
window.define = undefined; window.define = undefined;
window.React = React; window.React = React;
window.ReactDOM = ReactDOM; window.ReactDOM = ReactDOM;
window.dayjs = dayjs;
const umdPath = await getUMDPath(packageName); const umdPath = await getUMDPath(packageName);
let mod; let mod;
for (const item of umdPath) { for (const item of umdPath) {
...@@ -192,13 +203,13 @@ export function ChatView({ ...@@ -192,13 +203,13 @@ export function ChatView({
const reqRef = useRef(nanoid()); const reqRef = useRef(nanoid());
const [showTable, setShowTable] = useState(false); const [showTable, setShowTable] = useState(false);
const [props, setProps] = useState(propsRaw); const [props, setProps] = useState(propsRaw);
const { t } = useTranslation('chatView');
const [dependenciesMap, setDepend] = useState({ const [dependenciesMap, setDepend] = useState({
react: React, react: React,
lodash: get(window, '_'), lodash: get(window, '_'),
'react-dom': ReactDOM, 'react-dom': ReactDOM,
'styled-components': styledComponents, 'styled-components': styledComponents,
'echarts-for-react': ReactECharts, 'echarts-for-react': ReactECharts,
dayjs,
echarts: { echarts: {
default: echarts, default: echarts,
echarts: echarts, echarts: echarts,
...@@ -210,6 +221,8 @@ export function ChatView({ ...@@ -210,6 +221,8 @@ export function ChatView({
setProps(propsRaw); setProps(propsRaw);
}, [propsRaw]); }, [propsRaw]);
const [loadDependName, setLoadDependName] = useState<ReactElement | string>('');
const { trigger, data, isMutating } = useSWRMutation( const { trigger, data, isMutating } = useSWRMutation(
reqRef.current, reqRef.current,
(_, { arg: { need } }) => { (_, { arg: { need } }) => {
...@@ -237,18 +250,25 @@ export function ChatView({ ...@@ -237,18 +250,25 @@ export function ChatView({
node.source?.value && dependencies.push(node.source.value); node.source?.value && dependencies.push(node.source.value);
}, },
}); });
} catch (e) {} } catch (e) { }
const deps: any = {}; const deps: any = {};
for (const depend of dependencies) { for (const depend of dependencies) {
if (!get(dependenciesMap, depend)) { if (!get(dependenciesMap, depend)) {
setLoadDependName(<div>
{t("Loading dependencies")}: <Tag bordered color="orange">{depend}</Tag>
</div>)
await loadUMDModule(depend).then(mod => { await loadUMDModule(depend).then(mod => {
console.log(mod); console.log(mod);
if (mod) { if (mod) {
deps[depend] = mod; deps[depend] = mod;
} }
}); });
setLoadDependName(<div>
{t("Loading completed")}: <Tag bordered color="orange">{depend}</Tag>
</div>)
} }
} }
setLoadDependName("")
setDepend({ setDepend({
...dependenciesMap, ...dependenciesMap,
...deps, ...deps,
...@@ -256,7 +276,6 @@ export function ChatView({ ...@@ -256,7 +276,6 @@ export function ChatView({
}, },
} }
); );
console.log(dependenciesMap);
const SendButton = useCallback( const SendButton = useCallback(
({ inputRef }: { inputRef: any }) => { ({ inputRef }: { inputRef: any }) => {
...@@ -278,7 +297,6 @@ export function ChatView({ ...@@ -278,7 +297,6 @@ export function ChatView({
); );
const example = get(data, 'data.code'); const example = get(data, 'data.code');
const { t } = useTranslation('chatView');
functions = functions || init(t('Function for processing data')); functions = functions || init(t('Function for processing data'));
const Live = useMemo(() => { const Live = useMemo(() => {
...@@ -288,6 +306,7 @@ export function ChatView({ ...@@ -288,6 +306,7 @@ export function ChatView({
} catch (err) { } catch (err) {
node = <LiveEditor />; node = <LiveEditor />;
} }
console.log(props, "props")
return ( return (
<LiveProvider <LiveProvider
...@@ -494,8 +513,7 @@ export function ChatView({ ...@@ -494,8 +513,7 @@ export function ChatView({
} }
const data = await workerFn( const data = await workerFn(
propsRaw, propsRaw,
`${ `${editor?.getValue() || functions
editor?.getValue() || functions
};\n return ${functionName}(data);` };\n return ${functionName}(data);`
); );
ConnectDb.updateQuery( ConnectDb.updateQuery(
...@@ -543,7 +561,10 @@ export function ChatView({ ...@@ -543,7 +561,10 @@ export function ChatView({
<IconEye onClick={() => setShowCode(true)} /> <IconEye onClick={() => setShowCode(true)} />
)} )}
</div> </div>
<div className="overflow-hidden">{Live}</div> <div className="overflow-hidden">{loadDependName ? <div className="flex justify-center">
<Spin block loading />
<div className="ml-[10px]"> {loadDependName}</div>
</div> : Live}</div>
</div> </div>
) : isEqual(props, propsRaw) ? ( ) : isEqual(props, propsRaw) ? (
defaultNode || null defaultNode || null
......
...@@ -3,7 +3,6 @@ import useSWR from 'swr'; ...@@ -3,7 +3,6 @@ import useSWR from 'swr';
import getSchema from '@/client/api/getSchema'; import getSchema from '@/client/api/getSchema';
import { get } from 'lodash'; import { get } from 'lodash';
import { List, Avatar, Layout, Typography } from '@arco-design/web-react'; import { List, Avatar, Layout, Typography } from '@arco-design/web-react';
import '@arco-design/web-react/dist/css/arco.css';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { DndProvider, useDrag, useDrop } from 'react-dnd';
import Link from 'next/link'; import Link from 'next/link';
......
This source diff could not be displayed because it is too large. You can view the blob instead.
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
import { clientsClaim, setCacheNameDetails, skipWaiting } from 'workbox-core';
// Workbox 会在这里插入预缓存列表
precacheAndRoute(self.__WB_MANIFEST);
skipWaiting(); // 跳过install 过程
clientsClaim(); // 激活所有的窗口
registerRoute(
({ url }) => {
return url.href.startsWith('https://cdn.jsdelivr.net/npm');
},
({ url, request, event }) => {
const pattern = /npm\/react@\d+\.\d+\.\d+\/\+esm/;
const pattern1 = /npm\/react-dom@\d+\.\d+\.\d+\/\+esm/;
if (pattern.test(url.href)) {
console.log(url.href, 'href');
return event.respondWith(
new Response(
`
// 使用模块导出语法导出这两个对象
const react = window.React || {};
export const Children = react.Children;
export const Component = react.Component;
export const Fragment = react.Fragment;
export const Profiler = react.Profiler;
export const PureComponent = react.PureComponent;
export const StrictMode = react.StrictMode;
export const Suspense = react.Suspense;
export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
export const cloneElement = react.cloneElement;
export const createContext = react.createContext;
export const createElement = react.createElement;
export const createFactory = react.createFactory;
export const createRef = react.createRef;
export const forwardRef = react.forwardRef;
export const isValidElement = react.isValidElement;
export const lazy = react.lazy;
export const memo = react.memo;
export const startTransition = react.startTransition;
export const unstable_act = react.unstable_act;
export const useCallback = react.useCallback;
export const useContext = react.useContext;
export const useDebugValue = react.useDebugValue;
export const useDeferredValue = react.useDeferredValue;
export const useEffect = react.useEffect;
export const useId = react.useId;
export const useImperativeHandle = react.useImperativeHandle;
export const useInsertionEffect = react.useInsertionEffect;
export const useLayoutEffect = react.useLayoutEffect;
export const useMemo = react.useMemo;
export const useReducer = react.useReducer;
export const useRef = react.useRef;
export const useState = react.useState;
export const useSyncExternalStore = react.useSyncExternalStore;
export const useTransition = react.useTransition;
export const version = react.version;
export default react
`,
{
headers: { 'Content-Type': 'application/javascript' },
}
)
);
} else if (pattern1.test(url.href)) {
console.log(url.href, 'href');
return event.respondWith(
new Response(
`
// 使用模块导出语法导出这两个对象
const react = window.ReactDOM || {};
export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
export const createPortal = react.createPortal;
export const createRoot = react.createRoot;
export const findDOMNode = react.findDOMNode;
export const flushSync = react.flushSync;
export const hydrate = react.hydrate;
export const hydrateRoot = react.hydrateRoot;
export const render = react.render;
export const unmountComponentAtNode = react.unmountComponentAtNode;
export const unstable_batchedUpdates = react.unstable_batchedUpdates;
export const unstable_renderSubtreeIntoContainer = react.unstable_renderSubtreeIntoContainer;
export const version = react.version;
export default react
`,
{
headers: { 'Content-Type': 'application/javascript' },
}
)
);
}
const strategy = new NetworkFirst();
return strategy.handle({ request, event });
}
);
// self.addEventListener('fetch', event => {
// if (event.request.url.startsWith('https://data.jsdelivr.com/')) {
// console.log('Fetching:', event.request.url);
// }
// });
console.log(333);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment