@merittdev/horus-lens 0.1.0 → 0.2.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/dist/browser.cjs +1290 -142
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +2 -2
- package/dist/{chunk-MTQ3IO4U.js → chunk-JXSK4JG4.js} +273 -12
- package/dist/chunk-JXSK4JG4.js.map +1 -0
- package/dist/{chunk-A6SNBIRS.js → chunk-UT7E5LCG.js} +1017 -130
- package/dist/chunk-UT7E5LCG.js.map +1 -0
- package/dist/index.cjs +272 -11
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-BA540Fae.d.ts → index.d-BtnbCqUx.d.ts} +39 -1
- package/dist/index.d-Cyvb07sp.d.cts +301 -0
- package/dist/index.d-Cyvb07sp.d.ts +301 -0
- package/dist/{index.d-DOCLVJGS.d.cts → index.d-QzZn4EMM.d.cts} +39 -1
- package/dist/index.d.cts +355 -37
- package/dist/index.d.ts +355 -37
- package/dist/index.js +1 -1
- package/dist/lens.min.js +163 -43
- package/dist/lens.min.js.map +1 -1
- package/dist/react.cjs +1290 -142
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/package.json +3 -3
- package/dist/chunk-A6SNBIRS.js.map +0 -1
- package/dist/chunk-MTQ3IO4U.js.map +0 -1
- package/dist/index.d-Bzgtl7-B.d.cts +0 -161
- package/dist/index.d-Bzgtl7-B.d.ts +0 -161
package/dist/browser.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { L as LensConfig, a as LensClient } from './index.d-
|
|
1
|
+
import { L as LensConfig, a as LensClient } from './index.d-QzZn4EMM.cjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import './index.d-
|
|
3
|
+
import './index.d-Cyvb07sp.cjs';
|
|
4
4
|
|
|
5
5
|
declare const AppContextSchema: z.ZodObject<{
|
|
6
6
|
release: z.ZodOptional<z.ZodString>;
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { L as LensConfig, a as LensClient } from './index.d-
|
|
1
|
+
import { L as LensConfig, a as LensClient } from './index.d-BtnbCqUx.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import './index.d-
|
|
3
|
+
import './index.d-Cyvb07sp.js';
|
|
4
4
|
|
|
5
5
|
declare const AppContextSchema: z.ZodObject<{
|
|
6
6
|
release: z.ZodOptional<z.ZodString>;
|
package/dist/browser.js
CHANGED
|
@@ -14586,15 +14586,86 @@ var TargetElementSchema = external_exports.object({
|
|
|
14586
14586
|
boundingRect: external_exports.object({ x: external_exports.number(), y: external_exports.number(), width: external_exports.number(), height: external_exports.number() }).optional(),
|
|
14587
14587
|
reactComponents: external_exports.array(external_exports.string()).optional()
|
|
14588
14588
|
});
|
|
14589
|
-
var
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14589
|
+
var annotationCommon = {
|
|
14590
|
+
id: external_exports.string().optional(),
|
|
14591
|
+
/** Any CSS color string. */
|
|
14592
|
+
color: external_exports.string().optional(),
|
|
14593
|
+
strokeWidth: external_exports.number().optional()
|
|
14594
|
+
};
|
|
14595
|
+
var AnnotationPointSchema = external_exports.object({ x: external_exports.number(), y: external_exports.number() });
|
|
14596
|
+
var AnnotationSchema = external_exports.discriminatedUnion("kind", [
|
|
14597
|
+
external_exports.object({
|
|
14598
|
+
...annotationCommon,
|
|
14599
|
+
kind: external_exports.literal("rect"),
|
|
14600
|
+
x: external_exports.number(),
|
|
14601
|
+
y: external_exports.number(),
|
|
14602
|
+
width: external_exports.number(),
|
|
14603
|
+
height: external_exports.number(),
|
|
14604
|
+
/**
|
|
14605
|
+
* OPTIONAL, kept for back-compat with 0.1.x clients that emit
|
|
14606
|
+
* viewport-anchored rects. New clients emit document-pixel rects with no
|
|
14607
|
+
* viewport.
|
|
14608
|
+
*/
|
|
14609
|
+
viewport: external_exports.object({ width: external_exports.number(), height: external_exports.number() }).optional()
|
|
14610
|
+
}),
|
|
14611
|
+
external_exports.object({
|
|
14612
|
+
...annotationCommon,
|
|
14613
|
+
kind: external_exports.literal("ellipse"),
|
|
14614
|
+
x: external_exports.number(),
|
|
14615
|
+
y: external_exports.number(),
|
|
14616
|
+
width: external_exports.number(),
|
|
14617
|
+
height: external_exports.number()
|
|
14618
|
+
}),
|
|
14619
|
+
external_exports.object({
|
|
14620
|
+
...annotationCommon,
|
|
14621
|
+
kind: external_exports.literal("blur"),
|
|
14622
|
+
x: external_exports.number(),
|
|
14623
|
+
y: external_exports.number(),
|
|
14624
|
+
width: external_exports.number(),
|
|
14625
|
+
height: external_exports.number()
|
|
14626
|
+
}),
|
|
14627
|
+
external_exports.object({
|
|
14628
|
+
...annotationCommon,
|
|
14629
|
+
kind: external_exports.literal("arrow"),
|
|
14630
|
+
x1: external_exports.number(),
|
|
14631
|
+
y1: external_exports.number(),
|
|
14632
|
+
x2: external_exports.number(),
|
|
14633
|
+
y2: external_exports.number()
|
|
14634
|
+
}),
|
|
14635
|
+
external_exports.object({
|
|
14636
|
+
...annotationCommon,
|
|
14637
|
+
kind: external_exports.literal("line"),
|
|
14638
|
+
x1: external_exports.number(),
|
|
14639
|
+
y1: external_exports.number(),
|
|
14640
|
+
x2: external_exports.number(),
|
|
14641
|
+
y2: external_exports.number()
|
|
14642
|
+
}),
|
|
14643
|
+
external_exports.object({
|
|
14644
|
+
...annotationCommon,
|
|
14645
|
+
kind: external_exports.literal("pencil"),
|
|
14646
|
+
points: external_exports.array(AnnotationPointSchema).min(2)
|
|
14647
|
+
}),
|
|
14648
|
+
external_exports.object({
|
|
14649
|
+
...annotationCommon,
|
|
14650
|
+
kind: external_exports.literal("highlighter"),
|
|
14651
|
+
points: external_exports.array(AnnotationPointSchema).min(2)
|
|
14652
|
+
}),
|
|
14653
|
+
external_exports.object({
|
|
14654
|
+
...annotationCommon,
|
|
14655
|
+
kind: external_exports.literal("text"),
|
|
14656
|
+
x: external_exports.number(),
|
|
14657
|
+
y: external_exports.number(),
|
|
14658
|
+
text: external_exports.string(),
|
|
14659
|
+
fontSize: external_exports.number().optional()
|
|
14660
|
+
}),
|
|
14661
|
+
external_exports.object({
|
|
14662
|
+
...annotationCommon,
|
|
14663
|
+
kind: external_exports.literal("step"),
|
|
14664
|
+
x: external_exports.number(),
|
|
14665
|
+
y: external_exports.number(),
|
|
14666
|
+
n: external_exports.number()
|
|
14667
|
+
})
|
|
14668
|
+
]);
|
|
14598
14669
|
var AssetKindSchema = external_exports.enum(["replay", "console", "network", "dom", "screenshot", "attachment"]);
|
|
14599
14670
|
var AssetRefSchema = external_exports.object({
|
|
14600
14671
|
kind: AssetKindSchema,
|
|
@@ -29334,6 +29405,11 @@ var ReplayRecorder = class {
|
|
|
29334
29405
|
emit: (event, isCheckout) => this.onEmit(event, isCheckout),
|
|
29335
29406
|
checkoutEveryNms: this.windowMs,
|
|
29336
29407
|
recordCanvas: false,
|
|
29408
|
+
// Inline same-origin + CORS images as data URIs at snapshot time so the
|
|
29409
|
+
// dashboard replay paints on a different origin (tainted cross-origin
|
|
29410
|
+
// images fall back to their URL, which is fine for public CDNs).
|
|
29411
|
+
inlineImages: true,
|
|
29412
|
+
collectFonts: true,
|
|
29337
29413
|
// Keep the Lens overlay itself out of every recording.
|
|
29338
29414
|
blockSelector: `#${LENS_OVERLAY_HOST_ID}`
|
|
29339
29415
|
});
|
|
@@ -29440,7 +29516,20 @@ var ReplayRecorder = class {
|
|
|
29440
29516
|
console.warn("[lens] rrweb recording unavailable; replay disabled", err);
|
|
29441
29517
|
}
|
|
29442
29518
|
};
|
|
29443
|
-
|
|
29519
|
+
var SVG_RASTERIZE_TIMEOUT_MS = 3e3;
|
|
29520
|
+
function computeCropRect(crop, scale, rasterWidth, rasterHeight) {
|
|
29521
|
+
let sx = Math.round(crop.x * scale);
|
|
29522
|
+
let sy = Math.round(crop.y * scale);
|
|
29523
|
+
let sw = Math.round(crop.width * scale);
|
|
29524
|
+
let sh = Math.round(crop.height * scale);
|
|
29525
|
+
sx = Math.max(0, Math.min(sx, rasterWidth));
|
|
29526
|
+
sy = Math.max(0, Math.min(sy, rasterHeight));
|
|
29527
|
+
sw = Math.min(sw, rasterWidth - sx);
|
|
29528
|
+
sh = Math.min(sh, rasterHeight - sy);
|
|
29529
|
+
if (sw <= 0 || sh <= 0) return null;
|
|
29530
|
+
return { sx, sy, sw, sh };
|
|
29531
|
+
}
|
|
29532
|
+
async function captureScreenshot(excludeHost, crop, composite) {
|
|
29444
29533
|
if (typeof document === "undefined" || typeof window === "undefined") return null;
|
|
29445
29534
|
try {
|
|
29446
29535
|
const viewportPixels = window.innerWidth * window.innerHeight || 1;
|
|
@@ -29450,6 +29539,15 @@ async function captureScreenshot(excludeHost) {
|
|
|
29450
29539
|
scale,
|
|
29451
29540
|
type: "image/jpeg",
|
|
29452
29541
|
quality: 0.82,
|
|
29542
|
+
// JPEG has no alpha — transparent page regions (and any capture box
|
|
29543
|
+
// extending past short content) would otherwise encode as BLACK.
|
|
29544
|
+
backgroundColor: "#ffffff",
|
|
29545
|
+
// When compositing annotations, force the capture box to the editor's
|
|
29546
|
+
// document measurement (scrollHeight-based). modern-screenshot otherwise
|
|
29547
|
+
// sizes from documentElement's bounding box, which on pages SHORTER than
|
|
29548
|
+
// the viewport is the content height only — marks drawn in the lower
|
|
29549
|
+
// viewport band would fall off the raster and the crop would clamp short.
|
|
29550
|
+
...composite ? { width: composite.docWidth, height: composite.docHeight } : {},
|
|
29453
29551
|
// Exclude the overlay from the capture CLONE — never hide the live node.
|
|
29454
29552
|
filter: (node2) => node2 !== excludeHost,
|
|
29455
29553
|
// Per-resource fetch budget: a single slow cross-origin image must not
|
|
@@ -29474,12 +29572,171 @@ async function captureScreenshot(excludeHost) {
|
|
|
29474
29572
|
);
|
|
29475
29573
|
return null;
|
|
29476
29574
|
}
|
|
29575
|
+
if (composite) {
|
|
29576
|
+
const baked = await compositeScreenshot(blob2, composite, scale, crop);
|
|
29577
|
+
if (baked) return baked;
|
|
29578
|
+
if (composite.blurRegions.length > 0) {
|
|
29579
|
+
console.warn(
|
|
29580
|
+
"[lens] screenshot compositing failed with active redactions; dropping screenshot to avoid leaking un-blurred content"
|
|
29581
|
+
);
|
|
29582
|
+
return null;
|
|
29583
|
+
}
|
|
29584
|
+
}
|
|
29585
|
+
if (crop) {
|
|
29586
|
+
const cropped = await cropBlob(blob2, crop, scale);
|
|
29587
|
+
return cropped ?? blob2;
|
|
29588
|
+
}
|
|
29477
29589
|
return blob2;
|
|
29478
29590
|
} catch (err) {
|
|
29479
29591
|
console.warn("[lens] screenshot capture failed:", err);
|
|
29480
29592
|
return null;
|
|
29481
29593
|
}
|
|
29482
29594
|
}
|
|
29595
|
+
async function compositeScreenshot(blob2, composite, scale, crop) {
|
|
29596
|
+
try {
|
|
29597
|
+
if (typeof createImageBitmap !== "function" || typeof document === "undefined") return null;
|
|
29598
|
+
const bitmap = await createImageBitmap(blob2);
|
|
29599
|
+
const canvas = document.createElement("canvas");
|
|
29600
|
+
canvas.width = bitmap.width;
|
|
29601
|
+
canvas.height = bitmap.height;
|
|
29602
|
+
const ctx = canvas.getContext("2d");
|
|
29603
|
+
if (!ctx) {
|
|
29604
|
+
bitmap.close?.();
|
|
29605
|
+
return null;
|
|
29606
|
+
}
|
|
29607
|
+
ctx.fillStyle = "#ffffff";
|
|
29608
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
29609
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
29610
|
+
bitmap.close?.();
|
|
29611
|
+
applyBlurRegions(ctx, canvas, composite.blurRegions, scale);
|
|
29612
|
+
await drawSvgOverlay(ctx, composite, scale);
|
|
29613
|
+
if (crop) {
|
|
29614
|
+
const rect = computeCropRect(crop, scale, canvas.width, canvas.height);
|
|
29615
|
+
if (rect) {
|
|
29616
|
+
const out = document.createElement("canvas");
|
|
29617
|
+
out.width = rect.sw;
|
|
29618
|
+
out.height = rect.sh;
|
|
29619
|
+
const octx = out.getContext("2d");
|
|
29620
|
+
if (octx) {
|
|
29621
|
+
octx.drawImage(canvas, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
|
|
29622
|
+
return await canvasToJpegBlob(out);
|
|
29623
|
+
}
|
|
29624
|
+
}
|
|
29625
|
+
}
|
|
29626
|
+
return await canvasToJpegBlob(canvas);
|
|
29627
|
+
} catch (err) {
|
|
29628
|
+
console.warn("[lens] screenshot compositing failed:", err);
|
|
29629
|
+
return null;
|
|
29630
|
+
}
|
|
29631
|
+
}
|
|
29632
|
+
function applyBlurRegions(ctx, canvas, regions, scale) {
|
|
29633
|
+
if (regions.length === 0) return;
|
|
29634
|
+
const filterSupported = typeof ctx.filter === "string";
|
|
29635
|
+
const blurPx = Math.max(8, 12 * scale);
|
|
29636
|
+
const pad = Math.ceil(blurPx);
|
|
29637
|
+
for (const region of regions) {
|
|
29638
|
+
const x = Math.max(0, Math.min(Math.round(region.x * scale), canvas.width));
|
|
29639
|
+
const y = Math.max(0, Math.min(Math.round(region.y * scale), canvas.height));
|
|
29640
|
+
const w = Math.min(Math.round(region.width * scale), canvas.width - x);
|
|
29641
|
+
const h = Math.min(Math.round(region.height * scale), canvas.height - y);
|
|
29642
|
+
if (w <= 0 || h <= 0) continue;
|
|
29643
|
+
if (!filterSupported) {
|
|
29644
|
+
ctx.fillStyle = "rgba(127,127,127,1)";
|
|
29645
|
+
ctx.fillRect(x, y, w, h);
|
|
29646
|
+
continue;
|
|
29647
|
+
}
|
|
29648
|
+
const px = Math.max(0, x - pad);
|
|
29649
|
+
const py = Math.max(0, y - pad);
|
|
29650
|
+
const pw = Math.min(canvas.width, x + w + pad) - px;
|
|
29651
|
+
const ph = Math.min(canvas.height, y + h + pad) - py;
|
|
29652
|
+
if (pw <= 0 || ph <= 0) continue;
|
|
29653
|
+
const temp = document.createElement("canvas");
|
|
29654
|
+
temp.width = pw;
|
|
29655
|
+
temp.height = ph;
|
|
29656
|
+
const tctx = temp.getContext("2d");
|
|
29657
|
+
if (!tctx) {
|
|
29658
|
+
ctx.fillStyle = "rgba(127,127,127,1)";
|
|
29659
|
+
ctx.fillRect(x, y, w, h);
|
|
29660
|
+
continue;
|
|
29661
|
+
}
|
|
29662
|
+
tctx.filter = `blur(${blurPx}px)`;
|
|
29663
|
+
tctx.drawImage(canvas, px, py, pw, ph, 0, 0, pw, ph);
|
|
29664
|
+
tctx.filter = "none";
|
|
29665
|
+
ctx.save();
|
|
29666
|
+
ctx.beginPath();
|
|
29667
|
+
ctx.rect(x, y, w, h);
|
|
29668
|
+
ctx.clip();
|
|
29669
|
+
ctx.drawImage(temp, px, py);
|
|
29670
|
+
ctx.restore();
|
|
29671
|
+
}
|
|
29672
|
+
}
|
|
29673
|
+
async function drawSvgOverlay(ctx, composite, scale) {
|
|
29674
|
+
const { svgMarkup, docWidth, docHeight } = composite;
|
|
29675
|
+
if (!svgMarkup) return;
|
|
29676
|
+
const img = await loadSvgImage(svgMarkup);
|
|
29677
|
+
if (!img) return;
|
|
29678
|
+
try {
|
|
29679
|
+
ctx.drawImage(img, 0, 0, docWidth * scale, docHeight * scale);
|
|
29680
|
+
} catch (err) {
|
|
29681
|
+
console.warn("[lens] annotation overlay draw failed:", err);
|
|
29682
|
+
}
|
|
29683
|
+
}
|
|
29684
|
+
function loadSvgImage(svg) {
|
|
29685
|
+
return new Promise((resolve) => {
|
|
29686
|
+
if (typeof Image !== "function") {
|
|
29687
|
+
resolve(null);
|
|
29688
|
+
return;
|
|
29689
|
+
}
|
|
29690
|
+
let settled = false;
|
|
29691
|
+
const finish = (result2) => {
|
|
29692
|
+
if (settled) return;
|
|
29693
|
+
settled = true;
|
|
29694
|
+
clearTimeout(timer);
|
|
29695
|
+
resolve(result2);
|
|
29696
|
+
};
|
|
29697
|
+
const timer = setTimeout(() => {
|
|
29698
|
+
console.warn("[lens] annotation overlay rasterization timed out");
|
|
29699
|
+
finish(null);
|
|
29700
|
+
}, SVG_RASTERIZE_TIMEOUT_MS);
|
|
29701
|
+
const img = new Image();
|
|
29702
|
+
img.onload = () => finish(img);
|
|
29703
|
+
img.onerror = () => {
|
|
29704
|
+
console.warn("[lens] annotation overlay failed to rasterize");
|
|
29705
|
+
finish(null);
|
|
29706
|
+
};
|
|
29707
|
+
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
|
29708
|
+
});
|
|
29709
|
+
}
|
|
29710
|
+
function canvasToJpegBlob(canvas) {
|
|
29711
|
+
return new Promise((resolve) => {
|
|
29712
|
+
canvas.toBlob((out) => resolve(out), "image/jpeg", 0.82);
|
|
29713
|
+
});
|
|
29714
|
+
}
|
|
29715
|
+
async function cropBlob(blob2, crop, scale) {
|
|
29716
|
+
try {
|
|
29717
|
+
if (typeof createImageBitmap !== "function" || typeof document === "undefined") return null;
|
|
29718
|
+
const bitmap = await createImageBitmap(blob2);
|
|
29719
|
+
const rect = computeCropRect(crop, scale, bitmap.width, bitmap.height);
|
|
29720
|
+
if (!rect) {
|
|
29721
|
+
bitmap.close?.();
|
|
29722
|
+
return null;
|
|
29723
|
+
}
|
|
29724
|
+
const canvas = document.createElement("canvas");
|
|
29725
|
+
canvas.width = rect.sw;
|
|
29726
|
+
canvas.height = rect.sh;
|
|
29727
|
+
const ctx = canvas.getContext("2d");
|
|
29728
|
+
if (!ctx) {
|
|
29729
|
+
bitmap.close?.();
|
|
29730
|
+
return null;
|
|
29731
|
+
}
|
|
29732
|
+
ctx.drawImage(bitmap, rect.sx, rect.sy, rect.sw, rect.sh, 0, 0, rect.sw, rect.sh);
|
|
29733
|
+
bitmap.close?.();
|
|
29734
|
+
return await canvasToJpegBlob(canvas);
|
|
29735
|
+
} catch (err) {
|
|
29736
|
+
console.warn("[lens] screenshot crop failed:", err);
|
|
29737
|
+
return null;
|
|
29738
|
+
}
|
|
29739
|
+
}
|
|
29483
29740
|
function parseBrowser(ua) {
|
|
29484
29741
|
if (!ua) return void 0;
|
|
29485
29742
|
const checks = [
|
|
@@ -29744,7 +30001,11 @@ var LensClient = class {
|
|
|
29744
30001
|
const wantErrors = include.errors !== false;
|
|
29745
30002
|
const wantScreenshot = include.screenshot !== false;
|
|
29746
30003
|
const wantDom = include.dom !== false;
|
|
29747
|
-
const screenshotPromise = this.screenshotEnabled && wantScreenshot ? captureScreenshot(
|
|
30004
|
+
const screenshotPromise = this.screenshotEnabled && wantScreenshot ? captureScreenshot(
|
|
30005
|
+
input2.excludeFromScreenshot,
|
|
30006
|
+
input2.screenshotCrop,
|
|
30007
|
+
input2.annotationComposite
|
|
30008
|
+
) : Promise.resolve(null);
|
|
29748
30009
|
const replayEvents = wantReplay ? this.replay?.snapshot() ?? [] : [];
|
|
29749
30010
|
const errorEntries = this.errorBuffer.drain();
|
|
29750
30011
|
const consoleTail = this.consoleBuffer.tail(CONSOLE_TAIL_SIZE);
|
|
@@ -29883,4 +30144,4 @@ rrweb/dist/rrweb.js:
|
|
|
29883
30144
|
PERFORMANCE OF THIS SOFTWARE.
|
|
29884
30145
|
***************************************************************************** *)
|
|
29885
30146
|
*/
|
|
29886
|
-
//# sourceMappingURL=chunk-
|
|
30147
|
+
//# sourceMappingURL=chunk-JXSK4JG4.js.map
|