refactor(session-query): simplify tracing helpers

This commit is contained in:
Hypatia May
2026-07-14 17:20:57 +08:00
parent eb42eeda13
commit c5ac667e86
2 changed files with 12 additions and 15 deletions
@@ -22,7 +22,7 @@ import {
type Config, type Config,
} from './config.ts' } from './config.ts'
import { SessionCorpus } from './corpus.ts' import { SessionCorpus } from './corpus.ts'
import { eventRecords, traceEventLog, traceLineage } from './tracing.ts' import * as tracing from './tracing.ts'
export type * from './types.ts' export type * from './types.ts'
export type { Config, SessionQueryErrorCode } from './config.ts' export type { Config, SessionQueryErrorCode } from './config.ts'
@@ -71,7 +71,7 @@ export class SessionQueryService extends Service {
*/ */
async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]> { async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]> {
const loaded = await this._corpus.load(sessionId) const loaded = await this._corpus.load(sessionId)
return eventRecords(sessionId, loaded.events) return tracing.eventRecords(sessionId, loaded.events)
} }
/** /**
@@ -82,7 +82,7 @@ export class SessionQueryService extends Service {
*/ */
async traceSession(sessionId: SessionId): Promise<SessionLineageTrace> { async traceSession(sessionId: SessionId): Promise<SessionLineageTrace> {
const records = await this._corpus.listSessions() const records = await this._corpus.listSessions()
return traceLineage(records, sessionId) return tracing.traceSession(records, sessionId)
} }
/** /**
@@ -93,7 +93,7 @@ export class SessionQueryService extends Service {
*/ */
async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace> { async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace> {
const loaded = await this._corpus.load(request.sessionId) const loaded = await this._corpus.load(request.sessionId)
return traceEventLog(request.sessionId, loaded.events, request.seq) return tracing.traceEvent(request.sessionId, loaded.events, request.seq)
} }
/** /**
@@ -37,7 +37,7 @@ export function eventRecords(
* @param seq - target event seq. * @param seq - target event seq.
* @returns direct surface and provenance relationships. * @returns direct surface and provenance relationships.
*/ */
export function traceEventLog( export function traceEvent(
sessionId: SessionId, sessionId: SessionId,
events: readonly SessionEvent[], events: readonly SessionEvent[],
seq: number, seq: number,
@@ -59,7 +59,6 @@ export function traceEventLog(
replacement = analysis.replacedBy.get(replacement) replacement = analysis.replacedBy.get(replacement)
} }
const sourceEventSeqs = eventSources(target)
const derivedEventSeqs: number[] = [] const derivedEventSeqs: number[] = []
for (const event of events) { for (const event of events) {
if (event.seq <= seq) continue if (event.seq <= seq) continue
@@ -71,11 +70,11 @@ export function traceEventLog(
const targetRecord = analysis.records[seq]! const targetRecord = analysis.records[seq]!
const replacedBy = analysis.replacedBy.get(seq) const replacedBy = analysis.replacedBy.get(seq)
return { return {
target: { ...targetRecord }, target: targetRecord,
...replacedBy === undefined ? {} : { replacedBy }, ...replacedBy === undefined ? {} : { replacedBy },
replacementChain, replacementChain,
replacedEventSeqs: [...(analysis.replacedEventSeqs.get(seq) ?? [])], replacedEventSeqs: analysis.replacedEventSeqs.get(seq) ?? [],
sourceEventSeqs: [...sourceEventSeqs], sourceEventSeqs: [...eventSources(target)],
derivedEventSeqs, derivedEventSeqs,
} }
} }
@@ -86,7 +85,7 @@ export function traceEventLog(
* @param sessionId - target session id. * @param sessionId - target session id.
* @returns complete or explicitly partial lineage. * @returns complete or explicitly partial lineage.
*/ */
export function traceLineage( export function traceSession(
records: readonly SessionRecord[], records: readonly SessionRecord[],
sessionId: SessionId, sessionId: SessionId,
): SessionLineageTrace { ): SessionLineageTrace {
@@ -164,14 +163,12 @@ function analyzeEventLog(
) )
} }
const current = new Set(folded.nodes.map(node => node.seq)) const current = new Set(folded.nodes.map(node => node.seq))
const shadowed = new Set<number>()
const replacedBy = new Map<number, number>() const replacedBy = new Map<number, number>()
const replacedEventSeqs = new Map<number, number[]>() const replacedEventSeqs = new Map<number, number[]>()
for (const replacement of folded.replacements) { for (const replacement of folded.replacements) {
const removed = [...replacement.shadowedSeqs] const removed = replacement.shadowedSeqs
replacedEventSeqs.set(replacement.seq, removed) replacedEventSeqs.set(replacement.seq, removed)
for (const removedSeq of removed) { for (const removedSeq of removed) {
shadowed.add(removedSeq)
replacedBy.set(removedSeq, replacement.seq) replacedBy.set(removedSeq, replacement.seq)
} }
} }
@@ -183,14 +180,14 @@ function analyzeEventLog(
time: event.time, time: event.time,
surface: current.has(event.seq) surface: current.has(event.seq)
? 'current' ? 'current'
: shadowed.has(event.seq) ? 'shadowed' : 'log-only', : replacedBy.has(event.seq) ? 'shadowed' : 'log-only',
})), })),
replacedBy, replacedBy,
replacedEventSeqs, replacedEventSeqs,
} }
} }
function eventSources(event: SessionEvent): number[] { function eventSources(event: SessionEvent): readonly number[] {
return (event as SessionEvent<SurfaceEventType>).sourceEventSeqs ?? [] return (event as SessionEvent<SurfaceEventType>).sourceEventSeqs ?? []
} }