Skip to content

Commit 5d5810c

Browse files
feat(Sky): Add synchronous preload and async IIFE error surfacing
Improve Electron workbench loading reliability with three changes: 1. WindPreload: Convert Install() from fire-and-forget (.then chain) to top-level await, ensuring the preload polyfills complete before Layout.astro proceeds to Polyfills.js 2. Workbench.ts: Add pre-flight checks logging window.vscode, __TAURI__, _VSCODE_FILE_ROOT, and _VSCODE_USE_RELATIVE_IMPORTS. Add diagnostic polling at 2s/5s/10s/20s intervals to detect if the workbench renders successfully or silently fails. 3. astro.config.ts: Refactor Step 7 to use ESM wrapper approach (copy file + 1-line re-export) instead of content replacement. Add Step 8 to prepend global error listeners to workbench.js, catching unhandledrejection and error events from the async IIFE that runs in the background. The async IIFE in workbench.js does not await result.main(configuration), so boot errors were silently swallowed. Step 8 surfaces these errors through console.error for debugging.
1 parent 1352ef6 commit 5d5810c

3 files changed

Lines changed: 207 additions & 73 deletions

File tree

Source/Workbench/Electron/WindPreload.ts

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,54 @@
88
import Install from "@codeeditorland/wind/Target/Function/Install";
99

1010
console.log("[Electron] ===== Starting Wind preload installation =====");
11+
1112
console.log("[Electron] Workbench: Electron (A3)");
13+
1214
console.log(
1315
"[Electron] Approach: Electron workbench + complete Electron API polyfills",
1416
);
1517

16-
// Install the Wind preload polyfill (window.vscode globals)
17-
Install()
18-
.then(() => {
19-
console.log("[Electron] ✓ Wind preload installed successfully");
20-
21-
// Verify preloadGlobals is available
22-
if (window.preloadGlobals && window.preloadGlobals.process) {
23-
console.log("[Electron] ✓ preloadGlobals.process is available");
24-
const process = window.preloadGlobals.process;
25-
console.log("[Electron] - Platform:", process.platform);
26-
console.log("[Electron] - Arch:", process.arch);
27-
console.log("[Electron] - Type:", process.type);
28-
} else {
29-
console.warn("[Electron] ⚠ preloadGlobals.process not available");
30-
}
31-
32-
// Verify window.vscode is available
33-
if (window.vscode) {
34-
console.log("[Electron] ✓ window.vscode is available");
35-
console.log(
36-
"[Electron] - ipcRenderer:",
37-
typeof window.vscode.ipcRenderer,
38-
);
39-
console.log("[Electron] - process:", typeof window.vscode.process);
40-
console.log("[Electron] - context:", typeof window.vscode.context);
41-
} else {
42-
console.error("[Electron] ✗ window.vscode not available");
43-
}
44-
45-
// Verify Wind preload ready flag
46-
if (window.__WIND_PRELOAD_READY__) {
47-
console.log("[Electron] ✓ Wind preload ready flag is set");
48-
} else {
49-
console.warn("[Electron] ⚠ Wind preload ready flag is not set");
50-
}
18+
// Install the Wind preload polyfill (window.vscode globals).
19+
// Top-level await ensures Install() completes before Layout.astro
20+
// proceeds to Polyfills.js — the .then() chain was fire-and-forget.
21+
try {
22+
await Install();
23+
24+
console.log("[Electron] Wind preload installed successfully");
25+
26+
if (window.preloadGlobals?.process) {
27+
const Process = window.preloadGlobals.process;
28+
29+
console.log(
30+
"[Electron] preloadGlobals.process:",
31+
Process.platform,
32+
Process.arch,
33+
Process.type,
34+
);
35+
} else {
36+
console.warn("[Electron] preloadGlobals.process not available");
37+
}
5138

39+
if (window.vscode) {
5240
console.log(
53-
"[Electron] ===== Wind preload installation complete =====",
41+
"[Electron] window.vscode: ipcRenderer=%s process=%s context=%s",
42+
typeof window.vscode.ipcRenderer,
43+
typeof window.vscode.process,
44+
typeof window.vscode.context,
5445
);
55-
})
56-
.catch((error: unknown) => {
57-
console.error("[Electron] ✗ Wind preload install error:", error);
58-
});
46+
} else {
47+
console.error("[Electron] window.vscode not available");
48+
}
49+
50+
if (!window.__WIND_PRELOAD_READY__) {
51+
console.warn("[Electron] __WIND_PRELOAD_READY__ flag not set");
52+
}
53+
54+
console.log("[Electron] ===== Wind preload installation complete =====");
55+
} catch (Error: unknown) {
56+
console.error("[Electron] Wind preload install error:", Error);
57+
58+
if (Error instanceof globalThis.Error && Error.stack) {
59+
console.error(Error.stack);
60+
}
61+
}

