From 4929ca496b17a8dc70b9b8f7f08a434f8658e91d Mon Sep 17 00:00:00 2001 From: skycurtain Date: Sat, 14 Feb 2026 01:30:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20GraphTracer=20?= =?UTF-8?q?=E5=B9=B6=E9=87=8D=E6=9E=84=20ArrayTracer=20=E7=9A=84=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 GraphTracer 及其类型定义,支持图的创建和操作命令 - 重构 ArrayTracer 的 create 函数,使用 walker/commit 模式替代直接的 array 参数,提高灵活性 - 更新类型导出和命令联合类型以包含 GraphTracer - 调整示例代码以使用新的初始化方式 --- tracers.ts/src/index.ts | 7 +- tracers.ts/src/tracers/array-tracer.ts | 23 ++++++- tracers.ts/src/tracers/graph-tracer.ts | 33 +++++++++ tracers.ts/src/tracers/index.ts | 1 + tracers.ts/src/types/command.ts | 6 +- tracers.ts/src/types/common.ts | 2 +- tracers.ts/src/types/graph-tracer.ts | 94 ++++++++++++++++++++++++++ tracers.ts/src/types/index.ts | 1 + 8 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 tracers.ts/src/tracers/graph-tracer.ts create mode 100644 tracers.ts/src/types/graph-tracer.ts diff --git a/tracers.ts/src/index.ts b/tracers.ts/src/index.ts index 77788ee..2ceeba7 100644 --- a/tracers.ts/src/index.ts +++ b/tracers.ts/src/index.ts @@ -9,7 +9,12 @@ const controlTracer = createControlTracer({ description: 'ControlTracer' }); const arrayTracer = createArrayTracer({ description: 'ArrayTracer', - array: [1, 2, 3], + // array: [1, 2, 3], + walker: (commit) => { + commit(1); + commit(2); + commit(3); + }, }); arrayTracer.patch(0, 100); diff --git a/tracers.ts/src/tracers/array-tracer.ts b/tracers.ts/src/tracers/array-tracer.ts index 1437499..9a3bb4b 100644 --- a/tracers.ts/src/tracers/array-tracer.ts +++ b/tracers.ts/src/tracers/array-tracer.ts @@ -1,15 +1,32 @@ import { getTracerContext } from '../context'; import type { JsonValue } from '../types'; -interface ArrayTracerCreateOptions { +interface BaseArrayTracerCreateOptions { description?: string; - array?: T; } +interface ArrayTracerCreateOptionsFromArray< + T extends JsonValue[], +> extends BaseArrayTracerCreateOptions { + array: T; + walker?: never; +} + +interface ArrayTracerCreateOptionsFromWalker< + T extends JsonValue[], +> extends BaseArrayTracerCreateOptions { + array?: never; + walker: (commit: (item: T[number]) => void) => void; +} + +type ArrayTracerCreateOptions = + | ArrayTracerCreateOptionsFromArray + | ArrayTracerCreateOptionsFromWalker; + export const createArrayTracer = ( options: ArrayTracerCreateOptions, ) => { - const { description, array } = options; + const { description, array, walker } = options; const tracer = crypto.randomUUID(); // 优化:仅维护数组长度作为影子状态,这在 C++/Java 等强类型语言中也极易实现(仅需一个 int 变量) diff --git a/tracers.ts/src/tracers/graph-tracer.ts b/tracers.ts/src/tracers/graph-tracer.ts new file mode 100644 index 0000000..d57a9dc --- /dev/null +++ b/tracers.ts/src/tracers/graph-tracer.ts @@ -0,0 +1,33 @@ +import { getTracerContext } from '../context'; +import type { GraphTracerGraph } from '../types'; + +interface GraphTracerCreateOptions { + description?: string; + graph?: GraphTracerGraph; +} + +// 不要了,改为 walker/commit 方案 +// TODO: 后续我们会添加创建图的辅助函数 +// export const createGraphTracerHelper = () => {}; + +export const createGraphTracer = (options: GraphTracerCreateOptions) => { + const { description, graph } = options; + const tracer = crypto.randomUUID(); + + const { command } = getTracerContext(); + + command({ + type: 'GraphTracer', + tracer: tracer, + action: 'create', + params: { + description: description ?? 'GraphTracer', + graph: graph ?? { + directed: false, + weighted: false, + nodes: [], + edges: [], + }, + }, + }); +}; diff --git a/tracers.ts/src/tracers/index.ts b/tracers.ts/src/tracers/index.ts index f8e480d..6d6693f 100644 --- a/tracers.ts/src/tracers/index.ts +++ b/tracers.ts/src/tracers/index.ts @@ -1,3 +1,4 @@ export * from './array-tracer'; export * from './control-tracer'; +export * from './graph-tracer'; export * from './log-tracer'; diff --git a/tracers.ts/src/types/command.ts b/tracers.ts/src/types/command.ts index e312e20..de780bc 100644 --- a/tracers.ts/src/types/command.ts +++ b/tracers.ts/src/types/command.ts @@ -1,8 +1,10 @@ import type { ArrayTracerCommand } from './array-tracer'; import type { ControlTracerCommand } from './control-tracer'; +import type { GraphTracerCommand } from './graph-tracer'; import type { LogTracerCommand } from './log-tracer'; export type TracerCommand = - | ArrayTracerCommand | LogTracerCommand - | ControlTracerCommand; + | ControlTracerCommand + | ArrayTracerCommand + | GraphTracerCommand; diff --git a/tracers.ts/src/types/common.ts b/tracers.ts/src/types/common.ts index 9fc9bfc..0c0f311 100644 --- a/tracers.ts/src/types/common.ts +++ b/tracers.ts/src/types/common.ts @@ -6,7 +6,7 @@ export type JsonValue = | JsonValue[] | { [key: string]: JsonValue }; -export type TracerType = 'ArrayTracer' | 'LogTracer' | 'ControlTracer'; +export type TracerType = 'LogTracer' | 'ControlTracer' | 'ArrayTracer' | 'GraphTracer'; export type TracerId = ReturnType; diff --git a/tracers.ts/src/types/graph-tracer.ts b/tracers.ts/src/types/graph-tracer.ts new file mode 100644 index 0000000..dfff800 --- /dev/null +++ b/tracers.ts/src/types/graph-tracer.ts @@ -0,0 +1,94 @@ +import type { BaseTracerCommand, JsonValue } from './common'; + +export type GraphTracerGraphNode = { + id: string; + value: JsonValue; +}; + +export type GraphTracerGraphEdge = { + source: string; + target: string; + weight: JsonValue; +}; + +export type GraphTracerGraph = { + directed: boolean; + weighted: boolean; + nodes: GraphTracerGraphNode[]; + edges: GraphTracerGraphEdge[]; +}; + +type BaseGraphTracerCommand = BaseTracerCommand & { + type: 'GraphTracer'; +}; + +type GraphTracerCreateCommand = BaseGraphTracerCommand & { + action: 'create'; + params: { + description: string; + graph: GraphTracerGraph; + }; +}; + +type GraphTracerInsertCommand = BaseGraphTracerCommand & { + action: 'insert'; + params: {}; +}; + +type GraphTracerRemoveCommand = BaseGraphTracerCommand & { + action: 'remove'; + params: {}; +}; + +type GraphTracerUpdateCommand = BaseGraphTracerCommand & { + action: 'update'; + params: {}; +}; + +type GraphTracerConnectCommand = BaseGraphTracerCommand & { + action: 'connect'; + params: {}; +}; + +type GraphTracerDisconnectCommand = BaseGraphTracerCommand & { + action: 'disconnect'; + params: {}; +}; + +type GraphTracerWeightCommand = BaseGraphTracerCommand & { + action: 'weight'; + params: {}; +}; + +type GraphTracerVisitCommand = BaseGraphTracerCommand & { + action: 'visit'; + params: {}; +}; + +type GraphTracerLeaveCommand = BaseGraphTracerCommand & { + action: 'leave'; + params: {}; +}; + +type GraphTracerPickCommand = BaseGraphTracerCommand & { + action: 'pick'; + params: {}; +}; + +type GraphTracerDropCommand = BaseGraphTracerCommand & { + action: 'drop'; + params: {}; +}; + +export type GraphTracerCommand = + | GraphTracerCreateCommand + | GraphTracerInsertCommand + | GraphTracerRemoveCommand + | GraphTracerUpdateCommand + | GraphTracerConnectCommand + | GraphTracerDisconnectCommand + | GraphTracerWeightCommand + | GraphTracerVisitCommand + | GraphTracerLeaveCommand + | GraphTracerPickCommand + | GraphTracerDropCommand; diff --git a/tracers.ts/src/types/index.ts b/tracers.ts/src/types/index.ts index 39b1734..a3cfc15 100644 --- a/tracers.ts/src/types/index.ts +++ b/tracers.ts/src/types/index.ts @@ -2,4 +2,5 @@ export * from './array-tracer'; export * from './command'; export * from './common'; export * from './control-tracer'; +export * from './graph-tracer'; export * from './log-tracer';