Skip to content

Commit d86b0fd

Browse files
committed
feat: add some common codes
1 parent 3d3952e commit d86b0fd

File tree

136 files changed

+2424
-5935
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+2424
-5935
lines changed

packages/engine-core/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@
3535
"devDependencies": {
3636
"@types/lodash-es": "^4.17.12"
3737
},
38-
"peerDependencies": {
39-
"@alilc/lowcode-shared": "workspace:*"
40-
},
4138
"publishConfig": {
4239
"access": "public",
4340
"registry": "https://registry.npmjs.org/"
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type InstanceAccessor } from '@alilc/lowcode-shared';
1+
import { type InstanceAccessor, type TypeConstraint } from '@alilc/lowcode-shared';
22

33
export interface ICommandEvent {
44
commandId: string;
@@ -16,19 +16,12 @@ export interface ICommand {
1616
}
1717

1818
export interface ICommandMetadata {
19-
/**
20-
* A short summary of what the command does. This will be used in:
21-
* - API commands
22-
* - when showing keybindings that have no other UX
23-
* - when searching for commands in the Command Palette
24-
*/
2519
readonly description: string;
2620
readonly args?: ReadonlyArray<{
2721
readonly name: string;
2822
readonly isOptional?: boolean;
2923
readonly description?: string;
30-
// readonly constraint?: TypeConstraint;
31-
// readonly schema?: IJSONSchema;
24+
readonly constraint?: TypeConstraint;
25+
readonly default?: any;
3226
}>;
33-
readonly returns?: string;
3427
}

packages/engine-core/src/command/commandRegistry.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@ import {
33
type EventDisposable,
44
type EventListener,
55
Emitter,
6+
LinkedList,
7+
TypeConstraint,
8+
validateConstraints,
9+
Iterable,
610
} from '@alilc/lowcode-shared';
711
import { ICommand, ICommandHandler } from './command';
8-
import { Registry } from '../extension';
12+
import { Extensions, Registry } from '../common/registry';
13+
import { ICommandService } from './commandService';
914

1015
export type ICommandsMap = Map<string, ICommand>;
1116

@@ -24,10 +29,10 @@ export interface ICommandRegistry {
2429
class CommandsRegistry implements ICommandRegistry {
2530
private readonly _commands = new Map<string, LinkedList<ICommand>>();
2631

27-
private readonly _onDidRegisterCommand = new Emitter<string>();
32+
private readonly _didRegisterCommandEmitter = new Emitter<string>();
2833

2934
onDidRegisterCommand(fn: EventListener<string>) {
30-
return this._onDidRegisterCommand.on(fn);
35+
return this._didRegisterCommandEmitter.on(fn);
3136
}
3237

3338
registerCommand(idOrCommand: string | ICommand, handler?: ICommandHandler): EventDisposable {
@@ -66,21 +71,21 @@ class CommandsRegistry implements ICommandRegistry {
6671

6772
const removeFn = commands.unshift(idOrCommand);
6873

69-
const ret = toDisposable(() => {
74+
const ret = () => {
7075
removeFn();
7176
const command = this._commands.get(id);
7277
if (command?.isEmpty()) {
7378
this._commands.delete(id);
7479
}
75-
});
80+
};
7681

7782
// tell the world about this command
78-
this._onDidRegisterCommand.emit(id);
83+
this._didRegisterCommandEmitter.emit(id);
7984

8085
return ret;
8186
}
8287

83-
registerCommandAlias(oldId: string, newId: string): IDisposable {
88+
registerCommandAlias(oldId: string, newId: string): EventDisposable {
8489
return this.registerCommand(oldId, (accessor, ...args) =>
8590
accessor.get(ICommandService).executeCommand(newId, ...args),
8691
);
@@ -108,8 +113,4 @@ class CommandsRegistry implements ICommandRegistry {
108113

109114
const commandsRegistry = new CommandsRegistry();
110115

111-
export const Extension = {
112-
command: 'base.contributions.command',
113-
};
114-
115-
Registry.add(Extension.command, commandsRegistry);
116+
Registry.add(Extensions.Command, commandsRegistry);
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { createDecorator, Provide } from '@alilc/lowcode-shared';
2-
import { Registry } from '../extension';
3-
import { ICommandRegistry, Extension } from './commandRegistry';
1+
import { createDecorator, Provide, IInstantiationService } from '@alilc/lowcode-shared';
2+
import { Registry, Extensions } from '../common/registry';
3+
import { ICommandRegistry } from './commandRegistry';
44

55
export interface ICommandService {
66
executeCommand<T = any>(commandId: string, ...args: any[]): Promise<T | undefined>;
@@ -10,11 +10,23 @@ export const ICommandService = createDecorator<ICommandService>('commandService'
1010

1111
@Provide(ICommandService)
1212
export class CommandService implements ICommandService {
13+
constructor(@IInstantiationService private instantiationService: IInstantiationService) {}
14+
1315
executeCommand<T = any>(id: string, ...args: any[]): Promise<T | undefined> {
14-
const command = Registry.as<ICommandRegistry>(Extension.command).getCommand(id);
16+
return this.tryExecuteCommand(id, args);
17+
}
1518

19+
private tryExecuteCommand(id: string, args: any[]): Promise<any> {
20+
const command = Registry.as<ICommandRegistry>(Extensions.Command).getCommand(id);
1621
if (!command) {
1722
return Promise.reject(new Error(`command '${id}' not found`));
1823
}
24+
25+
try {
26+
const result = this.instantiationService.invokeFunction(command.handler, ...args);
27+
return Promise.resolve(result);
28+
} catch (err) {
29+
return Promise.reject(err);
30+
}
1931
}
2032
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './command';
2+
export * from './commandRegistry';
3+
export * from './commandService';

packages/engine-core/src/extension/registry.ts renamed to packages/engine-core/src/common/registry.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,9 @@ class RegistryImpl implements IRegistry {
3737
}
3838

3939
export const Registry: IRegistry = new RegistryImpl();
40+
41+
export const Extensions = {
42+
Configuration: 'base.contributions.configuration',
43+
Command: 'base.contributions.command',
44+
Widget: 'base.contributions.widget',
45+
};
Lines changed: 85 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,105 @@
1-
import { type StringDictionary, Emitter, type EventListener } from '@alilc/lowcode-shared';
2-
import { ConfigurationModel } from './configurationModel';
3-
import {
4-
type IConfigurationRegistry,
5-
type IRegisteredConfigurationPropertySchema,
6-
Extension,
7-
} from './configurationRegistry';
8-
import { Registry } from '../extension';
1+
import { type StringDictionary } from '@alilc/lowcode-shared';
2+
import { uniq } from 'lodash-es';
93

10-
export interface IConfigurationOverrides {
11-
overrideIdentifier?: string | null;
4+
export interface IInspectValue<T> {
5+
readonly value?: T;
6+
readonly override?: T;
7+
readonly overrides?: { readonly identifiers: string[]; readonly value: T }[];
128
}
139

14-
export interface IConfigurationUpdateOverrides {
15-
overrideIdentifiers?: string[] | null;
16-
}
17-
18-
export class DefaultConfiguration {
19-
private emitter = new Emitter<{
20-
defaults: ConfigurationModel;
21-
properties: string[];
22-
}>();
10+
export function toValuesTree(properties: StringDictionary): any {
11+
const root = Object.create(null);
2312

24-
private _configurationModel = ConfigurationModel.createEmptyModel();
25-
26-
get configurationModel(): ConfigurationModel {
27-
return this._configurationModel;
13+
for (const key of Object.keys(properties)) {
14+
addToValueTree(root, key, properties[key]);
2815
}
2916

30-
initialize(): ConfigurationModel {
31-
this.resetConfigurationModel();
32-
Registry.as<IConfigurationRegistry>(Extension.Configuration).onDidUpdateConfiguration(
33-
({ properties }) => this.onDidUpdateConfiguration([...properties]),
34-
);
35-
36-
return this.configurationModel;
37-
}
17+
return root;
18+
}
3819

39-
reload(): ConfigurationModel {
40-
this.resetConfigurationModel();
41-
return this.configurationModel;
42-
}
20+
export function addToValueTree(
21+
settingsTreeRoot: any,
22+
key: string,
23+
value: any,
24+
conflictReporter: (message: string) => void = console.error,
25+
): void {
26+
const segments = key.split('.');
27+
const last = segments.pop()!;
4328

44-
onDidChangeConfiguration(
45-
listener: EventListener<[{ defaults: ConfigurationModel; properties: string[] }]>,
46-
) {
47-
return this.emitter.on(listener);
29+
let curr = settingsTreeRoot;
30+
for (let i = 0; i < segments.length; i++) {
31+
const s = segments[i];
32+
let obj = curr[s];
33+
switch (typeof obj) {
34+
case 'undefined':
35+
obj = curr[s] = Object.create(null);
36+
break;
37+
case 'object':
38+
if (obj === null) {
39+
conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is null`);
40+
return;
41+
}
42+
break;
43+
default:
44+
conflictReporter(
45+
`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is ${JSON.stringify(obj)}`,
46+
);
47+
return;
48+
}
49+
curr = obj;
4850
}
4951

50-
private onDidUpdateConfiguration(properties: string[]): void {
51-
this.updateConfigurationModel(
52-
properties,
53-
Registry.as<IConfigurationRegistry>(Extension.Configuration).getConfigurationProperties(),
54-
);
55-
this.emitter.emit({ defaults: this.configurationModel, properties });
52+
if (typeof curr === 'object' && curr !== null) {
53+
try {
54+
curr[last] = value; // workaround https://github.com/microsoft/vscode/issues/13606
55+
} catch (e) {
56+
conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
57+
}
58+
} else {
59+
conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
5660
}
61+
}
5762

58-
private resetConfigurationModel(): void {
59-
this._configurationModel = ConfigurationModel.createEmptyModel();
63+
export function removeFromValueTree(valueTree: any, key: string): void {
64+
const segments = key.split('.');
65+
doRemoveFromValueTree(valueTree, segments);
66+
}
6067

61-
const properties = Registry.as<IConfigurationRegistry>(
62-
Extension.Configuration,
63-
).getConfigurationProperties();
68+
function doRemoveFromValueTree(valueTree: any, segments: string[]): void {
69+
const first = segments.shift()!;
70+
if (segments.length === 0) {
71+
// Reached last segment
72+
delete valueTree[first];
73+
return;
74+
}
6475

65-
this.updateConfigurationModel(Object.keys(properties), properties);
76+
if (Object.keys(valueTree).includes(first)) {
77+
const value = valueTree[first];
78+
if (typeof value === 'object' && !Array.isArray(value)) {
79+
doRemoveFromValueTree(value, segments);
80+
if (Object.keys(value).length === 0) {
81+
delete valueTree[first];
82+
}
83+
}
6684
}
85+
}
86+
87+
const OVERRIDE_IDENTIFIER_PATTERN = `\\[([^\\]]+)\\]`;
88+
const OVERRIDE_IDENTIFIER_REGEX = new RegExp(OVERRIDE_IDENTIFIER_PATTERN, 'g');
89+
export const OVERRIDE_PROPERTY_PATTERN = `^(${OVERRIDE_IDENTIFIER_PATTERN})+$`;
90+
export const OVERRIDE_PROPERTY_REGEX = new RegExp(OVERRIDE_PROPERTY_PATTERN);
6791

68-
private updateConfigurationModel(
69-
properties: string[],
70-
configurationProperties: StringDictionary<IRegisteredConfigurationPropertySchema>,
71-
): void {
72-
for (const key of properties) {
73-
const propertySchema = configurationProperties[key];
74-
if (propertySchema) {
75-
this.configurationModel.setValue(key, propertySchema.default);
76-
} else {
77-
this.configurationModel.removeValue(key);
92+
export function overrideIdentifiersFromKey(key: string): string[] {
93+
const identifiers: string[] = [];
94+
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
95+
let matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);
96+
while (matches?.length) {
97+
const identifier = matches[1].trim();
98+
if (identifier) {
99+
identifiers.push(identifier);
78100
}
101+
matches = OVERRIDE_IDENTIFIER_REGEX.exec(key);
79102
}
80103
}
104+
return uniq(identifiers);
81105
}

0 commit comments

Comments
 (0)