vaderjs-native 1.0.30 → 1.0.32
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 → README.MD} +3 -2
- package/cli/android/build.ts +83 -73
- package/index.ts +66 -16
- package/package.json +5 -5
package/{README.md → README.MD}
RENAMED
|
@@ -22,7 +22,7 @@ To build and run on Android, you need the **Android SDK**:
|
|
|
22
22
|
# Add to your .bashrc, .zshrc, or Windows ENV
|
|
23
23
|
ANDROID_HOME=$HOME/Android/Sdk
|
|
24
24
|
PATH=$PATH:$ANDROID_HOME/platform-tools
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
|
|
27
27
|
### 3. Windows Setup (Desktop)
|
|
28
28
|
|
|
@@ -208,4 +208,5 @@ VaderNative implements **Native Pipe & Log Tailing**.
|
|
|
208
208
|
* **Hot Module Replacement:** Fast development with real-time updates
|
|
209
209
|
* **Cross-Platform:** Build for web, Android, and Windows from the same codebase
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
|
|
212
|
+
|
package/cli/android/build.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { logger } from "../logger.js";
|
|
|
10
10
|
import { loadConfig } from "../../main.js";
|
|
11
11
|
import { Config } from "../../config/index.js";
|
|
12
12
|
import { fetchBinary } from "../binaries/fetch.js";
|
|
13
|
+
|
|
13
14
|
const PROJECT_ROOT = process.cwd();
|
|
14
15
|
const DIST_DIR = path.join(PROJECT_ROOT, "dist");
|
|
15
16
|
|
|
@@ -30,16 +31,13 @@ function patchPermissions(buildDir: string) {
|
|
|
30
31
|
|
|
31
32
|
let content = fsSync.readFileSync(manifestPath, "utf8");
|
|
32
33
|
|
|
33
|
-
// Remove existing permissions
|
|
34
34
|
content = content.replace(/<uses-permission android:name="[^"]*" \/>/g, "");
|
|
35
35
|
|
|
36
|
-
// Add basic permissions
|
|
37
36
|
const basePerms = [
|
|
38
37
|
' <uses-permission android:name="android.permission.INTERNET" />',
|
|
39
38
|
' <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />'
|
|
40
39
|
];
|
|
41
40
|
|
|
42
|
-
// Insert permissions before application tag
|
|
43
41
|
const applicationIndex = content.indexOf("<application");
|
|
44
42
|
if (applicationIndex !== -1) {
|
|
45
43
|
const beforeApplication = content.substring(0, applicationIndex);
|
|
@@ -54,16 +52,12 @@ function patchPermissions(buildDir: string) {
|
|
|
54
52
|
async function ensureLocalProperties(buildDir: string, sdkPath?: string) {
|
|
55
53
|
const localPropsPath = path.join(buildDir, "local.properties");
|
|
56
54
|
|
|
57
|
-
// If the file already exists, skip
|
|
58
|
-
|
|
59
|
-
// Determine SDK path if not passed in
|
|
60
55
|
if (!sdkPath) {
|
|
61
56
|
const sdkInfo = findAndroidSdk();
|
|
62
57
|
sdkPath = sdkInfo?.sdkPath;
|
|
63
58
|
if (!sdkPath) throw new Error("Android SDK not found");
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
// Write local.properties with the proper sdk path
|
|
67
61
|
await fs.writeFile(
|
|
68
62
|
localPropsPath,
|
|
69
63
|
`sdk.dir=${sdkPath.replace(/\\/g, "\\\\")}\n`
|
|
@@ -72,9 +66,7 @@ async function ensureLocalProperties(buildDir: string, sdkPath?: string) {
|
|
|
72
66
|
logger.success(`✅ Created local.properties → ${sdkPath}`);
|
|
73
67
|
}
|
|
74
68
|
|
|
75
|
-
|
|
76
69
|
async function copyDir(src: string, dest: string) {
|
|
77
|
-
// Async recursive copy with explicit encoding handling
|
|
78
70
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
79
71
|
await fs.mkdir(dest, { recursive: true });
|
|
80
72
|
await Promise.all(entries.map(async (entry) => {
|
|
@@ -83,7 +75,6 @@ async function copyDir(src: string, dest: string) {
|
|
|
83
75
|
if (entry.isDirectory()) {
|
|
84
76
|
await copyDir(srcPath, destPath);
|
|
85
77
|
} else {
|
|
86
|
-
// For .kt files, read and write to ensure encoding is preserved
|
|
87
78
|
if (entry.name.endsWith('.kt')) {
|
|
88
79
|
const content = await fs.readFile(srcPath, "utf8");
|
|
89
80
|
await fs.writeFile(destPath, content, "utf8");
|
|
@@ -94,25 +85,6 @@ async function copyDir(src: string, dest: string) {
|
|
|
94
85
|
}));
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
async function patchAllKotlinFiles(javaDir: string, APP_ID: string) {
|
|
98
|
-
async function patchDir(dir: string) {
|
|
99
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
100
|
-
await Promise.all(entries.map(async (entry) => {
|
|
101
|
-
const fullPath = path.join(dir, entry.name);
|
|
102
|
-
if (entry.isDirectory()) {
|
|
103
|
-
await patchDir(fullPath);
|
|
104
|
-
} else if (entry.name.endsWith('.kt')) {
|
|
105
|
-
let content = await fs.readFile(fullPath, "utf8");
|
|
106
|
-
content = content.replace(/package \{\{APP_PACKAGE\}\}/g, `package ${APP_ID}`);
|
|
107
|
-
await fs.writeFile(fullPath, content, "utf8");
|
|
108
|
-
}
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
await patchDir(javaDir);
|
|
113
|
-
logger.success("✅ All Kotlin files patched with package name");
|
|
114
|
-
}
|
|
115
|
-
|
|
116
88
|
async function removeDir(dir: string) {
|
|
117
89
|
if (existsSync(dir)) {
|
|
118
90
|
try {
|
|
@@ -120,7 +92,6 @@ async function removeDir(dir: string) {
|
|
|
120
92
|
} catch (error: any) {
|
|
121
93
|
if (error.code === 'EBUSY') {
|
|
122
94
|
logger.warn(`⚠️ Directory ${dir} is busy, retrying...`);
|
|
123
|
-
// Wait and retry
|
|
124
95
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
125
96
|
try {
|
|
126
97
|
await fs.rm(dir, { recursive: true, force: true });
|
|
@@ -145,7 +116,6 @@ async function patchMainActivity(buildDir: string, APP_ID: string, isDev: boolea
|
|
|
145
116
|
|
|
146
117
|
let content = await fs.readFile(mainActivityPath, "utf8");
|
|
147
118
|
|
|
148
|
-
// Replace package declaration
|
|
149
119
|
content = content.replace(/package \{\{APP_PACKAGE\}\}/g, `package ${APP_ID}`);
|
|
150
120
|
|
|
151
121
|
const baseUrl = isDev
|
|
@@ -158,19 +128,6 @@ async function patchMainActivity(buildDir: string, APP_ID: string, isDev: boolea
|
|
|
158
128
|
logger.success(`✅ MainActivity patched → ${baseUrl} (${isDev ? "DEV" : "PROD"} mode)`);
|
|
159
129
|
}
|
|
160
130
|
|
|
161
|
-
async function patchAndroidBridge(buildDir: string, APP_ID: string) {
|
|
162
|
-
const javaDir = path.join(buildDir, "app", "src", "main", "java");
|
|
163
|
-
const packageDir = path.join(javaDir, ...APP_ID.split("."));
|
|
164
|
-
const bridgePath = path.join(packageDir, "AndroidBridge.kt");
|
|
165
|
-
|
|
166
|
-
if (!existsSync(bridgePath)) return;
|
|
167
|
-
|
|
168
|
-
let content = await fs.readFile(bridgePath, "utf8");
|
|
169
|
-
content = content.replace(/package \{\{APP_PACKAGE\}\}/g, `package ${APP_ID}`);
|
|
170
|
-
await fs.writeFile(bridgePath, content, "utf8");
|
|
171
|
-
logger.success("✅ AndroidBridge patched");
|
|
172
|
-
}
|
|
173
|
-
|
|
174
131
|
async function copyAssets(buildDir: string, APP_ID: string) {
|
|
175
132
|
const assetsDir = path.join(buildDir, "app", "src", "main", "assets", APP_ID);
|
|
176
133
|
await removeDir(assetsDir);
|
|
@@ -196,7 +153,6 @@ async function renamePackage(buildDir: string, oldPackage: string, newPackage: s
|
|
|
196
153
|
return;
|
|
197
154
|
}
|
|
198
155
|
|
|
199
|
-
// Create parent directory first
|
|
200
156
|
await fs.mkdir(path.dirname(newDir), { recursive: true });
|
|
201
157
|
|
|
202
158
|
if (existsSync(newDir)) {
|
|
@@ -223,12 +179,10 @@ function patchAppMeta(buildDir: string, config: Config) {
|
|
|
223
179
|
|
|
224
180
|
let content = fsSync.readFileSync(manifestPath, "utf8");
|
|
225
181
|
|
|
226
|
-
// Update app name and label if provided
|
|
227
182
|
if (config.app?.name) {
|
|
228
183
|
content = content.replace(/android:label="[^"]*"/, `android:label="${config.app.name}"`);
|
|
229
184
|
}
|
|
230
185
|
|
|
231
|
-
// Update version info if provided
|
|
232
186
|
if (config.app?.version) {
|
|
233
187
|
content = content.replace(/android:versionCode="[^"]*"/, `android:versionCode="${config.app.version.code}"`);
|
|
234
188
|
content = content.replace(/android:versionName="[^"]*"/, `android:versionName="${config.app.version.name}"`);
|
|
@@ -277,30 +231,35 @@ export async function buildAndroid(isDev = false) {
|
|
|
277
231
|
logger.step("🚀 Android Build");
|
|
278
232
|
ensureAndroidInstalled();
|
|
279
233
|
|
|
280
|
-
//
|
|
281
|
-
// 1️⃣ Clean old build folder with retry
|
|
234
|
+
// 1️⃣ Clean old build folder
|
|
282
235
|
try {
|
|
283
236
|
await removeDir(BUILD_DIR);
|
|
284
237
|
} catch (error) {
|
|
285
238
|
logger.warn(`⚠️ Could not clean build directory, continuing...`);
|
|
286
239
|
}
|
|
287
|
-
// DON'T call mkdir here - it will be created by copyDir later
|
|
288
240
|
|
|
289
|
-
// 2️⃣ Copy template
|
|
241
|
+
// 2️⃣ Copy template
|
|
290
242
|
await copyDir(BUILD_SRC, BUILD_DIR);
|
|
291
243
|
|
|
292
|
-
// 3️⃣ Rename package and patch
|
|
244
|
+
// 3️⃣ Rename package and patch files
|
|
293
245
|
await renamePackage(BUILD_DIR, "myapp", APP_ID);
|
|
294
246
|
|
|
295
247
|
await ensureLocalProperties(BUILD_DIR);
|
|
248
|
+
|
|
296
249
|
// Patch AndroidBridge.kt directly
|
|
297
|
-
|
|
298
|
-
|
|
250
|
+
const bridgePath = path.join(BUILD_DIR, "app", "src", "main", "java", ...APP_ID.split("."), "AndroidBridge.kt");
|
|
251
|
+
if (existsSync(bridgePath)) {
|
|
299
252
|
let bridgeContent = await fs.readFile(bridgePath, "utf8");
|
|
300
|
-
|
|
301
|
-
|
|
253
|
+
|
|
254
|
+
// Remove any existing package declaration
|
|
255
|
+
bridgeContent = bridgeContent.replace(/^package\s+[^\n]+\n/, '');
|
|
256
|
+
|
|
257
|
+
// Add correct package declaration at the beginning
|
|
258
|
+
bridgeContent = `package ${APP_ID}\n\n${bridgeContent}`;
|
|
259
|
+
|
|
302
260
|
await fs.writeFile(bridgePath, bridgeContent, "utf8");
|
|
303
|
-
|
|
261
|
+
logger.success("✅ AndroidBridge patched with package name");
|
|
262
|
+
}
|
|
304
263
|
|
|
305
264
|
await patchMainActivity(BUILD_DIR, APP_ID, isDev, config);
|
|
306
265
|
await patchGradleFiles(BUILD_DIR, APP_ID);
|
|
@@ -311,7 +270,7 @@ export async function buildAndroid(isDev = false) {
|
|
|
311
270
|
// 5️⃣ Clean Gradle artifacts
|
|
312
271
|
await removeDir(path.join(BUILD_DIR, "app", "build"));
|
|
313
272
|
|
|
314
|
-
// 6️⃣
|
|
273
|
+
// 6️⃣ Apply patches and copy assets
|
|
315
274
|
patchPermissions(BUILD_DIR);
|
|
316
275
|
patchAppMeta(BUILD_DIR, config);
|
|
317
276
|
await copyAssets(BUILD_DIR, APP_ID);
|
|
@@ -320,30 +279,75 @@ export async function buildAndroid(isDev = false) {
|
|
|
320
279
|
await addDeepLinks(BUILD_DIR);
|
|
321
280
|
}
|
|
322
281
|
|
|
323
|
-
// 7️⃣ Gradle build
|
|
282
|
+
// 7️⃣ Gradle build - FIXED: Use Bun.spawn instead of Node's spawn
|
|
324
283
|
let gradleCmd = process.platform === "win32"
|
|
325
284
|
? path.join(BUILD_DIR, "gradlew.bat")
|
|
326
285
|
: path.join(BUILD_DIR, "gradlew");
|
|
327
286
|
|
|
328
|
-
|
|
287
|
+
// Check if gradlew exists
|
|
288
|
+
if (!existsSync(gradleCmd)) {
|
|
289
|
+
logger.error(`❌ Gradle wrapper not found at: ${gradleCmd}`);
|
|
290
|
+
logger.info("⚠️ Trying to use system gradle...");
|
|
291
|
+
gradleCmd = "gradle";
|
|
292
|
+
} else {
|
|
293
|
+
logger.info(`✅ Found gradlew at: ${gradleCmd}`);
|
|
294
|
+
}
|
|
329
295
|
|
|
330
|
-
logger.info("⚙️ Running Gradle assembleDebug
|
|
331
|
-
|
|
332
|
-
|
|
296
|
+
logger.info("⚙️ Running Gradle assembleDebug...");
|
|
297
|
+
|
|
298
|
+
// Use Bun.spawn which handles paths better
|
|
299
|
+
try {
|
|
300
|
+
const proc = Bun.spawn([gradleCmd, "assembleDebug", "--no-daemon"], {
|
|
333
301
|
cwd: BUILD_DIR,
|
|
334
|
-
|
|
335
|
-
|
|
302
|
+
stdout: "inherit",
|
|
303
|
+
stderr: "inherit",
|
|
304
|
+
stdin: "inherit"
|
|
336
305
|
});
|
|
337
|
-
proc.on("exit", code => (code === 0 ? resolve() : reject(new Error(`❌ Gradle failed (${code})`))));
|
|
338
|
-
proc.on("error", reject);
|
|
339
|
-
});
|
|
340
306
|
|
|
341
|
-
|
|
307
|
+
const exitCode = await proc.exited;
|
|
308
|
+
|
|
309
|
+
if (exitCode !== 0) {
|
|
310
|
+
throw new Error(`❌ Gradle failed with exit code ${exitCode}`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
logger.success("✅ Gradle build completed successfully");
|
|
314
|
+
} catch (error: any) {
|
|
315
|
+
logger.error(`❌ Failed to run Gradle: ${error.message}`);
|
|
316
|
+
|
|
317
|
+
// Fallback: try using cmd /c for Windows
|
|
318
|
+
if (process.platform === "win32") {
|
|
319
|
+
logger.info("🔄 Trying fallback method with cmd /c...");
|
|
320
|
+
try {
|
|
321
|
+
const cmd = `cd /d "${BUILD_DIR}" && "${gradleCmd}" assembleDebug --no-daemon`;
|
|
322
|
+
logger.info(`📝 Running: ${cmd}`);
|
|
323
|
+
|
|
324
|
+
const proc = Bun.spawn(["cmd", "/c", cmd], {
|
|
325
|
+
stdout: "inherit",
|
|
326
|
+
stderr: "inherit",
|
|
327
|
+
stdin: "inherit"
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
const exitCode = await proc.exited;
|
|
331
|
+
|
|
332
|
+
if (exitCode !== 0) {
|
|
333
|
+
throw new Error(`❌ Fallback also failed with exit code ${exitCode}`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
logger.success("✅ Gradle build completed with fallback method");
|
|
337
|
+
} catch (fallbackError: any) {
|
|
338
|
+
throw new Error(`❌ All Gradle build attempts failed: ${fallbackError.message}`);
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
throw error;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// 8️⃣ Cleanup Java processes if needed
|
|
342
346
|
try {
|
|
343
347
|
if (process.platform === "win32") {
|
|
344
|
-
execSync("taskkill /F /IM java.exe /T", { stdio: "ignore" });
|
|
348
|
+
execSync("taskkill /F /IM java.exe /T 2>nul", { stdio: "ignore" });
|
|
345
349
|
} else {
|
|
346
|
-
execSync("pkill -f java", { stdio: "ignore" });
|
|
350
|
+
execSync("pkill -f java 2>/dev/null", { stdio: "ignore" });
|
|
347
351
|
}
|
|
348
352
|
} catch {}
|
|
349
353
|
|
|
@@ -351,7 +355,6 @@ export async function buildAndroid(isDev = false) {
|
|
|
351
355
|
const APK_SRC = path.join(BUILD_DIR, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
|
|
352
356
|
const APK_DEST_DIR = path.join(PROJECT_ROOT, "build");
|
|
353
357
|
|
|
354
|
-
// FIX: Use existsSync check before mkdir
|
|
355
358
|
if (!existsSync(APK_DEST_DIR)) {
|
|
356
359
|
await fs.mkdir(APK_DEST_DIR, { recursive: true });
|
|
357
360
|
}
|
|
@@ -359,7 +362,14 @@ export async function buildAndroid(isDev = false) {
|
|
|
359
362
|
const APK_DEST = path.join(APK_DEST_DIR, `${APP_ID}-debug.apk`);
|
|
360
363
|
|
|
361
364
|
if (!existsSync(APK_SRC)) {
|
|
362
|
-
|
|
365
|
+
// Try alternative APK location
|
|
366
|
+
const altApkPath = path.join(BUILD_DIR, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
|
|
367
|
+
if (existsSync(altApkPath)) {
|
|
368
|
+
await fs.copyFile(altApkPath, APK_DEST);
|
|
369
|
+
logger.success(`✅ APK ready → ${APK_DEST}`);
|
|
370
|
+
return APK_DEST;
|
|
371
|
+
}
|
|
372
|
+
throw new Error(`❌ APK not found after build. Checked: ${APK_SRC}`);
|
|
363
373
|
}
|
|
364
374
|
|
|
365
375
|
await fs.copyFile(APK_SRC, APK_DEST);
|
package/index.ts
CHANGED
|
@@ -27,6 +27,7 @@ if (typeof window !== 'undefined') {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// Error Boundary Component
|
|
30
|
+
// Error Boundary Component - FIXED VERSION
|
|
30
31
|
export function ErrorBoundary({
|
|
31
32
|
children,
|
|
32
33
|
fallback,
|
|
@@ -35,6 +36,44 @@ export function ErrorBoundary({
|
|
|
35
36
|
children: VNode | VNode[];
|
|
36
37
|
fallback?: (error: Error, reset: () => void) => VNode;
|
|
37
38
|
onError?: (error: Error, errorInfo: { componentStack: string }) => void;
|
|
39
|
+
}): VNode | null {
|
|
40
|
+
// We need to use try-catch because hooks can also throw errors
|
|
41
|
+
try {
|
|
42
|
+
// Move the hook calls into a separate component
|
|
43
|
+
return ErrorBoundaryInner({ children, fallback, onError });
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// If hooks fail, render a simple fallback
|
|
46
|
+
const errorObj = error instanceof Error ? error : new Error(String(error));
|
|
47
|
+
if (fallback) {
|
|
48
|
+
return fallback(errorObj, () => window.location.reload());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return createElement(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
style: {
|
|
55
|
+
padding: '20px',
|
|
56
|
+
backgroundColor: '#f8d7da',
|
|
57
|
+
color: '#721c24',
|
|
58
|
+
border: '1px solid #f5c6cb',
|
|
59
|
+
borderRadius: '5px'
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
createElement("h3", {}, "Error Boundary Failed"),
|
|
63
|
+
createElement("pre", { style: { whiteSpace: 'pre-wrap' } }, errorObj.toString())
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Inner component that uses hooks
|
|
69
|
+
function ErrorBoundaryInner({
|
|
70
|
+
children,
|
|
71
|
+
fallback,
|
|
72
|
+
onError
|
|
73
|
+
}: {
|
|
74
|
+
children: VNode | VNode[];
|
|
75
|
+
fallback?: (error: Error, reset: () => void) => VNode;
|
|
76
|
+
onError?: (error: Error, errorInfo: { componentStack: string }) => void;
|
|
38
77
|
}): VNode | null {
|
|
39
78
|
const [error, setError] = useState<Error | null>(null);
|
|
40
79
|
const [errorInfo, setErrorInfo] = useState<{ componentStack: string } | null>(null);
|
|
@@ -44,21 +83,38 @@ export function ErrorBoundary({
|
|
|
44
83
|
setErrorInfo(null);
|
|
45
84
|
};
|
|
46
85
|
|
|
47
|
-
// Listen for global errors
|
|
48
86
|
useEffect(() => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
setError(
|
|
87
|
+
// Handle errors from children components
|
|
88
|
+
const handleError = (err: Error, componentStack?: string) => {
|
|
89
|
+
setError(err);
|
|
52
90
|
if (componentStack) {
|
|
53
91
|
setErrorInfo({ componentStack });
|
|
54
92
|
}
|
|
55
93
|
if (onError) {
|
|
56
|
-
onError(
|
|
94
|
+
onError(err, { componentStack: componentStack || '' });
|
|
57
95
|
}
|
|
58
96
|
};
|
|
59
|
-
|
|
97
|
+
|
|
98
|
+
// Store the previous handler
|
|
99
|
+
const previousHandler = globalErrorHandler;
|
|
100
|
+
globalErrorHandler = handleError;
|
|
101
|
+
|
|
102
|
+
// Also catch unhandled errors and promise rejections
|
|
103
|
+
const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
|
|
104
|
+
handleError(event.reason, 'Unhandled Promise Rejection');
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const handleUncaughtError = (event: ErrorEvent) => {
|
|
108
|
+
handleError(event.error, 'Uncaught Error');
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
window.addEventListener('unhandledrejection', handleUnhandledRejection);
|
|
112
|
+
window.addEventListener('error', handleUncaughtError);
|
|
113
|
+
|
|
60
114
|
return () => {
|
|
61
|
-
globalErrorHandler =
|
|
115
|
+
globalErrorHandler = previousHandler;
|
|
116
|
+
window.removeEventListener('unhandledrejection', handleUnhandledRejection);
|
|
117
|
+
window.removeEventListener('error', handleUncaughtError);
|
|
62
118
|
};
|
|
63
119
|
}, [onError]);
|
|
64
120
|
|
|
@@ -90,7 +146,7 @@ export function ErrorBoundary({
|
|
|
90
146
|
color: '#ff6b6b',
|
|
91
147
|
marginBottom: '20px',
|
|
92
148
|
fontSize: '24px'
|
|
93
|
-
} }, "⚠️
|
|
149
|
+
} }, "⚠️ Application Error"),
|
|
94
150
|
|
|
95
151
|
createElement("div", { style: {
|
|
96
152
|
backgroundColor: '#2a2a2a',
|
|
@@ -838,7 +894,7 @@ export function render(element: VNode, container: Node): void {
|
|
|
838
894
|
wipRoot = {
|
|
839
895
|
dom: container,
|
|
840
896
|
props: {
|
|
841
|
-
children: [element],
|
|
897
|
+
children: isDev ? [createElement(ErrorBoundary, {}, element)] : [element],
|
|
842
898
|
},
|
|
843
899
|
alternate: currentRoot,
|
|
844
900
|
};
|
|
@@ -2237,10 +2293,4 @@ Object.defineProperty(window, "Vader", {
|
|
|
2237
2293
|
configurable: false,
|
|
2238
2294
|
});
|
|
2239
2295
|
|
|
2240
|
-
|
|
2241
|
-
const originalRender = Vader.render;
|
|
2242
|
-
Vader.render = function(element: VNode, container: Node) {
|
|
2243
|
-
// Wrap in error boundary in dev mode
|
|
2244
|
-
renderWithErrorBoundary(element, container);
|
|
2245
|
-
};
|
|
2246
|
-
}
|
|
2296
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vaderjs-native",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"binaryVersion":"1.0.26",
|
|
3
|
+
"version": "1.0.32",
|
|
4
|
+
"binaryVersion": "1.0.26",
|
|
5
5
|
"description": "Build Native Applications using Vaderjs framework.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"vaderjs": "./main.ts"
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"url": "https://github.com/Postr-Inc/Vaderjs-Native"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"dependencies": {
|
|
14
|
+
"dependencies": {
|
|
15
15
|
"vaderjs-types": "latest",
|
|
16
|
-
"extract-zip":"latest"
|
|
17
|
-
}
|
|
16
|
+
"extract-zip": "latest"
|
|
17
|
+
}
|
|
18
18
|
}
|