@vibecodeapp/sdk 0.4.12 → 0.4.14
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.
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
* Web version of Screenshot - listens for screenshot requests from parent iframe
|
|
3
3
|
*
|
|
4
4
|
* On web, this component listens for postMessage requests and captures
|
|
5
|
-
* the current page using
|
|
6
|
-
*
|
|
7
|
-
* html-to-image is faster than html2canvas, but html2canvas is more reliable on Safari/Firefox.
|
|
8
|
-
* due to the fact that html-to-image uses foreignObjects.
|
|
5
|
+
* the current page using @renoun/screenshot for cross-browser DOM-to-canvas
|
|
6
|
+
* rendering with full CSS support.
|
|
9
7
|
*/
|
|
10
8
|
export declare function VibeScreenshot(): null;
|
|
11
9
|
//# sourceMappingURL=Screenshot.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screenshot.web.d.ts","sourceRoot":"","sources":["../../src/dev/Screenshot.web.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Screenshot.web.d.ts","sourceRoot":"","sources":["../../src/dev/Screenshot.web.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAyIH,wBAAgB,cAAc,SAyB7B"}
|
|
@@ -2,65 +2,109 @@
|
|
|
2
2
|
* Web version of Screenshot - listens for screenshot requests from parent iframe
|
|
3
3
|
*
|
|
4
4
|
* On web, this component listens for postMessage requests and captures
|
|
5
|
-
* the current page using
|
|
6
|
-
*
|
|
7
|
-
* html-to-image is faster than html2canvas, but html2canvas is more reliable on Safari/Firefox.
|
|
8
|
-
* due to the fact that html-to-image uses foreignObjects.
|
|
5
|
+
* the current page using @renoun/screenshot for cross-browser DOM-to-canvas
|
|
6
|
+
* rendering with full CSS support.
|
|
9
7
|
*/
|
|
8
|
+
import { screenshot } from '@renoun/screenshot';
|
|
10
9
|
import { useEffect } from 'react';
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Check if a URL is cross-origin.
|
|
12
|
+
*/
|
|
13
|
+
function isCrossOrigin(url) {
|
|
14
|
+
if (!url || url.startsWith('data:') || url.startsWith('blob:'))
|
|
15
|
+
return false;
|
|
16
|
+
try {
|
|
17
|
+
const imgUrl = new URL(url, window.location.href);
|
|
18
|
+
return imgUrl.origin !== window.location.origin;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
13
21
|
return false;
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Convert an image to a data URI by reloading with CORS.
|
|
26
|
+
* Returns the data URI if successful, null if CORS is blocked.
|
|
27
|
+
*/
|
|
28
|
+
function convertImageToDataUri(src) {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
const img = new Image();
|
|
31
|
+
img.crossOrigin = 'anonymous';
|
|
32
|
+
img.onload = () => {
|
|
33
|
+
try {
|
|
34
|
+
const canvas = document.createElement('canvas');
|
|
35
|
+
canvas.width = img.naturalWidth;
|
|
36
|
+
canvas.height = img.naturalHeight;
|
|
37
|
+
const ctx = canvas.getContext('2d');
|
|
38
|
+
if (!ctx) {
|
|
39
|
+
resolve(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
ctx.drawImage(img, 0, 0);
|
|
43
|
+
resolve(canvas.toDataURL('image/png'));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
resolve(null);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
img.onerror = () => resolve(null);
|
|
50
|
+
// Add cache buster to force fresh CORS request
|
|
51
|
+
img.src = src + (src.includes('?') ? '&' : '?') + '_cors=1';
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Prepare images for screenshot capture by handling CORS issues.
|
|
56
|
+
* Returns a restore function to revert changes.
|
|
57
|
+
*/
|
|
58
|
+
async function prepareImagesForCapture() {
|
|
59
|
+
const images = document.querySelectorAll('img');
|
|
60
|
+
const originalSrcs = new Map();
|
|
61
|
+
const hiddenImages = [];
|
|
62
|
+
const promises = Array.from(images).map(async (img) => {
|
|
63
|
+
if (!img.src || !isCrossOrigin(img.src))
|
|
64
|
+
return;
|
|
65
|
+
const dataUri = await convertImageToDataUri(img.src);
|
|
66
|
+
if (dataUri) {
|
|
67
|
+
originalSrcs.set(img, img.src);
|
|
68
|
+
img.src = dataUri;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
hiddenImages.push(img);
|
|
72
|
+
img.dataset.screenshotHidden = img.style.visibility;
|
|
73
|
+
img.style.visibility = 'hidden';
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
await Promise.all(promises);
|
|
77
|
+
return () => {
|
|
78
|
+
originalSrcs.forEach((src, img) => {
|
|
79
|
+
img.src = src;
|
|
80
|
+
});
|
|
81
|
+
hiddenImages.forEach((img) => {
|
|
82
|
+
img.style.visibility = img.dataset.screenshotHidden || '';
|
|
83
|
+
delete img.dataset.screenshotHidden;
|
|
84
|
+
});
|
|
85
|
+
};
|
|
16
86
|
}
|
|
17
87
|
async function captureScreenshot() {
|
|
18
88
|
const scale = window.devicePixelRatio || 1;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
filter: (node) => node.tagName !== 'NOSCRIPT',
|
|
89
|
+
const width = document.body.scrollWidth;
|
|
90
|
+
const height = document.body.scrollHeight;
|
|
91
|
+
const restore = await prepareImagesForCapture();
|
|
92
|
+
try {
|
|
93
|
+
const blob = await screenshot.blob(document.body, {
|
|
94
|
+
format: 'png',
|
|
95
|
+
scale,
|
|
96
|
+
width,
|
|
97
|
+
height,
|
|
29
98
|
});
|
|
30
|
-
if (!blob) {
|
|
31
|
-
throw new Error('Failed to create blob from html-to-image');
|
|
32
|
-
}
|
|
33
|
-
const buffer = await blob.arrayBuffer();
|
|
34
99
|
return {
|
|
35
|
-
image:
|
|
100
|
+
image: await blob.arrayBuffer(),
|
|
36
101
|
width: width * scale,
|
|
37
102
|
height: height * scale,
|
|
38
103
|
};
|
|
39
104
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const canvas = await html2canvas(document.body, {
|
|
44
|
-
useCORS: true,
|
|
45
|
-
allowTaint: true,
|
|
46
|
-
backgroundColor: null,
|
|
47
|
-
scale,
|
|
48
|
-
});
|
|
49
|
-
return new Promise((resolve, reject) => {
|
|
50
|
-
canvas.toBlob((blob) => {
|
|
51
|
-
if (!blob) {
|
|
52
|
-
reject(new Error('Failed to create blob from canvas'));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
blob.arrayBuffer().then((buffer) => {
|
|
56
|
-
resolve({
|
|
57
|
-
image: buffer,
|
|
58
|
-
width: canvas.width,
|
|
59
|
-
height: canvas.height,
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}, 'image/png');
|
|
63
|
-
});
|
|
105
|
+
finally {
|
|
106
|
+
restore();
|
|
107
|
+
}
|
|
64
108
|
}
|
|
65
109
|
function postScreenshotToParent(data) {
|
|
66
110
|
try {
|
|
@@ -90,7 +134,6 @@ export function VibeScreenshot() {
|
|
|
90
134
|
});
|
|
91
135
|
}
|
|
92
136
|
catch (error) {
|
|
93
|
-
// Failed to capture screenshot - silently fail
|
|
94
137
|
console.warn('[Vibecode] Screenshot capture failed:', error);
|
|
95
138
|
}
|
|
96
139
|
}
|
|
@@ -98,7 +141,6 @@ export function VibeScreenshot() {
|
|
|
98
141
|
window.addEventListener('message', handleMessage);
|
|
99
142
|
return () => window.removeEventListener('message', handleMessage);
|
|
100
143
|
}, []);
|
|
101
|
-
// This component renders nothing
|
|
102
144
|
return null;
|
|
103
145
|
}
|
|
104
146
|
//# sourceMappingURL=Screenshot.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Screenshot.web.js","sourceRoot":"","sources":["../../src/dev/Screenshot.web.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Screenshot.web.js","sourceRoot":"","sources":["../../src/dev/Screenshot.web.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibecodeapp/sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "SDK for Vibecodeapp.com - Web polyfills and Metro configuration for React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -37,19 +37,17 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@blazejkustra/react-native-alert": "^1.0.0",
|
|
40
|
+
"@renoun/screenshot": "^0.1.0",
|
|
40
41
|
"@stardazed/streams-text-encoding": "^1.0.2",
|
|
41
42
|
"@teovilla/react-native-web-maps": "^0.9.5",
|
|
42
43
|
"assert": "^2.1.0",
|
|
43
44
|
"cosmiconfig": "^8.3.6",
|
|
44
|
-
"html-to-image": "^1.11.11",
|
|
45
|
-
"html2canvas": "^1.4.1",
|
|
46
45
|
"p-limit": "^3.1.0",
|
|
47
46
|
"react-native-svg-transformer": "^1.5.1"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
49
|
"@biomejs/biome": "^2.3.8",
|
|
51
50
|
"@types/bun": "^1.3.4",
|
|
52
|
-
"@types/html2canvas": "^1.0.0",
|
|
53
51
|
"@types/react": "19.1.11",
|
|
54
52
|
"react": "19.1.0",
|
|
55
53
|
"react-native": "0.81.4",
|