@uptimizr/replay 0.1.0
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/AGENTS.md +57 -0
- package/LICENSE +201 -0
- package/README.md +96 -0
- package/dist/drivers/babylon-lite.d.ts +134 -0
- package/dist/drivers/babylon-lite.d.ts.map +1 -0
- package/dist/drivers/babylon-lite.js +167 -0
- package/dist/drivers/babylon-lite.js.map +1 -0
- package/dist/drivers/babylon.d.ts +99 -0
- package/dist/drivers/babylon.d.ts.map +1 -0
- package/dist/drivers/babylon.js +176 -0
- package/dist/drivers/babylon.js.map +1 -0
- package/dist/drivers/playcanvas.d.ts +122 -0
- package/dist/drivers/playcanvas.d.ts.map +1 -0
- package/dist/drivers/playcanvas.js +206 -0
- package/dist/drivers/playcanvas.js.map +1 -0
- package/dist/drivers/three.d.ts +127 -0
- package/dist/drivers/three.d.ts.map +1 -0
- package/dist/drivers/three.js +194 -0
- package/dist/drivers/three.js.map +1 -0
- package/dist/fetchSession.d.ts +43 -0
- package/dist/fetchSession.d.ts.map +1 -0
- package/dist/fetchSession.js +103 -0
- package/dist/fetchSession.js.map +1 -0
- package/dist/global.d.ts +62 -0
- package/dist/global.d.ts.map +1 -0
- package/dist/global.js +95 -0
- package/dist/global.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/player.d.ts +35 -0
- package/dist/player.d.ts.map +1 -0
- package/dist/player.js +104 -0
- package/dist/player.js.map +1 -0
- package/dist/reconstruct.d.ts +74 -0
- package/dist/reconstruct.d.ts.map +1 -0
- package/dist/reconstruct.js +266 -0
- package/dist/reconstruct.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/uptimizr-replay.global.js +71 -0
- package/llms.txt +17 -0
- package/package.json +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playcanvas.js","sourceRoot":"","sources":["../../src/drivers/playcanvas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { CustomPropValue } from "@uptimizr/schema";
|
|
2
|
+
import type { ReplayDriver } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Structural view of the three.js objects this driver writes to. Kept minimal and
|
|
5
|
+
* structural so `three` stays an **optional peer dependency** — the driver never
|
|
6
|
+
* imports three at runtime; the host page owns the scene and the real objects.
|
|
7
|
+
*/
|
|
8
|
+
interface ThreeReplayCamera {
|
|
9
|
+
position: {
|
|
10
|
+
set(x: number, y: number, z: number): void;
|
|
11
|
+
};
|
|
12
|
+
/** `Object3D.lookAt(x, y, z)` — for a camera, orients so it looks at the point. */
|
|
13
|
+
lookAt(x: number, y: number, z: number): void;
|
|
14
|
+
/** Present on `PerspectiveCamera`. */
|
|
15
|
+
isPerspectiveCamera?: boolean;
|
|
16
|
+
/** Vertical FOV in **degrees** (three.js convention). */
|
|
17
|
+
fov?: number;
|
|
18
|
+
updateProjectionMatrix?: () => void;
|
|
19
|
+
}
|
|
20
|
+
interface ThreeReplayScene {
|
|
21
|
+
/** three exposes the active camera per-render, not on the scene; pass it explicitly. */
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
/** A three.js node a replay can drive (an `Object3D` — mesh, group, etc.). */
|
|
25
|
+
export type ThreeReplayNode = object;
|
|
26
|
+
export interface ThreeReplayDriverOptions {
|
|
27
|
+
/** Scene to re-drive (read/write only — never emits analytics events). */
|
|
28
|
+
scene: ThreeReplayScene;
|
|
29
|
+
/** Camera to move. three has no `scene.activeCamera`, so this is required. */
|
|
30
|
+
camera: ThreeReplayCamera;
|
|
31
|
+
/** Called for each replayed pointer event, so the host can render a marker. */
|
|
32
|
+
onPointer?: (screen: [number, number] | undefined, hitPoint: [number, number, number] | undefined, hitMesh: string | undefined, type: "pointer_move" | "pointer_click" | "pointer_down" | "pointer_up") => void;
|
|
33
|
+
/** Called for each replayed mesh interaction, so the host can highlight it. */
|
|
34
|
+
onMeshInteraction?: (mesh: string, kind: string, point: [number, number, number] | undefined) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Scene-actor resolvers for `node_transform` drive-back (ADR 0027). Maps a
|
|
37
|
+
* recorded `nodeId` to the live three `Object3D` to re-drive — a direct
|
|
38
|
+
* reference or a `() => node` resolver. Tier-1 (world-frame) samples are
|
|
39
|
+
* converted canonical → three and applied to the node's local transform
|
|
40
|
+
* (correct for root actors). Tier-2 bone samples drive the matching named
|
|
41
|
+
* `Bone` of the node's `skeleton` (a `SkinnedMesh`) in its local frame; every
|
|
42
|
+
* sample is also forwarded via {@link onNodeTransform}.
|
|
43
|
+
*/
|
|
44
|
+
nodes?: Record<string, ThreeReplayNode | (() => ThreeReplayNode | null | undefined)>;
|
|
45
|
+
/**
|
|
46
|
+
* Called for **every** replayed `node_transform` (Tier 1 and Tier 2), after any
|
|
47
|
+
* node drive-back. The position/rotation are converted into three's
|
|
48
|
+
* right-handed frame; `boneId` is set for Tier-2 samples.
|
|
49
|
+
*/
|
|
50
|
+
onNodeTransform?: (nodeId: string, transform: {
|
|
51
|
+
boneId: string | undefined;
|
|
52
|
+
childPath: string | undefined;
|
|
53
|
+
position: [number, number, number];
|
|
54
|
+
rotation: [number, number, number, number];
|
|
55
|
+
scale: [number, number, number] | undefined;
|
|
56
|
+
}, ts: number) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Called for each replayed developer-defined `custom` event. The driver can't
|
|
59
|
+
* know how to render an arbitrary domain event, so it forwards the name, props,
|
|
60
|
+
* and timestamp for the host to visualize (marker, toast, log, ...).
|
|
61
|
+
*/
|
|
62
|
+
onCustom?: (name: string, props: Record<string, CustomPropValue> | undefined, ts: number) => void;
|
|
63
|
+
/**
|
|
64
|
+
* Called for each replayed `input_action` (discrete keyboard/gamepad action,
|
|
65
|
+
* ADR 0023). Forwarded with the action, raw `code`/`button`, source, and
|
|
66
|
+
* timestamp so a replay UI can annotate the timeline.
|
|
67
|
+
*/
|
|
68
|
+
onInputAction?: (input: {
|
|
69
|
+
action: string;
|
|
70
|
+
code: string | undefined;
|
|
71
|
+
button: number | undefined;
|
|
72
|
+
pressed: boolean | undefined;
|
|
73
|
+
source: string | undefined;
|
|
74
|
+
}, ts: number) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Called for each replayed browser/engine lifecycle event (viewport resize, tab
|
|
77
|
+
* visibility, window focus, GPU context loss/restore). The driver doesn't
|
|
78
|
+
* re-drive these — it forwards them so a replay UI can annotate the timeline.
|
|
79
|
+
*/
|
|
80
|
+
onLifecycle?: (event: {
|
|
81
|
+
type: "viewport_resize";
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
dpr: number | undefined;
|
|
85
|
+
} | {
|
|
86
|
+
type: "visibility_change";
|
|
87
|
+
state: "visible" | "hidden";
|
|
88
|
+
} | {
|
|
89
|
+
type: "focus_change";
|
|
90
|
+
focused: boolean;
|
|
91
|
+
} | {
|
|
92
|
+
type: "context_lost";
|
|
93
|
+
} | {
|
|
94
|
+
type: "context_restored";
|
|
95
|
+
}, ts: number) => void;
|
|
96
|
+
/**
|
|
97
|
+
* Called for each replayed `runtime_error` event (opt-in capture, ADR 0013).
|
|
98
|
+
* Forwarded so a replay UI can mark where a JS error or unhandled rejection
|
|
99
|
+
* interrupted the session.
|
|
100
|
+
*/
|
|
101
|
+
onError?: (error: {
|
|
102
|
+
kind: "error" | "unhandledrejection";
|
|
103
|
+
message: string;
|
|
104
|
+
source: string | undefined;
|
|
105
|
+
lineno: number | undefined;
|
|
106
|
+
colno: number | undefined;
|
|
107
|
+
stack: string | undefined;
|
|
108
|
+
}, ts: number) => void;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* three.js replay driver. Re-drives camera pose (and surfaces pointer/mesh events
|
|
112
|
+
* to host callbacks) in the user's own three.js scene.
|
|
113
|
+
*
|
|
114
|
+
* ## Coordinate frame (canonical → three)
|
|
115
|
+
* Events arrive in the canonical **left-handed, y-up** frame (ADR 0018); three is
|
|
116
|
+
* **right-handed**, so world-space data is converted back with the shared
|
|
117
|
+
* `fromCanonical*` helpers (the Z-negation reflection is its own inverse). Camera
|
|
118
|
+
* orientation is applied via `camera.lookAt(target)` — `lookAt` resolves three's
|
|
119
|
+
* −Z-forward convention internally, so the driver does **not** re-derive a forward
|
|
120
|
+
* axis from the recorded direction (avoiding the orientation trap documented in
|
|
121
|
+
* sdk-core `coordinates.ts`).
|
|
122
|
+
*
|
|
123
|
+
* It only reads/writes the scene — it never emits analytics events (ADR 0006).
|
|
124
|
+
*/
|
|
125
|
+
export declare function createThreeReplayDriver(options: ThreeReplayDriverOptions): ReplayDriver;
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=three.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"three.d.ts","sourceRoot":"","sources":["../../src/drivers/three.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { fromCanonicalDirection, fromCanonicalPosition, fromCanonicalQuat, } from "@uptimizr/sdk-core";
|
|
2
|
+
/**
|
|
3
|
+
* Walk a `/`-separated {@link NodeTransformEvent.childPath} from a resolved root
|
|
4
|
+
* actor to the descendant node, matching each segment against direct children by
|
|
5
|
+
* `name` (ADR 0033). Returns `null` if any segment is missing.
|
|
6
|
+
*/
|
|
7
|
+
function resolveChildByPath(root, childPath) {
|
|
8
|
+
let cur = root;
|
|
9
|
+
for (const segment of childPath.split("/")) {
|
|
10
|
+
if (!segment)
|
|
11
|
+
continue;
|
|
12
|
+
const children = cur?.children;
|
|
13
|
+
if (!Array.isArray(children))
|
|
14
|
+
return null;
|
|
15
|
+
cur = children.find((c) => c.name === segment) ?? null;
|
|
16
|
+
if (!cur)
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return cur;
|
|
20
|
+
}
|
|
21
|
+
/** Resolve a node entry (direct ref or `() => node`) to a live node, or `null`. */
|
|
22
|
+
function resolveReplayNode(entry) {
|
|
23
|
+
if (!entry)
|
|
24
|
+
return null;
|
|
25
|
+
if (typeof entry === "function") {
|
|
26
|
+
return entry() ?? null;
|
|
27
|
+
}
|
|
28
|
+
return entry;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* three.js replay driver. Re-drives camera pose (and surfaces pointer/mesh events
|
|
32
|
+
* to host callbacks) in the user's own three.js scene.
|
|
33
|
+
*
|
|
34
|
+
* ## Coordinate frame (canonical → three)
|
|
35
|
+
* Events arrive in the canonical **left-handed, y-up** frame (ADR 0018); three is
|
|
36
|
+
* **right-handed**, so world-space data is converted back with the shared
|
|
37
|
+
* `fromCanonical*` helpers (the Z-negation reflection is its own inverse). Camera
|
|
38
|
+
* orientation is applied via `camera.lookAt(target)` — `lookAt` resolves three's
|
|
39
|
+
* −Z-forward convention internally, so the driver does **not** re-derive a forward
|
|
40
|
+
* axis from the recorded direction (avoiding the orientation trap documented in
|
|
41
|
+
* sdk-core `coordinates.ts`).
|
|
42
|
+
*
|
|
43
|
+
* It only reads/writes the scene — it never emits analytics events (ADR 0006).
|
|
44
|
+
*/
|
|
45
|
+
export function createThreeReplayDriver(options) {
|
|
46
|
+
return {
|
|
47
|
+
reset() {
|
|
48
|
+
// Camera state is fully determined by the next camera_sample, so there is
|
|
49
|
+
// nothing to restore; host-rendered markers are the host's responsibility.
|
|
50
|
+
},
|
|
51
|
+
apply(event) {
|
|
52
|
+
switch (event.type) {
|
|
53
|
+
case "camera_sample": {
|
|
54
|
+
const cam = options.camera;
|
|
55
|
+
if (!cam)
|
|
56
|
+
return;
|
|
57
|
+
// Position: canonical → three (Z-negated).
|
|
58
|
+
const [px, py, pz] = fromCanonicalPosition(event.position, "right");
|
|
59
|
+
cam.position.set(px, py, pz);
|
|
60
|
+
// Look target: an explicit recorded target, else position + direction —
|
|
61
|
+
// both converted to three's frame. lookAt handles the −Z forward axis.
|
|
62
|
+
let tx;
|
|
63
|
+
let ty;
|
|
64
|
+
let tz;
|
|
65
|
+
if (event.target) {
|
|
66
|
+
[tx, ty, tz] = fromCanonicalPosition(event.target, "right");
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const [dx, dy, dz] = fromCanonicalDirection(event.direction, "right");
|
|
70
|
+
tx = px + dx;
|
|
71
|
+
ty = py + dy;
|
|
72
|
+
tz = pz + dz;
|
|
73
|
+
}
|
|
74
|
+
cam.lookAt(tx, ty, tz);
|
|
75
|
+
// three's perspective FOV is in degrees; the wire carries radians.
|
|
76
|
+
if (cam.isPerspectiveCamera && typeof event.fov === "number") {
|
|
77
|
+
cam.fov = (event.fov * 180) / Math.PI;
|
|
78
|
+
cam.updateProjectionMatrix?.();
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case "pointer_move":
|
|
83
|
+
case "pointer_click":
|
|
84
|
+
case "pointer_down":
|
|
85
|
+
case "pointer_up": {
|
|
86
|
+
// Convert the world-space hit point back into three's frame so a host
|
|
87
|
+
// marker lands correctly; screen coords are engine-independent.
|
|
88
|
+
const hitPoint = event.hitPoint
|
|
89
|
+
? fromCanonicalPosition(event.hitPoint, "right")
|
|
90
|
+
: undefined;
|
|
91
|
+
options.onPointer?.(event.screen, hitPoint, event.hitMesh, event.type);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "mesh_interaction": {
|
|
95
|
+
const point = event.point ? fromCanonicalPosition(event.point, "right") : undefined;
|
|
96
|
+
options.onMeshInteraction?.(event.mesh, event.kind, point);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case "custom":
|
|
100
|
+
options.onCustom?.(event.name, event.props, event.ts);
|
|
101
|
+
break;
|
|
102
|
+
case "input_action":
|
|
103
|
+
options.onInputAction?.({
|
|
104
|
+
action: event.action,
|
|
105
|
+
code: event.code,
|
|
106
|
+
button: event.button,
|
|
107
|
+
pressed: event.pressed,
|
|
108
|
+
source: event.source,
|
|
109
|
+
}, event.ts);
|
|
110
|
+
break;
|
|
111
|
+
case "viewport_resize":
|
|
112
|
+
options.onLifecycle?.({ type: "viewport_resize", width: event.width, height: event.height, dpr: event.dpr }, event.ts);
|
|
113
|
+
break;
|
|
114
|
+
case "visibility_change":
|
|
115
|
+
options.onLifecycle?.({ type: "visibility_change", state: event.state }, event.ts);
|
|
116
|
+
break;
|
|
117
|
+
case "focus_change":
|
|
118
|
+
options.onLifecycle?.({ type: "focus_change", focused: event.focused }, event.ts);
|
|
119
|
+
break;
|
|
120
|
+
case "context_lost":
|
|
121
|
+
options.onLifecycle?.({ type: "context_lost" }, event.ts);
|
|
122
|
+
break;
|
|
123
|
+
case "context_restored":
|
|
124
|
+
options.onLifecycle?.({ type: "context_restored" }, event.ts);
|
|
125
|
+
break;
|
|
126
|
+
case "runtime_error":
|
|
127
|
+
options.onError?.({
|
|
128
|
+
kind: event.kind,
|
|
129
|
+
message: event.message,
|
|
130
|
+
source: event.source,
|
|
131
|
+
lineno: event.lineno,
|
|
132
|
+
colno: event.colno,
|
|
133
|
+
stack: event.stack,
|
|
134
|
+
}, event.ts);
|
|
135
|
+
break;
|
|
136
|
+
case "camera_gesture":
|
|
137
|
+
// Derived navigation annotation (ADR 0025); the camera trajectory is
|
|
138
|
+
// reconstructed from camera_sample, so replay intentionally ignores it.
|
|
139
|
+
break;
|
|
140
|
+
case "node_transform": {
|
|
141
|
+
const node = resolveReplayNode(options.nodes?.[event.nodeId]);
|
|
142
|
+
if (node) {
|
|
143
|
+
if (event.boneId !== undefined) {
|
|
144
|
+
// Tier 2: drive the named bone's parent-relative LOCAL pose. The
|
|
145
|
+
// canonical reflection conjugates a local transform the same way it
|
|
146
|
+
// does a world one, so the same convert applies (ADR 0027).
|
|
147
|
+
const bone = node.skeleton?.bones?.find((b) => b.name === event.boneId);
|
|
148
|
+
if (bone) {
|
|
149
|
+
const [px, py, pz] = fromCanonicalPosition(event.position, "right");
|
|
150
|
+
bone.position?.set(px, py, pz);
|
|
151
|
+
const [qx, qy, qz, qw] = fromCanonicalQuat(event.rotation, "right");
|
|
152
|
+
bone.quaternion?.set(qx, qy, qz, qw);
|
|
153
|
+
if (event.scale) {
|
|
154
|
+
bone.scale?.set(event.scale[0], event.scale[1], event.scale[2]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Tier 1: the declared root (no childPath) or a subtree child
|
|
160
|
+
// resolved by its relative path (ADR 0033). Both carry a world-frame
|
|
161
|
+
// pose; canonical → three (Z-negated position + reflected quat).
|
|
162
|
+
const target = event.childPath === undefined ? node : resolveChildByPath(node, event.childPath);
|
|
163
|
+
if (target) {
|
|
164
|
+
const [px, py, pz] = fromCanonicalPosition(event.position, "right");
|
|
165
|
+
target.position?.set(px, py, pz);
|
|
166
|
+
const [qx, qy, qz, qw] = fromCanonicalQuat(event.rotation, "right");
|
|
167
|
+
target.quaternion?.set(qx, qy, qz, qw);
|
|
168
|
+
if (event.scale) {
|
|
169
|
+
target.scale?.set(event.scale[0], event.scale[1], event.scale[2]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Forward the (frame-converted) sample so the host can render a proxy
|
|
175
|
+
// marker or annotate the timeline; `boneId` is set for Tier-2 samples,
|
|
176
|
+
// `childPath` for Tier-1 subtree children (ADR 0033).
|
|
177
|
+
const fwdPos = fromCanonicalPosition(event.position, "right");
|
|
178
|
+
const fwdRot = fromCanonicalQuat(event.rotation, "right");
|
|
179
|
+
options.onNodeTransform?.(event.nodeId, {
|
|
180
|
+
boneId: event.boneId,
|
|
181
|
+
childPath: event.childPath,
|
|
182
|
+
position: fwdPos,
|
|
183
|
+
rotation: fwdRot,
|
|
184
|
+
scale: event.scale,
|
|
185
|
+
}, event.ts);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
default:
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=three.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"three.js","sourceRoot":"","sources":["../../src/drivers/three.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type AnyEvent } from "@uptimizr/schema";
|
|
2
|
+
export interface FetchSessionOptions {
|
|
3
|
+
/** Collector base URL, e.g. `https://collect.example.com`. */
|
|
4
|
+
endpoint: string;
|
|
5
|
+
/** Project API key (sent as `x-api-key`). */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/** Session id to fetch. */
|
|
8
|
+
sessionId: string;
|
|
9
|
+
/** Override the global `fetch` (for testing or non-browser hosts). */
|
|
10
|
+
fetchImpl?: typeof fetch;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Fetch the ordered event stream for a session from the collector's replay
|
|
14
|
+
* endpoint (`GET /api/v1/sessions/:id/events`). Validates the payload against the
|
|
15
|
+
* schema and returns events sorted by timestamp, ready for {@link ReplayPlayer}.
|
|
16
|
+
*/
|
|
17
|
+
export declare function fetchSessionEvents(options: FetchSessionOptions): Promise<AnyEvent[]>;
|
|
18
|
+
/** Optional hooks for the streaming fetch. */
|
|
19
|
+
export interface StreamSessionOptions extends FetchSessionOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Called for each line that fails to parse/validate (skipped, not fatal), so
|
|
22
|
+
* callers can surface or count malformed rows. The count is cumulative.
|
|
23
|
+
*/
|
|
24
|
+
onMalformedLine?: (count: number) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Streaming counterpart to {@link fetchSessionEvents}: yields events as they
|
|
28
|
+
* arrive instead of buffering the whole session, so playback can start before
|
|
29
|
+
* the full stream has downloaded and neither side holds the entire session at
|
|
30
|
+
* once (ADR 0015).
|
|
31
|
+
*
|
|
32
|
+
* Negotiates NDJSON via `Accept: application/x-ndjson` (and a `?format=ndjson`
|
|
33
|
+
* hint). A collector that supports it streams one event per line, validated
|
|
34
|
+
* per-line — a malformed line is skipped (and reported via `onMalformedLine`)
|
|
35
|
+
* rather than failing the whole fetch. A collector that does **not** support
|
|
36
|
+
* NDJSON returns the buffered JSON array, which is transparently parsed and
|
|
37
|
+
* yielded, so this works against old and new servers alike.
|
|
38
|
+
*
|
|
39
|
+
* Events are yielded in server order (`ts ASC`); {@link ReplayPlayer} also sorts
|
|
40
|
+
* defensively, so ordering is guaranteed regardless of transport.
|
|
41
|
+
*/
|
|
42
|
+
export declare function fetchSessionEventsStream(options: StreamSessionOptions): AsyncGenerator<AnyEvent>;
|
|
43
|
+
//# sourceMappingURL=fetchSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchSession.d.ts","sourceRoot":"","sources":["../src/fetchSession.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAY1F;AAED,8CAA8C;AAC9C,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAuB,wBAAwB,CAC7C,OAAO,EAAE,oBAAoB,GAC5B,cAAc,CAAC,QAAQ,CAAC,CAkE1B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { anyEventSchema } from "@uptimizr/schema";
|
|
3
|
+
const sessionPayloadSchema = z.array(anyEventSchema);
|
|
4
|
+
/**
|
|
5
|
+
* Fetch the ordered event stream for a session from the collector's replay
|
|
6
|
+
* endpoint (`GET /api/v1/sessions/:id/events`). Validates the payload against the
|
|
7
|
+
* schema and returns events sorted by timestamp, ready for {@link ReplayPlayer}.
|
|
8
|
+
*/
|
|
9
|
+
export async function fetchSessionEvents(options) {
|
|
10
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
11
|
+
const url = `${options.endpoint}/api/v1/sessions/${encodeURIComponent(options.sessionId)}/events`;
|
|
12
|
+
const res = await fetchImpl(url, { headers: { "x-api-key": options.apiKey } });
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
throw new Error(`replay fetch failed: ${res.status}`);
|
|
15
|
+
}
|
|
16
|
+
const parsed = sessionPayloadSchema.safeParse(await res.json());
|
|
17
|
+
if (!parsed.success) {
|
|
18
|
+
throw new Error("replay fetch returned an invalid session payload");
|
|
19
|
+
}
|
|
20
|
+
return parsed.data.sort((a, b) => a.ts - b.ts);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Streaming counterpart to {@link fetchSessionEvents}: yields events as they
|
|
24
|
+
* arrive instead of buffering the whole session, so playback can start before
|
|
25
|
+
* the full stream has downloaded and neither side holds the entire session at
|
|
26
|
+
* once (ADR 0015).
|
|
27
|
+
*
|
|
28
|
+
* Negotiates NDJSON via `Accept: application/x-ndjson` (and a `?format=ndjson`
|
|
29
|
+
* hint). A collector that supports it streams one event per line, validated
|
|
30
|
+
* per-line — a malformed line is skipped (and reported via `onMalformedLine`)
|
|
31
|
+
* rather than failing the whole fetch. A collector that does **not** support
|
|
32
|
+
* NDJSON returns the buffered JSON array, which is transparently parsed and
|
|
33
|
+
* yielded, so this works against old and new servers alike.
|
|
34
|
+
*
|
|
35
|
+
* Events are yielded in server order (`ts ASC`); {@link ReplayPlayer} also sorts
|
|
36
|
+
* defensively, so ordering is guaranteed regardless of transport.
|
|
37
|
+
*/
|
|
38
|
+
export async function* fetchSessionEventsStream(options) {
|
|
39
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
40
|
+
const base = `${options.endpoint}/api/v1/sessions/${encodeURIComponent(options.sessionId)}/events`;
|
|
41
|
+
const res = await fetchImpl(`${base}?format=ndjson`, {
|
|
42
|
+
headers: { "x-api-key": options.apiKey, accept: "application/x-ndjson" },
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
throw new Error(`replay fetch failed: ${res.status}`);
|
|
46
|
+
}
|
|
47
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
48
|
+
// Fallback: a server that ignored the negotiation returned the JSON array.
|
|
49
|
+
if (!contentType.includes("application/x-ndjson")) {
|
|
50
|
+
const parsed = sessionPayloadSchema.safeParse(await res.json());
|
|
51
|
+
if (!parsed.success) {
|
|
52
|
+
throw new Error("replay fetch returned an invalid session payload");
|
|
53
|
+
}
|
|
54
|
+
for (const event of parsed.data.sort((a, b) => a.ts - b.ts)) {
|
|
55
|
+
yield event;
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!res.body) {
|
|
60
|
+
throw new Error("replay stream returned no body");
|
|
61
|
+
}
|
|
62
|
+
let malformed = 0;
|
|
63
|
+
const reportMalformed = () => options.onMalformedLine?.(++malformed);
|
|
64
|
+
const reader = res.body.getReader();
|
|
65
|
+
const decoder = new TextDecoder();
|
|
66
|
+
let buffer = "";
|
|
67
|
+
const handleLine = function* (line) {
|
|
68
|
+
const trimmed = line.trim();
|
|
69
|
+
if (trimmed.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
let json;
|
|
72
|
+
try {
|
|
73
|
+
json = JSON.parse(trimmed);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
reportMalformed();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const parsed = anyEventSchema.safeParse(json);
|
|
80
|
+
if (parsed.success) {
|
|
81
|
+
yield parsed.data;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
reportMalformed();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
for (;;) {
|
|
88
|
+
const { done, value } = await reader.read();
|
|
89
|
+
if (done)
|
|
90
|
+
break;
|
|
91
|
+
buffer += decoder.decode(value, { stream: true });
|
|
92
|
+
let newline = buffer.indexOf("\n");
|
|
93
|
+
while (newline >= 0) {
|
|
94
|
+
const line = buffer.slice(0, newline);
|
|
95
|
+
buffer = buffer.slice(newline + 1);
|
|
96
|
+
yield* handleLine(line);
|
|
97
|
+
newline = buffer.indexOf("\n");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Flush any trailing line without a final newline.
|
|
101
|
+
yield* handleLine(buffer);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=fetchSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchSession.js","sourceRoot":"","sources":["../src/fetchSession.ts"],"names":[],"mappings":"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"}
|
package/dist/global.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global (IIFE) entry for `@uptimizr/replay` — exposes `window.UptimizrReplay`
|
|
3
|
+
* for `<script>`-tag use (e.g. on playground.babylonjs.com), mirroring the
|
|
4
|
+
* collector's `window.Uptimizr`.
|
|
5
|
+
*
|
|
6
|
+
* Unlike the npm entry (where `@babylonjs/core` is a peer dependency the host app
|
|
7
|
+
* provides), this build bundles the small `Vector3` value the Babylon driver
|
|
8
|
+
* constructs to push camera pose. The host page's Babylon still owns the scene;
|
|
9
|
+
* we only hand it plain `{x,y,z}` vectors, so a separately-bundled `Vector3` is
|
|
10
|
+
* interchangeable.
|
|
11
|
+
*/
|
|
12
|
+
import type { Camera, Scene } from "@babylonjs/core";
|
|
13
|
+
import { createBabylonReplayDriver, type BabylonReplayDriverOptions } from "./drivers/babylon.js";
|
|
14
|
+
import { fetchSessionEvents, fetchSessionEventsStream } from "./fetchSession.js";
|
|
15
|
+
import { ReplayPlayer } from "./player.js";
|
|
16
|
+
import type { ReplayHandle } from "./types.js";
|
|
17
|
+
/** One-call replay: fetch a session and re-drive it in the given Babylon scene. */
|
|
18
|
+
export interface ReplayInSceneOptions {
|
|
19
|
+
/** Scene to re-drive. */
|
|
20
|
+
scene: Scene;
|
|
21
|
+
/** Collector base URL, e.g. `https://collect.example.com`. */
|
|
22
|
+
endpoint: string;
|
|
23
|
+
/** Project API key (sent as `x-api-key`). */
|
|
24
|
+
apiKey: string;
|
|
25
|
+
/** Session id to replay. */
|
|
26
|
+
sessionId: string;
|
|
27
|
+
/** Camera to move. Defaults to `scene.activeCamera`. */
|
|
28
|
+
camera?: Camera;
|
|
29
|
+
/** Playback speed multiplier. Default 1. */
|
|
30
|
+
speed?: number;
|
|
31
|
+
/** Per pointer event, so the host can render a cursor/marker. */
|
|
32
|
+
onPointer?: BabylonReplayDriverOptions["onPointer"];
|
|
33
|
+
/** Per mesh interaction, so the host can highlight a mesh. */
|
|
34
|
+
onMeshInteraction?: BabylonReplayDriverOptions["onMeshInteraction"];
|
|
35
|
+
/** Per developer-defined `custom` event. */
|
|
36
|
+
onCustom?: BabylonReplayDriverOptions["onCustom"];
|
|
37
|
+
/** Per browser/engine lifecycle event (resize, visibility, focus, context loss). */
|
|
38
|
+
onLifecycle?: BabylonReplayDriverOptions["onLifecycle"];
|
|
39
|
+
/** Per captured `runtime_error` event (opt-in capture). */
|
|
40
|
+
onError?: BabylonReplayDriverOptions["onError"];
|
|
41
|
+
/** Progress callback (clamped elapsed and total duration, in ms). */
|
|
42
|
+
onProgress?: (elapsedMs: number, durationMs: number) => void;
|
|
43
|
+
/** Called once when playback reaches the end. */
|
|
44
|
+
onComplete?: () => void;
|
|
45
|
+
/** Log each step (fetch, event counts, play, progress, complete) to the console. */
|
|
46
|
+
debug?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch a captured session from the collector and play it back in `scene`,
|
|
50
|
+
* starting immediately. Returns the {@link ReplayHandle} so callers can
|
|
51
|
+
* pause/seek/stop. The collector must have raw-session retention enabled for the
|
|
52
|
+
* session-events endpoint to return data (ADR 0003).
|
|
53
|
+
*
|
|
54
|
+
* Emits a concise console summary (and, with `debug: true`, per-step logs) so it
|
|
55
|
+
* is clear whether playback is running. The common "nothing happens" causes —
|
|
56
|
+
* an empty session, a session with no `camera_sample` events, or a scene with no
|
|
57
|
+
* active camera — are surfaced as console warnings.
|
|
58
|
+
*/
|
|
59
|
+
export declare function replayInScene(options: ReplayInSceneOptions): Promise<ReplayHandle>;
|
|
60
|
+
export { createBabylonReplayDriver, fetchSessionEvents, fetchSessionEventsStream, ReplayPlayer };
|
|
61
|
+
export type { BabylonReplayDriverOptions, ReplayHandle };
|
|
62
|
+
//# sourceMappingURL=global.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,KAAK,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,yBAAyB;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACpD,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;IACpE,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,0BAA0B,CAAC,UAAU,CAAC,CAAC;IAClD,oFAAoF;IACpF,WAAW,CAAC,EAAE,0BAA0B,CAAC,aAAa,CAAC,CAAC;IACxD,2DAA2D;IAC3D,OAAO,CAAC,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAChD,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAyFxF;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,YAAY,EAAE,CAAC;AACjG,YAAY,EAAE,0BAA0B,EAAE,YAAY,EAAE,CAAC"}
|