重构tracer设计

This commit is contained in:
2026-02-04 01:07:15 +08:00
parent dbaa8a7785
commit 881185e8cd
13 changed files with 411 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
import { getTracerContext } from '../context';
import type { JsonValue } from '../types';
interface ArrayTracerCreateOptions<T extends JsonValue> {
description?: string;
array?: T[];
}
export const createArrayTracer = <T extends JsonValue>(
options: ArrayTracerCreateOptions<T>,
) => {
const { description = 'ArrayTracer', array } = options;
const tracer = crypto.randomUUID();
const { command } = getTracerContext();
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'create',
params: {
description: description,
array: array,
},
});
const preset = (array: T[]) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'preset',
params: {
array: array,
},
});
};
const scale = (size: number) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'scale',
params: {
size: size,
},
});
};
const pick = (index: number) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'pick',
params: {
index: index,
},
});
};
const drop = (index: number) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'drop',
params: {
index: index,
},
});
};
const patch = (index: number, value: T) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'patch',
params: {
index: index,
value: value,
},
});
};
const unset = (index: number) => {
command({
type: 'ArrayTracer',
tracer: tracer,
action: 'unset',
params: {
index: index,
},
});
};
return {
// preset,
scale,
pick,
drop,
patch,
unset,
};
};

View File

@@ -0,0 +1,81 @@
import { getTracerContext } from '../context';
export const getLocation = (targetFn?: Function) => {
const stackObject: { stack: string } = { stack: '' };
Error.captureStackTrace(stackObject, targetFn ?? getLocation);
const { stack } = stackObject;
// D:\Projects\structrail-sdk\tracers.ts\src\index.ts:23:18
const location = stack.split('\n').at(1)?.trim().split(' ').at(1)?.trim();
// console.log(location);
if (!location) return null;
const matches = location?.match(/:(\d+):?(\d+)?\)?$/);
// console.log(matches);
const file = location?.replace(matches?.at(0) ?? '', '');
// console.log(file);
const line = parseInt(matches?.at(1) ?? '0');
// console.log(line);
return {
file,
line,
};
};
interface ControlTracerCreateOptions {
description?: string;
}
export const createControlTracer = (options: ControlTracerCreateOptions) => {
const { description = 'ControlTracer' } = options;
const tracer = crypto.randomUUID();
const { command } = getTracerContext();
command({
type: 'ControlTracer',
tracer: tracer,
action: 'create',
params: {
description: description,
},
});
const step = (...range: (number | [number, number])[]) => {
const { line: currentLine } = getLocation(step) ?? {};
if (!currentLine) return;
// console.log(currentLine);
const linesSet = new Set<number>([currentLine]);
range.forEach((item) => {
if (Array.isArray(item) && item.length === 2) {
const [offsetStart, offsetEnd] = item;
const lineStart = currentLine - offsetStart;
const lineEnd = currentLine - offsetEnd;
const lineMin = Math.min(lineStart, lineEnd);
const lineMax = Math.max(lineStart, lineEnd);
for (let line = lineMin; line <= lineMax; line++) {
linesSet.add(line);
}
}
if (typeof item === 'number') {
const line = item;
linesSet.add(currentLine - line);
}
});
const lines = Array.from(linesSet).sort((line1, line2) => line1 - line2);
command({
type: 'ControlTracer',
tracer: tracer,
action: 'step',
params: {
lines: lines,
},
});
};
return {
step,
};
};

View File

@@ -0,0 +1,3 @@
export * from './array-tracer';
export * from './control-tracer';
export * from './log-tracer';

View File

@@ -0,0 +1,44 @@
import { getTracerContext } from '../context';
interface LogTracerCreateOptions {
description?: string;
}
export const createLogTracer = (options: LogTracerCreateOptions) => {
const { description = 'LogTracer' } = options;
const tracer = crypto.randomUUID();
const { command } = getTracerContext();
command({
type: 'LogTracer',
tracer: tracer,
action: 'create',
params: {
description: description,
},
});
const log = (...args: unknown[]) => {
const parsed = args.map((arg) => {
if (typeof arg === 'string') {
return arg;
}
return JSON.stringify(arg);
});
const message = parsed.join(' ');
command({
type: 'LogTracer',
tracer: tracer,
action: 'log',
params: {
message: message,
},
});
};
return {
log,
};
};