Enable oxlint's import/no-cycle rule (import plugin) so circular module dependencies are caught in CI, similar to eslint-plugin-import/no-cycle and biome no-import-cycles discussed in the issue. Relocate shared types and dependencies to remove cycles under src/common: - Types.ts: host IInsertEvent, IDeleteEvent, IParams, UnderlineStyle, IBuffer, and IBufferSet; drop imports from CircularList, buffer/Types, parser/Types, and Services - CoreTerminal.ts: define and export ICoreTerminal - ServiceRegistry.ts: define IServiceIdentifier (break Services registry loop) - UnicodeService: stop constructing UnicodeV6; CoreTerminal registers the default v6 provider after service creation - buffer/Types.ts and parser/Types.ts: re-export moved types for callers Fixes https://github.com/xtermjs/xterm.js/issues/5897 Co-authored-by: Cursor <cursoragent@cursor.com>
56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
/**
|
|
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*
|
|
* This was heavily inspired from microsoft/vscode's dependency injection system (MIT).
|
|
*/
|
|
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
export interface IServiceIdentifier<T> {
|
|
(...args: any[]): void;
|
|
type: T;
|
|
_id: string;
|
|
}
|
|
|
|
const enum Constants {
|
|
DI_TARGET = 'di$target',
|
|
DI_DEPENDENCIES = 'di$dependencies'
|
|
}
|
|
|
|
export const serviceRegistry: Map<string, IServiceIdentifier<any>> = new Map();
|
|
|
|
export function getServiceDependencies(ctor: any): { id: IServiceIdentifier<any>, index: number, optional: boolean }[] {
|
|
return ctor[Constants.DI_DEPENDENCIES] || [];
|
|
}
|
|
|
|
export function createDecorator<T>(id: string): IServiceIdentifier<T> {
|
|
if (serviceRegistry.has(id)) {
|
|
return serviceRegistry.get(id)!;
|
|
}
|
|
|
|
const decorator: any = function (target: Function, key: string, index: number): any {
|
|
if (arguments.length !== 3) {
|
|
throw new Error('@IServiceName-decorator can only be used to decorate a parameter');
|
|
}
|
|
|
|
storeServiceDependency(decorator, target, index);
|
|
};
|
|
|
|
decorator._id = id;
|
|
|
|
serviceRegistry.set(id, decorator);
|
|
return decorator;
|
|
}
|
|
|
|
function storeServiceDependency(id: Function, target: Function, index: number): void {
|
|
if ((target as any)[Constants.DI_TARGET] === target) {
|
|
(target as any)[Constants.DI_DEPENDENCIES].push({ id, index });
|
|
} else {
|
|
(target as any)[Constants.DI_DEPENDENCIES] = [{ id, index }];
|
|
(target as any)[Constants.DI_TARGET] = target;
|
|
}
|
|
}
|