@reactra/replay-devtools 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/chrome.d.ts +81 -0
- package/dist/chrome.d.ts.map +1 -0
- package/dist/chrome.js +156 -0
- package/dist/chrome.js.map +1 -0
- package/dist/compare.d.ts +31 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +165 -0
- package/dist/compare.js.map +1 -0
- package/dist/helpers.d.ts +101 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +236 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/panel.d.ts +25 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +725 -0
- package/dist/panel.js.map +1 -0
- package/dist/styles.d.ts +10 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +388 -0
- package/dist/styles.js.map +1 -0
- package/dist/timeline.d.ts +34 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +144 -0
- package/dist/timeline.js.map +1 -0
- package/dist/tokens.d.ts +10 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +317 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ReplayEvent, SessionBundle } from "@reactra/behaviours/replayable";
|
|
2
|
+
import { diffKeys } from "@reactra/replay";
|
|
3
|
+
import type { ReplayPlayer } from "@reactra/replay";
|
|
4
|
+
export { diffKeys };
|
|
5
|
+
/** Visual identity of one event type on the timeline + table. */
|
|
6
|
+
export interface EventStyle {
|
|
7
|
+
/** CSS color for the timeline tick / table chip. */
|
|
8
|
+
color: string;
|
|
9
|
+
/** Single-character glyph for compact rows. */
|
|
10
|
+
glyph: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const eventStyle: (e: ReplayEvent) => EventStyle;
|
|
13
|
+
/** One-line human summary of a recorded event (table detail column). */
|
|
14
|
+
export declare const describeEvent: (e: ReplayEvent) => string;
|
|
15
|
+
/** "+12.3s" — timeline offset formatting. */
|
|
16
|
+
export declare const formatOffset: (ms: number) => string;
|
|
17
|
+
/**
|
|
18
|
+
* The sessions-list query string for a "key=value" filter-box value —
|
|
19
|
+
* `?meta.<key>=<value>` (the replay-server read API; NOT a Reactra spec
|
|
20
|
+
* contract). Whitespace-trimmed; no "=" or empty key/value → "".
|
|
21
|
+
*/
|
|
22
|
+
export declare const sessionsQuery: (metaFilter: string) => string;
|
|
23
|
+
/** Bearer-or-custom auth headers for the read API fetches. */
|
|
24
|
+
export declare const authHeaders: (token?: string, headers?: () => HeadersInit) => HeadersInit;
|
|
25
|
+
/**
|
|
26
|
+
* Sorted unique event offsets — the timeline's discrete stops. With a
|
|
27
|
+
* `predicate`, only matching events contribute stops: the transport
|
|
28
|
+
* (prev/next/playback/drive) then walks ONLY the filtered events — the
|
|
29
|
+
* type/instance chips and the from/to window all funnel through here.
|
|
30
|
+
*/
|
|
31
|
+
export declare const eventStops: (bundle: SessionBundle, predicate?: (e: ReplayEvent) => boolean) => number[];
|
|
32
|
+
/**
|
|
33
|
+
* Clamp one dragged edge of the timeline window (the Chrome-Network-style
|
|
34
|
+
* brush). The dragged edge stays inside [0, duration] and never crosses the
|
|
35
|
+
* opposite edge.
|
|
36
|
+
*/
|
|
37
|
+
export declare const clampWindowEdge: (edge: "from" | "to", value: number, other: number, duration: number) => number;
|
|
38
|
+
/** The index of the latest stop ≤ `offset` (-1 = before all stops). */
|
|
39
|
+
export declare const stopIndexAt: (stops: readonly number[], offset: number) => number;
|
|
40
|
+
/** Recorded instance ids in first-seen order (filter chips + state cards). */
|
|
41
|
+
export declare const instanceIds: (bundle: SessionBundle) => string[];
|
|
42
|
+
/**
|
|
43
|
+
* Playback delay until the next stop, at `speed`× real time. The gap is floored
|
|
44
|
+
* at MIN_STEP_MS so clustered/same-timestamp events remain visible, then divided
|
|
45
|
+
* by `speed`; long recorded idles are clamped so auto-play never stalls the
|
|
46
|
+
* viewer (max 2s wall time).
|
|
47
|
+
*/
|
|
48
|
+
export declare const playbackDelay: (curOffset: number, nextOffset: number, speed: number) => number;
|
|
49
|
+
/**
|
|
50
|
+
* Gridline offsets for the timeline's time scale: the smallest "nice" step
|
|
51
|
+
* (100ms / 250ms / … / 1h) that yields at most `targetCount` ticks across
|
|
52
|
+
* `durationMs`, starting at 0. A zero/negative duration has just the origin.
|
|
53
|
+
*/
|
|
54
|
+
export declare const timeScaleTicks: (durationMs: number, targetCount?: number) => number[];
|
|
55
|
+
/**
|
|
56
|
+
* Route-first drive decision (Replay §5 C2): given the route `path` folded at
|
|
57
|
+
* the scrub target and the current browser location, return the path to
|
|
58
|
+
* `navigate()` to — or `undefined` when no navigation is needed (no recorded
|
|
59
|
+
* route, or the URL already matches). Navigating only on a real difference
|
|
60
|
+
* keeps scrub idempotent and avoids spurious history churn.
|
|
61
|
+
*/
|
|
62
|
+
export declare const routeDriveTarget: (recordedPath: string | undefined, currentLocation: string) => string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* A filesystem-safe download filename for a `SessionBundle`.
|
|
65
|
+
*
|
|
66
|
+
* Format: `replay-<sessionId>-<YYYY-MM-DD>.json`. All characters are safe
|
|
67
|
+
* for every major OS file system — no spaces, slashes, colons, or other
|
|
68
|
+
* characters that require escaping in a `Content-Disposition` header or a
|
|
69
|
+
* `<a download>` attribute.
|
|
70
|
+
*/
|
|
71
|
+
export declare const bundleFilename: (b: SessionBundle) => string;
|
|
72
|
+
/**
|
|
73
|
+
* Serialize a `SessionBundle` to a JSON string that round-trips without loss.
|
|
74
|
+
*
|
|
75
|
+
* The output is the wire format — importing and exporting a bundle should
|
|
76
|
+
* produce a byte-identical file (modulo key ordering, which `JSON.parse` then
|
|
77
|
+
* `JSON.stringify` may alter, but the data is structurally equal).
|
|
78
|
+
*/
|
|
79
|
+
export declare const bundleToBlobText: (b: SessionBundle) => string;
|
|
80
|
+
/**
|
|
81
|
+
* Walk `stops` from `fromIndex + dir` (direction `dir`: 1=forward, -1=backward)
|
|
82
|
+
* and return the index of the first stop where `key` changes for instance `id`.
|
|
83
|
+
*
|
|
84
|
+
* "Changes" means the key is in `diffKeys(stateAt(j-1), stateAt(j))` — the
|
|
85
|
+
* same shallow-JSON comparison the state-card highlights use. When walking
|
|
86
|
+
* backward the comparison is reversed: the "previous" is `stops[j]` and the
|
|
87
|
+
* "current" for the diff is the stop that was displayed at the cursor
|
|
88
|
+
* (i.e. `stops[j+1]`), so clicking "previous change" lands on the stop that
|
|
89
|
+
* INTRODUCED the value the cursor is showing.
|
|
90
|
+
*
|
|
91
|
+
* Returns `null` when no such stop exists (reached end of range, or `id`/`key`
|
|
92
|
+
* absent throughout). Pure — no panel state touched; safe to call in a handler.
|
|
93
|
+
*
|
|
94
|
+
* Per-stop cost is one `statesAt` call (O(n) over snapshots). The walk is
|
|
95
|
+
* bounded by the filtered `stops` length, which is the set the panel already
|
|
96
|
+
* renders.
|
|
97
|
+
*/
|
|
98
|
+
export declare const nextChangeStop: (player: ReplayPlayer, bundle: SessionBundle, stops: readonly number[], fromIndex: number, id: string, key: string, dir: 1 | -1) => number | null;
|
|
99
|
+
/** Compact scale-tick label: "0s", "12s", "1.5s", "2m", "2m30s". */
|
|
100
|
+
export declare const formatScaleTick: (ms: number) => string;
|
|
101
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAInD,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,eAAO,MAAM,UAAU,GAAI,GAAG,WAAW,KAAG,UAsB3C,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,aAAa,GAAI,GAAG,WAAW,KAAG,MAe9C,CAAA;AAED,6CAA6C;AAC7C,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,KAAG,MAAuC,CAAA;AAEjF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,YAAY,MAAM,KAAG,MAOlD,CAAA;AAED,8DAA8D;AAC9D,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,UAAU,MAAM,WAAW,KAC1B,WAIF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,aAAa,EACrB,YAAY,CAAC,CAAC,EAAE,WAAW,KAAK,OAAO,KACtC,MAAM,EAKgB,CAAA;AAEzB;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,GAAG,IAAI,EACnB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,UAAU,MAAM,KACf,MAGF,CAAA;AAED,uEAAuE;AACvE,eAAO,MAAM,WAAW,GAAI,OAAO,SAAS,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,MAOtE,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,WAAW,GAAI,QAAQ,aAAa,KAAG,MAAM,EAMzD,CAAA;AAWD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,WAAW,MAAM,EAAE,YAAY,MAAM,EAAE,OAAO,MAAM,KAAG,MACd,CAAA;AAQvE;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,MAAM,EAAE,oBAAe,KAAG,MAAM,EAO1E,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC3B,cAAc,MAAM,GAAG,SAAS,EAChC,iBAAiB,MAAM,KACtB,MAAM,GAAG,SAGX,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,aAAa,KAAG,MAIjD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,GAAG,aAAa,KAAG,MAA2B,CAAA;AAE/E;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,GACzB,QAAQ,YAAY,EACpB,QAAQ,aAAa,EACrB,OAAO,SAAS,MAAM,EAAE,EACxB,WAAW,MAAM,EACjB,IAAI,MAAM,EACV,KAAK,MAAM,EACX,KAAK,CAAC,GAAG,CAAC,CAAC,KACV,MAAM,GAAG,IAwBX,CAAA;AAED,oEAAoE;AACpE,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,KAAG,MAO5C,CAAA"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// @reactra/replay-devtools — pure panel logic (no React, no DOM).
|
|
2
|
+
//
|
|
3
|
+
// Owner: reactra-runtime-spec.md §3 (`@reactra/replay-devtools`, internal
|
|
4
|
+
// tier — exported for tests); the event/bundle shapes are Replay spec §3.
|
|
5
|
+
// Everything here is Node-portable by construction so the panel's behaviour
|
|
6
|
+
// is unit-testable without a renderer.
|
|
7
|
+
import { diffKeys } from "@reactra/replay";
|
|
8
|
+
// COND-2: diffKeys is now defined in @reactra/replay; re-exported here so all
|
|
9
|
+
// existing import paths (replay-devtools consumers + the /timeline subpath) keep
|
|
10
|
+
// working unchanged.
|
|
11
|
+
export { diffKeys };
|
|
12
|
+
// Timeline color language: one hue per concern, keyframes emphasized. The colors
|
|
13
|
+
// are `--rdt-ev-*` TOKENS (not literal hex) so they stay visible on BOTH the dark
|
|
14
|
+
// and light track/table backgrounds — a single fixed hue (especially the
|
|
15
|
+
// near-white keyframe marker) is invisible on a light background. Owner: /tokens.
|
|
16
|
+
export const eventStyle = (e) => {
|
|
17
|
+
switch (e.type) {
|
|
18
|
+
case "action":
|
|
19
|
+
return { color: "var(--rdt-ev-action)", glyph: "▶" };
|
|
20
|
+
case "state_snapshot":
|
|
21
|
+
return e.keyframe
|
|
22
|
+
? { color: "var(--rdt-ev-keyframe)", glyph: "⬛" }
|
|
23
|
+
: { color: "var(--rdt-ev-delta)", glyph: "Δ" };
|
|
24
|
+
case "resource":
|
|
25
|
+
return { color: "var(--rdt-ev-resource)", glyph: "◆" };
|
|
26
|
+
case "mount":
|
|
27
|
+
return e.phase === "mount"
|
|
28
|
+
? { color: "var(--rdt-ev-mount)", glyph: "+" }
|
|
29
|
+
: { color: "var(--rdt-ev-unmount)", glyph: "−" };
|
|
30
|
+
case "gap":
|
|
31
|
+
return { color: "var(--rdt-ev-gap)", glyph: "⚠" };
|
|
32
|
+
case "tx_mark":
|
|
33
|
+
return {
|
|
34
|
+
color: "var(--rdt-ev-action)",
|
|
35
|
+
glyph: e.phase === "optimistic" ? "⚡" : e.phase === "rolledback" ? "↩" : "✓",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/** One-line human summary of a recorded event (table detail column). */
|
|
40
|
+
export const describeEvent = (e) => {
|
|
41
|
+
switch (e.type) {
|
|
42
|
+
case "mount":
|
|
43
|
+
return e.phase;
|
|
44
|
+
case "action":
|
|
45
|
+
return `${e.name}(${e.payload.map((p) => JSON.stringify(p)).join(", ")}) — ${e.duration.toFixed(1)}ms`;
|
|
46
|
+
case "state_snapshot":
|
|
47
|
+
return `${e.keyframe ? "keyframe " : ""}${JSON.stringify(e.state)}`;
|
|
48
|
+
case "resource":
|
|
49
|
+
return `${e.name} → ${e.status}`;
|
|
50
|
+
case "gap":
|
|
51
|
+
return `${e.dropped} events dropped (rate guard)`;
|
|
52
|
+
case "tx_mark":
|
|
53
|
+
return `command ${e.phase}: ${JSON.stringify(e.state)}`;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/** "+12.3s" — timeline offset formatting. */
|
|
57
|
+
export const formatOffset = (ms) => `+${(ms / 1000).toFixed(1)}s`;
|
|
58
|
+
/**
|
|
59
|
+
* The sessions-list query string for a "key=value" filter-box value —
|
|
60
|
+
* `?meta.<key>=<value>` (the replay-server read API; NOT a Reactra spec
|
|
61
|
+
* contract). Whitespace-trimmed; no "=" or empty key/value → "".
|
|
62
|
+
*/
|
|
63
|
+
export const sessionsQuery = (metaFilter) => {
|
|
64
|
+
const eq = metaFilter.indexOf("=");
|
|
65
|
+
if (eq <= 0)
|
|
66
|
+
return "";
|
|
67
|
+
const key = metaFilter.slice(0, eq).trim();
|
|
68
|
+
const value = metaFilter.slice(eq + 1).trim();
|
|
69
|
+
if (!key || !value)
|
|
70
|
+
return "";
|
|
71
|
+
return `?meta.${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
72
|
+
};
|
|
73
|
+
/** Bearer-or-custom auth headers for the read API fetches. */
|
|
74
|
+
export const authHeaders = (token, headers) => {
|
|
75
|
+
if (headers)
|
|
76
|
+
return headers();
|
|
77
|
+
if (token)
|
|
78
|
+
return { authorization: `Bearer ${token}` };
|
|
79
|
+
return {};
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Sorted unique event offsets — the timeline's discrete stops. With a
|
|
83
|
+
* `predicate`, only matching events contribute stops: the transport
|
|
84
|
+
* (prev/next/playback/drive) then walks ONLY the filtered events — the
|
|
85
|
+
* type/instance chips and the from/to window all funnel through here.
|
|
86
|
+
*/
|
|
87
|
+
export const eventStops = (bundle, predicate) => [
|
|
88
|
+
...new Set(bundle.events.filter((e) => !predicate || predicate(e)).map((e) => e.timestamp - bundle.startTime)),
|
|
89
|
+
].sort((a, b) => a - b);
|
|
90
|
+
/**
|
|
91
|
+
* Clamp one dragged edge of the timeline window (the Chrome-Network-style
|
|
92
|
+
* brush). The dragged edge stays inside [0, duration] and never crosses the
|
|
93
|
+
* opposite edge.
|
|
94
|
+
*/
|
|
95
|
+
export const clampWindowEdge = (edge, value, other, duration) => {
|
|
96
|
+
const v = Math.min(duration, Math.max(0, value));
|
|
97
|
+
return edge === "from" ? Math.min(v, other) : Math.max(v, other);
|
|
98
|
+
};
|
|
99
|
+
/** The index of the latest stop ≤ `offset` (-1 = before all stops). */
|
|
100
|
+
export const stopIndexAt = (stops, offset) => {
|
|
101
|
+
let i = -1;
|
|
102
|
+
for (const t of stops) {
|
|
103
|
+
if (t <= offset)
|
|
104
|
+
i++;
|
|
105
|
+
else
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
return i;
|
|
109
|
+
};
|
|
110
|
+
/** Recorded instance ids in first-seen order (filter chips + state cards). */
|
|
111
|
+
export const instanceIds = (bundle) => {
|
|
112
|
+
const seen = [];
|
|
113
|
+
for (const e of bundle.events) {
|
|
114
|
+
if (!seen.includes(e.componentId))
|
|
115
|
+
seen.push(e.componentId);
|
|
116
|
+
}
|
|
117
|
+
return seen;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* The minimum per-step gap (ms) auto-play honours before dividing by `speed`.
|
|
121
|
+
* Recorded commits often cluster within a few ms of each other (React commits
|
|
122
|
+
* in bursts), so a raw 16ms floor flashed the whole flow past in one frame and
|
|
123
|
+
* read as "nothing played". 200ms makes each step perceptible at 1× while
|
|
124
|
+
* higher speeds still accelerate it (e.g. 4× → 50ms/step).
|
|
125
|
+
*/
|
|
126
|
+
const MIN_STEP_MS = 200;
|
|
127
|
+
/**
|
|
128
|
+
* Playback delay until the next stop, at `speed`× real time. The gap is floored
|
|
129
|
+
* at MIN_STEP_MS so clustered/same-timestamp events remain visible, then divided
|
|
130
|
+
* by `speed`; long recorded idles are clamped so auto-play never stalls the
|
|
131
|
+
* viewer (max 2s wall time).
|
|
132
|
+
*/
|
|
133
|
+
export const playbackDelay = (curOffset, nextOffset, speed) => Math.min(2000, Math.max(MIN_STEP_MS, nextOffset - curOffset) / speed);
|
|
134
|
+
/** The "nice" step candidates for the timeline's time scale, in ms. */
|
|
135
|
+
const SCALE_STEPS = [
|
|
136
|
+
100, 250, 500, 1_000, 2_000, 5_000, 10_000, 15_000, 30_000,
|
|
137
|
+
60_000, 120_000, 300_000, 600_000, 1_800_000, 3_600_000,
|
|
138
|
+
];
|
|
139
|
+
/**
|
|
140
|
+
* Gridline offsets for the timeline's time scale: the smallest "nice" step
|
|
141
|
+
* (100ms / 250ms / … / 1h) that yields at most `targetCount` ticks across
|
|
142
|
+
* `durationMs`, starting at 0. A zero/negative duration has just the origin.
|
|
143
|
+
*/
|
|
144
|
+
export const timeScaleTicks = (durationMs, targetCount = 8) => {
|
|
145
|
+
if (durationMs <= 0)
|
|
146
|
+
return [0];
|
|
147
|
+
const step = SCALE_STEPS.find((s) => durationMs / s <= targetCount) ?? SCALE_STEPS[SCALE_STEPS.length - 1];
|
|
148
|
+
const ticks = [];
|
|
149
|
+
for (let t = 0; t <= durationMs; t += step)
|
|
150
|
+
ticks.push(t);
|
|
151
|
+
return ticks;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Route-first drive decision (Replay §5 C2): given the route `path` folded at
|
|
155
|
+
* the scrub target and the current browser location, return the path to
|
|
156
|
+
* `navigate()` to — or `undefined` when no navigation is needed (no recorded
|
|
157
|
+
* route, or the URL already matches). Navigating only on a real difference
|
|
158
|
+
* keeps scrub idempotent and avoids spurious history churn.
|
|
159
|
+
*/
|
|
160
|
+
export const routeDriveTarget = (recordedPath, currentLocation) => {
|
|
161
|
+
if (recordedPath === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
return recordedPath === currentLocation ? undefined : recordedPath;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* A filesystem-safe download filename for a `SessionBundle`.
|
|
167
|
+
*
|
|
168
|
+
* Format: `replay-<sessionId>-<YYYY-MM-DD>.json`. All characters are safe
|
|
169
|
+
* for every major OS file system — no spaces, slashes, colons, or other
|
|
170
|
+
* characters that require escaping in a `Content-Disposition` header or a
|
|
171
|
+
* `<a download>` attribute.
|
|
172
|
+
*/
|
|
173
|
+
export const bundleFilename = (b) => {
|
|
174
|
+
const d = new Date(b.startTime);
|
|
175
|
+
const ymd = `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}-${String(d.getUTCDate()).padStart(2, "0")}`;
|
|
176
|
+
return `replay-${b.sessionId}-${ymd}.json`;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Serialize a `SessionBundle` to a JSON string that round-trips without loss.
|
|
180
|
+
*
|
|
181
|
+
* The output is the wire format — importing and exporting a bundle should
|
|
182
|
+
* produce a byte-identical file (modulo key ordering, which `JSON.parse` then
|
|
183
|
+
* `JSON.stringify` may alter, but the data is structurally equal).
|
|
184
|
+
*/
|
|
185
|
+
export const bundleToBlobText = (b) => JSON.stringify(b);
|
|
186
|
+
/**
|
|
187
|
+
* Walk `stops` from `fromIndex + dir` (direction `dir`: 1=forward, -1=backward)
|
|
188
|
+
* and return the index of the first stop where `key` changes for instance `id`.
|
|
189
|
+
*
|
|
190
|
+
* "Changes" means the key is in `diffKeys(stateAt(j-1), stateAt(j))` — the
|
|
191
|
+
* same shallow-JSON comparison the state-card highlights use. When walking
|
|
192
|
+
* backward the comparison is reversed: the "previous" is `stops[j]` and the
|
|
193
|
+
* "current" for the diff is the stop that was displayed at the cursor
|
|
194
|
+
* (i.e. `stops[j+1]`), so clicking "previous change" lands on the stop that
|
|
195
|
+
* INTRODUCED the value the cursor is showing.
|
|
196
|
+
*
|
|
197
|
+
* Returns `null` when no such stop exists (reached end of range, or `id`/`key`
|
|
198
|
+
* absent throughout). Pure — no panel state touched; safe to call in a handler.
|
|
199
|
+
*
|
|
200
|
+
* Per-stop cost is one `statesAt` call (O(n) over snapshots). The walk is
|
|
201
|
+
* bounded by the filtered `stops` length, which is the set the panel already
|
|
202
|
+
* renders.
|
|
203
|
+
*/
|
|
204
|
+
export const nextChangeStop = (player, bundle, stops, fromIndex, id, key, dir) => {
|
|
205
|
+
const start = fromIndex + dir;
|
|
206
|
+
const end = dir === 1 ? stops.length - 1 : 0;
|
|
207
|
+
for (let j = start; dir === 1 ? j <= end : j >= end; j += dir) {
|
|
208
|
+
const curStop = stops[j];
|
|
209
|
+
if (curStop === undefined)
|
|
210
|
+
break;
|
|
211
|
+
const curState = player.statesAt(bundle.startTime + curStop).get(id);
|
|
212
|
+
if (!curState || !(key in curState))
|
|
213
|
+
continue;
|
|
214
|
+
// A stop "changes" `key` when diffKeys(state@(j-1), state@j) includes it.
|
|
215
|
+
// This is the same comparison in both directions — walking backward just
|
|
216
|
+
// means we visit the stops in reverse order to find the most-recent prior
|
|
217
|
+
// change point.
|
|
218
|
+
const prevStop = stops[j - 1];
|
|
219
|
+
const prevState = prevStop !== undefined
|
|
220
|
+
? player.statesAt(bundle.startTime + prevStop).get(id)
|
|
221
|
+
: undefined;
|
|
222
|
+
if (diffKeys(prevState, curState).includes(key))
|
|
223
|
+
return j;
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
};
|
|
227
|
+
/** Compact scale-tick label: "0s", "12s", "1.5s", "2m", "2m30s". */
|
|
228
|
+
export const formatScaleTick = (ms) => {
|
|
229
|
+
if (ms >= 60_000) {
|
|
230
|
+
const m = Math.floor(ms / 60_000);
|
|
231
|
+
const s = Math.round((ms % 60_000) / 1000);
|
|
232
|
+
return s === 0 ? `${m}m` : `${m}m${s}s`;
|
|
233
|
+
}
|
|
234
|
+
return `${Number((ms / 1000).toFixed(2))}s`;
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ReplayDevtools, type ReplayDevtoolsProps } from "./panel.ts";
|
|
2
|
+
export { authHeaders as __authHeaders, bundleFilename as __bundleFilename, bundleToBlobText as __bundleToBlobText, describeEvent as __describeEvent, diffKeys as __diffKeys, eventStops as __eventStops, eventStyle as __eventStyle, formatOffset as __formatOffset, instanceIds as __instanceIds, playbackDelay as __playbackDelay, sessionsQuery as __sessionsQuery, stopIndexAt as __stopIndexAt, } from "./helpers.ts";
|
|
3
|
+
export { __resetStylesForTest, ensureStyles as __ensureStyles } from "./styles.ts";
|
|
4
|
+
export { __resetTokensForTest } from "./tokens.ts";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAGrE,OAAO,EACL,WAAW,IAAI,aAAa,EAC5B,cAAc,IAAI,gBAAgB,EAClC,gBAAgB,IAAI,kBAAkB,EACtC,aAAa,IAAI,eAAe,EAChC,QAAQ,IAAI,UAAU,EACtB,UAAU,IAAI,YAAY,EAC1B,UAAU,IAAI,YAAY,EAC1B,YAAY,IAAI,cAAc,EAC9B,WAAW,IAAI,aAAa,EAC5B,aAAa,IAAI,eAAe,EAChC,aAAa,IAAI,eAAe,EAChC,WAAW,IAAI,aAAa,GAC7B,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,oBAAoB,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @reactra/replay-devtools — public surface.
|
|
2
|
+
//
|
|
3
|
+
// Owner: reactra-runtime-spec.md §2 (UI-companion tier) + §3. User-facing:
|
|
4
|
+
// the panel and its props type. The pure helpers are internal tier —
|
|
5
|
+
// re-exported __-prefixed for tests only, never documented as user API.
|
|
6
|
+
//
|
|
7
|
+
// The `/chrome` and `/tokens` subpaths are separate named exports (not
|
|
8
|
+
// re-exported here) — consumers import from `@reactra/replay-devtools/chrome`
|
|
9
|
+
// and `@reactra/replay-devtools/tokens` directly (package.json exports map).
|
|
10
|
+
export { ReplayDevtools } from "./panel.js";
|
|
11
|
+
// Internal tier (tests only — Runtime spec §1 visibility tiers).
|
|
12
|
+
export { authHeaders as __authHeaders, bundleFilename as __bundleFilename, bundleToBlobText as __bundleToBlobText, describeEvent as __describeEvent, diffKeys as __diffKeys, eventStops as __eventStops, eventStyle as __eventStyle, formatOffset as __formatOffset, instanceIds as __instanceIds, playbackDelay as __playbackDelay, sessionsQuery as __sessionsQuery, stopIndexAt as __stopIndexAt, } from "./helpers.js";
|
|
13
|
+
export { __resetStylesForTest, ensureStyles as __ensureStyles } from "./styles.js";
|
|
14
|
+
export { __resetTokensForTest } from "./tokens.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,2EAA2E;AAC3E,qEAAqE;AACrE,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,8EAA8E;AAC9E,6EAA6E;AAE7E,OAAO,EAAE,cAAc,EAA4B,MAAM,YAAY,CAAA;AAErE,iEAAiE;AACjE,OAAO,EACL,WAAW,IAAI,aAAa,EAC5B,cAAc,IAAI,gBAAgB,EAClC,gBAAgB,IAAI,kBAAkB,EACtC,aAAa,IAAI,eAAe,EAChC,QAAQ,IAAI,UAAU,EACtB,UAAU,IAAI,YAAY,EAC1B,UAAU,IAAI,YAAY,EAC1B,YAAY,IAAI,cAAc,EAC9B,WAAW,IAAI,aAAa,EAC5B,aAAa,IAAI,eAAe,EAChC,aAAa,IAAI,eAAe,EAChC,WAAW,IAAI,aAAa,GAC7B,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,oBAAoB,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/panel.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
/** Props of the session-recorder panel (Runtime spec §3). */
|
|
3
|
+
export interface ReplayDevtoolsProps {
|
|
4
|
+
/** Base path of the replay-server HTTP READ API (default `"/replay"`). */
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
/** Bearer-token sugar for the read API (REPLAY_TOKEN deployments). */
|
|
7
|
+
token?: string;
|
|
8
|
+
/** Custom auth-header supplier — wins over `token`. */
|
|
9
|
+
headers?: () => HeadersInit;
|
|
10
|
+
/** Start with the drawer open instead of the collapsed pill. */
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
/** Show the live re-drive toggle (default true). */
|
|
13
|
+
drive?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The Reactra session-recorder panel: finalize-and-scrub, a color-coded
|
|
17
|
+
* visual timeline, transport controls with auto-playback, keyboard stepping
|
|
18
|
+
* (←/→/space), per-instance state cards with change highlighting, event-type
|
|
19
|
+
* and instance filters, live re-drive, and server-session browsing.
|
|
20
|
+
*
|
|
21
|
+
* Window chrome: Shift+Alt+R hotkey, drag-to-resize, minimize, pop-out,
|
|
22
|
+
* System→Light→Dark theme — all powered by the shared `/chrome` helpers.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ReplayDevtools: (props: ReplayDevtoolsProps) => ReactNode;
|
|
25
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"AA2BA,OAAO,EAA4D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAiChG,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,WAAW,CAAA;IAC3B,gEAAgE;IAChE,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAaD;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,mBAAmB,KAAG,SAq3B3D,CAAA"}
|