@nextera.one/axis-server-sdk 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/axis-sensor-GBEI3Fab.d.mts +209 -0
- package/dist/axis-sensor-GBEI3Fab.d.ts +209 -0
- package/dist/cce/index.d.mts +162 -0
- package/dist/cce/index.d.ts +162 -0
- package/dist/cce/index.js +1502 -0
- package/dist/cce/index.js.map +1 -0
- package/dist/cce/index.mjs +1442 -0
- package/dist/cce/index.mjs.map +1 -0
- package/dist/cce-pipeline-B-zUBHo3.d.mts +294 -0
- package/dist/cce-pipeline-DbGBSsCG.d.ts +294 -0
- package/dist/idel/index.d.mts +24 -0
- package/dist/idel/index.d.ts +24 -0
- package/dist/idel/index.js +306 -0
- package/dist/idel/index.js.map +1 -0
- package/dist/idel/index.mjs +279 -0
- package/dist/idel/index.mjs.map +1 -0
- package/dist/idel.types-DuUAcOnQ.d.mts +83 -0
- package/dist/idel.types-DuUAcOnQ.d.ts +83 -0
- package/dist/index-B2G6cbRL.d.mts +824 -0
- package/dist/index-DbSxdR0f.d.ts +824 -0
- package/dist/index-_S4fmVUJ.d.mts +501 -0
- package/dist/index-l3Hhirqb.d.ts +501 -0
- package/dist/index.d.mts +91 -1891
- package/dist/index.d.ts +91 -1891
- package/dist/index.js +9339 -5123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10326 -5816
- package/dist/index.mjs.map +1 -1
- package/dist/needle/index.d.mts +4 -0
- package/dist/needle/index.d.ts +4 -0
- package/dist/needle/index.js +3499 -0
- package/dist/needle/index.js.map +1 -0
- package/dist/needle/index.mjs +3528 -0
- package/dist/needle/index.mjs.map +1 -0
- package/dist/sensors/index.d.mts +5 -0
- package/dist/sensors/index.d.ts +5 -0
- package/dist/sensors/index.js +12860 -0
- package/dist/sensors/index.js.map +1 -0
- package/dist/sensors/index.mjs +12928 -0
- package/dist/sensors/index.mjs.map +1 -0
- package/dist/timeline/index.d.mts +54 -0
- package/dist/timeline/index.d.ts +54 -0
- package/dist/timeline/index.js +389 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/timeline/index.mjs +362 -0
- package/dist/timeline/index.mjs.map +1 -0
- package/dist/timeline.types-Cn0aqbUj.d.mts +125 -0
- package/dist/timeline.types-Cn0aqbUj.d.ts +125 -0
- package/package.json +28 -10
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { i as TimelineEvent, T as TimelineBranch, f as StateSnapshot, k as TimelineHandler, b as ReplayRequest, c as ReplayResult, F as ForkRequest, a as ForkResult, d as SimulationRequest, e as SimulationResult, g as TimelineComparison } from '../timeline.types-Cn0aqbUj.mjs';
|
|
2
|
+
export { R as ReplayDifference, n as ReplayMode, S as SimulatedSideEffect, h as TimelineDomain, j as TimelineEventStatus, l as TimelineHandlerContext, m as TimelineHandlerResult } from '../timeline.types-Cn0aqbUj.mjs';
|
|
3
|
+
|
|
4
|
+
interface TimelineStore {
|
|
5
|
+
saveEvent(event: TimelineEvent): Promise<void>;
|
|
6
|
+
getEvent(eventId: string): Promise<TimelineEvent | null>;
|
|
7
|
+
getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]>;
|
|
8
|
+
getEventsByBranch(branchId: string): Promise<TimelineEvent[]>;
|
|
9
|
+
saveBranch(branch: TimelineBranch): Promise<void>;
|
|
10
|
+
getBranch(branchId: string): Promise<TimelineBranch | null>;
|
|
11
|
+
getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]>;
|
|
12
|
+
saveSnapshot(snapshot: StateSnapshot): Promise<void>;
|
|
13
|
+
getSnapshot(snapshotId: string): Promise<StateSnapshot | null>;
|
|
14
|
+
getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null>;
|
|
15
|
+
}
|
|
16
|
+
declare class InMemoryTimelineStore implements TimelineStore {
|
|
17
|
+
private events;
|
|
18
|
+
private branches;
|
|
19
|
+
private snapshots;
|
|
20
|
+
saveEvent(event: TimelineEvent): Promise<void>;
|
|
21
|
+
getEvent(eventId: string): Promise<TimelineEvent | null>;
|
|
22
|
+
getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]>;
|
|
23
|
+
getEventsByBranch(branchId: string): Promise<TimelineEvent[]>;
|
|
24
|
+
saveBranch(branch: TimelineBranch): Promise<void>;
|
|
25
|
+
getBranch(branchId: string): Promise<TimelineBranch | null>;
|
|
26
|
+
getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]>;
|
|
27
|
+
saveSnapshot(snapshot: StateSnapshot): Promise<void>;
|
|
28
|
+
getSnapshot(snapshotId: string): Promise<StateSnapshot | null>;
|
|
29
|
+
getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class TimelineEngine {
|
|
33
|
+
private readonly store;
|
|
34
|
+
private handlers;
|
|
35
|
+
constructor(store: TimelineStore);
|
|
36
|
+
registerHandler(handler: TimelineHandler): void;
|
|
37
|
+
recordEvent(intent: string, actorId: string, payload: Record<string, unknown>, result: Record<string, unknown>, options?: {
|
|
38
|
+
timelineId?: string;
|
|
39
|
+
branchId?: string;
|
|
40
|
+
capsuleId?: string;
|
|
41
|
+
tpsCoordinate?: string;
|
|
42
|
+
witnessId?: string;
|
|
43
|
+
determinism?: TimelineEvent['determinism'];
|
|
44
|
+
parentEventId?: string;
|
|
45
|
+
}): Promise<TimelineEvent>;
|
|
46
|
+
replay(request: ReplayRequest): Promise<ReplayResult>;
|
|
47
|
+
fork(request: ForkRequest): Promise<ForkResult>;
|
|
48
|
+
simulate(request: SimulationRequest): Promise<SimulationResult>;
|
|
49
|
+
compare(timelineIdA: string, timelineIdB: string): Promise<TimelineComparison>;
|
|
50
|
+
createSnapshot(eventId: string, stateData: Record<string, unknown>): Promise<StateSnapshot>;
|
|
51
|
+
restoreSnapshot(snapshotId: string): Promise<StateSnapshot>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ForkRequest, ForkResult, InMemoryTimelineStore, ReplayRequest, ReplayResult, SimulationRequest, SimulationResult, StateSnapshot, TimelineBranch, TimelineComparison, TimelineEngine, TimelineEvent, TimelineHandler, type TimelineStore };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { i as TimelineEvent, T as TimelineBranch, f as StateSnapshot, k as TimelineHandler, b as ReplayRequest, c as ReplayResult, F as ForkRequest, a as ForkResult, d as SimulationRequest, e as SimulationResult, g as TimelineComparison } from '../timeline.types-Cn0aqbUj.js';
|
|
2
|
+
export { R as ReplayDifference, n as ReplayMode, S as SimulatedSideEffect, h as TimelineDomain, j as TimelineEventStatus, l as TimelineHandlerContext, m as TimelineHandlerResult } from '../timeline.types-Cn0aqbUj.js';
|
|
3
|
+
|
|
4
|
+
interface TimelineStore {
|
|
5
|
+
saveEvent(event: TimelineEvent): Promise<void>;
|
|
6
|
+
getEvent(eventId: string): Promise<TimelineEvent | null>;
|
|
7
|
+
getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]>;
|
|
8
|
+
getEventsByBranch(branchId: string): Promise<TimelineEvent[]>;
|
|
9
|
+
saveBranch(branch: TimelineBranch): Promise<void>;
|
|
10
|
+
getBranch(branchId: string): Promise<TimelineBranch | null>;
|
|
11
|
+
getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]>;
|
|
12
|
+
saveSnapshot(snapshot: StateSnapshot): Promise<void>;
|
|
13
|
+
getSnapshot(snapshotId: string): Promise<StateSnapshot | null>;
|
|
14
|
+
getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null>;
|
|
15
|
+
}
|
|
16
|
+
declare class InMemoryTimelineStore implements TimelineStore {
|
|
17
|
+
private events;
|
|
18
|
+
private branches;
|
|
19
|
+
private snapshots;
|
|
20
|
+
saveEvent(event: TimelineEvent): Promise<void>;
|
|
21
|
+
getEvent(eventId: string): Promise<TimelineEvent | null>;
|
|
22
|
+
getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]>;
|
|
23
|
+
getEventsByBranch(branchId: string): Promise<TimelineEvent[]>;
|
|
24
|
+
saveBranch(branch: TimelineBranch): Promise<void>;
|
|
25
|
+
getBranch(branchId: string): Promise<TimelineBranch | null>;
|
|
26
|
+
getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]>;
|
|
27
|
+
saveSnapshot(snapshot: StateSnapshot): Promise<void>;
|
|
28
|
+
getSnapshot(snapshotId: string): Promise<StateSnapshot | null>;
|
|
29
|
+
getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class TimelineEngine {
|
|
33
|
+
private readonly store;
|
|
34
|
+
private handlers;
|
|
35
|
+
constructor(store: TimelineStore);
|
|
36
|
+
registerHandler(handler: TimelineHandler): void;
|
|
37
|
+
recordEvent(intent: string, actorId: string, payload: Record<string, unknown>, result: Record<string, unknown>, options?: {
|
|
38
|
+
timelineId?: string;
|
|
39
|
+
branchId?: string;
|
|
40
|
+
capsuleId?: string;
|
|
41
|
+
tpsCoordinate?: string;
|
|
42
|
+
witnessId?: string;
|
|
43
|
+
determinism?: TimelineEvent['determinism'];
|
|
44
|
+
parentEventId?: string;
|
|
45
|
+
}): Promise<TimelineEvent>;
|
|
46
|
+
replay(request: ReplayRequest): Promise<ReplayResult>;
|
|
47
|
+
fork(request: ForkRequest): Promise<ForkResult>;
|
|
48
|
+
simulate(request: SimulationRequest): Promise<SimulationResult>;
|
|
49
|
+
compare(timelineIdA: string, timelineIdB: string): Promise<TimelineComparison>;
|
|
50
|
+
createSnapshot(eventId: string, stateData: Record<string, unknown>): Promise<StateSnapshot>;
|
|
51
|
+
restoreSnapshot(snapshotId: string): Promise<StateSnapshot>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ForkRequest, ForkResult, InMemoryTimelineStore, ReplayRequest, ReplayResult, SimulationRequest, SimulationResult, StateSnapshot, TimelineBranch, TimelineComparison, TimelineEngine, TimelineEvent, TimelineHandler, type TimelineStore };
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/timeline/index.ts
|
|
20
|
+
var timeline_exports = {};
|
|
21
|
+
__export(timeline_exports, {
|
|
22
|
+
InMemoryTimelineStore: () => InMemoryTimelineStore,
|
|
23
|
+
TimelineEngine: () => TimelineEngine
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(timeline_exports);
|
|
26
|
+
|
|
27
|
+
// src/timeline/timeline.store.ts
|
|
28
|
+
var InMemoryTimelineStore = class {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.events = /* @__PURE__ */ new Map();
|
|
31
|
+
this.branches = /* @__PURE__ */ new Map();
|
|
32
|
+
this.snapshots = /* @__PURE__ */ new Map();
|
|
33
|
+
}
|
|
34
|
+
async saveEvent(event) {
|
|
35
|
+
this.events.set(event.event_id, event);
|
|
36
|
+
}
|
|
37
|
+
async getEvent(eventId) {
|
|
38
|
+
return this.events.get(eventId) ?? null;
|
|
39
|
+
}
|
|
40
|
+
async getEventsByTimeline(timelineId) {
|
|
41
|
+
return [...this.events.values()].filter((e) => e.timeline_id === timelineId);
|
|
42
|
+
}
|
|
43
|
+
async getEventsByBranch(branchId) {
|
|
44
|
+
return [...this.events.values()].filter((e) => e.branch_id === branchId);
|
|
45
|
+
}
|
|
46
|
+
async saveBranch(branch) {
|
|
47
|
+
this.branches.set(branch.branch_id, branch);
|
|
48
|
+
}
|
|
49
|
+
async getBranch(branchId) {
|
|
50
|
+
return this.branches.get(branchId) ?? null;
|
|
51
|
+
}
|
|
52
|
+
async getBranchesByTimeline(timelineId) {
|
|
53
|
+
return [...this.branches.values()].filter((b) => b.timeline_id === timelineId);
|
|
54
|
+
}
|
|
55
|
+
async saveSnapshot(snapshot) {
|
|
56
|
+
this.snapshots.set(snapshot.snapshot_id, snapshot);
|
|
57
|
+
}
|
|
58
|
+
async getSnapshot(snapshotId) {
|
|
59
|
+
return this.snapshots.get(snapshotId) ?? null;
|
|
60
|
+
}
|
|
61
|
+
async getSnapshotByEvent(eventId) {
|
|
62
|
+
return [...this.snapshots.values()].find((s) => s.event_id === eventId) ?? null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/timeline/timeline.engine.ts
|
|
67
|
+
var import_crypto = require("crypto");
|
|
68
|
+
function generateId(prefix) {
|
|
69
|
+
return `${prefix}_${(0, import_crypto.randomBytes)(16).toString("hex")}`;
|
|
70
|
+
}
|
|
71
|
+
function sha256(data) {
|
|
72
|
+
return (0, import_crypto.createHash)("sha256").update(data).digest("hex");
|
|
73
|
+
}
|
|
74
|
+
function hashPayload(payload) {
|
|
75
|
+
return sha256(JSON.stringify(payload));
|
|
76
|
+
}
|
|
77
|
+
function diffObjects(a, b) {
|
|
78
|
+
const diffs = [];
|
|
79
|
+
const allKeys = /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
80
|
+
for (const key of allKeys) {
|
|
81
|
+
const va = a[key];
|
|
82
|
+
const vb = b[key];
|
|
83
|
+
if (JSON.stringify(va) !== JSON.stringify(vb)) {
|
|
84
|
+
diffs.push({ field: key, original: va, replayed: vb });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return diffs;
|
|
88
|
+
}
|
|
89
|
+
var TimelineEngine = class {
|
|
90
|
+
constructor(store) {
|
|
91
|
+
this.store = store;
|
|
92
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
93
|
+
}
|
|
94
|
+
/** Register an intent handler for timeline execution */
|
|
95
|
+
registerHandler(handler) {
|
|
96
|
+
this.handlers.set(handler.intent, handler);
|
|
97
|
+
}
|
|
98
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
99
|
+
// Record (store a real execution as a timeline event)
|
|
100
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
101
|
+
async recordEvent(intent, actorId, payload, result, options = {}) {
|
|
102
|
+
const event = {
|
|
103
|
+
event_id: generateId("evt"),
|
|
104
|
+
timeline_id: options.timelineId ?? "prime",
|
|
105
|
+
branch_id: options.branchId ?? "main",
|
|
106
|
+
parent_event_id: options.parentEventId ?? null,
|
|
107
|
+
intent,
|
|
108
|
+
actor_id: actorId,
|
|
109
|
+
capsule_id: options.capsuleId,
|
|
110
|
+
tps_coordinate: options.tpsCoordinate,
|
|
111
|
+
payload_hash: hashPayload(payload),
|
|
112
|
+
result_hash: hashPayload(result),
|
|
113
|
+
status: "executed",
|
|
114
|
+
domain: "prime",
|
|
115
|
+
determinism: options.determinism ?? "deterministic",
|
|
116
|
+
witness_id: options.witnessId,
|
|
117
|
+
created_at: Date.now(),
|
|
118
|
+
metadata: { payload, result }
|
|
119
|
+
};
|
|
120
|
+
await this.store.saveEvent(event);
|
|
121
|
+
return event;
|
|
122
|
+
}
|
|
123
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
124
|
+
// Replay
|
|
125
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
126
|
+
async replay(request) {
|
|
127
|
+
const originalEvent = await this.store.getEvent(request.source_event_id);
|
|
128
|
+
if (!originalEvent) {
|
|
129
|
+
throw new Error(`Event ${request.source_event_id} not found`);
|
|
130
|
+
}
|
|
131
|
+
const handler = this.handlers.get(originalEvent.intent);
|
|
132
|
+
if (!handler) {
|
|
133
|
+
throw new Error(`No handler registered for intent '${originalEvent.intent}'`);
|
|
134
|
+
}
|
|
135
|
+
const originalPayload = originalEvent.metadata?.payload ?? {};
|
|
136
|
+
const replayPayload = request.mode === "analytical" && request.override_payload ? request.override_payload : originalPayload;
|
|
137
|
+
const snapshot = await this.store.getSnapshotByEvent(originalEvent.event_id);
|
|
138
|
+
const context = {
|
|
139
|
+
event_id: generateId("evt"),
|
|
140
|
+
timeline_id: originalEvent.timeline_id,
|
|
141
|
+
branch_id: `replay_${originalEvent.branch_id}`,
|
|
142
|
+
domain: "audit",
|
|
143
|
+
actor_id: originalEvent.actor_id,
|
|
144
|
+
tps_coordinate: originalEvent.tps_coordinate,
|
|
145
|
+
snapshot: snapshot ?? void 0,
|
|
146
|
+
is_replay: true,
|
|
147
|
+
is_simulation: false
|
|
148
|
+
};
|
|
149
|
+
const startMs = Date.now();
|
|
150
|
+
const handlerResult = await handler.execute(replayPayload, context);
|
|
151
|
+
const durationMs = Date.now() - startMs;
|
|
152
|
+
const replayedEvent = {
|
|
153
|
+
event_id: context.event_id,
|
|
154
|
+
timeline_id: originalEvent.timeline_id,
|
|
155
|
+
branch_id: context.branch_id,
|
|
156
|
+
parent_event_id: originalEvent.event_id,
|
|
157
|
+
intent: originalEvent.intent,
|
|
158
|
+
actor_id: originalEvent.actor_id,
|
|
159
|
+
capsule_id: originalEvent.capsule_id,
|
|
160
|
+
tps_coordinate: originalEvent.tps_coordinate,
|
|
161
|
+
payload_hash: hashPayload(replayPayload),
|
|
162
|
+
result_hash: hashPayload(handlerResult.result_data),
|
|
163
|
+
status: "replayed",
|
|
164
|
+
domain: "audit",
|
|
165
|
+
determinism: originalEvent.determinism,
|
|
166
|
+
created_at: Date.now(),
|
|
167
|
+
metadata: { payload: replayPayload, result: handlerResult.result_data }
|
|
168
|
+
};
|
|
169
|
+
await this.store.saveEvent(replayedEvent);
|
|
170
|
+
const originalResult = originalEvent.metadata?.result ?? {};
|
|
171
|
+
const differences = diffObjects(originalResult, handlerResult.result_data);
|
|
172
|
+
const deterministicMatch = originalEvent.result_hash === replayedEvent.result_hash;
|
|
173
|
+
return {
|
|
174
|
+
original_event: originalEvent,
|
|
175
|
+
replayed_event: replayedEvent,
|
|
176
|
+
mode: request.mode,
|
|
177
|
+
deterministic_match: deterministicMatch,
|
|
178
|
+
differences,
|
|
179
|
+
duration_ms: durationMs
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
183
|
+
// Fork
|
|
184
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
185
|
+
async fork(request) {
|
|
186
|
+
const sourceEvent = await this.store.getEvent(request.source_event_id);
|
|
187
|
+
if (!sourceEvent) {
|
|
188
|
+
throw new Error(`Event ${request.source_event_id} not found`);
|
|
189
|
+
}
|
|
190
|
+
const handler = this.handlers.get(sourceEvent.intent);
|
|
191
|
+
if (!handler) {
|
|
192
|
+
throw new Error(`No handler registered for intent '${sourceEvent.intent}'`);
|
|
193
|
+
}
|
|
194
|
+
const branch = {
|
|
195
|
+
branch_id: generateId("branch"),
|
|
196
|
+
timeline_id: generateId("timeline"),
|
|
197
|
+
origin_timeline_id: sourceEvent.timeline_id,
|
|
198
|
+
origin_event_id: sourceEvent.event_id,
|
|
199
|
+
branch_type: "fork",
|
|
200
|
+
creator_subject_id: request.actor_id,
|
|
201
|
+
purpose: request.purpose,
|
|
202
|
+
status: "active"
|
|
203
|
+
};
|
|
204
|
+
await this.store.saveBranch(branch);
|
|
205
|
+
const snapshot = {
|
|
206
|
+
snapshot_id: generateId("snap"),
|
|
207
|
+
timeline_id: sourceEvent.timeline_id,
|
|
208
|
+
event_id: sourceEvent.event_id,
|
|
209
|
+
tps_coordinate: sourceEvent.tps_coordinate,
|
|
210
|
+
state_hash: hashPayload(
|
|
211
|
+
sourceEvent.metadata?.result ?? {}
|
|
212
|
+
),
|
|
213
|
+
state_data: sourceEvent.metadata?.result ?? {},
|
|
214
|
+
created_at: Date.now()
|
|
215
|
+
};
|
|
216
|
+
await this.store.saveSnapshot(snapshot);
|
|
217
|
+
const context = {
|
|
218
|
+
event_id: generateId("evt"),
|
|
219
|
+
timeline_id: branch.timeline_id,
|
|
220
|
+
branch_id: branch.branch_id,
|
|
221
|
+
domain: "fork",
|
|
222
|
+
actor_id: request.actor_id,
|
|
223
|
+
tps_coordinate: sourceEvent.tps_coordinate,
|
|
224
|
+
snapshot,
|
|
225
|
+
is_replay: false,
|
|
226
|
+
is_simulation: false
|
|
227
|
+
};
|
|
228
|
+
const handlerResult = await handler.execute(request.new_payload, context);
|
|
229
|
+
const forkedEvent = {
|
|
230
|
+
event_id: context.event_id,
|
|
231
|
+
timeline_id: branch.timeline_id,
|
|
232
|
+
branch_id: branch.branch_id,
|
|
233
|
+
parent_event_id: sourceEvent.event_id,
|
|
234
|
+
intent: sourceEvent.intent,
|
|
235
|
+
actor_id: request.actor_id,
|
|
236
|
+
tps_coordinate: sourceEvent.tps_coordinate,
|
|
237
|
+
payload_hash: hashPayload(request.new_payload),
|
|
238
|
+
result_hash: hashPayload(handlerResult.result_data),
|
|
239
|
+
status: "forked",
|
|
240
|
+
domain: "fork",
|
|
241
|
+
determinism: sourceEvent.determinism,
|
|
242
|
+
created_at: Date.now(),
|
|
243
|
+
metadata: {
|
|
244
|
+
payload: request.new_payload,
|
|
245
|
+
result: handlerResult.result_data
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
await this.store.saveEvent(forkedEvent);
|
|
249
|
+
return { branch, forked_event: forkedEvent, snapshot };
|
|
250
|
+
}
|
|
251
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
252
|
+
// Simulate
|
|
253
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
254
|
+
async simulate(request) {
|
|
255
|
+
const handler = this.handlers.get(request.intent);
|
|
256
|
+
if (!handler) {
|
|
257
|
+
throw new Error(`No handler registered for intent '${request.intent}'`);
|
|
258
|
+
}
|
|
259
|
+
let snapshot;
|
|
260
|
+
if (request.from_snapshot_id) {
|
|
261
|
+
const loaded = await this.store.getSnapshot(request.from_snapshot_id);
|
|
262
|
+
if (!loaded) {
|
|
263
|
+
throw new Error(`Snapshot ${request.from_snapshot_id} not found`);
|
|
264
|
+
}
|
|
265
|
+
snapshot = loaded;
|
|
266
|
+
}
|
|
267
|
+
const branch = {
|
|
268
|
+
branch_id: generateId("branch"),
|
|
269
|
+
timeline_id: generateId("timeline"),
|
|
270
|
+
origin_timeline_id: "prime",
|
|
271
|
+
origin_event_id: "simulation_origin",
|
|
272
|
+
branch_type: "simulation",
|
|
273
|
+
created_at_tps: request.at_tps,
|
|
274
|
+
creator_subject_id: request.actor_id,
|
|
275
|
+
purpose: request.purpose,
|
|
276
|
+
status: "active"
|
|
277
|
+
};
|
|
278
|
+
await this.store.saveBranch(branch);
|
|
279
|
+
const context = {
|
|
280
|
+
event_id: generateId("evt"),
|
|
281
|
+
timeline_id: branch.timeline_id,
|
|
282
|
+
branch_id: branch.branch_id,
|
|
283
|
+
domain: "shadow",
|
|
284
|
+
actor_id: request.actor_id,
|
|
285
|
+
tps_coordinate: request.at_tps,
|
|
286
|
+
snapshot,
|
|
287
|
+
is_replay: false,
|
|
288
|
+
is_simulation: true
|
|
289
|
+
};
|
|
290
|
+
const startMs = Date.now();
|
|
291
|
+
const handlerResult = await handler.execute(request.payload, context);
|
|
292
|
+
const durationMs = Date.now() - startMs;
|
|
293
|
+
const simulatedEvent = {
|
|
294
|
+
event_id: context.event_id,
|
|
295
|
+
timeline_id: branch.timeline_id,
|
|
296
|
+
branch_id: branch.branch_id,
|
|
297
|
+
parent_event_id: null,
|
|
298
|
+
intent: request.intent,
|
|
299
|
+
actor_id: request.actor_id,
|
|
300
|
+
tps_coordinate: request.at_tps,
|
|
301
|
+
payload_hash: hashPayload(request.payload),
|
|
302
|
+
result_hash: hashPayload(handlerResult.result_data),
|
|
303
|
+
status: "simulated",
|
|
304
|
+
domain: "shadow",
|
|
305
|
+
determinism: "bounded_nondeterministic",
|
|
306
|
+
created_at: Date.now(),
|
|
307
|
+
metadata: { payload: request.payload, result: handlerResult.result_data }
|
|
308
|
+
};
|
|
309
|
+
await this.store.saveEvent(simulatedEvent);
|
|
310
|
+
branch.status = "completed";
|
|
311
|
+
await this.store.saveBranch(branch);
|
|
312
|
+
return {
|
|
313
|
+
branch,
|
|
314
|
+
simulated_event: simulatedEvent,
|
|
315
|
+
predicted_outcome: handlerResult.result_data,
|
|
316
|
+
side_effects: handlerResult.side_effects ?? [],
|
|
317
|
+
duration_ms: durationMs
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
321
|
+
// Compare timelines
|
|
322
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
323
|
+
async compare(timelineIdA, timelineIdB) {
|
|
324
|
+
const eventsA = await this.store.getEventsByTimeline(timelineIdA);
|
|
325
|
+
const eventsB = await this.store.getEventsByTimeline(timelineIdB);
|
|
326
|
+
eventsA.sort((a, b) => a.created_at - b.created_at);
|
|
327
|
+
eventsB.sort((a, b) => a.created_at - b.created_at);
|
|
328
|
+
const maxLen = Math.max(eventsA.length, eventsB.length);
|
|
329
|
+
const eventPairs = [];
|
|
330
|
+
let divergencePoint;
|
|
331
|
+
for (let i = 0; i < maxLen; i++) {
|
|
332
|
+
const a = eventsA[i];
|
|
333
|
+
const b = eventsB[i];
|
|
334
|
+
if (!a || !b) {
|
|
335
|
+
if (!divergencePoint) {
|
|
336
|
+
divergencePoint = a?.event_id ?? b?.event_id;
|
|
337
|
+
}
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
const match = a.result_hash === b.result_hash;
|
|
341
|
+
const resultA = a.metadata?.result ?? {};
|
|
342
|
+
const resultB = b.metadata?.result ?? {};
|
|
343
|
+
const differences = match ? [] : diffObjects(resultA, resultB);
|
|
344
|
+
if (!match && !divergencePoint) {
|
|
345
|
+
divergencePoint = a.event_id;
|
|
346
|
+
}
|
|
347
|
+
eventPairs.push({ event_a: a, event_b: b, match, differences });
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
timeline_a: timelineIdA,
|
|
351
|
+
timeline_b: timelineIdB,
|
|
352
|
+
event_pairs: eventPairs,
|
|
353
|
+
divergence_point: divergencePoint
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
357
|
+
// State snapshot management
|
|
358
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
359
|
+
async createSnapshot(eventId, stateData) {
|
|
360
|
+
const event = await this.store.getEvent(eventId);
|
|
361
|
+
if (!event) {
|
|
362
|
+
throw new Error(`Event ${eventId} not found`);
|
|
363
|
+
}
|
|
364
|
+
const snapshot = {
|
|
365
|
+
snapshot_id: generateId("snap"),
|
|
366
|
+
timeline_id: event.timeline_id,
|
|
367
|
+
event_id: eventId,
|
|
368
|
+
tps_coordinate: event.tps_coordinate,
|
|
369
|
+
state_hash: hashPayload(stateData),
|
|
370
|
+
state_data: stateData,
|
|
371
|
+
created_at: Date.now()
|
|
372
|
+
};
|
|
373
|
+
await this.store.saveSnapshot(snapshot);
|
|
374
|
+
return snapshot;
|
|
375
|
+
}
|
|
376
|
+
async restoreSnapshot(snapshotId) {
|
|
377
|
+
const snapshot = await this.store.getSnapshot(snapshotId);
|
|
378
|
+
if (!snapshot) {
|
|
379
|
+
throw new Error(`Snapshot ${snapshotId} not found`);
|
|
380
|
+
}
|
|
381
|
+
return snapshot;
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
385
|
+
0 && (module.exports = {
|
|
386
|
+
InMemoryTimelineStore,
|
|
387
|
+
TimelineEngine
|
|
388
|
+
});
|
|
389
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/timeline/index.ts","../../src/timeline/timeline.store.ts","../../src/timeline/timeline.engine.ts"],"sourcesContent":["export * from './timeline.types';\nexport * from './timeline.store';\nexport * from './timeline.engine';\n","/**\n * Timeline Store Interface\n *\n * Pluggable storage interface for timeline events, branches, and snapshots.\n * Implementations can use in-memory, database, or any persistence layer.\n */\n\nimport type {\n TimelineEvent,\n TimelineBranch,\n StateSnapshot,\n} from './timeline.types';\n\nexport interface TimelineStore {\n // Events\n saveEvent(event: TimelineEvent): Promise<void>;\n getEvent(eventId: string): Promise<TimelineEvent | null>;\n getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]>;\n getEventsByBranch(branchId: string): Promise<TimelineEvent[]>;\n\n // Branches\n saveBranch(branch: TimelineBranch): Promise<void>;\n getBranch(branchId: string): Promise<TimelineBranch | null>;\n getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]>;\n\n // Snapshots\n saveSnapshot(snapshot: StateSnapshot): Promise<void>;\n getSnapshot(snapshotId: string): Promise<StateSnapshot | null>;\n getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null>;\n}\n\n/**\n * In-memory timeline store for development and testing.\n */\nexport class InMemoryTimelineStore implements TimelineStore {\n private events = new Map<string, TimelineEvent>();\n private branches = new Map<string, TimelineBranch>();\n private snapshots = new Map<string, StateSnapshot>();\n\n async saveEvent(event: TimelineEvent): Promise<void> {\n this.events.set(event.event_id, event);\n }\n\n async getEvent(eventId: string): Promise<TimelineEvent | null> {\n return this.events.get(eventId) ?? null;\n }\n\n async getEventsByTimeline(timelineId: string): Promise<TimelineEvent[]> {\n return [...this.events.values()].filter((e) => e.timeline_id === timelineId);\n }\n\n async getEventsByBranch(branchId: string): Promise<TimelineEvent[]> {\n return [...this.events.values()].filter((e) => e.branch_id === branchId);\n }\n\n async saveBranch(branch: TimelineBranch): Promise<void> {\n this.branches.set(branch.branch_id, branch);\n }\n\n async getBranch(branchId: string): Promise<TimelineBranch | null> {\n return this.branches.get(branchId) ?? null;\n }\n\n async getBranchesByTimeline(timelineId: string): Promise<TimelineBranch[]> {\n return [...this.branches.values()].filter((b) => b.timeline_id === timelineId);\n }\n\n async saveSnapshot(snapshot: StateSnapshot): Promise<void> {\n this.snapshots.set(snapshot.snapshot_id, snapshot);\n }\n\n async getSnapshot(snapshotId: string): Promise<StateSnapshot | null> {\n return this.snapshots.get(snapshotId) ?? null;\n }\n\n async getSnapshotByEvent(eventId: string): Promise<StateSnapshot | null> {\n return (\n [...this.snapshots.values()].find((s) => s.event_id === eventId) ?? null\n );\n }\n}\n","/**\n * Timeline Engine\n *\n * Implements the three timeline operations:\n * - Replay: reconstruct and re-execute past events deterministically\n * - Fork: branch from a prior state with changed conditions\n * - Simulate: run scenarios in a shadow domain with no real effect\n *\n * Rules enforced:\n * 1. No past overwrite — original timeline is never modified\n * 2. Replay is not rewrite — original witness remains intact\n * 3. Forks are explicit — named branches with lineage\n * 4. Reality and shadow are separated — simulation never escapes\n * 5. Determinism is declared — each handler states its determinism class\n * 6. Witness is immutable — records are never altered\n */\n\nimport { createHash, randomBytes } from 'crypto';\n\nimport type {\n ForkRequest,\n ForkResult,\n ReplayDifference,\n ReplayRequest,\n ReplayResult,\n SimulatedSideEffect,\n SimulationRequest,\n SimulationResult,\n StateSnapshot,\n TimelineBranch,\n TimelineComparison,\n TimelineDomain,\n TimelineEvent,\n TimelineHandler,\n TimelineHandlerContext,\n TimelineHandlerResult,\n} from './timeline.types';\nimport type { TimelineStore } from './timeline.store';\n\n// ────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────────────────\n\nfunction generateId(prefix: string): string {\n return `${prefix}_${randomBytes(16).toString('hex')}`;\n}\n\nfunction sha256(data: string): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nfunction hashPayload(payload: Record<string, unknown>): string {\n return sha256(JSON.stringify(payload));\n}\n\nfunction diffObjects(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): ReplayDifference[] {\n const diffs: ReplayDifference[] = [];\n const allKeys = new Set([...Object.keys(a), ...Object.keys(b)]);\n\n for (const key of allKeys) {\n const va = a[key];\n const vb = b[key];\n if (JSON.stringify(va) !== JSON.stringify(vb)) {\n diffs.push({ field: key, original: va, replayed: vb });\n }\n }\n\n return diffs;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// Timeline Engine\n// ────────────────────────────────────────────────────────────────────────────\n\nexport class TimelineEngine {\n private handlers = new Map<string, TimelineHandler>();\n\n constructor(private readonly store: TimelineStore) {}\n\n /** Register an intent handler for timeline execution */\n registerHandler(handler: TimelineHandler): void {\n this.handlers.set(handler.intent, handler);\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // Record (store a real execution as a timeline event)\n // ──────────────────────────────────────────────────────────────────────\n\n async recordEvent(\n intent: string,\n actorId: string,\n payload: Record<string, unknown>,\n result: Record<string, unknown>,\n options: {\n timelineId?: string;\n branchId?: string;\n capsuleId?: string;\n tpsCoordinate?: string;\n witnessId?: string;\n determinism?: TimelineEvent['determinism'];\n parentEventId?: string;\n } = {},\n ): Promise<TimelineEvent> {\n const event: TimelineEvent = {\n event_id: generateId('evt'),\n timeline_id: options.timelineId ?? 'prime',\n branch_id: options.branchId ?? 'main',\n parent_event_id: options.parentEventId ?? null,\n intent,\n actor_id: actorId,\n capsule_id: options.capsuleId,\n tps_coordinate: options.tpsCoordinate,\n payload_hash: hashPayload(payload),\n result_hash: hashPayload(result),\n status: 'executed',\n domain: 'prime',\n determinism: options.determinism ?? 'deterministic',\n witness_id: options.witnessId,\n created_at: Date.now(),\n metadata: { payload, result },\n };\n\n await this.store.saveEvent(event);\n return event;\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // Replay\n // ──────────────────────────────────────────────────────────────────────\n\n async replay(request: ReplayRequest): Promise<ReplayResult> {\n const originalEvent = await this.store.getEvent(request.source_event_id);\n if (!originalEvent) {\n throw new Error(`Event ${request.source_event_id} not found`);\n }\n\n const handler = this.handlers.get(originalEvent.intent);\n if (!handler) {\n throw new Error(`No handler registered for intent '${originalEvent.intent}'`);\n }\n\n // Get original payload from metadata\n const originalPayload =\n (originalEvent.metadata?.payload as Record<string, unknown>) ?? {};\n const replayPayload =\n request.mode === 'analytical' && request.override_payload\n ? request.override_payload\n : originalPayload;\n\n // Load snapshot if available\n const snapshot = await this.store.getSnapshotByEvent(originalEvent.event_id);\n\n const context: TimelineHandlerContext = {\n event_id: generateId('evt'),\n timeline_id: originalEvent.timeline_id,\n branch_id: `replay_${originalEvent.branch_id}`,\n domain: 'audit',\n actor_id: originalEvent.actor_id,\n tps_coordinate: originalEvent.tps_coordinate,\n snapshot: snapshot ?? undefined,\n is_replay: true,\n is_simulation: false,\n };\n\n const startMs = Date.now();\n const handlerResult = await handler.execute(replayPayload, context);\n const durationMs = Date.now() - startMs;\n\n const replayedEvent: TimelineEvent = {\n event_id: context.event_id,\n timeline_id: originalEvent.timeline_id,\n branch_id: context.branch_id,\n parent_event_id: originalEvent.event_id,\n intent: originalEvent.intent,\n actor_id: originalEvent.actor_id,\n capsule_id: originalEvent.capsule_id,\n tps_coordinate: originalEvent.tps_coordinate,\n payload_hash: hashPayload(replayPayload),\n result_hash: hashPayload(handlerResult.result_data),\n status: 'replayed',\n domain: 'audit',\n determinism: originalEvent.determinism,\n created_at: Date.now(),\n metadata: { payload: replayPayload, result: handlerResult.result_data },\n };\n\n await this.store.saveEvent(replayedEvent);\n\n // Compare results\n const originalResult =\n (originalEvent.metadata?.result as Record<string, unknown>) ?? {};\n const differences = diffObjects(originalResult, handlerResult.result_data);\n const deterministicMatch =\n originalEvent.result_hash === replayedEvent.result_hash;\n\n return {\n original_event: originalEvent,\n replayed_event: replayedEvent,\n mode: request.mode,\n deterministic_match: deterministicMatch,\n differences,\n duration_ms: durationMs,\n };\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // Fork\n // ──────────────────────────────────────────────────────────────────────\n\n async fork(request: ForkRequest): Promise<ForkResult> {\n const sourceEvent = await this.store.getEvent(request.source_event_id);\n if (!sourceEvent) {\n throw new Error(`Event ${request.source_event_id} not found`);\n }\n\n const handler = this.handlers.get(sourceEvent.intent);\n if (!handler) {\n throw new Error(`No handler registered for intent '${sourceEvent.intent}'`);\n }\n\n // Create branch\n const branch: TimelineBranch = {\n branch_id: generateId('branch'),\n timeline_id: generateId('timeline'),\n origin_timeline_id: sourceEvent.timeline_id,\n origin_event_id: sourceEvent.event_id,\n branch_type: 'fork',\n creator_subject_id: request.actor_id,\n purpose: request.purpose,\n status: 'active',\n };\n\n await this.store.saveBranch(branch);\n\n // Take snapshot of source state\n const snapshot: StateSnapshot = {\n snapshot_id: generateId('snap'),\n timeline_id: sourceEvent.timeline_id,\n event_id: sourceEvent.event_id,\n tps_coordinate: sourceEvent.tps_coordinate,\n state_hash: hashPayload(\n (sourceEvent.metadata?.result as Record<string, unknown>) ?? {},\n ),\n state_data:\n (sourceEvent.metadata?.result as Record<string, unknown>) ?? {},\n created_at: Date.now(),\n };\n\n await this.store.saveSnapshot(snapshot);\n\n // Execute with new payload\n const context: TimelineHandlerContext = {\n event_id: generateId('evt'),\n timeline_id: branch.timeline_id,\n branch_id: branch.branch_id,\n domain: 'fork',\n actor_id: request.actor_id,\n tps_coordinate: sourceEvent.tps_coordinate,\n snapshot,\n is_replay: false,\n is_simulation: false,\n };\n\n const handlerResult = await handler.execute(request.new_payload, context);\n\n const forkedEvent: TimelineEvent = {\n event_id: context.event_id,\n timeline_id: branch.timeline_id,\n branch_id: branch.branch_id,\n parent_event_id: sourceEvent.event_id,\n intent: sourceEvent.intent,\n actor_id: request.actor_id,\n tps_coordinate: sourceEvent.tps_coordinate,\n payload_hash: hashPayload(request.new_payload),\n result_hash: hashPayload(handlerResult.result_data),\n status: 'forked',\n domain: 'fork',\n determinism: sourceEvent.determinism,\n created_at: Date.now(),\n metadata: {\n payload: request.new_payload,\n result: handlerResult.result_data,\n },\n };\n\n await this.store.saveEvent(forkedEvent);\n\n return { branch, forked_event: forkedEvent, snapshot };\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // Simulate\n // ──────────────────────────────────────────────────────────────────────\n\n async simulate(request: SimulationRequest): Promise<SimulationResult> {\n const handler = this.handlers.get(request.intent);\n if (!handler) {\n throw new Error(`No handler registered for intent '${request.intent}'`);\n }\n\n // Load source snapshot if specified\n let snapshot: StateSnapshot | undefined;\n if (request.from_snapshot_id) {\n const loaded = await this.store.getSnapshot(request.from_snapshot_id);\n if (!loaded) {\n throw new Error(`Snapshot ${request.from_snapshot_id} not found`);\n }\n snapshot = loaded;\n }\n\n // Create shadow branch\n const branch: TimelineBranch = {\n branch_id: generateId('branch'),\n timeline_id: generateId('timeline'),\n origin_timeline_id: 'prime',\n origin_event_id: 'simulation_origin',\n branch_type: 'simulation',\n created_at_tps: request.at_tps,\n creator_subject_id: request.actor_id,\n purpose: request.purpose,\n status: 'active',\n };\n\n await this.store.saveBranch(branch);\n\n const context: TimelineHandlerContext = {\n event_id: generateId('evt'),\n timeline_id: branch.timeline_id,\n branch_id: branch.branch_id,\n domain: 'shadow',\n actor_id: request.actor_id,\n tps_coordinate: request.at_tps,\n snapshot,\n is_replay: false,\n is_simulation: true,\n };\n\n const startMs = Date.now();\n const handlerResult = await handler.execute(request.payload, context);\n const durationMs = Date.now() - startMs;\n\n const simulatedEvent: TimelineEvent = {\n event_id: context.event_id,\n timeline_id: branch.timeline_id,\n branch_id: branch.branch_id,\n parent_event_id: null,\n intent: request.intent,\n actor_id: request.actor_id,\n tps_coordinate: request.at_tps,\n payload_hash: hashPayload(request.payload),\n result_hash: hashPayload(handlerResult.result_data),\n status: 'simulated',\n domain: 'shadow',\n determinism: 'bounded_nondeterministic',\n created_at: Date.now(),\n metadata: { payload: request.payload, result: handlerResult.result_data },\n };\n\n await this.store.saveEvent(simulatedEvent);\n\n // Mark branch as completed\n branch.status = 'completed';\n await this.store.saveBranch(branch);\n\n return {\n branch,\n simulated_event: simulatedEvent,\n predicted_outcome: handlerResult.result_data,\n side_effects: handlerResult.side_effects ?? [],\n duration_ms: durationMs,\n };\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // Compare timelines\n // ──────────────────────────────────────────────────────────────────────\n\n async compare(\n timelineIdA: string,\n timelineIdB: string,\n ): Promise<TimelineComparison> {\n const eventsA = await this.store.getEventsByTimeline(timelineIdA);\n const eventsB = await this.store.getEventsByTimeline(timelineIdB);\n\n // Sort by creation time\n eventsA.sort((a, b) => a.created_at - b.created_at);\n eventsB.sort((a, b) => a.created_at - b.created_at);\n\n const maxLen = Math.max(eventsA.length, eventsB.length);\n const eventPairs: TimelineComparison['event_pairs'] = [];\n let divergencePoint: string | undefined;\n\n for (let i = 0; i < maxLen; i++) {\n const a = eventsA[i];\n const b = eventsB[i];\n\n if (!a || !b) {\n if (!divergencePoint) {\n divergencePoint = a?.event_id ?? b?.event_id;\n }\n continue;\n }\n\n const match = a.result_hash === b.result_hash;\n const resultA =\n (a.metadata?.result as Record<string, unknown>) ?? {};\n const resultB =\n (b.metadata?.result as Record<string, unknown>) ?? {};\n const differences = match ? [] : diffObjects(resultA, resultB);\n\n if (!match && !divergencePoint) {\n divergencePoint = a.event_id;\n }\n\n eventPairs.push({ event_a: a, event_b: b, match, differences });\n }\n\n return {\n timeline_a: timelineIdA,\n timeline_b: timelineIdB,\n event_pairs: eventPairs,\n divergence_point: divergencePoint,\n };\n }\n\n // ──────────────────────────────────────────────────────────────────────\n // State snapshot management\n // ──────────────────────────────────────────────────────────────────────\n\n async createSnapshot(\n eventId: string,\n stateData: Record<string, unknown>,\n ): Promise<StateSnapshot> {\n const event = await this.store.getEvent(eventId);\n if (!event) {\n throw new Error(`Event ${eventId} not found`);\n }\n\n const snapshot: StateSnapshot = {\n snapshot_id: generateId('snap'),\n timeline_id: event.timeline_id,\n event_id: eventId,\n tps_coordinate: event.tps_coordinate,\n state_hash: hashPayload(stateData),\n state_data: stateData,\n created_at: Date.now(),\n };\n\n await this.store.saveSnapshot(snapshot);\n return snapshot;\n }\n\n async restoreSnapshot(snapshotId: string): Promise<StateSnapshot> {\n const snapshot = await this.store.getSnapshot(snapshotId);\n if (!snapshot) {\n throw new Error(`Snapshot ${snapshotId} not found`);\n }\n return snapshot;\n }\n}\n"],"mappings":"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","names":[]}
|