xfy b1b1c88a74 chore(biome): 引入 Biome v2.5 monorepo 配置并格式化全量源码
新增根 biome.json(v2.5,v2 起原生支持 monorepo,子包自动向上查找):

- formatter: 2 空格缩进、单引号、行宽 100、LF、尾逗号、箭头函数括号
  (匹配现有代码风格)
- linter: recommended preset + 项目化裁剪
  - useTemplate/useTemplate off(geometry.ts 故意保留字符串拼接,
    且测试用精确浮点断言锁定行为)
  - noNonNullAssertion off(测试与 DOM 访问里的 ! 是惯用写法)
  - noConsole off(4 个 lib 用 console.error/warn 做错误上报)
  - CSS 关闭 noDescendingSpecificity/noDuplicateProperties
    (手写 CSS 的 fallback 模式)
  - useImportType/useNodejsImportProtocol/noUnusedVariables warn
- vcs.useIgnoreFile 自动读 .gitignore;排除 public/target/node_modules/
  dist/.dioxus/static + Tailwind 入口 input.css(含 @theme 等 Biome 无法
  解析的 at-rules)

首次格式化覆盖 29 个源文件:import 排序、node: 协议、引号/缩进统一,
并修复 index.ts 两处 forEach 回调隐式返回值(useIterableCallbackReturn)。
90 个 vitest 用例全绿,确认无语义改动。
2026-07-02 17:54:46 +08:00

128 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { PostgreSQL, sql } from '@codemirror/lang-sql';
import { Compartment, EditorState } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { vim } from '@replit/codemirror-vim';
import { basicSetup } from 'codemirror';
import { type ThemeName, themeExtension } from './themes';
/** SQL 补全用 schema 数据(由 Rust 侧从实时库拉取注入)。 */
export interface SqlSchema {
tables: { name: string; columns: string[] }[];
}
/**
* 传给 CodeMirrorEditor.create 的配置。
* 必须是 class非 interface以便 TS 擦除后存活,
* wasm 侧能用 `new EditorOptions()` 构造,并通过 setter 填充字段。
*/
export class EditorOptions {
language?: string;
theme?: ThemeName;
vim?: boolean;
schema?: SqlSchema;
value?: string;
onChange?: (value: string) => void;
onReady?: () => void;
}
/**
* CodeMirror 实例封装。
* create() 时用三个 Compartment 注入 theme/schema/vim
* 支持后续热切换reconfigure而不重建实例——保留 Vim 状态、光标、撤销栈。
*/
export class CodeMirrorInstance {
private view: EditorView;
private themeCompartment = new Compartment();
private schemaCompartment = new Compartment();
private vimCompartment = new Compartment();
constructor(container: HTMLElement, options: EditorOptions) {
const theme: ThemeName = options.theme ?? 'light';
const schema = options.schema ?? { tables: [] };
this.view = new EditorView({
state: EditorState.create({
doc: options.value ?? '',
extensions: [
basicSetup,
// vim 必须在 keymap 最前(@replit/codemirror-vim 仓库要求)
this.vimCompartment.of(options.vim ? [vim()] : []),
this.themeCompartment.of(themeExtension(theme)),
this.schemaCompartment.of(
sql({
dialect: PostgreSQL,
schema: schemaToCompletions(schema),
upperCaseKeywords: true,
}),
),
EditorView.updateListener.of((v) => {
if (v.docChanged) {
options.onChange?.(this.view.state.doc.toString());
}
}),
],
}),
parent: container,
});
options.onReady?.();
}
getValue(): string {
return this.view.state.doc.toString();
}
setValue(s: string): void {
this.view.dispatch({
changes: { from: 0, to: this.view.state.doc.length, insert: s },
});
}
/** 热切换主题不重建实例Compartment.reconfigure。 */
setTheme(theme: ThemeName): void {
this.view.dispatch({
effects: this.themeCompartment.reconfigure(themeExtension(theme)),
});
}
/** 更新 SQL 补全 schemaCompartment.reconfigure。 */
setSchema(schema: SqlSchema): void {
this.view.dispatch({
effects: this.schemaCompartment.reconfigure(
sql({
dialect: PostgreSQL,
schema: schemaToCompletions(schema),
upperCaseKeywords: true,
}),
),
});
}
focus(): void {
this.view.focus();
}
destroy(): void {
this.view.destroy();
}
}
/** 把 SqlSchema 转成 @codemirror/lang-sql 期望的补全结构。 */
function schemaToCompletions(schema: SqlSchema) {
return schema.tables.map((t) => ({
label: t.name,
type: 'table',
detail: 'table',
columns: t.columns.map((c) => ({ label: c, type: 'column' })),
}));
}
// 暴露 EditorOptions 到 window供 wasm-bindgen 用 new EditorOptions()。
// IIFE 的 name 只能挂一个全局CodeMirrorEditor故手动 hoist EditorOptions。
declare global {
interface Window {
EditorOptions: typeof EditorOptions;
}
}
window.EditorOptions = EditorOptions;