@replohq/sandbox-runtime 1.18.1 → 1.19.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 (35) hide show
  1. package/_vendor/replo-utils/lib/crypto.d.ts +1 -0
  2. package/_vendor/replo-utils/lib/crypto.mjs +1 -1
  3. package/_vendor/replo-utils/lib/fonts.mjs +2 -2
  4. package/_vendor/replo-utils/lib/math.mjs +3 -3
  5. package/_vendor/replo-utils/lib/misc.mjs +4 -4
  6. package/_vendor/replo-utils/lib/pageCapture.mjs +1 -1
  7. package/_vendor/schemas/errors.d.ts +0 -1
  8. package/_vendor/schemas/generated/pageHeatmap.d.ts +57 -0
  9. package/_vendor/schemas/generated/pageHeatmap.mjs +1 -0
  10. package/_vendor/schemas/iframeRpcChannel.mjs +6 -6
  11. package/_vendor/schemas/pageHeatmap.d.ts +132 -0
  12. package/_vendor/schemas/pageHeatmap.mjs +72 -0
  13. package/_vendor/schemas/previewHealthIframeRpc.mjs +6 -6
  14. package/_vendor/schemas/selectMode.mjs +5 -5
  15. package/_vendor/schemas/selectModeIframeRpc.mjs +5 -5
  16. package/buildMetadata.js +3 -3
  17. package/{chunk-KRA4LUIR.mjs → chunk-36IPO47A.mjs} +2 -2
  18. package/{chunk-TP4ZXK4R.mjs → chunk-QTGDSYSU.mjs} +1 -1
  19. package/{chunk-FLYEIRFK.mjs → chunk-SKVPFN7M.mjs} +1 -1
  20. package/{chunk-PH3S6LJI.mjs → chunk-THOBCJJA.mjs} +2 -2
  21. package/{chunk-LIPH4O4F.mjs → chunk-ZTT7SNYN.mjs} +5 -2
  22. package/heatmaps/HeatLayerMount.d.ts +1 -0
  23. package/heatmaps/HeatLayerMount.js +12 -0
  24. package/heatmaps/heatBadges.d.ts +25 -0
  25. package/heatmaps/heatBadges.js +98 -0
  26. package/heatmaps/heatCore.d.ts +34 -0
  27. package/heatmaps/heatCore.js +465 -0
  28. package/heatmaps/heatLayer.d.ts +1 -0
  29. package/heatmaps/heatLayer.js +85 -0
  30. package/heatmaps/heatRender.d.ts +36 -0
  31. package/heatmaps/heatRender.js +198 -0
  32. package/package.json +4 -4
  33. package/sandbox-runtime.js +2 -0
  34. /package/{chunk-TESFJQID.mjs → chunk-4ITJNSXZ.mjs} +0 -0
  35. /package/{chunk-G3S6ZNPF.mjs → chunk-XYS6G2ZC.mjs} +0 -0
