@lightworkai.official/debug-capture 0.19.8 → 0.19.10
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/README.md +26 -9
- package/dist/debug-capture.js +17 -16
- package/dist/index.mjs +22 -21
- package/dist/replayPack.d.ts +56 -3
- package/dist/replayPictures.d.ts +33 -0
- package/dist/types.d.ts +10 -2
- package/dist/ui/chatBubble.d.ts +13 -6
- package/package.json +1 -1
- package/src/replayPack.ts +369 -44
- package/src/replayPictures.ts +200 -0
- package/src/submit.ts +1 -1
- package/src/types.ts +14 -2
- package/src/ui/chatBubble.ts +56 -25
package/dist/replayPack.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PictureEncoder } from "./replayPictures";
|
|
1
2
|
import type { ReplayCapture, ReplayEvent, ReplaySummary } from "./types";
|
|
2
3
|
/** The name the desk looks for. Changing it here changes it nowhere else. */
|
|
3
4
|
export declare const REPLAY_FILENAME = "session-replay.json.gz";
|
|
@@ -6,6 +7,12 @@ export interface PackedReplay {
|
|
|
6
7
|
filename: string;
|
|
7
8
|
summary: ReplaySummary;
|
|
8
9
|
}
|
|
10
|
+
export interface PackOptions {
|
|
11
|
+
/** JPEG quality for a canvas picture the browser could only make as PNG. Default 0.5. */
|
|
12
|
+
quality?: number;
|
|
13
|
+
/** How such a picture is made lighter. Default the browser's own encoder; null skips the step. */
|
|
14
|
+
lighten?: PictureEncoder | null;
|
|
15
|
+
}
|
|
9
16
|
/** Is there something to attach, before the work of packing it. */
|
|
10
17
|
export declare function hasReplayEvents(replay: ReplayCapture | null | undefined): replay is ReplayCapture;
|
|
11
18
|
/**
|
|
@@ -14,9 +21,55 @@ export declare function hasReplayEvents(replay: ReplayCapture | null | undefined
|
|
|
14
21
|
* The cap is applied to what is SENT — compressed bytes when compression is
|
|
15
22
|
* available — because that is the number the server's per-file limit is
|
|
16
23
|
* measured against.
|
|
24
|
+
*
|
|
25
|
+
* Over the cap, a report still carries a recording. Each step below is taken
|
|
26
|
+
* only when the one before it did not fit, and each gives up less than the
|
|
27
|
+
* next:
|
|
28
|
+
*
|
|
29
|
+
* 1. Safari's PNG canvas pictures saved again as JPEG (replayPictures) —
|
|
30
|
+
* nothing visible is lost.
|
|
31
|
+
* 2. Canvas pictures kept from the latest moment that fits, the earlier
|
|
32
|
+
* ones left out: the document as it last looked, over the whole
|
|
33
|
+
* recording. A canvas whose picture went plays blank until it is next
|
|
34
|
+
* drawn.
|
|
35
|
+
* 3. Every canvas picture left out: the canvases stay, blank; every
|
|
36
|
+
* click, page and field is still there.
|
|
37
|
+
* 4. Large pictures embedded in the page itself (a `data:` image, a font
|
|
38
|
+
* inlined in a stylesheet) swapped for an empty one.
|
|
39
|
+
* 5. The oldest part left out: the recording is kept in stretches that
|
|
40
|
+
* each begin with a full picture of the page (capture/replay — a
|
|
41
|
+
* checkout every half of the configured length), so the latest
|
|
42
|
+
* stretches play on their own. As many as fit, newest first.
|
|
43
|
+
* 6. The latest stretch from its start, as far as fits — it then stops
|
|
44
|
+
* before the report, and the ticket says by how much.
|
|
45
|
+
* 7. Long text and styles shortened, when not even the page's own picture
|
|
46
|
+
* fits.
|
|
47
|
+
*
|
|
48
|
+
* Only a page whose single picture is over the cap after all of that goes
|
|
49
|
+
* without — millions of elements. CIB-5880 (2026-11-02) went without at
|
|
50
|
+
* step 3: the strip missed every canvas added after the snapshot, and
|
|
51
|
+
* Safari's pictures are PNG.
|
|
17
52
|
*/
|
|
18
|
-
export declare function packReplay(replay: ReplayCapture | null | undefined, maxBytes: number): Promise<PackedReplay | {
|
|
53
|
+
export declare function packReplay(replay: ReplayCapture | null | undefined, maxBytes: number, options?: PackOptions): Promise<PackedReplay | {
|
|
19
54
|
summary: ReplaySummary;
|
|
20
55
|
}>;
|
|
21
|
-
/**
|
|
22
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Every canvas picture removed, in place — the canvases stay, blank. The
|
|
58
|
+
* snapshot's and those on a canvas added later alike: missing the second
|
|
59
|
+
* kind is how CIB-5749 went out marked `canvasDropped` with 1.05 MB of
|
|
60
|
+
* pictures on fourteen canvases still in it. Canvas frames are dropped by
|
|
61
|
+
* the caller (`isCanvasFrame`). Whether there was anything to remove.
|
|
62
|
+
*/
|
|
63
|
+
export declare function stripCanvas(events: readonly ReplayEvent[]): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Large pictures the page itself holds — an `<img src="data:…">`, a font or
|
|
66
|
+
* background inlined in a stylesheet — swapped for an empty one, in place,
|
|
67
|
+
* wherever the events carry them: attributes, styles, style rules.
|
|
68
|
+
*/
|
|
69
|
+
export declare function dropEmbedded(events: readonly ReplayEvent[]): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* The recording in its stretches, each from a Meta and full snapshot to the
|
|
72
|
+
* next — the units it can be shortened by and still play. Anything before
|
|
73
|
+
* the first Meta rides with the first stretch.
|
|
74
|
+
*/
|
|
75
|
+
export declare function splitWindows(events: readonly ReplayEvent[]): ReplayEvent[][];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReplayEvent } from "./types";
|
|
2
|
+
export interface Picture {
|
|
3
|
+
base64: string;
|
|
4
|
+
type: string;
|
|
5
|
+
}
|
|
6
|
+
/** A picture as JPEG, or null to keep it as it is. */
|
|
7
|
+
export type PictureEncoder = (picture: Picture) => Promise<Picture | null>;
|
|
8
|
+
/** One place a picture is kept, and how to put a new one there. */
|
|
9
|
+
interface Slot {
|
|
10
|
+
picture: Picture;
|
|
11
|
+
put: (next: Picture) => void;
|
|
12
|
+
}
|
|
13
|
+
/** Every canvas picture in the events, wherever the recorder put it. */
|
|
14
|
+
export declare function pictureSlots(events: readonly ReplayEvent[]): Slot[];
|
|
15
|
+
/** Every picture's base64, as often as it occurs — gzip's 32 KB window never sees a picture's earlier copy. */
|
|
16
|
+
export declare function pictureStrings(events: readonly ReplayEvent[]): string[];
|
|
17
|
+
/** Whether there is anything for `lightenPictures` to do — before the work of decoding. */
|
|
18
|
+
export declare function hasHeavyPngs(events: readonly ReplayEvent[]): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Each large PNG replaced by what `encode` makes of it, when that is smaller.
|
|
21
|
+
* The same picture is encoded once however often it recurs — a page's
|
|
22
|
+
* picture is in every snapshot the recording holds. Returns how many changed.
|
|
23
|
+
* A picture the encoder fails on stays as it was: this never throws.
|
|
24
|
+
*/
|
|
25
|
+
export declare function lightenPictures(events: ReplayEvent[], encode: PictureEncoder): Promise<number>;
|
|
26
|
+
/**
|
|
27
|
+
* The browser's own encoder: the PNG decoded, checked opaque pixel by pixel,
|
|
28
|
+
* and saved as JPEG at `quality`. Null where the browser lacks what it takes
|
|
29
|
+
* (no `createImageBitmap`), for a picture anything shows through, and for a
|
|
30
|
+
* browser that hands back something other than a JPEG.
|
|
31
|
+
*/
|
|
32
|
+
export declare function browserJpeg(quality: number): PictureEncoder | null;
|
|
33
|
+
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -189,7 +189,7 @@ export interface ReplayCapture {
|
|
|
189
189
|
* attachment loads — or say why there is none.
|
|
190
190
|
*/
|
|
191
191
|
export interface ReplaySummary {
|
|
192
|
-
/** Whole seconds covered,
|
|
192
|
+
/** Whole seconds covered by what was attached (or, with `omitted`, by what was recorded). */
|
|
193
193
|
seconds?: number;
|
|
194
194
|
events?: number;
|
|
195
195
|
startedAt?: string;
|
|
@@ -197,8 +197,16 @@ export interface ReplaySummary {
|
|
|
197
197
|
/** Size of the attachment as sent, and whether it is gzip. */
|
|
198
198
|
bytes?: number;
|
|
199
199
|
compressed?: boolean;
|
|
200
|
-
/**
|
|
200
|
+
/** Canvas pictures left out: the canvases play blank. */
|
|
201
201
|
canvasDropped?: boolean;
|
|
202
|
+
/** Large pictures embedded in the page (a `data:` image, an inlined font) left out. */
|
|
203
|
+
picturesDropped?: boolean;
|
|
204
|
+
/** Long text and styles shortened — only when not even one picture of the page fitted otherwise. */
|
|
205
|
+
simplified?: boolean;
|
|
206
|
+
/** Only part of the recording went: how long the whole was. `seconds` is what was sent. */
|
|
207
|
+
recordedSeconds?: number;
|
|
208
|
+
/** The part sent stops this many seconds before the report was made. */
|
|
209
|
+
endsEarlySeconds?: number;
|
|
202
210
|
/** Present when the host records but this report carries no replay. */
|
|
203
211
|
omitted?: "too-large" | "empty";
|
|
204
212
|
}
|
package/dist/ui/chatBubble.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { type PlaceRule } from "./bubblePlace";
|
|
2
|
+
/**
|
|
3
|
+
* The desk's size for it, px (0.19.10; the owner, 11-02: "make it smaller or bigger as a config") — the desk offers
|
|
4
|
+
* 44 to 72; anything else it might say is brought within reach of a finger and of the corner. Pure.
|
|
5
|
+
*/
|
|
6
|
+
export declare function bubbleSize(v: unknown): number;
|
|
2
7
|
/** The panel's address: the support host's page, told the realm, signing in by hand-off (no token in the address). */
|
|
3
8
|
export declare function supportFrameUrl(host: string, realmKey: string): string;
|
|
4
9
|
/** Where the panel's เปิดในระบบแจ้งปัญหา may land: the person's chat or their เรื่อง — anything else, their chat. Pure. */
|
|
@@ -9,9 +14,9 @@ export declare function supportFaceUrl(host: string): string;
|
|
|
9
14
|
* How far the call's card and frame rise from their own 16px so they clear the bubble — its offset, its size and the
|
|
10
15
|
* gap above it (0.19.1: 0.19.0 assumed the bubble at the corner, and a raised one sat under a ringing call). Pure.
|
|
11
16
|
*/
|
|
12
|
-
export declare function chatLift(bubbleY: number): number;
|
|
17
|
+
export declare function chatLift(bubbleY: number, s?: number): number;
|
|
13
18
|
/** The panel above the bubble, never past the top of the window — its height for the bubble's offset (0.19.1). Pure. */
|
|
14
|
-
export declare function panelHeight(bubbleY: number): string;
|
|
19
|
+
export declare function panelHeight(bubbleY: number, s?: number): string;
|
|
15
20
|
export interface BubbleSpot {
|
|
16
21
|
side: "right" | "left";
|
|
17
22
|
/** In from that side, px. */
|
|
@@ -23,16 +28,16 @@ export interface BubbleSpot {
|
|
|
23
28
|
export declare function settleBubble(px: number, py: number, view: {
|
|
24
29
|
w: number;
|
|
25
30
|
h: number;
|
|
26
|
-
}, inset: number): BubbleSpot;
|
|
31
|
+
}, inset: number, s?: number): BubbleSpot;
|
|
27
32
|
/** A height that keeps the whole bubble on screen. Pure. */
|
|
28
|
-
export declare function clampBubbleY(y: number, viewH: number): number;
|
|
33
|
+
export declare function clampBubbleY(y: number, viewH: number, s?: number): number;
|
|
29
34
|
/** How far the call's card rises to clear the bubble: only a bubble on its side, low enough to meet it. Pure. */
|
|
30
|
-
export declare function liftFor(spot: BubbleSpot): number;
|
|
35
|
+
export declare function liftFor(spot: BubbleSpot, s?: number): number;
|
|
31
36
|
/**
|
|
32
37
|
* The panel by the bubble, where it was not dragged: above it when the room above is enough (or more than below),
|
|
33
38
|
* else below it — its own height, never past the window. Pure.
|
|
34
39
|
*/
|
|
35
|
-
export declare function anchorPanel(spot: BubbleSpot, viewH: number): {
|
|
40
|
+
export declare function anchorPanel(spot: BubbleSpot, viewH: number, s?: number): {
|
|
36
41
|
bottom?: number;
|
|
37
42
|
top?: number;
|
|
38
43
|
height: number;
|
|
@@ -75,6 +80,8 @@ export interface DeskLook {
|
|
|
75
80
|
avoid?: boolean;
|
|
76
81
|
/** A page's own place (0.19.6): hidden there, or started in a corner at a height — the desk's rules. */
|
|
77
82
|
places?: PlaceRule[];
|
|
83
|
+
/** ขนาดปุ่ม, px (0.19.10) — 56 when the desk does not say. */
|
|
84
|
+
size?: number;
|
|
78
85
|
}
|
|
79
86
|
/** The face's address for a desk's look: its own path on the support host, the shipped one, or none (the glyph). Pure. */
|
|
80
87
|
export declare function lookFaceUrl(host: string, look: DeskLook | null): string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightworkai.official/debug-capture",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.10",
|
|
4
4
|
"description": "Report-a-problem widget: rolling network/console/action capture, optional rrweb session replay, annotated screenshot, and submission to a Lightwork Support host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|