rj-grid 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +92 -0
  3. package/dist/rj-grid.js +14074 -0
  4. package/dist/style.css +2050 -0
  5. package/dist/types/index.d.ts +13 -0
  6. package/dist/types/src/RjAdvGroup.vue.d.ts +32 -0
  7. package/dist/types/src/RjAdvancedFilterDialog.vue.d.ts +38 -0
  8. package/dist/types/src/RjCell.vue.d.ts +82 -0
  9. package/dist/types/src/RjChartDialog.vue.d.ts +22 -0
  10. package/dist/types/src/RjColumnMenu.vue.d.ts +109 -0
  11. package/dist/types/src/RjConfirmDialog.vue.d.ts +23 -0
  12. package/dist/types/src/RjContextMenu.vue.d.ts +26 -0
  13. package/dist/types/src/RjEditor.vue.d.ts +28 -0
  14. package/dist/types/src/RjFilterMenu.vue.d.ts +58 -0
  15. package/dist/types/src/RjGrid.vue.d.ts +1046 -0
  16. package/dist/types/src/RjHeader.vue.d.ts +80 -0
  17. package/dist/types/src/RjImgList.vue.d.ts +29 -0
  18. package/dist/types/src/RjPager.vue.d.ts +41 -0
  19. package/dist/types/src/RjQueryBar.vue.d.ts +47 -0
  20. package/dist/types/src/RjRowFormDialog.vue.d.ts +50 -0
  21. package/dist/types/src/RjSlotRender.d.ts +56 -0
  22. package/dist/types/src/RjSparkline.vue.d.ts +43 -0
  23. package/dist/types/src/RjToolPanel.vue.d.ts +103 -0
  24. package/dist/types/src/RjViewManager.vue.d.ts +28 -0
  25. package/dist/types/src/editHistory.d.ts +27 -0
  26. package/dist/types/src/export.d.ts +24 -0
  27. package/dist/types/src/expression.d.ts +19 -0
  28. package/dist/types/src/filtering.d.ts +29 -0
  29. package/dist/types/src/formula.d.ts +88 -0
  30. package/dist/types/src/icons.d.ts +35 -0
  31. package/dist/types/src/locale.d.ts +21 -0
  32. package/dist/types/src/nlq.d.ts +51 -0
  33. package/dist/types/src/print.d.ts +37 -0
  34. package/dist/types/src/query.d.ts +28 -0
  35. package/dist/types/src/rowForm.d.ts +41 -0
  36. package/dist/types/src/serverGroups.d.ts +52 -0
  37. package/dist/types/src/ssrm.d.ts +102 -0
  38. package/dist/types/src/theme.d.ts +33 -0
  39. package/dist/types/src/types.d.ts +624 -0
  40. package/dist/types/src/useColumnState.d.ts +70 -0
  41. package/dist/types/src/useInteraction.d.ts +150 -0
  42. package/dist/types/src/useQueryViews.d.ts +16 -0
  43. package/dist/types/src/useRowModel.d.ts +225 -0
  44. package/dist/types/src/utils.d.ts +130 -0
  45. package/package.json +90 -0