@@ -0,0 +1,198 @@
1
+ const STOPS = [
2
+ { offset: 0, color: "rgba(40, 60, 255, 0)" },
3
+ { offset: 0.18, color: "rgba(40, 90, 255, 0.55)" },
4
+ { offset: 0.38, color: "rgba(0, 200, 220, 0.7)" },
5
+ { offset: 0.55, color: "rgba(60, 220, 90, 0.78)" },
6
+ { offset: 0.72, color: "rgba(255, 225, 40, 0.86)" },
7
+ { offset: 0.86, color: "rgba(255, 140, 20, 0.92)" },
8
+ { offset: 1, color: "rgba(240, 30, 40, 0.95)" }
9
+ ];
10
+ const SCRIM_COLOR = "rgba(20, 18, 40, 0.24)";
11
+ const MARK_LINE_COLOR = "rgba(255, 255, 255, 0.95)";
12
+ const MARK_LABEL_BACKGROUND = "rgba(23, 23, 23, 0.85)";
13
+ const REACH_MARKS = [0.75, 0.5, 0.25];
14
+ const LABEL_FONT_PX = 13;
15
+ let paletteCache = null;
16
+ function getPalette() {
17
+ if (paletteCache) {
18
+ return paletteCache;
19
+ }
20
+ const canvas = document.createElement("canvas");
21
+ canvas.width = 256;
22
+ canvas.height = 1;
23
+ const context = canvas.getContext("2d", { willReadFrequently: true });
24
+ if (!context) {
25
+ return null;
26
+ }
27
+ const gradient = context.createLinearGradient(0, 0, 256, 0);
28
+ for (const stop of STOPS) {
29
+ gradient.addColorStop(stop.offset, stop.color);
30
+ }
31
+ context.fillStyle = gradient;
32
+ context.fillRect(0, 0, 256, 1);
33
+ paletteCache = context.getImageData(0, 0, 256, 1).data;
34
+ return paletteCache;
35
+ }
36
+ const stampCache = /* @__PURE__ */ new Map();
37
+ function getDiscStamp(radius) {
38
+ const cached = stampCache.get(radius);
39
+ if (cached) {
40
+ return cached;
41
+ }
42
+ const size = Math.max(1, Math.ceil(radius * 4));
43
+ const stamp = document.createElement("canvas");
44
+ stamp.width = size;
45
+ stamp.height = size;
46
+ const context = stamp.getContext("2d");
47
+ if (!context) {
48
+ return null;
49
+ }
50
+ const gradient = context.createRadialGradient(
51
+ size / 2,
52
+ size / 2,
53
+ 0,
54
+ size / 2,
55
+ size / 2,
56
+ radius * 2
57
+ );
58
+ gradient.addColorStop(0, "rgba(0, 0, 0, 1)");
59
+ gradient.addColorStop(0.45, "rgba(0, 0, 0, 0.45)");
60
+ gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
61
+ context.fillStyle = gradient;
62
+ context.fillRect(0, 0, size, size);
63
+ stampCache.set(radius, stamp);
64
+ return stamp;
65
+ }
66
+ function withScrimBehind(context) {
67
+ context.globalCompositeOperation = "destination-over";
68
+ context.fillStyle = SCRIM_COLOR;
69
+ context.fillRect(0, 0, context.canvas.width, context.canvas.height);
70
+ context.globalCompositeOperation = "source-over";
71
+ }
72
+ function drawHeatPoints({
73
+ context,
74
+ points,
75
+ radius
76
+ }) {
77
+ const { width, height } = context.canvas;
78
+ context.clearRect(0, 0, width, height);
79
+ const stamp = getDiscStamp(radius);
80
+ const palette = getPalette();
81
+ if (points.length > 0 && stamp && palette) {
82
+ const cells = /* @__PURE__ */ new Map();
83
+ for (const point of points) {
84
+ const key = `${Math.round(point.x / radius)},${Math.round(point.y / radius)}`;
85
+ cells.set(key, (cells.get(key) ?? 0) + point.weight);
86
+ }
87
+ const sums = [...cells.values()].sort((first, second) => first - second);
88
+ const max = Math.max(1, sums[Math.floor(sums.length * 0.97)] ?? 1);
89
+ for (const point of points) {
90
+ context.globalAlpha = Math.min(1, Math.max(0.04, point.weight / max));
91
+ context.drawImage(stamp, point.x - radius * 2, point.y - radius * 2);
92
+ }
93
+ context.globalAlpha = 1;
94
+ const image = context.getImageData(0, 0, width, height);
95
+ const pixels = image.data;
96
+ for (let index = 0; index < pixels.length; index += 4) {
97
+ const alpha = pixels[index + 3] ?? 0;
98
+ if (alpha === 0) {
99
+ continue;
100
+ }
101
+ const offset = alpha * 4;
102
+ pixels[index] = palette[offset] ?? 0;
103
+ pixels[index + 1] = palette[offset + 1] ?? 0;
104
+ pixels[index + 2] = palette[offset + 2] ?? 0;
105
+ pixels[index + 3] = palette[offset + 3] ?? 0;
106
+ }
107
+ context.putImageData(image, 0, 0);
108
+ }
109
+ withScrimBehind(context);
110
+ }
111
+ function getScrollReach(buckets) {
112
+ const total = buckets.reduce((sum, bucket) => sum + bucket.views, 0);
113
+ const reach = Array.from({ length: 101 }, () => 0);
114
+ if (total === 0) {
115
+ return reach;
116
+ }
117
+ const viewsByPct = /* @__PURE__ */ new Map();
118
+ for (const bucket of buckets) {
119
+ viewsByPct.set(
120
+ bucket.pct,
121
+ (viewsByPct.get(bucket.pct) ?? 0) + bucket.views
122
+ );
123
+ }
124
+ let remaining = total;
125
+ for (let pct = 0; pct <= 100; pct++) {
126
+ reach[pct] = remaining / total;
127
+ remaining -= viewsByPct.get(pct) ?? 0;
128
+ }
129
+ return reach;
130
+ }
131
+ function drawScrollBands({
132
+ context,
133
+ reach
134
+ }) {
135
+ const { width, height } = context.canvas;
136
+ context.clearRect(0, 0, width, height);
137
+ const palette = getPalette();
138
+ if (!palette) {
139
+ return;
140
+ }
141
+ for (let pct = 0; pct < 100; pct++) {
142
+ const share = Math.min(1, Math.max(0, reach[pct] ?? 0));
143
+ const offset = Math.round(share * 255) * 4;
144
+ const alpha = Math.min(0.62, (palette[offset + 3] ?? 0) / 255 * 0.7);
145
+ context.fillStyle = `rgba(${palette[offset] ?? 0}, ${palette[offset + 1] ?? 0}, ${palette[offset + 2] ?? 0}, ${alpha})`;
146
+ const top = Math.floor(pct / 100 * height);
147
+ const bottom = Math.ceil((pct + 1) / 100 * height);
148
+ context.fillRect(0, top, width, bottom - top);
149
+ }
150
+ }
151
+ function getReachMarks({
152
+ reach,
153
+ height
154
+ }) {
155
+ return REACH_MARKS.flatMap((share) => {
156
+ const pct = reach.findIndex((value) => value < share);
157
+ return pct > 0 ? [{ share, y: pct / 100 * height }] : [];
158
+ });
159
+ }
160
+ function drawMarkLine({
161
+ context,
162
+ y,
163
+ label,
164
+ dashed,
165
+ scale
166
+ }) {
167
+ const { width } = context.canvas;
168
+ context.save();
169
+ context.strokeStyle = MARK_LINE_COLOR;
170
+ context.lineWidth = Math.max(1, 2 * scale);
171
+ context.setLineDash(dashed ? [8 * scale, 6 * scale] : []);
172
+ context.beginPath();
173
+ context.moveTo(0, y);
174
+ context.lineTo(width, y);
175
+ context.stroke();
176
+ const fontPx = LABEL_FONT_PX * scale;
177
+ context.font = `500 ${fontPx}px system-ui, -apple-system, sans-serif`;
178
+ const paddingX = 10 * scale;
179
+ const labelHeight = fontPx + 10 * scale;
180
+ const labelWidth = context.measureText(label).width + paddingX * 2;
181
+ const left = 24 * scale;
182
+ const top = Math.max(0, y - labelHeight - 6 * scale);
183
+ context.fillStyle = MARK_LABEL_BACKGROUND;
184
+ context.beginPath();
185
+ context.roundRect(left, top, labelWidth, labelHeight, labelHeight / 2);
186
+ context.fill();
187
+ context.fillStyle = "#fff";
188
+ context.textBaseline = "middle";
189
+ context.fillText(label, left + paddingX, top + labelHeight / 2);
190
+ context.restore();
191
+ }
192
+ export {
193
+ drawHeatPoints,
194
+ drawMarkLine,
195
+ drawScrollBands,
196
+ getReachMarks,
197
+ getScrollReach
198
+ };
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sandbox-runtime",
3
- "version": "1.18.1",
3
+ "version": "1.19.0",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sandbox-runtime",
6
- "version": "1.18.1",
6
+ "version": "1.19.0",
7
7
  "branch": "HEAD",
