refactor(editor): remove selection global types (#9532)

Closes: [BS-2217](https://linear.app/affine-design/issue/BS-2217/remove-global-types-in-selection)
This commit is contained in:
Saul-Mirone
2025-01-06 03:45:10 +00:00
parent 8669936f2f
commit fc863e484c
105 changed files with 501 additions and 358 deletions
@@ -1,10 +1,6 @@
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
type SelectionConstructor<T = unknown> = {
type: string;
group: string;
new (...args: unknown[]): T;
};
import type { SelectionConstructor } from './manager';
export type BaseSelectionOptions = {
blockId: string;
@@ -21,9 +17,8 @@ export abstract class BaseSelection {
return (this.constructor as SelectionConstructor).group;
}
get type(): BlockSuite.SelectionType {
return (this.constructor as SelectionConstructor)
.type as BlockSuite.SelectionType;
get type(): string {
return (this.constructor as SelectionConstructor).type as string;
}
constructor({ blockId }: BaseSelectionOptions) {
@@ -39,10 +34,10 @@ export abstract class BaseSelection {
abstract equals(other: BaseSelection): boolean;
is<T extends BlockSuite.SelectionType>(
is<T extends SelectionConstructor>(
type: T
): this is BlockSuite.SelectionInstance[T] {
return this.type === type;
): this is T extends SelectionConstructor<infer U> ? U : never {
return this.type === type.type;
}
abstract toJSON(): Record<string, unknown>;
@@ -1,27 +1,3 @@
import type {
BlockSelection,
CursorSelection,
SurfaceSelection,
TextSelection,
} from './variants/index.js';
export * from './base.js';
export * from './manager.js';
export * from './variants/index.js';
declare global {
namespace BlockSuite {
interface Selection {
block: typeof BlockSelection;
cursor: typeof CursorSelection;
surface: typeof SurfaceSelection;
text: typeof TextSelection;
}
type SelectionType = keyof Selection;
type SelectionInstance = {
[P in SelectionType]: InstanceType<Selection[P]>;
};
}
}
@@ -8,11 +8,12 @@ import { SelectionIdentifier } from '../identifier.js';
import type { BlockStdScope } from '../scope/index.js';
import type { BaseSelection } from './base.js';
export interface SelectionConstructor {
export interface SelectionConstructor<T extends BaseSelection = BaseSelection> {
type: string;
group: string;
new (...args: any[]): BaseSelection;
fromJSON(json: Record<string, unknown>): BaseSelection;
new (...args: any[]): T;
fromJSON(json: Record<string, unknown>): T;
}
export class SelectionManager extends LifeCycleWatcher {
@@ -143,18 +144,11 @@ export class SelectionManager extends LifeCycleWatcher {
}
}
create<T extends BlockSuite.SelectionType>(
type: T,
...args: ConstructorParameters<BlockSuite.Selection[T]>
): BlockSuite.SelectionInstance[T] {
const ctor = this._selectionConstructors[type];
if (!ctor) {
throw new BlockSuiteError(
ErrorCode.SelectionError,
`Unknown selection type: ${type}`
);
}
return new ctor(...args) as BlockSuite.SelectionInstance[T];
create<T extends SelectionConstructor>(
Type: T,
...args: ConstructorParameters<T>
): InstanceType<T> {
return new Type(...args) as InstanceType<T>;
}
dispose() {
@@ -162,27 +156,23 @@ export class SelectionManager extends LifeCycleWatcher {
this.disposables.dispose();
}
filter<T extends BlockSuite.SelectionType>(type: T) {
filter<T extends SelectionConstructor>(type: T) {
return this.filter$(type).value;
}
filter$<T extends BlockSuite.SelectionType>(type: T) {
filter$<T extends SelectionConstructor>(type: T) {
return computed(() =>
this.value.filter((sel): sel is BlockSuite.SelectionInstance[T] =>
sel.is(type)
)
this.value.filter((sel): sel is InstanceType<T> => sel.is(type))
);
}
find<T extends BlockSuite.SelectionType>(type: T) {
find<T extends SelectionConstructor>(type: T) {
return this.find$(type).value;
}
find$<T extends BlockSuite.SelectionType>(type: T) {
find$<T extends SelectionConstructor>(type: T) {
return computed(() =>
this.value.find((sel): sel is BlockSuite.SelectionInstance[T] =>
sel.is(type)
)
this.value.find((sel): sel is InstanceType<T> => sel.is(type))
);
}