MCPcopy
hub / github.com/cpaczek/skylight / ReplayUpstream

Class ReplayUpstream

tracker/src/upstream.ts:128–200  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

126 * relative timing, shifted to the present so staleness math behaves.
127 */
128export class ReplayUpstream implements Upstream {
129 private aircraft = new Map<string, Aircraft>();
130 private config: Config = DEFAULT_CONFIG;
131 private timers: ReturnType<typeof setTimeout>[] = [];
132 private running = false;
133
134 constructor(
135 private file: string,
136 private events: UpstreamEvents = {},
137 private speed = 1,
138 ) {}
139
140 start(): void {
141 if (this.running) return;
142 this.running = true;
143 const lines = readFileSync(this.file, "utf8").split("\n").filter(Boolean);
144 const snaps: { t: number; aircraft: Aircraft[] }[] = [];
145 for (const line of lines) {
146 try {
147 const rec = JSON.parse(line);
148 if (rec.kind === "snapshot") snaps.push({ t: rec.t, aircraft: rec.aircraft });
149 } catch {
150 // tolerate partial lines from crashed sessions
151 }
152 }
153 if (!snaps.length) {
154 console.error(`[replay] no snapshots in ${this.file}`);
155 return;
156 }
157 console.log(`[replay] ${snaps.length} snapshots from ${this.file}`);
158 const t0 = snaps[0].t;
159 const wall0 = Date.now();
160 for (const snap of snaps) {
161 const delay = (snap.t - t0) / this.speed;
162 this.timers.push(
163 setTimeout(() => {
164 const now = Date.now();
165 const shift = now - snap.t; // re-stamp into the present
166 this.aircraft.clear();
167 const shifted = snap.aircraft.map((ac) => ({
168 ...ac,
169 ts: (ac.ts ?? snap.t) + shift,
170 }));
171 for (const ac of shifted) this.aircraft.set(ac.hex, ac);
172 this.events.onSnapshot?.(wall0 + delay * this.speed, shifted);
173 }, delay),
174 );
175 }
176 }
177
178 stop(): void {
179 for (const t of this.timers) clearTimeout(t);
180 this.timers = [];
181 this.running = false;
182 }
183
184 isConnected(): boolean {
185 return this.running;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected