Skip to content

Commit ee7b6bf

Browse files
author
winjo
committed
feat: 增加文件事件回调等
1 parent 83c2d42 commit ee7b6bf

9 files changed

Lines changed: 218 additions & 47 deletions

File tree

packages/alex/src/api/renderApp.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState, useEffect, useRef, useMemo } from 'react';
22
import ReactDOM from 'react-dom';
33
import { IReporterService, localize, getDebugLogger } from '@ali/ide-core-common';
4-
import { REPORT_NAME } from '@alipay/alex-core';
4+
import { REPORT_NAME, RuntimeConfig } from '@alipay/alex-core';
55
import { createApp } from './createApp';
66
import { Root } from '../core/Root';
77
import { RootProps, LandingProps } from '../core/types';
@@ -46,9 +46,11 @@ export const renderApp = (domElement: HTMLElement, props: IAppRendererProps) =>
4646
domElement
4747
);
4848

49-
(app.injector.get(
50-
IReporterService
51-
) as IReporterService).point(REPORT_NAME.ALEX_APP_START_ERROR, err?.message, { error: err });
49+
(app.injector.get(IReporterService) as IReporterService).point(
50+
REPORT_NAME.ALEX_APP_START_ERROR,
51+
err?.message,
52+
{ error: err }
53+
);
5254
getDebugLogger().error(err);
5355
setTimeout(() => {
5456
throw err;
@@ -65,6 +67,11 @@ export const AppRenderer: React.FC<IAppRendererProps> = ({ onLoad, Landing, ...o
6567
const themeType = useConstant(() => app.currentThemeType);
6668
const appElementRef = useRef<React.ReactElement | null>(null);
6769

70+
// 确保回调始终为最新
71+
// TODO: 用 PropsService
72+
const runtimeConfig: RuntimeConfig = app.injector.get(RuntimeConfig);
73+
runtimeConfig.workspace = opts.runtimeConfig.workspace;
74+
6875
const [state, setState] = useState<{
6976
status: RootProps['status'];
7077
error?: RootProps['error'];
Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,44 @@
11
import { Autowired } from '@ali/common-di';
2-
import { Domain, ClientAppContribution, IEventBus } from '@ali/ide-core-browser';
3-
import { ExtensionBeforeActivateEvent } from '@ali/ide-kaitian-extension/lib/browser/types';
2+
import { Domain, ClientAppContribution, IEventBus, Disposable } from '@ali/ide-core-browser';
3+
import {
4+
ExtensionBeforeActivateEvent,
5+
ExtensionWillActivateEvent,
6+
} from '@ali/ide-kaitian-extension/lib/browser/types';
47
import { IPluginService } from '@alipay/alex-plugin';
8+
import { IMainLayoutService } from '@ali/ide-main-layout';
59

610
@Domain(ClientAppContribution)
7-
export class ExtensionActivateContribution implements ClientAppContribution {
11+
export class ExtensionActivateContribution extends Disposable implements ClientAppContribution {
812
@Autowired(IEventBus)
913
private readonly eventBus: IEventBus;
1014

1115
@Autowired(IPluginService)
1216
pluginService: IPluginService;
1317

18+
@Autowired(IMainLayoutService)
19+
mainLayoutService: IMainLayoutService;
20+
1421
initialize() {
15-
this.eventBus.on(ExtensionBeforeActivateEvent, async () => {
16-
try {
17-
// 确保插件先激活
18-
await this.pluginService.whenReady.promise;
19-
} catch (e) {
20-
console.error(e);
21-
}
22-
});
22+
this.addDispose(
23+
this.eventBus.on(ExtensionBeforeActivateEvent, async () => {
24+
try {
25+
// 确保插件先激活
26+
await this.pluginService.whenReady.promise;
27+
} catch (e) {
28+
console.error(e);
29+
}
30+
})
31+
);
32+
33+
// 如果有 browserMain,则等待 view ready,否则可能引起 bug
34+
// 待 kaitian 修复 https://yuque.antfin-inc.com/ide-framework/topics/629
35+
this.addDispose(
36+
this.eventBus.on(ExtensionWillActivateEvent, (e) => {
37+
if (e.payload.contributes.browserMain) {
38+
return this.mainLayoutService.viewReady.promise;
39+
}
40+
return Promise.resolve();
41+
})
42+
);
2343
}
2444
}

packages/code-api/src/common/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const CODE_PLATFORM_CONFIG: Record<ICodePlatform, ICodePlatformConfig> =
6868
[CodePlatform.gitlab]: {
6969
platform: CodePlatform.gitlab,
7070
hostname: ['gitlab.alibaba-inc.com', 'code.aone.alibaba-inc.com'],
71-
origin: 'https://code.alipay.com',
71+
origin: 'https://gitlab.alibaba-inc.com',
7272
endpoint: 'https://gitlab.alibaba-inc.com',
7373
brand: 'GitLab',
7474
line: {

packages/core/src/client/custom/editor.ts

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Autowired } from '@ali/common-di';
22
import { ClientAppContribution } from '@ali/ide-core-browser';
3-
import { OnEvent, WithEventBus, BasicEvent, Domain } from '@ali/ide-core-common';
3+
import { OnEvent, WithEventBus, BasicEvent, Domain, URI } from '@ali/ide-core-common';
44
import {
55
EditorDocumentModelSavedEvent,
66
EditorDocumentModelContentChangedEvent,
77
IEditorDocumentModelService,
88
} from '@ali/ide-editor/lib/browser';
9-
import { IFileServiceClient } from '@ali/ide-file-service/lib/common';
9+
import { IFileServiceClient, FileChangeType } from '@ali/ide-file-service/lib/common';
1010
import { AppConfig, RuntimeConfig } from '../../common/types';
1111
import * as path from 'path';
1212

@@ -31,12 +31,78 @@ export class EditorActionEventContribution extends WithEventBus implements Clien
3131

3232
onStart() {}
3333

34+
initialize() {
35+
type EventType = { uri: string; filepath: string };
36+
37+
this.addDispose(
38+
this.fileService.onFilesChanged((changes) => {
39+
const created: EventType[] = [];
40+
const changed: EventType[] = [];
41+
const deleted: EventType[] = [];
42+
43+
for (const change of changes) {
44+
const relativePath = this.getWorkspaceRelativePath(new URI(change.uri));
45+
if (relativePath === null) {
46+
continue;
47+
}
48+
const obj: EventType = { uri: change.uri, filepath: relativePath };
49+
switch (change.type) {
50+
case FileChangeType.ADDED:
51+
created.push(obj);
52+
break;
53+
case FileChangeType.UPDATED:
54+
changed.push(obj);
55+
break;
56+
case FileChangeType.DELETED:
57+
deleted.push(obj);
58+
break;
59+
default:
60+
break;
61+
}
62+
}
63+
64+
const { workspace } = this.runtimeConfig;
65+
if (created.length && workspace?.onDidCreateFiles) {
66+
workspace.onDidCreateFiles(created.map((data) => data.filepath));
67+
}
68+
if (deleted.length && workspace?.onDidDeleteFiles) {
69+
workspace.onDidDeleteFiles(deleted.map((data) => data.filepath));
70+
}
71+
if (changed.length && workspace?.onDidChangeFiles) {
72+
const { onDidChangeFiles } = workspace;
73+
// TODO: 直接返回 buffer? 编码假定为 utf8 了
74+
Promise.all(
75+
changed.map(async ({ uri, filepath }) => {
76+
const { content } = await this.fileService.resolveContent(uri);
77+
return {
78+
filepath,
79+
content,
80+
};
81+
})
82+
)
83+
.then((data) => {
84+
onDidChangeFiles(data);
85+
})
86+
.catch((err) => {
87+
console.error(err);
88+
});
89+
}
90+
})
91+
);
92+
}
93+
3494
@OnEvent(EditorDocumentModelSavedEvent)
3595
async onEditorDocumentModelSavingEvent(e: EditorDocumentModelSavedEvent) {
3696
if (this.runtimeConfig.workspace?.onDidSaveTextDocument) {
3797
const uri = e.payload;
98+
if (uri.scheme !== 'file') {
99+
return;
100+
}
38101
const { content } = await this.fileService.resolveContent(uri.toString(true));
39-
const filepath = path.relative(this.appConfig.workspaceDir, uri.codeUri.fsPath);
102+
const filepath = this.getWorkspaceRelativePath(uri);
103+
if (filepath === null) {
104+
return;
105+
}
40106
this.runtimeConfig.workspace.onDidSaveTextDocument({ filepath, content });
41107
}
42108
}
@@ -45,14 +111,30 @@ export class EditorActionEventContribution extends WithEventBus implements Clien
45111
async onEditorDocumentModelContentChangedEvent(e: EditorDocumentModelContentChangedEvent) {
46112
if (this.runtimeConfig.workspace?.onDidChangeTextDocument) {
47113
const { uri } = e.payload;
114+
if (uri.scheme !== 'file') {
115+
return;
116+
}
48117
const model = this.docModelService.getModelReference(uri);
49118
if (model) {
50-
const filepath = path.relative(this.appConfig.workspaceDir, uri.codeUri.fsPath);
119+
const filepath = this.getWorkspaceRelativePath(uri);
120+
if (filepath === null) {
121+
return;
122+
}
51123
this.runtimeConfig.workspace.onDidChangeTextDocument({
52124
filepath,
53125
content: model.instance.getText(),
54126
});
127+
model.dispose();
55128
}
56129
}
57130
}
131+
132+
getWorkspaceRelativePath(uri: URI): string | null {
133+
const absolutePath = uri.codeUri.path;
134+
const { workspaceDir } = this.appConfig;
135+
if (!absolutePath.startsWith(workspaceDir)) {
136+
return null;
137+
}
138+
return path.relative(this.appConfig.workspaceDir, absolutePath);
139+
}
58140
}

packages/core/src/client/index.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
PreferenceScope,
99
PreferenceProvider,
1010
} from '@ali/ide-core-browser';
11-
import { BasicModule } from '@ali/ide-core-common';
11+
import { BackService, BasicModule } from '@ali/ide-core-common';
1212
import { WSChannelHandler } from '@ali/ide-connection';
1313

1414
import { FCServiceCenter, ClientPort, initFCService } from '../connection';
@@ -157,29 +157,33 @@ export async function bindConnectionService(injector: Injector, modules: ModuleC
157157

158158
const { getFCService } = initFCService(clientCenter);
159159

160+
const backServiceList: BackService[] = [];
161+
160162
for (const module of modules) {
161163
const moduleInstance = injector.get(module) as BasicModule;
162-
if (!moduleInstance.backServices) {
163-
continue;
164-
}
165-
for (const backService of moduleInstance.backServices) {
166-
if (!isBackServicesInBrowser(backService)) {
167-
continue;
164+
if (moduleInstance.backServices) {
165+
for (const backService of moduleInstance.backServices) {
166+
if (isBackServicesInBrowser(backService)) {
167+
backServiceList.push(backService);
168+
}
168169
}
169-
const { servicePath } = backService;
170-
const fcService = getFCService(servicePath);
170+
}
171+
}
171172

172-
const injectService = {
173-
token: servicePath,
174-
useValue: fcService,
175-
} as Provider;
173+
for (const backService of backServiceList) {
174+
const { servicePath } = backService;
175+
const fcService = getFCService(servicePath);
176176

177-
injector.addProviders(injectService);
177+
const injectService = {
178+
token: servicePath,
179+
useValue: fcService,
180+
} as Provider;
178181

179-
if (backService.clientToken) {
180-
const clientService = injector.get(backService.clientToken);
181-
fcService.onRequestService(clientService);
182-
}
182+
injector.addProviders(injectService);
183+
184+
if (backService.clientToken) {
185+
const clientService = injector.get(backService.clientToken);
186+
fcService.onRequestService(clientService);
183187
}
184188
}
185189
}

packages/core/src/common/types.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,38 @@ export interface RuntimeConfig {
3232
scenario?: string | null;
3333
/** 工作空间配置 */
3434
workspace?: {
35+
/**
36+
* 文件系统配置
37+
*/
3538
filesystem: FileSystemConfiguration;
39+
/**
40+
* 文档保存事件
41+
* @param data.filepath 文档相对工作空间路径
42+
* @param data.content 文档内容
43+
*/
3644
onDidSaveTextDocument?: (data: { filepath: string; content: string }) => void;
45+
/**
46+
* 文档更改事件
47+
* @param data.filepath 文档相对工作空间路径
48+
* @param data.content 文档内容
49+
*/
3750
onDidChangeTextDocument?: (data: { filepath: string; content: string }) => void;
51+
/**
52+
* 文件创建事件
53+
* @param files 相对工作空间文件路径
54+
*/
55+
onDidCreateFiles?: (files: string[]) => void;
56+
/**
57+
* 文件删除事件
58+
* @param files 相对工作空间文件路径
59+
*/
60+
onDidDeleteFiles?: (files: string[]) => void;
61+
/**
62+
* 文件变更事件
63+
* @param data.filepath 相对工作空间文件路径
64+
* @param data.content 文件内容
65+
*/
66+
onDidChangeFiles?: (data: { filepath: string; content: string }[]) => void;
3867
};
3968
/** 默认打开的文件,多个文件时,会展示最右边的文件 */
4069
defaultOpenFile?: string | string[];

packages/integrations/src/filesystem/index.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,26 @@ const App = () => {
122122
}
123123
}, [fsType]);
124124

125-
const workspace = filesystem ? { filesystem } : undefined;
125+
const workspace = filesystem
126+
? {
127+
filesystem,
128+
onDidChangeTextDocument(e) {
129+
console.log('>>>onDidChangeTextDocument', e);
130+
},
131+
onDidSaveTextDocument(e) {
132+
console.log('>>>onDidSaveTextDocument', e);
133+
},
134+
onDidCreateFiles(e) {
135+
console.log('>>>onDidCreateFiles', e);
136+
},
137+
onDidChangeFiles(e) {
138+
console.log('>>>onDidChangeFiles', e);
139+
},
140+
onDidDeleteFiles(e) {
141+
console.log('>>>onDidDeleteFiles', e);
142+
},
143+
}
144+
: undefined;
126145

127146
return (
128147
<div style={{ height: '100%' }}>

scripts/build-assets.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const fs = require('fs');
77
const signale = require('signale');
88
const { invoke, exec } = require('./utils/utils');
99
const { upload } = require('./utils/upload');
10+
const pkg = require('../package.json');
1011

1112
invoke(async () => {
1213
signale.pending(`开始编译 worker-host 和 webview`);
@@ -39,14 +40,22 @@ invoke(async () => {
3940
key: 'webview/index.html',
4041
transform: (v) => transformHttps(v.slice(0, v.lastIndexOf('/'))),
4142
},
43+
__WEBVIEW_SCRIPT__: {
44+
key: 'webview',
45+
transform: transformHttps,
46+
},
4247
};
43-
const config = Object.keys(env).reduce((obj, name) => {
44-
const { key, transform } = env[name];
45-
if (cdnResult[key]) {
46-
obj[name] = transform(cdnResult[key]);
47-
}
48-
return obj;
49-
}, {});
48+
const config = Object.keys(env).reduce(
49+
(obj, name) => {
50+
const { key, transform } = env[name];
51+
if (cdnResult[key]) {
52+
obj[name] = transform(cdnResult[key]);
53+
}
54+
return obj;
55+
},
56+
{ __KAITIAN_VERSION__: pkg.engines.kaitian }
57+
);
58+
5059
fs.writeFileSync(
5160
path.resolve(__dirname, '../packages/toolkit/define.json'),
5261
JSON.stringify(config, null, 2)

0 commit comments

Comments
 (0)