@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.
Files changed (46) hide show
  1. package/AGENTS.md +57 -0
  2. package/LICENSE +201 -0
  3. package/README.md +96 -0
  4. package/dist/drivers/babylon-lite.d.ts +134 -0
  5. package/dist/drivers/babylon-lite.d.ts.map +1 -0
  6. package/dist/drivers/babylon-lite.js +167 -0
  7. package/dist/drivers/babylon-lite.js.map +1 -0
  8. package/dist/drivers/babylon.d.ts +99 -0
  9. package/dist/drivers/babylon.d.ts.map +1 -0
  10. package/dist/drivers/babylon.js +176 -0
  11. package/dist/drivers/babylon.js.map +1 -0
  12. package/dist/drivers/playcanvas.d.ts +122 -0
  13. package/dist/drivers/playcanvas.d.ts.map +1 -0
  14. package/dist/drivers/playcanvas.js +206 -0
  15. package/dist/drivers/playcanvas.js.map +1 -0
  16. package/dist/drivers/three.d.ts +127 -0
  17. package/dist/drivers/three.d.ts.map +1 -0
  18. package/dist/drivers/three.js +194 -0
  19. package/dist/drivers/three.js.map +1 -0
  20. package/dist/fetchSession.d.ts +43 -0
  21. package/dist/fetchSession.d.ts.map +1 -0
  22. package/dist/fetchSession.js +103 -0
  23. package/dist/fetchSession.js.map +1 -0
  24. package/dist/global.d.ts +62 -0
  25. package/dist/global.d.ts.map +1 -0
  26. package/dist/global.js +95 -0
  27. package/dist/global.js.map +1 -0
  28. package/dist/index.d.ts +14 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +11 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/player.d.ts +35 -0
  33. package/dist/player.d.ts.map +1 -0
  34. package/dist/player.js +104 -0
  35. package/dist/player.js.map +1 -0
  36. package/dist/reconstruct.d.ts +74 -0
  37. package/dist/reconstruct.d.ts.map +1 -0
  38. package/dist/reconstruct.js +266 -0
  39. package/dist/reconstruct.js.map +1 -0
  40. package/dist/types.d.ts +39 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +2 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/uptimizr-replay.global.js +71 -0
  45. package/llms.txt +17 -0
  46. 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":"AAAA,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAmD5B;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,IAAsB,EAAE,SAAiB;IACnE,IAAI,GAAG,GAA4B,IAAI,CAAC;IACxC,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,QAAQ,GAAmC,GAAG,EAAE,QAAQ,CAAC;QAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;QACzE,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AACnF,SAAS,iBAAiB,CACxB,KAA+E;IAE/E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,OAAQ,KAAK,EAA0C,IAAI,IAAI,CAAC;IAClE,CAAC;IACD,OAAO,KAAyB,CAAC;AACnC,CAAC;AAmGD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAiC;IACvE,OAAO;QACL,KAAK;YACH,0EAA0E;YAC1E,2EAA2E;QAC7E,CAAC;QACD,KAAK,CAAC,KAAe;YACnB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,eAAe,CAAC,CAAC,CAAC;oBACrB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;oBAC3B,IAAI,CAAC,GAAG;wBAAE,OAAO;oBACjB,2CAA2C;oBAC3C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBACpE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC7B,wEAAwE;oBACxE,uEAAuE;oBACvE,IAAI,EAAU,CAAC;oBACf,IAAI,EAAU,CAAC;oBACf,IAAI,EAAU,CAAC;oBACf,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;wBACjB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBAC9D,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,sBAAsB,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;wBACtE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;wBACb,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;wBACb,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;oBACf,CAAC;oBACD,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBACvB,mEAAmE;oBACnE,IAAI,GAAG,CAAC,mBAAmB,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;wBAC7D,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;wBACtC,GAAG,CAAC,sBAAsB,EAAE,EAAE,CAAC;oBACjC,CAAC;oBACD,MAAM;gBACR,CAAC;gBACD,KAAK,cAAc,CAAC;gBACpB,KAAK,eAAe,CAAC;gBACrB,KAAK,cAAc,CAAC;gBACpB,KAAK,YAAY,CAAC,CAAC,CAAC;oBAClB,sEAAsE;oBACtE,gEAAgE;oBAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ;wBAC7B,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC;wBAChD,CAAC,CAAC,SAAS,CAAC;oBACd,OAAO,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBACvE,MAAM;gBACR,CAAC;gBACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;oBACxB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACpF,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBAC3D,MAAM;gBACR,CAAC;gBACD,KAAK,QAAQ;oBACX,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBACtD,MAAM;gBACR,KAAK,cAAc;oBACjB,OAAO,CAAC,aAAa,EAAE,CACrB;wBACE,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,MAAM,EAAE,KAAK,CAAC,MAAM;qBACrB,EACD,KAAK,CAAC,EAAE,CACT,CAAC;oBACF,MAAM;gBACR,KAAK,iBAAiB;oBACpB,OAAO,CAAC,WAAW,EAAE,CACnB,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,EACrF,KAAK,CAAC,EAAE,CACT,CAAC;oBACF,MAAM;gBACR,KAAK,mBAAmB;oBACtB,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBACnF,MAAM;gBACR,KAAK,cAAc;oBACjB,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBAClF,MAAM;gBACR,KAAK,cAAc;oBACjB,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC1D,MAAM;gBACR,KAAK,kBAAkB;oBACrB,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC9D,MAAM;gBACR,KAAK,eAAe;oBAClB,OAAO,CAAC,OAAO,EAAE,CACf;wBACE,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,KAAK,EAAE,KAAK,CAAC,KAAK;qBACnB,EACD,KAAK,CAAC,EAAE,CACT,CAAC;oBACF,MAAM;gBACR,KAAK,gBAAgB;oBACnB,qEAAqE;oBACrE,wEAAwE;oBACxE,MAAM;gBACR,KAAK,gBAAgB,CAAC,CAAC,CAAC;oBACtB,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC9D,IAAI,IAAI,EAAE,CAAC;wBACT,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;4BAC/B,iEAAiE;4BACjE,oEAAoE;4BACpE,4DAA4D;4BAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;4BACxE,IAAI,IAAI,EAAE,CAAC;gCACT,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCACpE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gCAC/B,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCACpE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gCACrC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oCAChB,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gCAClE,CAAC;4BACH,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,8DAA8D;4BAC9D,qEAAqE;4BACrE,iEAAiE;4BACjE,MAAM,MAAM,GACV,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;4BACnF,IAAI,MAAM,EAAE,CAAC;gCACX,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCACpE,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gCACjC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gCACpE,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;gCACvC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oCAChB,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gCACpE,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,sEAAsE;oBACtE,uEAAuE;oBACvE,sDAAsD;oBACtD,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAA6B,CAAC;oBAC1F,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAKvD,CAAC;oBACF,OAAO,CAAC,eAAe,EAAE,CACvB,KAAK,CAAC,MAAM,EACZ;wBACE,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,QAAQ,EAAE,MAAM;wBAChB,QAAQ,EAAE,MAAM;wBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;qBACnB,EACD,KAAK,CAAC,EAAE,CACT,CAAC;oBACF,MAAM;gBACR,CAAC;gBACD;oBACE,MAAM;YACV,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -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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"}
@@ -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"}