refactor(tracers): 统一命令字段名并重构数组追踪器创建逻辑
- 将所有命令的 `params` 字段重命名为 `payload`,以保持命名一致性 - 将 `ArrayTracerCreateOptions` 从联合类型简化为单一接口,移除 `array` 参数,新增 `initial` 和 `walker` 参数 - 引入 `buildInitial` 函数集中处理初始数组的构建逻辑 - 使用 `metadata` 对象管理数组长度状态,替代独立的 `arrayLength` 变量 - 更新错误消息格式,移除方括号前缀 - 调整泛型参数,使 `createArrayTracer` 更通用
This commit is contained in:
@@ -1,44 +1,51 @@
|
||||
import { getTracerContext } from '../context';
|
||||
import type { JsonValue } from '../types';
|
||||
|
||||
interface BaseArrayTracerCreateOptions {
|
||||
interface ArrayTracerCreateOptions<T extends JsonValue> {
|
||||
description?: string;
|
||||
initial?: T[];
|
||||
walker?: (builder: { add: (item: T) => void }) => void;
|
||||
}
|
||||
|
||||
interface ArrayTracerCreateOptionsFromArray<
|
||||
T extends JsonValue[],
|
||||
> extends BaseArrayTracerCreateOptions {
|
||||
array: T;
|
||||
walker?: never;
|
||||
}
|
||||
type ArrayTracerMetadata = {
|
||||
// initial: JsonValue[];
|
||||
length: number;
|
||||
};
|
||||
|
||||
interface ArrayTracerCreateOptionsFromWalker<
|
||||
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[]>(
|
||||
export const createArrayTracer = <T extends JsonValue = JsonValue>(
|
||||
options: ArrayTracerCreateOptions<T>,
|
||||
) => {
|
||||
const { description, array, walker } = options;
|
||||
const { description, initial, walker } = options;
|
||||
const tracer = crypto.randomUUID();
|
||||
|
||||
// 优化:仅维护数组长度作为影子状态,这在 C++/Java 等强类型语言中也极易实现(仅需一个 int 变量)
|
||||
// 这种“最小必要状态”策略既能实现越界校验,又避免了在强类型语言中处理泛型存储的复杂性,且内存开销极低。
|
||||
let arrayLength = array ? array.length : 0;
|
||||
const metadata: ArrayTracerMetadata = {
|
||||
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 validateIndex = (index: number) => {
|
||||
if (index < 0 || index >= arrayLength) {
|
||||
if (index < 0 || index >= metadata.length) {
|
||||
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',
|
||||
tracer: tracer,
|
||||
action: 'create',
|
||||
params: {
|
||||
payload: {
|
||||
description: description ?? 'ArrayTracer',
|
||||
array: array ?? [],
|
||||
initial: buildInitial(),
|
||||
},
|
||||
});
|
||||
|
||||
// size 为正时,数组长度增加;为负时,数组长度减少(但不能小于 0)
|
||||
const scale = (size: number) => {
|
||||
arrayLength += size;
|
||||
if (arrayLength < 0) {
|
||||
metadata.length += size;
|
||||
if (metadata.length < 0) {
|
||||
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',
|
||||
tracer: tracer,
|
||||
action: 'scale',
|
||||
params: {
|
||||
payload: {
|
||||
size: size,
|
||||
},
|
||||
});
|
||||
@@ -79,7 +86,7 @@ export const createArrayTracer = <T extends JsonValue[]>(
|
||||
type: 'ArrayTracer',
|
||||
tracer: tracer,
|
||||
action: 'pick',
|
||||
params: {
|
||||
payload: {
|
||||
index: index,
|
||||
},
|
||||
});
|
||||
@@ -92,20 +99,20 @@ export const createArrayTracer = <T extends JsonValue[]>(
|
||||
type: 'ArrayTracer',
|
||||
tracer: tracer,
|
||||
action: 'drop',
|
||||
params: {
|
||||
payload: {
|
||||
index: index,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const patch = (index: number, value: T[number]) => {
|
||||
const patch = (index: number, value: T) => {
|
||||
validateIndex(index);
|
||||
|
||||
command({
|
||||
type: 'ArrayTracer',
|
||||
tracer: tracer,
|
||||
action: 'patch',
|
||||
params: {
|
||||
payload: {
|
||||
index: index,
|
||||
value: value,
|
||||
},
|
||||
@@ -119,7 +126,7 @@ export const createArrayTracer = <T extends JsonValue[]>(
|
||||
type: 'ArrayTracer',
|
||||
tracer: tracer,
|
||||
action: 'unset',
|
||||
params: {
|
||||
payload: {
|
||||
index: index,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,36 +6,36 @@ type BaseArrayTracerCommand = BaseTracerCommand & {
|
||||
|
||||
type ArrayTracerCreateCommand = BaseArrayTracerCommand & {
|
||||
action: 'create';
|
||||
params: {
|
||||
payload: {
|
||||
description: string;
|
||||
array: JsonValue[];
|
||||
initial: JsonValue[];
|
||||
};
|
||||
};
|
||||
|
||||
type ArrayTracerScaleCommand = BaseArrayTracerCommand & {
|
||||
action: 'scale';
|
||||
params: {
|
||||
payload: {
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
|
||||
type ArrayTracerPickCommand = BaseArrayTracerCommand & {
|
||||
action: 'pick';
|
||||
params: {
|
||||
payload: {
|
||||
index: number;
|
||||
};
|
||||
};
|
||||
|
||||
type ArrayTracerDropCommand = BaseArrayTracerCommand & {
|
||||
action: 'drop';
|
||||
params: {
|
||||
payload: {
|
||||
index: number;
|
||||
};
|
||||
};
|
||||
|
||||
type ArrayTracerPatchCommand = BaseArrayTracerCommand & {
|
||||
action: 'patch';
|
||||
params: {
|
||||
payload: {
|
||||
index: number;
|
||||
value: JsonValue;
|
||||
};
|
||||
@@ -43,7 +43,7 @@ type ArrayTracerPatchCommand = BaseArrayTracerCommand & {
|
||||
|
||||
type ArrayTracerUnsetCommand = BaseArrayTracerCommand & {
|
||||
action: 'unset';
|
||||
params: {
|
||||
payload: {
|
||||
index: number;
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user