Source/Workbench/Electron/Workbench.ts

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,115 @@
1616
* The electron-browser files are only available when Electron=true in the
1717
* build profile (debug-electron), which un-excludes electron-browser paths
1818
* in Output's ESBuild Exclude/Electron.ts and Exclude/Bootstrap.ts.
19+
*
20+
* IMPORTANT: workbench.js is an async IIFE (async function() { ... })().
21+
* The import() resolves after the IIFE STARTS, not after it completes.
22+
* The IIFE runs in the background — its errors are surfaced by Step 8's
23+
* unhandledrejection listener (patched into workbench.js by astro.config.ts).
1924
*/
2025

2126
console.log("[Electron] ===== Loading Electron VSCode workbench =====");
27+
28+
// Pre-flight: verify prerequisites
29+
console.log("[Electron] Pre-flight checks:");
30+
31+
console.log("[Electron] window.vscode:", typeof (window as any).vscode);
32+
33+
console.log(
34+
"[Electron] window.vscode.context:",
35+
typeof (window as any).vscode?.context,
36+
);
37+
38+
console.log(
39+
"[Electron] window.vscode.ipcRenderer:",
40+
typeof (window as any).vscode?.ipcRenderer,
41+
);
42+
43+
console.log(
44+
"[Electron] window.vscode.process:",
45+
typeof (window as any).vscode?.process,
46+
);
47+
48+
console.log("[Electron] window.__TAURI__:", typeof (window as any).__TAURI__);
49+
50+
console.log(
51+
"[Electron] _VSCODE_FILE_ROOT:",
52+
(globalThis as any)._VSCODE_FILE_ROOT,
53+
);
54+
55+
console.log(
56+
"[Electron] _VSCODE_USE_RELATIVE_IMPORTS:",
57+
(globalThis as any)._VSCODE_USE_RELATIVE_IMPORTS,
58+
);
59+
2260
console.log(
23-
"[Electron] Workbench: vs/code/electron-browser/workbench/workbench.js",
61+
"[Electron] VSCODE_DEV:",
62+
(window as any).vscode?.process?.env?.VSCODE_DEV,
2463
);
2564

2665
try {
2766
const WorkbenchUrl =
2867
"/Static/Application/vs/code/electron-browser/workbench/workbench.js";
2968

3069
console.log("[Electron] Importing:", WorkbenchUrl);
70+
3171
await import(/* @vite-ignore */ WorkbenchUrl);
3272

33-
console.log("[Electron] Workbench script loaded successfully");
34-
console.log("[Electron] ===== Workbench load complete =====");
73+
// The import() resolved — the IIFE has STARTED (not completed).
74+
// workbench.js runs: resolveConfiguration → load(workbench.desktop.main.js) → main(config)
75+
// All of that happens asynchronously. Step 8's error listeners surface any failures.
76+
console.log(
77+
"[Electron] Workbench module imported (IIFE running in background)",
78+
);
79+
80+
// Diagnostic: poll for workbench render state.
81+
// This helps identify whether the IIFE completes or silently dies.
82+
const CheckIntervals = [2000, 5000, 10000, 20000];
83+
84+
for (const Delay of CheckIntervals) {
85+
setTimeout(() => {
86+
const HasSplash = !!document.getElementById("monaco-parts-splash");
87+
88+
const HasWorkbench = !!document.querySelector(".monaco-workbench");
89+
90+
const HasShellColors = !!document.querySelector(
91+
".initialShellColors",
92+
);
93+
94+
if (HasWorkbench) {
95+
console.log(
96+
`[Electron] +${Delay}ms: Workbench rendered successfully`,
97+
);
98+
} else {
99+
console.warn(
100+
`[Electron] +${Delay}ms: Workbench NOT rendered (splash=${HasSplash}, shellColors=${HasShellColors})`,
101+
);
102+
103+
if (Delay === CheckIntervals[CheckIntervals.length - 1]) {
104+
console.error(
105+
"[Electron] Workbench did not render within %dms. Check console for errors above.",
106+
Delay,
107+
);
108+
}
109+
}
110+
}, Delay);
111+
}
35112
} catch (Error: unknown) {
36113
console.error("[Electron] Failed to load Electron workbench:", Error);
37114

38115
if (Error instanceof TypeError && String(Error).includes("MIME")) {
39116
console.error(
40117
"[Electron] MIME error: the file may not exist in Target/Static/Application/vs/",
41118
);
119+
42120
console.error(
43121
"[Electron] Ensure Electron=true is set and CopyVSCodeAssets copies electron-browser/",
44122
);
45123
}
46-
}
47124

48-
console.log("[Electron] ===== Workbench load sequence complete =====");
125+
if (Error instanceof globalThis.Error && Error.stack) {
126+
console.error(Error.stack);
127+
}
128+
}
49129

50130
export default {};

0 commit comments

Comments
 (0)