Skip to content

Commit

Permalink
Export Replay and add visitor-pattern forEachFrame.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesremuscat committed Apr 14, 2023
1 parent e51427e commit 29776c9
Showing 1 changed file with 49 additions and 2 deletions.
51 changes: 49 additions & 2 deletions src/replay.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import { diff, patch } from './diffs.js';

export const REPLAY_FRAME_REGEX = /^([0-9]{5,11})(i?).json$/;

class Replay {
export class Replay {
constructor(zipFile) {
this._file = zipFile;
this._keyframes = {};
this._iframes = {};

this.forEachFrame = this.forEachFrame.bind(this);
}

async _init() {
const entries = await this._file.getEntries();
const entries = await this.listEntries();

await Promise.all(
entries.map(
Expand Down Expand Up @@ -57,6 +59,10 @@ class Replay {
this.manifest.startTime = firstFrame;
}

async listEntries() {
return await this._file.getEntries();
}

async readEntry(e) {
const text = await e.getData(new TextWriter());
return JSON.parse(text);
Expand All @@ -81,18 +87,59 @@ class Replay {
myState = await applyIframe(myState, ifrState);
}

if (!myState.manifest) {
myState.manifest = this.manifest;
}

if (!myState.lastUpdated) {
myState.lastUpdated = time;
}

return myState;
}

async getStateAtRelative(relTime) {
return await this.getStateAt(this.manifest.startTime + relTime);
}

async forEachFrame(callback) {
const keyframes = Object.keys(this._keyframes).map(k => parseInt(k, 10)).sort();
const iframes = Object.keys(this._iframes).map(k => parseInt(k, 10)).sort();

let prevFrame = null;
while (keyframes.length > 0) {
const k = keyframes.shift();

const kf = await this.readEntry(this._keyframes[k]);

prevFrame = kf;

if (!prevFrame.manifest) {
prevFrame.manifest = this.manifest;
}

if (!prevFrame.lastUpdated) {
prevFrame.lastUpdated = k;
}

callback(kf, k);

while (iframes.length > 0 && (keyframes.length === 0 || iframes[0] < keyframes[0])) {
const i = iframes.shift();
const ifr = await this.readEntry(this._iframes[i]);
prevFrame = await applyIframe(prevFrame, ifr);
prevFrame.lastUpdated = i;
callback(prevFrame, i);
}
}
}
}

const applyIframe = (base, iframe) => {
return new Promise(
(resolve) => {
const result = {
...base,
cars: patch(iframe['cars'], base['cars']),
session: patch(iframe['session'], base['session']),
messages: iframe['messages'].concat(base['messages']).slice(0, 100),
Expand Down

0 comments on commit 29776c9

Please # to comment.