refactor(tracers): 统一命令字段名并重构数组追踪器创建逻辑

- 将所有命令的 `params` 字段重命名为 `payload`,以保持命名一致性
- 将 `ArrayTracerCreateOptions` 从联合类型简化为单一接口,移除 `array` 参数,新增 `initial` 和 `walker` 参数
- 引入 `buildInitial` 函数集中处理初始数组的构建逻辑
- 使用 `metadata` 对象管理数组长度状态,替代独立的 `arrayLength` 变量
- 更新错误消息格式,移除方括号前缀
- 调整泛型参数,使 `createArrayTracer` 更通用
This commit is contained in:
2026-03-04 02:34:12 +08:00
parent 2dfc4ced67
commit 9aad52347b
2 changed files with 50 additions and 43 deletions

View File

@@ -1,44 +1,51 @@
import { getTracerContext } from '../context'; import { getTracerContext } from '../context';
import type { JsonValue } from '../types'; import type { JsonValue } from '../types';
interface BaseArrayTracerCreateOptions { interface ArrayTracerCreateOptions<T extends JsonValue> {
description?: string; description?: string;
initial?: T[];
walker?: (builder: { add: (item: T) => void }) => void;
} }
interface ArrayTracerCreateOptionsFromArray< type ArrayTracerMetadata = {
T extends JsonValue[], // initial: JsonValue[];
> extends BaseArrayTracerCreateOptions { length: number;
array: T; };
walker?: never;
}
interface ArrayTracerCreateOptionsFromWalker< export const createArrayTracer = <T extends JsonValue = JsonValue>(
T extends JsonValue[],
> extends BaseArrayTracerCreateOptions {
array?: never;
walker: (commit: (item: T[number]) => void) => void;
}
type ArrayTracerCreateOptions<T extends JsonValue[]> =
| ArrayTracerCreateOptionsFromArray<T>
| ArrayTracerCreateOptionsFromWalker<T>;
export const createArrayTracer = <T extends JsonValue[]>(
options: ArrayTracerCreateOptions<T>, options: ArrayTracerCreateOptions<T>,
) => { ) => {
const { description, array, walker } = options; const { description, initial, walker } = options;
const tracer = crypto.randomUUID(); const tracer = crypto.randomUUID();
// 优化:仅维护数组长度作为影子状态,这在 C++/Java 等强类型语言中也极易实现(仅需一个 int 变量) const metadata: ArrayTracerMetadata = {
// 这种“最小必要状态”策略既能实现越界校验,又避免了在强类型语言中处理泛型存储的复杂性,且内存开销极低。 length: 0,
let arrayLength = array ? array.length : 0; };
const buildInitial = () => {
if (!!initial) {
return [...initial];
}
if (!!walker) {
const initial: T[] = [];
walker({
add: (item) => {
initial.push(item);
},
});
return initial;
}
return [];
};
// console.log(_initial);
const { command } = getTracerContext(); const { command } = getTracerContext();
const validateIndex = (index: number) => { const validateIndex = (index: number) => {
if (index < 0 || index >= arrayLength) { if (index < 0 || index >= metadata.length) {
throw new Error( throw new Error(
`[ArrayTracer] Index out of bounds: index ${index} is not within [0, ${arrayLength})`, `ArrayTracer: Index out of bounds: index ${index} is not within [0, ${metadata.length})`,
); );
} }
}; };
@@ -47,18 +54,18 @@ export const createArrayTracer = <T extends JsonValue[]>(
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'create', action: 'create',
params: { payload: {
description: description ?? 'ArrayTracer', description: description ?? 'ArrayTracer',
array: array ?? [], initial: buildInitial(),
}, },
}); });
// size 为正时,数组长度增加;为负时,数组长度减少(但不能小于 0 // size 为正时,数组长度增加;为负时,数组长度减少(但不能小于 0
const scale = (size: number) => { const scale = (size: number) => {
arrayLength += size; metadata.length += size;
if (arrayLength < 0) { if (metadata.length < 0) {
throw new Error( throw new Error(
`[ArrayTracer] Invalid size: ${size}, array length cannot be negative`, `ArrayTracer: Invalid size: ${size}, array length cannot be negative`,
); );
} }
@@ -66,7 +73,7 @@ export const createArrayTracer = <T extends JsonValue[]>(
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'scale', action: 'scale',
params: { payload: {
size: size, size: size,
}, },
}); });
@@ -79,7 +86,7 @@ export const createArrayTracer = <T extends JsonValue[]>(
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'pick', action: 'pick',
params: { payload: {
index: index, index: index,
}, },
}); });
@@ -92,20 +99,20 @@ export const createArrayTracer = <T extends JsonValue[]>(
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'drop', action: 'drop',
params: { payload: {
index: index, index: index,
}, },
}); });
}; };
const patch = (index: number, value: T[number]) => { const patch = (index: number, value: T) => {
validateIndex(index); validateIndex(index);
command({ command({
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'patch', action: 'patch',
params: { payload: {
index: index, index: index,
value: value, value: value,
}, },
@@ -119,7 +126,7 @@ export const createArrayTracer = <T extends JsonValue[]>(
type: 'ArrayTracer', type: 'ArrayTracer',
tracer: tracer, tracer: tracer,
action: 'unset', action: 'unset',
params: { payload: {
index: index, index: index,
}, },
}); });

View File

@@ -6,36 +6,36 @@ type BaseArrayTracerCommand = BaseTracerCommand & {
type ArrayTracerCreateCommand = BaseArrayTracerCommand & { type ArrayTracerCreateCommand = BaseArrayTracerCommand & {
action: 'create'; action: 'create';
params: { payload: {
description: string; description: string;
array: JsonValue[]; initial: JsonValue[];
}; };
}; };
type ArrayTracerScaleCommand = BaseArrayTracerCommand & { type ArrayTracerScaleCommand = BaseArrayTracerCommand & {
action: 'scale'; action: 'scale';
params: { payload: {
size: number; size: number;
}; };
}; };
type ArrayTracerPickCommand = BaseArrayTracerCommand & { type ArrayTracerPickCommand = BaseArrayTracerCommand & {
action: 'pick'; action: 'pick';
params: { payload: {
index: number; index: number;
}; };
}; };
type ArrayTracerDropCommand = BaseArrayTracerCommand & { type ArrayTracerDropCommand = BaseArrayTracerCommand & {
action: 'drop'; action: 'drop';
params: { payload: {
index: number; index: number;
}; };
}; };
type ArrayTracerPatchCommand = BaseArrayTracerCommand & { type ArrayTracerPatchCommand = BaseArrayTracerCommand & {
action: 'patch'; action: 'patch';
params: { payload: {
index: number; index: number;
value: JsonValue; value: JsonValue;
}; };
@@ -43,7 +43,7 @@ type ArrayTracerPatchCommand = BaseArrayTracerCommand & {
type ArrayTracerUnsetCommand = BaseArrayTracerCommand & { type ArrayTracerUnsetCommand = BaseArrayTracerCommand & {
action: 'unset'; action: 'unset';
params: { payload: {
index: number; index: number;
}; };
}; };