feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
19
frontend/packages/project-ide/core/src/renderer/context.ts
Normal file
19
frontend/packages/project-ide/core/src/renderer/context.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export const IDEContainerContext = React.createContext<any>({});
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
useMemo,
|
||||
useEffect,
|
||||
forwardRef,
|
||||
useImperativeHandle,
|
||||
type ForwardRefRenderFunction,
|
||||
} from 'react';
|
||||
|
||||
import { type interfaces, Container } from 'inversify';
|
||||
|
||||
import { loadPlugins, PluginContext, type PluginsProvider } from '../common';
|
||||
import { Application, IDEContainerModule } from '../application';
|
||||
import { IDEContainerContext } from './context';
|
||||
|
||||
export interface IDEProviderProps {
|
||||
containerModules?: interfaces.ContainerModule[]; // 注入的 IOC 包
|
||||
container?: interfaces.Container;
|
||||
customPluginContext?: (container: interfaces.Container) => PluginContext; // 自定义插件的上下文
|
||||
plugins?: PluginsProvider<any>;
|
||||
children?: React.ReactElement<any, any> | null;
|
||||
}
|
||||
|
||||
export interface IDEProviderRef {
|
||||
getContainer: () => interfaces.Container | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* IDE 容器
|
||||
*/
|
||||
const IDEProviderWithRef: ForwardRefRenderFunction<
|
||||
IDEProviderRef,
|
||||
IDEProviderProps
|
||||
> = (props, ref) => {
|
||||
const {
|
||||
containerModules,
|
||||
customPluginContext,
|
||||
container: fromContainer,
|
||||
plugins,
|
||||
} = props;
|
||||
|
||||
/**
|
||||
* 创建 IOC 包
|
||||
*/
|
||||
const container = useMemo(() => {
|
||||
const mainContainer: interfaces.Container =
|
||||
fromContainer || new Container();
|
||||
mainContainer.load(IDEContainerModule);
|
||||
if (containerModules) {
|
||||
containerModules.forEach(module => mainContainer.load(module));
|
||||
}
|
||||
if (customPluginContext) {
|
||||
mainContainer
|
||||
.rebind(PluginContext)
|
||||
.toConstantValue(customPluginContext(mainContainer));
|
||||
}
|
||||
if (plugins) {
|
||||
loadPlugins(plugins(mainContainer.get(PluginContext)), mainContainer);
|
||||
}
|
||||
mainContainer.get(Application).init();
|
||||
return mainContainer;
|
||||
// @action 这里 props 数据如果更改不会触发刷新,不允许修改
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const application = container.get(Application);
|
||||
application.start();
|
||||
return () => {
|
||||
application.dispose();
|
||||
};
|
||||
}, [container]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
getContainer: () => container,
|
||||
}));
|
||||
|
||||
return (
|
||||
<IDEContainerContext.Provider value={container}>
|
||||
{props.children}
|
||||
</IDEContainerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const IDEProvider = forwardRef(IDEProviderWithRef);
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { useIDEContainer } from './use-ide-container';
|
||||
|
||||
export const IDERendererProvider = Symbol('IDERendererProvider');
|
||||
|
||||
export type IDERendererProvider = (props: {
|
||||
className?: string;
|
||||
}) => React.ReactElement<any, any> | null;
|
||||
|
||||
export const IDERenderer: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}: {
|
||||
className?: string;
|
||||
}) => {
|
||||
const container = useIDEContainer();
|
||||
const RendererProvider =
|
||||
container.get<IDERendererProvider>(IDERendererProvider)!;
|
||||
return <RendererProvider className={className} />;
|
||||
};
|
||||
29
frontend/packages/project-ide/core/src/renderer/index.ts
Normal file
29
frontend/packages/project-ide/core/src/renderer/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useIDEService } from './use-ide-service';
|
||||
export { useRefresh } from './use-refresh';
|
||||
export { useIDEContainer } from './use-ide-container';
|
||||
export { IDEContainerContext } from './context';
|
||||
export { IDERenderer, IDERendererProvider } from './ide-renderer';
|
||||
export {
|
||||
IDEProvider,
|
||||
type IDEProviderProps,
|
||||
type IDEProviderRef,
|
||||
} from './ide-provider';
|
||||
export { useNavigation } from './use-navigation';
|
||||
export { useLocation } from './use-location';
|
||||
export { useStyling } from './use-styling';
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { type interfaces } from 'inversify';
|
||||
|
||||
import { IDEContainerContext } from './context';
|
||||
|
||||
/**
|
||||
* 获取 ide inversify container
|
||||
*/
|
||||
export function useIDEContainer(): interfaces.Container {
|
||||
return React.useContext(IDEContainerContext);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type interfaces } from 'inversify';
|
||||
|
||||
import { useIDEContainer } from './use-ide-container';
|
||||
|
||||
/**
|
||||
* 获取IDE的 IOC 模块
|
||||
* @param identifier
|
||||
*/
|
||||
export function useIDEService<T>(identifier: interfaces.ServiceIdentifier): T {
|
||||
const container = useIDEContainer();
|
||||
return container.get(identifier) as T;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { NavigationService } from '../navigation';
|
||||
import { type URI } from '../common';
|
||||
import { useIDEService } from './use-ide-service';
|
||||
|
||||
interface LocationInfo {
|
||||
uri?: URI;
|
||||
canGoBack?: boolean;
|
||||
canGoForward?: boolean;
|
||||
}
|
||||
|
||||
const useLocation = () => {
|
||||
const navigation = useIDEService<NavigationService>(NavigationService);
|
||||
const [location, setLocation] = useState<LocationInfo>({});
|
||||
|
||||
useEffect(() => {
|
||||
const dispose = navigation.onDidHistoryChange(next => {
|
||||
setLocation({
|
||||
uri: next?.uri,
|
||||
canGoBack: navigation.canGoBack(),
|
||||
canGoForward: navigation.canGoForward(),
|
||||
});
|
||||
});
|
||||
return () => dispose.dispose();
|
||||
}, []);
|
||||
|
||||
return location;
|
||||
};
|
||||
|
||||
export { useLocation };
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { NavigationHistory, NavigationService } from '../navigation';
|
||||
import { type URI } from '../common';
|
||||
import { useIDEService } from './use-ide-service';
|
||||
|
||||
const useNavigation = (): {
|
||||
/** 可传入 URI 或 string,传入 string 时以 / 开头,和 react-router-dom 对齐 */
|
||||
navigate: (uri: URI | string, replace?: boolean, options?: any) => void;
|
||||
history: NavigationHistory;
|
||||
back: () => Promise<void>;
|
||||
forward: () => Promise<void>;
|
||||
} => {
|
||||
const navigationService = useIDEService<NavigationService>(NavigationService);
|
||||
const historyService = useIDEService<NavigationHistory>(NavigationHistory);
|
||||
|
||||
const navigate = useCallback(
|
||||
(uri: URI | string, replace?: boolean, options?: any) =>
|
||||
navigationService.goto(uri, replace, options),
|
||||
[navigationService],
|
||||
);
|
||||
|
||||
const back = useCallback(() => navigationService.back(), [navigationService]);
|
||||
const forward = useCallback(
|
||||
() => navigationService.forward(),
|
||||
[navigationService],
|
||||
);
|
||||
|
||||
return { navigate, history: historyService, back, forward };
|
||||
};
|
||||
|
||||
export { useNavigation };
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useRefresh } from '@flowgram-adapter/common';
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import {
|
||||
StylingService,
|
||||
type Collector,
|
||||
type ColorTheme,
|
||||
ColorService,
|
||||
} from '../styles';
|
||||
import { useTheme } from './use-theme';
|
||||
import { useIDEService } from './use-ide-service';
|
||||
|
||||
type Register = (
|
||||
collector: Pick<Collector, 'prefix'>,
|
||||
theme: ColorTheme,
|
||||
) => string;
|
||||
|
||||
const useStyling = (
|
||||
id: string,
|
||||
fn: Register,
|
||||
deps: React.DependencyList = [],
|
||||
) => {
|
||||
const stylingService = useIDEService<StylingService>(StylingService);
|
||||
const colorService = useIDEService<ColorService>(ColorService);
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
const css = fn(
|
||||
{
|
||||
prefix: 'flowide',
|
||||
},
|
||||
{
|
||||
type: theme.type,
|
||||
label: theme.label,
|
||||
getColor: _id => colorService.getThemeColor(_id, theme.type),
|
||||
},
|
||||
);
|
||||
const dispose = stylingService.register(id, css);
|
||||
return () => dispose.dispose();
|
||||
}, [id, theme, ...deps]);
|
||||
};
|
||||
|
||||
export { useStyling };
|
||||
38
frontend/packages/project-ide/core/src/renderer/use-theme.ts
Normal file
38
frontend/packages/project-ide/core/src/renderer/use-theme.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { ThemeService } from '../styles';
|
||||
import { useIDEService } from './use-ide-service';
|
||||
|
||||
const useTheme = () => {
|
||||
const themeService = useIDEService<ThemeService>(ThemeService);
|
||||
const [theme, setTheme] = useState(themeService.getCurrent());
|
||||
|
||||
useEffect(() => {
|
||||
const dispose = themeService.onDidThemeChange(({ next }) => {
|
||||
setTheme(next);
|
||||
});
|
||||
return () => dispose.dispose();
|
||||
}, []);
|
||||
|
||||
return {
|
||||
theme,
|
||||
};
|
||||
};
|
||||
|
||||
export { useTheme };
|
||||
Reference in New Issue
Block a user