8
- "commit": "770da909743d238b91a6529e4dc38a079fdfd43a",
9
- "builtAt": "2026-10-22T00:12:53.373Z"
8
+ "commit": "1aa1f09e1dd141b243b7bb3b1ff1bc947fa01371",
9
+ "builtAt": "2026-10-23T05:44:42.441Z"
10
10
  },
11
11
  "description": "Replo sandbox runtime — editor integration for agent-built Next.js sites.",
12
12
  "license": "SEE LICENSE IN LICENSE",
@@ -5,6 +5,7 @@ import { AnnotationLayerMount } from "./annotations/AnnotationLayerMount";
5
5
  import { ClientErrorBoundary } from "./ClientErrorBoundary";
6
6
  import { DesignLibraryPreview } from "./design-library-preview/DesignLibraryPreview";
7
7
  import { DocumentReadyBeacon } from "./DocumentReadyBeacon";
8
+ import { HeatLayerMount } from "./heatmaps/HeatLayerMount";
8
9
  import LinkInterceptor from "./LinkInterceptor";
9
10
  import { NavigationReceiver } from "./NavigationReceiver";
10
11
  import { PageCaptureResponder } from "./PageCaptureResponder";
@@ -26,6 +27,7 @@ function SandboxRuntime({ children }) {
26
27
  /* @__PURE__ */ jsx(PageCaptureResponder, {}),
27
28
  /* @__PURE__ */ jsx(EditorSelection, {}),
28
29
  /* @__PURE__ */ jsx(AnnotationLayerMount, {}),
30
+ /* @__PURE__ */ jsx(HeatLayerMount, {}),
29
31
  /* @__PURE__ */ jsx(DesignLibraryPreview, {}),
30
32
  children
31
33
  ] })
File without changes
File without changes