@@ -0,0 +1,88 @@
1
+ export type CellValue = number | string | boolean | null | undefined;
2
+ export type FormulaValue = number | string | boolean;
3
+ /** 求值上下文:列顺序 + 行数 + 取值器(0 基行列) */
4
+ export interface FormulaCtx {
5
+ /** 有序列标识(colId 或 field),A/B/C 按索引映射 */
6
+ columns: string[];
7
+ /** 数据行数(用于整列/相对行的边界与 #REF! 判定) */
8
+ rowCount: number;
9
+ /** 读取原始单元格值 */
10
+ getValue: (col: number, row: number) => CellValue;
11
+ }
12
+ /** 单元格坐标(0 基) */
13
+ export interface CellCoord {
14
+ col: number;
15
+ row: number;
16
+ }
17
+ /** 依赖项:某段列区间内的行范围(whole=true 表示整列跨所有行) */
18
+ export interface FormulaDep {
19
+ c1: number;
20
+ c2: number;
21
+ r1: number;
22
+ r2: number;
23
+ whole: boolean;
24
+ }
25
+ export declare const ERR: {
26
+ readonly REF: "#REF!";
27
+ readonly VALUE: "#VALUE!";
28
+ readonly NAME: "#NAME?";
29
+ readonly DIV0: "#DIV/0!";
30
+ readonly NUM: "#NUM!";
31
+ readonly NA: "#N/A";
32
+ readonly CIRC: "#CIRCULAR!";
33
+ };
34
+ /** 是否为公式文本(以 = 开头) */
35
+ export declare function isFormula(v: any): v is string;
36
+ export declare function lettersToCol(s: string): number;
37
+ export declare function colToLetters(idx: number): string;
38
+ type NumNode = {
39
+ t: 'num';
40
+ v: number;
41
+ };
42
+ type StrNode = {
43
+ t: 'str';
44
+ v: string;
45
+ };
46
+ type BoolNode = {
47
+ t: 'bool';
48
+ v: boolean;
49
+ };
50
+ type RefNode = {
51
+ t: 'ref';
52
+ token: string;
53
+ };
54
+ type FuncNode = {
55
+ t: 'func';
56
+ name: string;
57
+ args: AstNode[];
58
+ };
59
+ type BinNode = {
60
+ t: 'bin';
61
+ op: string;
62
+ l: AstNode;
63
+ r: AstNode;
64
+ };
65
+ type UnNode = {
66
+ t: 'un';
67
+ op: string;
68
+ e: AstNode;
69
+ };
70
+ type PctNode = {
71
+ t: 'pct';
72
+ e: AstNode;
73
+ };
74
+ export type AstNode = NumNode | StrNode | BoolNode | RefNode | FuncNode | BinNode | UnNode | PctNode;
75
+ /** 对外解析:失败返回 null */
76
+ export declare function parse(input: string): AstNode | null;
77
+ /** 提取依赖(供依赖图 / 循环检测使用) */
78
+ export declare function collectDeps(ast: AstNode, ctx: FormulaCtx): FormulaDep[];
79
+ /**
80
+ * 求值公式,返回结果值;错误以哨兵字符串返回(不抛出)。
81
+ * @param input 公式文本(可含前导 =)
82
+ * @param ctx 求值上下文
83
+ * @param at 当前单元格坐标(相对/整列引用解析用)
84
+ */
85
+ export declare function evaluate(input: string, ctx: FormulaCtx, at: CellCoord): FormulaValue;
86
+ /** 解析并求值(已编译 AST 复用场景) */
87
+ export declare function evaluateAst(ast: AstNode, ctx: FormulaCtx, at: CellCoord): FormulaValue;
88
+ export {};
@@ -0,0 +1,35 @@
1
+ import type { InjectionKey, ComputedRef } from 'vue';
2
+ /** 内置图标名(可扩展的语义键) */
3
+ export declare const RJ_DEFAULT_ICONS: {
4
+ readonly sortAscending: "▲";
5
+ readonly sortDescending: "▼";
6
+ readonly sortUnSort: "⇅";
7
+ readonly filter: "▼";
8
+ readonly columnMenu: "⋮";
9
+ readonly rowDrag: "⠿";
10
+ readonly menuGeneral: "☰";
11
+ readonly menuFilter: "⏷";
12
+ readonly menuColumns: "▤";
13
+ readonly checked: "✓";
14
+ readonly indeterminate: "–";
15
+ readonly rowGroupOpen: "▾";
16
+ readonly rowGroupClose: "▸";
17
+ readonly expand: "▸";
18
+ readonly collapse: "▾";
19
+ readonly pin: "📌";
20
+ readonly visible: "👁";
21
+ readonly hidden: "🚫";
22
+ readonly remove: "✕";
23
+ /** 浮层/对话框关闭按钮(与 remove 同字形,语义分开便于单独覆盖) */
24
+ readonly close: "✕";
25
+ readonly add: "+";
26
+ readonly submenuRight: "▸";
27
+ };
28
+ export type RjIconName = keyof typeof RJ_DEFAULT_ICONS;
29
+ export type RjIcons = Record<RjIconName, string>;
30
+ /** 用户可传入的部分覆盖 */
31
+ export type RjIconsOverride = Partial<RjIcons>;
32
+ /** 合并默认图标与覆盖(空串/未定义不覆盖)——纯函数 */
33
+ export declare function mergeIcons(overrides?: RjIconsOverride): RjIcons;
34
+ /** 注入键:网格根 provide,子组件 inject 消费 */
35
+ export declare const RJ_ICONS_KEY: InjectionKey<ComputedRef<RjIcons>>;
@@ -0,0 +1,21 @@
1
+ import type { InjectionKey } from 'vue';
2
+ export type RjMessages = Record<string, string>;
3
+ export type RjLang = 'zh' | 'en';
4
+ /** 中文(默认)文案目录:既是内置默认,也是英文目录缺失键的回退 */
5
+ export declare const zhCN: RjMessages;
6
+ /** 英文文案:以中文为底,逐键覆盖,缺失键自动回退中文 */
7
+ export declare const enUS: RjMessages;
8
+ export declare const RJ_PRESETS: Record<RjLang, RjMessages>;
9
+ /** 归一语言标识:zh-CN/zh_TW/en-US/en 等 → 'zh' | 'en' */
10
+ export declare function normalizeLang(lang?: string): RjLang;
11
+ /** 解析最终文案表:预设底 + 局部覆盖(override 优先级最高) */
12
+ export declare function resolveMessages(lang?: string, override?: RjMessages | null): RjMessages;
13
+ /** 插值:把 {key} 替换为 params[key] */
14
+ export declare function interpolate(str: string, params?: Record<string, string | number>): string;
15
+ /** 翻译查表:命中返回并插值,未命中返回 key 本身(便于发现漏译) */
16
+ export declare function translate(messages: RjMessages, key: string, params?: Record<string, string | number>): string;
17
+ export type RjTranslate = (key: string, params?: Record<string, string | number>) => string;
18
+ /** 注入键:网格根 provide 翻译函数,子组件 inject 消费 */
19
+ export declare const RJ_LOCALE_KEY: InjectionKey<RjTranslate>;
20
+ /** 子组件默认翻译函数(未 inject 到时回退,避免单独使用时崩溃) */
21
+ export declare const defaultTranslate: RjTranslate;
@@ -0,0 +1,51 @@
1
+ import type { RjFilterModel, RjSortState } from './types';
2
+ export type RjNlqFilterType = 'text' | 'number' | 'date' | 'select';
3
+ /** 参与解析的列描述(由网格从列定义构建) */
4
+ export interface RjNlqColumn {
5
+ colId: string;
6
+ field?: string;
7
+ title?: string;
8
+ filterType: RjNlqFilterType;
9
+ /** 额外可识别的别名(不含 title/field) */
10
+ aliases?: string[];
11
+ /** select / 低基数列的候选值,用于把口语值映射到真实值 */
12
+ options?: string[];
13
+ /** options 来自列定义(权威枚举):此时拒绝候选之外的口语值;数据采样的 options 不拒绝 */
14
+ strictOptions?: boolean;
15
+ }
16
+ /** 单条解析出的列筛选条件 */
17
+ export interface RjNlqClause {
18
+ colId: string;
19
+ field?: string;
20
+ title?: string;
21
+ filterType: RjNlqFilterType;
22
+ op: string;
23
+ value1?: any;
24
+ value2?: any;
25
+ /** 与前一条件是否 OR 连接 */
26
+ or: boolean;
27
+ raw: string;
28
+ }
29
+ /** 解析结果 */
30
+ export interface RjNlqResult {
31
+ ok: boolean;
32
+ /** 空查询 / 无法识别 时的说明键(交由 i18n 展示) */
33
+ message?: 'empty' | 'unrecognized';
34
+ /** 按列聚合后的筛选模型(跨列 AND,与网格既有语义一致) */
35
+ filters: {
36
+ colId: string;
37
+ field?: string;
38
+ title?: string;
39
+ model: RjFilterModel;
40
+ }[];
41
+ sort?: RjSortState;
42
+ groupBy?: string;
43
+ groupColId?: string;
44
+ limit?: number;
45
+ search?: string;
46
+ clauses: RjNlqClause[];
47
+ }
48
+ /** 解析自然语言查询 */
49
+ export declare function parseNLQ(text: string, columns: RjNlqColumn[]): RjNlqResult;
50
+ /** 生成人类可读的解析摘要(供 UI 回显,key 交由上层 i18n;此处给结构串) */
51
+ export declare function explainNLQ(r: RjNlqResult): string;
@@ -0,0 +1,37 @@
1
+ import type { RjPrintOptions } from './types';
2
+ export type { RjPrintOptions };
3
+ /** 打印列描述(叶子列) */
4
+ export interface RjPrintColumn {
5
+ title: string;
6
+ /** 期望宽度(px);用于 colgroup 按比例分配,缩放适配时可忽略 */
7
+ width?: number;
8
+ align?: 'left' | 'center' | 'right';
9
+ }
10
+ /** 多级列头单元格:colSpan 之和须等于列数 */
11
+ export interface RjPrintHeaderCell {
12
+ title: string;
13
+ colSpan: number;
14
+ /** 跨行(叶子列在多级表头中占据到表头底部),默认 1 */
15
+ rowSpan?: number;
16
+ }
17
+ /** buildPrintHtml 输入:列 + 可选多级列头 + 纯数据行(不含表头) */
18
+ export interface RjPrintInput {
19
+ columns: RjPrintColumn[];
20
+ /** 外层在前,逐层向下;缺省时用 columns.title 作单层表头 */
21
+ headerLevels?: RjPrintHeaderCell[][];
22
+ /** 仅数据行;行内元素按 columns 顺序 */
23
+ matrix: any[][];
24
+ /** 与 matrix 对齐的行样式:0 普通 / 1 分组小计 / 2 总计汇总 */
25
+ rowStyles?: number[];
26
+ }
27
+ /** 页码文案模板(内置中文兜底;实际取词由调用端经 pageNumberText 注入当前语言) */
28
+ export declare const DEFAULT_PAGE_TEXT = "\u7B2C {p} \u9875 / \u5171 {t} \u9875";
29
+ /** 构造打印文档 HTML(纯函数,确定性输出) */
30
+ export declare function buildPrintHtml(input: RjPrintInput, opts?: RjPrintOptions): string;
31
+ /**
32
+ * 打开隐藏 iframe 并调用浏览器打印(打印对话框可「另存为 PDF」)。
33
+ * 返回文档 HTML 长度仅供调用方参考;打印后自动清理 iframe。
34
+ */
35
+ export declare function openPrintDialog(html: string): void;
36
+ /** 便捷封装:构造 HTML 并立即打印 */
37
+ export declare function printHtml(input: RjPrintInput, opts?: RjPrintOptions): void;
@@ -0,0 +1,28 @@
1
+ import type { RjColumn, RjEditorOption, RjQueryCondition, RjQueryFieldDef, RjQueryFieldKind, RjQueryOperator } from './types';
2
+ /** 由列类型/筛选/编辑器推导查询字段类别 */
3
+ export declare function kindOfColumn(col: RjColumn): RjQueryFieldKind;
4
+ /** 取列的下拉候选:editor.options(静态)或 filterValueMap(枚举映射) */
5
+ export declare function optionsOfColumn(col: RjColumn): RjEditorOption[];
6
+ /**
7
+ * 从列定义派生查询字段候选池:
8
+ * - 跳过无 field / 内部列 / 显式 filter:false 的列;
9
+ * - 用 override 覆盖标题、类别或候选(宿主可为枚举列补 options)。
10
+ */
11
+ export declare function deriveQueryFields(columns: RjColumn[], override?: RjQueryFieldDef[]): RjQueryFieldDef[];
12
+ /** 各类别对应的合理运算符集合 */
13
+ export declare function queryOpsOfKind(kind: RjQueryFieldKind): RjQueryOperator[];
14
+ /** 新增字段时的默认运算符(取该类别最常用的一项) */
15
+ export declare function defaultQueryOperator(kind: RjQueryFieldKind): RjQueryOperator;
16
+ /** 条件是否已填值(刚挂字段还没输入的不参与过滤) */
17
+ export declare function queryHasValue(c: RjQueryCondition): boolean;
18
+ /** 生效(已填值)的条件集合 */
19
+ export declare function activeQueryConditions(list: RjQueryCondition[]): RjQueryCondition[];
20
+ /**
21
+ * 单元格原始值与单个条件比对(纯函数:调用方负责取值)。
22
+ * 日期类走时间戳、数值类走 Number、其余走字符串宽松比较。
23
+ */
24
+ export declare function matchQueryValue(rawValue: any, c: RjQueryCondition, kind?: RjQueryFieldKind): boolean;
25
+ /** 行是否通过全部生效条件(AND);colOf 提供该列定义以决定取值口径与类别 */
26
+ export declare function rowPassesQuery(row: RjRowDataLike, conds: RjQueryCondition[], colOf: (field: string) => RjColumn | undefined): boolean;
27
+ type RjRowDataLike = Record<string, any>;
28
+ export {};
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 内置行编辑弹窗的纯逻辑:表单字段推导 + 批量写入 + 按钮禁用求值。
3
+ * 不依赖 DOM / Vue,单测直接驱动(__tests__/rowForm.spec.ts)。
4
+ */
5
+ import type { RjColumn, RjEditorConfig, RjEditorOption, RjQueryAction, RjRowData, RjRowFormConfig } from './types';
6
+ /** 表单控件类型(由列的 editor/type 归一而来) */
7
+ export type RjFormFieldKind = 'text' | 'number' | 'date' | 'select' | 'textarea' | 'checkbox';
8
+ /** 单个表单字段:弹窗按此渲染,validator/col 原样带上供提交校验 */
9
+ export interface RjFormField {
10
+ field: string;
11
+ colId: string;
12
+ title: string;
13
+ kind: RjFormFieldKind;
14
+ options: RjEditorOption[];
15
+ /** textarea 行数 */
16
+ rows: number;
17
+ validator?: RjEditorConfig['validator'];
18
+ col: RjColumn;
19
+ }
20
+ /** 列上的 editor 声明归一为配置对象(editor 可为裸类型字符串) */
21
+ export declare function normalizeEditor(col: RjColumn): RjEditorConfig | undefined;
22
+ /** 控件类型:editor.type 优先,否则由列预设 type 映射;custom 无法进表单,回落文本 */
23
+ export declare function formFieldKind(col: RjColumn, editor?: RjEditorConfig): RjFormFieldKind;
24
+ /** 由可见叶子列生成表单字段(sampleRows 用于对函数形式的 editor.options 求值) */
25
+ export declare function buildFormFields(cols: RjColumn[], cfg: RjRowFormConfig | undefined, sampleRows: RjRowData[]): RjFormField[];
26
+ /**
27
+ * 把 { field: value } 批量写入每一行(原地改,配合 applyTransaction({ update }) 使用)。
28
+ * changes 只含弹窗里勾选过的字段,未勾选字段天然不覆盖。
29
+ */
30
+ export declare function applyFormChanges(rows: RjRowData[], changes: Record<string, any>): RjRowData[];
31
+ /**
32
+ * 新增弹窗提交:由 preset 浅拷 + 表单值组装新行对象(不改动 preset 本身)。
33
+ * 主键/默认值等由宿主在 row-form-add 里补齐后调后端,组件只负责形状。
34
+ */
35
+ export declare function createFormRow(preset: RjRowData | undefined, changes: Record<string, any>): RjRowData;
36
+ /** 读某行在某字段上的当前值(表单预填用,走 a.b.c 路径) */
37
+ export declare function fieldValue(row: RjRowData, field: string): any;
38
+ /** 查询栏按钮禁用求值:布尔直通,函数按选中行判定 */
39
+ export declare function queryActionDisabled(action: RjQueryAction, rows: RjRowData[]): boolean;
40
+ /** 查询栏按钮确认文案求值(无 confirm 返回空串) */
41
+ export declare function queryActionConfirm(action: RjQueryAction, rows: RjRowData[]): string;
@@ -0,0 +1,52 @@
1
+ import type { RjRowData } from './types';
2
+ import type { RjDisplayRow } from './useRowModel';
3
+ /** 某组的懒取子项状态(由行模型持有,避免在纯函数里发请求) */
4
+ export interface SgChildState {
5
+ /** 已取回的子项平铺序列(空数组 = 后端确认无子行;与「取数失败」不同一状态) */
6
+ kids?: RjRowData[];
7
+ /** 正在取 */
8
+ loading?: boolean;
9
+ /** 本代取数连续失败到上限:不再渲染子行、也不再登记请求(重取数/改分组/清缓存后自然恢复) */
10
+ error?: boolean;
11
+ }
12
+ /** 组元信息(按 path 索引,供子块取数参数复用,免去反解 path) */
13
+ export interface SgGroupMeta {
14
+ level: number;
15
+ /** 该层级的分组字段 */
16
+ field: string;
17
+ /** 从根到本组的组值路径 */
18
+ values: any[];
19
+ }
20
+ /** 待取子块的组 */
21
+ export interface SgNeedLoad extends SgGroupMeta {
22
+ path: string;
23
+ }
24
+ export interface SgFlattenOptions {
25
+ /** 分组字段,按层级顺序(与后端 __level 对应) */
26
+ fields: string[];
27
+ /** 行主键 */
28
+ keyOf: (row: RjRowData) => string | number;
29
+ rowHeight: number;
30
+ /** 被收起的组 path(默认全部展开,与后端已内联返回子行的观感一致) */
31
+ collapsed?: Set<string>;
32
+ /** path → 懒取子项状态 */
33
+ childMap?: Map<string, SgChildState>;
34
+ /** 宿主判定某组行是否可展开(对应 isServerSideGroup);缺省时按「有子行就可展开」推断 */
35
+ isExpandable?: (row: RjRowData) => boolean;
36
+ }
37
+ export interface SgFlattenResult {
38
+ rows: RjDisplayRow[];
39
+ /** 需要发起 type:'group' 子块请求的组(调用方去重后取数,回填 childMap) */
40
+ needLoad: SgNeedLoad[];
41
+ /** 本次出现过的全部组(path → 元信息) */
42
+ metas: Map<string, SgGroupMeta>;
43
+ /** 与 rows 等长:显示下标 → 输入序列绝对下标(-1 = 非输入序列行,如懒取子行/组占位) */
44
+ absAt: number[];
45
+ }
46
+ /**
47
+ * 补齐组行契约字段(__path/__level/__groupField/__groupValue/__groupLabels)。
48
+ * 后端给全就原样返回;缺则浅拷贝补齐,不修改源对象。
49
+ */
50
+ export declare function decorateGroupRow(row: RjRowData, path: string, level: number, field: string, value: any, labels: any[]): RjRowData;
51
+ /** 平铺(可含未加载空洞)→ 显示行序列 + 待取子块 + 下标映射 */
52
+ export declare function flattenServerGroups(items: (RjRowData | undefined)[], opts: SgFlattenOptions): SgFlattenResult;
@@ -0,0 +1,102 @@
1
+ import type { RjRowData, RjTransaction } from './types';
2
+ /** 块加载状态(仅描述进行中的请求,已加载由覆盖度派生) */
3
+ export interface SsrmInflight {
4
+ seq: number;
5
+ status: 'loading' | 'error';
6
+ }
7
+ export interface SsrmStoreOptions {
8
+ /** 每块行数 */
9
+ blockSize: number;
10
+ /** 缓存中最多保留的已加载块数(0/undefined = 不限);超出按 LRU 淘汰 */
11
+ maxBlocksInCache?: number;
12
+ /** 视口外额外保留块数 */
13
+ cacheOverflow?: number;
14
+ /** 取行主键 */
15
+ keyOf: (row: RjRowData) => string | number;
16
+ }
17
+ export interface SsrmDeltaResult {
18
+ /** 受影响的绝对行下标(供局部重绘) */
19
+ changed: number[];
20
+ /** 需要闪烁高亮的 key */
21
+ flash: (string | number)[];
22
+ /** 结构是否发生变化(add/remove 导致行位移) */
23
+ structural: boolean;
24
+ }
25
+ export declare class SsrmStore {
26
+ /** 服务端总行数;-1 表示未知(尚未收到 total) */
27
+ rowCount: number;
28
+ readonly blockSize: number;
29
+ readonly maxBlocksInCache: number;
30
+ readonly cacheOverflow: number;
31
+ private readonly keyOf;
32
+ /** dense 行槽:长度 = max(rowCount,0);undefined 表示未加载 */
33
+ slots: (RjRowData | undefined)[];
34
+ /** 每个块的进行中标记(loading / error 重试) */
35
+ private inflight;
36
+ /** 每块的最近访问时间(LRU),仅在覆盖完整时有效 */
37
+ private touch;
38
+ private clock;
39
+ private seq;
40
+ constructor(opts: SsrmStoreOptions);
41
+ blockIndexOf(row: number): number;
42
+ startRowOf(blockIndex: number): number;
43
+ /** 块实际结束行(不含);末块受 rowCount 截断 */
44
+ endRowOf(blockIndex: number): number;
45
+ blockCount(): number;
46
+ /** 该块行区间是否被完全填充(= 已加载) */
47
+ isBlockLoaded(blockIndex: number): boolean;
48
+ /** 设定/更新总数并调整 slots 长度,保留已加载内容 */
49
+ configure(total: number): void;
50
+ reset(): void;
51
+ rowAt(i: number): RjRowData | undefined;
52
+ loadedRowCount(): number;
53
+ /**
54
+ * 规划需要请求的块:覆盖 [first-prefetch, last+prefetch] 且未加载、非进行中的块,
55
+ * 按「距视口中心由近及远」排序(优先补最可见处)。
56
+ */
57
+ planLoad(first: number, last: number, prefetch?: number): number[];
58
+ /** 标记块开始加载,返回本次请求的 seq(用于竞态守卫) */
59
+ beginLoad(blockIndex: number): number;
60
+ /** 提交块数据:seq 过期则丢弃;写入 slots;返回是否被应用 */
61
+ commitLoad(blockIndex: number, seq: number, rows: RjRowData[]): boolean;
62
+ /** 标记块加载失败(可重试) */
63
+ failLoad(blockIndex: number, seq: number): void;
64
+ isLoadingAny(): boolean;
65
+ /** 指定块是否正在加载中(用于 boot 块去重) */
66
+ isBlockBusy(blockIndex: number): boolean;
67
+ /**
68
+ * 依据保留集合淘汰「已加载且不在 keep 内」的块,按 LRU(touch 时钟)优先淘汰最久未用。
69
+ * 进行中的块永不淘汰。返回被淘汰的块索引。
70
+ */
71
+ prune(keep: Set<number>): number[];
72
+ /** keep 集合:视口块 ± cacheOverflow */
73
+ keepSet(first: number, last: number): Set<number>;
74
+ /**
75
+ * 对已加载内容应用增量:
76
+ * - update:按 key 原地替换已加载行(不位移),闪烁;
77
+ * - upsert:命中已加载则更新,否则忽略(服务端权威,避免破坏块区间);
78
+ * - add:追加到末尾(rowCount++),闪烁;
79
+ * - remove:按 key 从已加载槽移除并左移尾块(structural)。
80
+ */
81
+ applyDelta(tx: RjTransaction): SsrmDeltaResult;
82
+ }
83
+ /**
84
+ * 把多次事务在「一次刷新」内合并后统一应用,降低高频推送的重排/重绘成本。
85
+ * 合并规则:remove 的 key 覆盖之前对同 key 的 add/update;后到的 update 覆盖先到的。
86
+ */
87
+ export type SsrmTxApplier = (tx: RjTransaction) => void;
88
+ export declare class SsrmTxBatcher {
89
+ private queue;
90
+ private scheduled;
91
+ private apply;
92
+ private defer;
93
+ constructor(apply: SsrmTxApplier, opts?: {
94
+ defer?: (fn: () => void) => void;
95
+ });
96
+ push(tx: RjTransaction): void;
97
+ /** 立即合并并应用队列(返回合并后的事务,便于测试/回调) */
98
+ flush(): RjTransaction;
99
+ get pending(): number;
100
+ }
101
+ /** 合并多笔事务为一笔:同 key 后者胜;remove 压制 add/update */
102
+ export declare function mergeTransactions(list: RjTransaction[]): RjTransaction;
@@ -0,0 +1,33 @@
1
+ export interface RjThemeParams {
2
+ /** 预设风格:legacy=沿用内置默认;其余为 AG Grid 风格预设 */
3
+ preset?: 'legacy' | 'alpine' | 'quartz' | 'material';
4
+ /** 明暗模式:auto 由组件按系统偏好解析后传入具体值 */
5
+ mode?: 'light' | 'dark' | 'auto';
6
+ /** 主强调色(选中/悬停/焦点等派生色的基准) */
7
+ accentColor?: string;
8
+ /** 单元格/主体背景 */
9
+ backgroundColor?: string;
10
+ /** 斑马纹奇/偶行背景 */
11
+ oddRowBackgroundColor?: string;
12
+ /** 表头背景 */
13
+ headerBackgroundColor?: string;
14
+ /** 边框色 */
15
+ borderColor?: string;
16
+ /** 主文本色 */
17
+ foregroundColor?: string;
18
+ /** 次要文本色 */
19
+ secondaryForegroundColor?: string;
20
+ /** 字号 */
21
+ fontSize?: number | string;
22
+ /** 圆角 */
23
+ radius?: number | string;
24
+ /** 直接覆盖任意 --rj-* 变量(逃生舱) */
25
+ vars?: Record<string, string>;
26
+ }
27
+ /**
28
+ * 把主题参数编译为 CSS 变量集合(仅包含需要覆盖的键,未设置的键沿用 scss 默认)。
29
+ * 纯函数:无 DOM / 无时间戳 / 无随机,确定性可单测/快照。
30
+ */
31
+ export declare function buildThemeVars(params?: RjThemeParams): Record<string, string>;
32
+ /** 解析 auto → light/dark(组件侧调用,注入 matchMedia 判定结果) */
33
+ export declare function resolveMode(mode: RjThemeParams['mode'], prefersDark: boolean): 'light' | 'dark';