重构tracer设计
This commit is contained in:
1
tracers.ts/src/context/index.ts
Normal file
1
tracers.ts/src/context/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './tracer-context';
|
||||||
22
tracers.ts/src/context/tracer-context.ts
Normal file
22
tracers.ts/src/context/tracer-context.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import type { TracerCommand } from '../types';
|
||||||
|
|
||||||
|
const createTracerContext = () => {
|
||||||
|
const commands: TracerCommand[] = [];
|
||||||
|
|
||||||
|
const getTracerContext = () => {
|
||||||
|
const command = (command: TracerCommand) => {
|
||||||
|
commands.push(command);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
commands,
|
||||||
|
command,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
getTracerContext,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const { getTracerContext } = createTracerContext();
|
||||||
20
tracers.ts/src/index.ts
Normal file
20
tracers.ts/src/index.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { getTracerContext } from './context';
|
||||||
|
import {
|
||||||
|
createArrayTracer,
|
||||||
|
createControlTracer,
|
||||||
|
createLogTracer,
|
||||||
|
} from './tracers';
|
||||||
|
|
||||||
|
const logTracer = createLogTracer({ description: 'LogTracer' });
|
||||||
|
const controlTracer = createControlTracer({ description: 'ControlTracer' });
|
||||||
|
|
||||||
|
const arrayTracer = createArrayTracer<number>({
|
||||||
|
description: 'ArrayTracer',
|
||||||
|
array: [1, 2, 3],
|
||||||
|
});
|
||||||
|
|
||||||
|
arrayTracer.patch(0, 100);
|
||||||
|
|
||||||
|
controlTracer.step();
|
||||||
|
|
||||||
|
console.log(getTracerContext().commands);
|
||||||
102
tracers.ts/src/tracers/array-tracer.ts
Normal file
102
tracers.ts/src/tracers/array-tracer.ts
Normal 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,
|
||||||
|
};
|
||||||
|
};
|
||||||
81
tracers.ts/src/tracers/control-tracer.ts
Normal file
81
tracers.ts/src/tracers/control-tracer.ts
Normal 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,
|
||||||
|
};
|
||||||
|
};
|
||||||
3
tracers.ts/src/tracers/index.ts
Normal file
3
tracers.ts/src/tracers/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './array-tracer';
|
||||||
|
export * from './control-tracer';
|
||||||
|
export * from './log-tracer';
|
||||||
44
tracers.ts/src/tracers/log-tracer.ts
Normal file
44
tracers.ts/src/tracers/log-tracer.ts
Normal 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,
|
||||||
|
};
|
||||||
|
};
|
||||||
65
tracers.ts/src/types/array-tracer.ts
Normal file
65
tracers.ts/src/types/array-tracer.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import type { BaseTracerCommand, JsonValue } from './common';
|
||||||
|
|
||||||
|
type BaseArrayTracerCommand = BaseTracerCommand & {
|
||||||
|
type: 'ArrayTracer';
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerCreateCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'create';
|
||||||
|
params: {
|
||||||
|
description: string;
|
||||||
|
array?: JsonValue[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerPresetCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'preset';
|
||||||
|
params: {
|
||||||
|
array: JsonValue[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerScaleCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'scale';
|
||||||
|
params: {
|
||||||
|
size: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerPickCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'pick';
|
||||||
|
params: {
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerDropCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'drop';
|
||||||
|
params: {
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerPatchCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'patch';
|
||||||
|
params: {
|
||||||
|
index: number;
|
||||||
|
value: JsonValue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ArrayTracerUnsetCommand = BaseArrayTracerCommand & {
|
||||||
|
action: 'unset';
|
||||||
|
params: {
|
||||||
|
index: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ArrayTracerCommand =
|
||||||
|
| ArrayTracerCreateCommand
|
||||||
|
| ArrayTracerPresetCommand
|
||||||
|
| ArrayTracerScaleCommand
|
||||||
|
| ArrayTracerPickCommand
|
||||||
|
| ArrayTracerDropCommand
|
||||||
|
| ArrayTracerPatchCommand
|
||||||
|
| ArrayTracerUnsetCommand;
|
||||||
8
tracers.ts/src/types/command.ts
Normal file
8
tracers.ts/src/types/command.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type { ArrayTracerCommand } from './array-tracer';
|
||||||
|
import type { ControlTracerCommand } from './control-tracer';
|
||||||
|
import type { LogTracerCommand } from './log-tracer';
|
||||||
|
|
||||||
|
export type TracerCommand =
|
||||||
|
| ArrayTracerCommand
|
||||||
|
| LogTracerCommand
|
||||||
|
| ControlTracerCommand;
|
||||||
16
tracers.ts/src/types/common.ts
Normal file
16
tracers.ts/src/types/common.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export type JsonValue =
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| null
|
||||||
|
| JsonValue[]
|
||||||
|
| { [key: string]: JsonValue };
|
||||||
|
|
||||||
|
export type TracerType = 'ArrayTracer' | 'LogTracer' | 'ControlTracer';
|
||||||
|
|
||||||
|
export type TracerId = ReturnType<typeof crypto.randomUUID>;
|
||||||
|
|
||||||
|
export type BaseTracerCommand = {
|
||||||
|
type: TracerType;
|
||||||
|
tracer: TracerId;
|
||||||
|
};
|
||||||
23
tracers.ts/src/types/control-tracer.ts
Normal file
23
tracers.ts/src/types/control-tracer.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import type { BaseTracerCommand } from './common';
|
||||||
|
|
||||||
|
type BaseControlTracerCommand = BaseTracerCommand & {
|
||||||
|
type: 'ControlTracer';
|
||||||
|
};
|
||||||
|
|
||||||
|
type ControlTracerCreateCommand = BaseControlTracerCommand & {
|
||||||
|
action: 'create';
|
||||||
|
params: {
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type ControlTracerStepCommand = BaseControlTracerCommand & {
|
||||||
|
action: 'step';
|
||||||
|
params: {
|
||||||
|
lines: number[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ControlTracerCommand =
|
||||||
|
| ControlTracerCreateCommand
|
||||||
|
| ControlTracerStepCommand;
|
||||||
5
tracers.ts/src/types/index.ts
Normal file
5
tracers.ts/src/types/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from './array-tracer';
|
||||||
|
export * from './command';
|
||||||
|
export * from './common';
|
||||||
|
export * from './control-tracer';
|
||||||
|
export * from './log-tracer';
|
||||||
21
tracers.ts/src/types/log-tracer.ts
Normal file
21
tracers.ts/src/types/log-tracer.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import type { BaseTracerCommand } from "./common";
|
||||||
|
|
||||||
|
type BaseLogTracerCommand = BaseTracerCommand & {
|
||||||
|
type: 'LogTracer';
|
||||||
|
};
|
||||||
|
|
||||||
|
type LogTracerCreateCommand = BaseLogTracerCommand & {
|
||||||
|
action: 'create';
|
||||||
|
params: {
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type LogTracerLogCommand = BaseLogTracerCommand & {
|
||||||
|
action: 'log';
|
||||||
|
params: {
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LogTracerCommand = LogTracerCreateCommand | LogTracerLogCommand;
|
||||||
Reference in New Issue
Block a user