sparkbun 0.1.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 (131) hide show
  1. package/bin/sparkbun.cjs +18 -0
  2. package/dist-linux-arm64/bsdiff +0 -0
  3. package/dist-linux-arm64/bspatch +0 -0
  4. package/dist-linux-arm64/libElectrobunCore.so +0 -0
  5. package/dist-linux-arm64/libNativeWrapper.so +0 -0
  6. package/dist-linux-arm64/libasar.so +0 -0
  7. package/dist-linux-x64/bsdiff +0 -0
  8. package/dist-linux-x64/bspatch +0 -0
  9. package/dist-linux-x64/libElectrobunCore.so +0 -0
  10. package/dist-linux-x64/libNativeWrapper.so +0 -0
  11. package/dist-linux-x64/libasar.so +0 -0
  12. package/dist-macos-arm64/bsdiff +0 -0
  13. package/dist-macos-arm64/bspatch +0 -0
  14. package/dist-macos-arm64/libElectrobunCore.dylib +0 -0
  15. package/dist-macos-arm64/libNativeWrapper.dylib +0 -0
  16. package/dist-macos-arm64/libasar.dylib +0 -0
  17. package/dist-macos-arm64/libwebgpu_dawn.dylib +0 -0
  18. package/dist-macos-arm64/preload-full.js +885 -0
  19. package/dist-macos-arm64/preload-sandboxed.js +111 -0
  20. package/dist-macos-arm64/process_helper +0 -0
  21. package/dist-win-x64/ElectrobunCore.dll +0 -0
  22. package/dist-win-x64/WebView2Loader.dll +0 -0
  23. package/dist-win-x64/bsdiff.exe +0 -0
  24. package/dist-win-x64/bspatch.exe +0 -0
  25. package/dist-win-x64/libNativeWrapper.dll +0 -0
  26. package/dist-win-x64/zig-asar/arm64/libasar.dll +0 -0
  27. package/dist-win-x64/zig-asar/x64/libasar.dll +0 -0
  28. package/package.json +47 -0
  29. package/scripts/build-and-upload-artifacts.js +207 -0
  30. package/scripts/gen-webgpu-ffi.mjs +162 -0
  31. package/scripts/install-windows-deps.ps1 +80 -0
  32. package/scripts/package-release.js +237 -0
  33. package/scripts/push-version.js +84 -0
  34. package/scripts/update-bun-version.ts +122 -0
  35. package/scripts/update-cef-version.ts +145 -0
  36. package/src/browser/builtinrpcSchema.ts +19 -0
  37. package/src/browser/global.d.ts +36 -0
  38. package/src/browser/index.ts +234 -0
  39. package/src/browser/webviewtag.ts +88 -0
  40. package/src/browser/wgputag.ts +48 -0
  41. package/src/bun/SparkBunConfig.ts +497 -0
  42. package/src/bun/__tests__/ffi-contract.test.ts +105 -0
  43. package/src/bun/core/ApplicationMenu.ts +70 -0
  44. package/src/bun/core/BrowserView.ts +416 -0
  45. package/src/bun/core/BrowserWindow.ts +396 -0
  46. package/src/bun/core/BuildConfig.ts +71 -0
  47. package/src/bun/core/ContextMenu.ts +75 -0
  48. package/src/bun/core/GpuWindow.ts +289 -0
  49. package/src/bun/core/Paths.ts +5 -0
  50. package/src/bun/core/Socket.ts +22 -0
  51. package/src/bun/core/Tray.ts +197 -0
  52. package/src/bun/core/Updater.ts +1131 -0
  53. package/src/bun/core/Utils.ts +487 -0
  54. package/src/bun/core/WGPUView.ts +167 -0
  55. package/src/bun/core/menuRoles.ts +181 -0
  56. package/src/bun/events/ApplicationEvents.ts +22 -0
  57. package/src/bun/events/event.ts +27 -0
  58. package/src/bun/events/eventEmitter.ts +45 -0
  59. package/src/bun/events/trayEvents.ts +11 -0
  60. package/src/bun/events/webviewEvents.ts +39 -0
  61. package/src/bun/events/windowEvents.ts +23 -0
  62. package/src/bun/index.ts +120 -0
  63. package/src/bun/preload/.generated/compiled.ts +2 -0
  64. package/src/bun/preload/build.ts +65 -0
  65. package/src/bun/preload/dragRegions.ts +41 -0
  66. package/src/bun/preload/encryption.ts +86 -0
  67. package/src/bun/preload/events.ts +171 -0
  68. package/src/bun/preload/globals.d.ts +45 -0
  69. package/src/bun/preload/index-sandboxed.ts +28 -0
  70. package/src/bun/preload/index.ts +77 -0
  71. package/src/bun/preload/internalRpc.ts +80 -0
  72. package/src/bun/preload/overlaySync.ts +107 -0
  73. package/src/bun/preload/webviewTag.ts +451 -0
  74. package/src/bun/preload/wgpuTag.ts +246 -0
  75. package/src/bun/proc/linux.md +43 -0
  76. package/src/bun/proc/native.ts +3253 -0
  77. package/src/bun/webGPU.ts +346 -0
  78. package/src/bun/webgpuAdapter.ts +3011 -0
  79. package/src/cli/bun.lockb +0 -0
  80. package/src/cli/index.ts +4653 -0
  81. package/src/cli/package-lock.json +81 -0
  82. package/src/cli/package.json +11 -0
  83. package/src/cli/templates/embedded.ts +2 -0
  84. package/src/core/build.zig +16 -0
  85. package/src/core/main.zig +3378 -0
  86. package/src/extractor/build.zig +22 -0
  87. package/src/installer/installer-template.ts +216 -0
  88. package/src/launcher/main.ts +221 -0
  89. package/src/native/build/libNativeWrapper.so +0 -0
  90. package/src/native/linux/build/nativeWrapper.o +0 -0
  91. package/src/native/linux/cef_loader.cpp +110 -0
  92. package/src/native/linux/cef_loader.h +28 -0
  93. package/src/native/linux/cef_process_helper_linux.cpp +160 -0
  94. package/src/native/linux/nativeWrapper.cpp +11768 -0
  95. package/src/native/macos/cef_process_helper_mac.cc +160 -0
  96. package/src/native/macos/nativeWrapper.mm +9172 -0
  97. package/src/native/shared/accelerator_parser.h +72 -0
  98. package/src/native/shared/app_paths.h +110 -0
  99. package/src/native/shared/asar.h +35 -0
  100. package/src/native/shared/cache_migration.h +244 -0
  101. package/src/native/shared/callbacks.h +57 -0
  102. package/src/native/shared/cef_response_filter.h +189 -0
  103. package/src/native/shared/chromium_flags.h +181 -0
  104. package/src/native/shared/config.h +66 -0
  105. package/src/native/shared/download_event.h +197 -0
  106. package/src/native/shared/ffi_helpers.h +139 -0
  107. package/src/native/shared/glob_match.h +59 -0
  108. package/src/native/shared/json_menu_parser.h +223 -0
  109. package/src/native/shared/mime_types.h +101 -0
  110. package/src/native/shared/navigation_rules.h +98 -0
  111. package/src/native/shared/partition_context.h +137 -0
  112. package/src/native/shared/pending_resize_queue.h +45 -0
  113. package/src/native/shared/permissions.h +118 -0
  114. package/src/native/shared/permissions_cef.h +74 -0
  115. package/src/native/shared/preload_script.h +71 -0
  116. package/src/native/shared/shutdown_guard.h +134 -0
  117. package/src/native/shared/thread_safe_map.h +138 -0
  118. package/src/native/shared/webview_storage.h +91 -0
  119. package/src/native/win/cef_process_helper_win.cpp +143 -0
  120. package/src/native/win/dcomp_compositor.h +352 -0
  121. package/src/native/win/nativeWrapper.cpp +12434 -0
  122. package/src/npmbin/index.js +34 -0
  123. package/src/shared/bun-version.ts +3 -0
  124. package/src/shared/cef-version.ts +5 -0
  125. package/src/shared/naming.test.ts +327 -0
  126. package/src/shared/naming.ts +188 -0
  127. package/src/shared/platform.ts +48 -0
  128. package/src/shared/rpc.ts +541 -0
  129. package/src/shared/sparkbun-version.ts +2 -0
  130. package/src/types/three.d.ts +1 -0
  131. package/tsconfig.json +31 -0
@@ -0,0 +1,237 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { execSync } from "child_process";
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import { fileURLToPath } from "url";
7
+ import process from "process";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+
12
+ const platform = process.platform;
13
+ const arch = process.arch;
14
+
15
+ // Map Node.js platform/arch to our naming
16
+ const platformMap = {
17
+ darwin: "darwin",
18
+ linux: "linux",
19
+ win32: "win",
20
+ };
21
+
22
+ const archMap = {
23
+ x64: "x64",
24
+ arm64: "arm64",
25
+ };
26
+
27
+ const platformName = platformMap[platform] || platform;
28
+ // Always use x64 for Windows since we only build x64 Windows binaries
29
+ const archName = platform === "win32" ? "x64" : archMap[arch] || arch;
30
+
31
+ console.log(`Packaging Electrobun for ${platformName}-${archName}...`);
32
+
33
+ // Build everything including CLI (no CI mode needed)
34
+ console.log("Building full release...");
35
+ try {
36
+ execSync("bun build.ts --release", { stdio: "inherit" });
37
+ } catch (error) {
38
+ console.error("Build failed:", error.message);
39
+ process.exit(1);
40
+ }
41
+
42
+ // Generate template embeddings before building CLI
43
+ console.log("Generating template embeddings...");
44
+ const templatesDir = path.join(__dirname, "..", "..", "templates");
45
+ const outputFile = path.join(
46
+ __dirname,
47
+ "..",
48
+ "src",
49
+ "cli",
50
+ "templates",
51
+ "embedded.ts",
52
+ );
53
+
54
+ // Ensure the templates directory exists for embedded.ts
55
+ const templatesOutputDir = path.dirname(outputFile);
56
+ if (!fs.existsSync(templatesOutputDir)) {
57
+ fs.mkdirSync(templatesOutputDir, { recursive: true });
58
+ }
59
+
60
+ // Verify that embedded.ts was created by build.ts, or create a minimal one
61
+ if (!fs.existsSync(outputFile)) {
62
+ console.log("embedded.ts not found after build, creating minimal version...");
63
+ fs.writeFileSync(
64
+ outputFile,
65
+ `// Auto-generated template embeddings
66
+ export const templates: Record<string, { name: string; files: Record<string, string> }> = {};
67
+
68
+ export function getTemplate(name: string) {
69
+ return templates[name];
70
+ }
71
+
72
+ export function getTemplateNames(): string[] {
73
+ return Object.keys(templates);
74
+ }
75
+ `,
76
+ );
77
+ } else {
78
+ // If templates exist, run the generation through build.ts
79
+ console.log("Templates found, generating embeddings...");
80
+ // This is already done by the build.ts --release command above
81
+ }
82
+
83
+ // Build CLI binary
84
+ console.log("Building CLI binary...");
85
+ if (!fs.existsSync("bin")) {
86
+ fs.mkdirSync("bin", { recursive: true });
87
+ }
88
+
89
+ // Use baseline target for Windows to ensure compatibility with ARM64 emulation
90
+ const compileTarget =
91
+ platform === "win32" ? "--target=bun-windows-x64-baseline" : "";
92
+ const vendoredBun = path.join(
93
+ "vendors",
94
+ "bun",
95
+ platform === "win32" ? "bun.exe" : "bun",
96
+ );
97
+
98
+ // Workaround for Windows 2025 runner cross-drive issues with Bun cache
99
+ if (platform === "win32" && process.env.GITHUB_ACTIONS) {
100
+ // Set Bun cache to same drive as workspace
101
+ const workspaceDrive = process.cwd().substring(0, 2);
102
+ const bunCacheDir = `${workspaceDrive}\\temp\\bun-cache`;
103
+ console.log(`Setting BUN_INSTALL_CACHE_DIR to: ${bunCacheDir}`);
104
+
105
+ // Ensure cache directory exists
106
+ fs.mkdirSync(bunCacheDir, { recursive: true });
107
+
108
+ // Set environment variable directly in the command for Windows
109
+ execSync(
110
+ `set "BUN_INSTALL_CACHE_DIR=${bunCacheDir}" && "${vendoredBun}" build src/cli/index.ts --compile ${compileTarget} --outfile bin/electrobun`,
111
+ { stdio: "inherit", shell: true },
112
+ );
113
+ } else {
114
+ execSync(
115
+ `"${vendoredBun}" build src/cli/index.ts --compile ${compileTarget} --outfile bin/electrobun`,
116
+ { stdio: "inherit" },
117
+ );
118
+ }
119
+
120
+ // Create separate tarballs for CLI, core binaries, and CEF
121
+ const distPath = path.join(__dirname, "..", "dist");
122
+ const cliOutputFile = path.join(
123
+ __dirname,
124
+ "..",
125
+ `electrobun-cli-${platformName}-${archName}.tar.gz`,
126
+ );
127
+ const coreOutputFile = path.join(
128
+ __dirname,
129
+ "..",
130
+ `electrobun-core-${platformName}-${archName}.tar.gz`,
131
+ );
132
+ const cefOutputFile = path.join(
133
+ __dirname,
134
+ "..",
135
+ `electrobun-cef-${platformName}-${archName}.tar.gz`,
136
+ );
137
+
138
+ console.log(`Creating CLI tarball: ${cliOutputFile}`);
139
+
140
+ // Check if dist exists
141
+ if (!fs.existsSync(distPath)) {
142
+ console.error("Error: dist directory not found");
143
+ process.exit(1);
144
+ }
145
+
146
+ // Create a tar.gz file using system tar (preserves file permissions)
147
+ function createTarGz(tarGzPath, cwd, entries) {
148
+ execSync(
149
+ `tar -czf "${tarGzPath}" ${entries.map((e) => `"${e}"`).join(" ")}`,
150
+ {
151
+ cwd,
152
+ stdio: "pipe",
153
+ },
154
+ );
155
+ }
156
+
157
+ async function createTarballs() {
158
+ // Validate that we have platform-specific binaries, not just npm files
159
+ const expectedBinaries = [
160
+ platform === "win32" ? "electrobun.exe" : "electrobun",
161
+ platform === "win32" ? "bun.exe" : "bun",
162
+ ];
163
+
164
+ const missingBinaries = expectedBinaries.filter(
165
+ (binary) => !fs.existsSync(path.join(distPath, binary)),
166
+ );
167
+
168
+ if (missingBinaries.length > 0) {
169
+ console.error(
170
+ `Error: Missing expected binaries in dist/: ${missingBinaries.join(", ")}`,
171
+ );
172
+ console.error("This suggests the build failed or was incomplete.");
173
+ console.error("Contents of dist/:");
174
+ if (fs.existsSync(distPath)) {
175
+ fs.readdirSync(distPath).forEach((file) => console.error(` ${file}`));
176
+ } else {
177
+ console.error(" (dist directory does not exist)");
178
+ }
179
+ process.exit(1);
180
+ }
181
+
182
+ console.log("Validation passed: Found expected platform binaries in dist/");
183
+
184
+ // 1. Create CLI-only tarball
185
+ const binPath = path.join(__dirname, "..", "bin");
186
+ const cliSrc = path.join(
187
+ binPath,
188
+ "electrobun" + (platform === "win32" ? ".exe" : ""),
189
+ );
190
+
191
+ if (fs.existsSync(cliSrc)) {
192
+ console.log(`Creating CLI tarball: ${cliOutputFile}`);
193
+
194
+ // Create CLI tarball directly from bin directory (system tar preserves permissions)
195
+ createTarGz(cliOutputFile, binPath, [
196
+ "electrobun" + (platform === "win32" ? ".exe" : ""),
197
+ ]);
198
+
199
+ const cliStats = fs.statSync(cliOutputFile);
200
+ const cliSizeMB = (cliStats.size / 1024 / 1024).toFixed(2);
201
+ console.log(`CLI tarball size: ${cliSizeMB} MB`);
202
+ }
203
+
204
+ // 2. Create core binaries tarball (exclude CEF and CLI)
205
+ const coreFiles = fs
206
+ .readdirSync(distPath)
207
+ .filter((file) => file !== "cef" && !file.startsWith("electrobun"));
208
+
209
+ if (coreFiles.length > 0) {
210
+ console.log(`Creating core binaries tarball: ${coreOutputFile}`);
211
+
212
+ createTarGz(coreOutputFile, distPath, coreFiles);
213
+
214
+ const coreStats = fs.statSync(coreOutputFile);
215
+ const coreSizeMB = (coreStats.size / 1024 / 1024).toFixed(2);
216
+ console.log(`Core binaries tarball size: ${coreSizeMB} MB`);
217
+ }
218
+
219
+ // 3. Create CEF tarball if CEF directory exists
220
+ const cefPath = path.join(distPath, "cef");
221
+ if (fs.existsSync(cefPath)) {
222
+ console.log(`Creating CEF tarball: ${cefOutputFile}`);
223
+
224
+ createTarGz(cefOutputFile, distPath, ["cef"]);
225
+
226
+ const cefStats = fs.statSync(cefOutputFile);
227
+ const cefSizeMB = (cefStats.size / 1024 / 1024).toFixed(2);
228
+ console.log(`CEF tarball size: ${cefSizeMB} MB`);
229
+ } else {
230
+ console.log("No CEF directory found, skipping CEF tarball");
231
+ }
232
+ }
233
+
234
+ createTarballs().catch((err) => {
235
+ console.error("Error creating tarballs:", err);
236
+ process.exit(1);
237
+ });
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Version bump, commit, tag, and push script
4
+ *
5
+ * Usage: bun scripts/push-version.js <type>
6
+ *
7
+ * Types:
8
+ * beta - prerelease bump (0.5.0-beta.0 -> 0.5.0-beta.1)
9
+ * patch - prepatch bump (0.5.0-beta.0 -> 0.5.1-beta.0)
10
+ * minor - preminor bump (0.5.0-beta.0 -> 0.6.0-beta.0)
11
+ * major - premajor bump (0.5.0-beta.0 -> 1.0.0-beta.0)
12
+ * stable - patch bump without beta (0.5.0 -> 0.5.1)
13
+ */
14
+
15
+ import { execSync } from "child_process";
16
+ import { readFileSync, writeFileSync } from "fs";
17
+ import { join } from "path";
18
+
19
+ const type = process.argv[2];
20
+
21
+ if (!type || !["beta", "patch", "minor", "major", "stable"].includes(type)) {
22
+ console.error(
23
+ "Usage: bun scripts/push-version.js <beta|patch|minor|major|stable>",
24
+ );
25
+ process.exit(1);
26
+ }
27
+
28
+ const packageDir = import.meta.dir.replace("/scripts", "");
29
+ const repoRoot = join(packageDir, "..");
30
+ const packageJsonPath = join(packageDir, "package.json");
31
+
32
+ // Read current version
33
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
34
+ const currentVersion = packageJson.version;
35
+
36
+ // Determine npm version command
37
+ const versionCmd = {
38
+ beta: "prerelease --preid=beta",
39
+ patch: "prepatch --preid=beta",
40
+ minor: "preminor --preid=beta",
41
+ major: "premajor --preid=beta",
42
+ stable: "patch",
43
+ }[type];
44
+
45
+ console.log(`Current version: ${currentVersion}`);
46
+ console.log(`Running: npm version ${versionCmd}`);
47
+
48
+ // Bump version (without git operations)
49
+ execSync(`npm version ${versionCmd} --no-git-tag-version`, {
50
+ cwd: packageDir,
51
+ stdio: "inherit",
52
+ });
53
+
54
+ // Read new version
55
+ const updatedPackageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
56
+ const newVersion = updatedPackageJson.version;
57
+ const tagName = `v${newVersion}`;
58
+
59
+ console.log(`New version: ${newVersion}`);
60
+
61
+ // Update kitchen sink version to match
62
+ const kitchenConfigPath = join(repoRoot, "kitchen", "electrobun.config.ts");
63
+ let kitchenConfig = readFileSync(kitchenConfigPath, "utf-8");
64
+ kitchenConfig = kitchenConfig.replace(
65
+ /version:\s*["'].*["']/,
66
+ `version: "${newVersion}"`,
67
+ );
68
+ writeFileSync(kitchenConfigPath, kitchenConfig);
69
+ console.log(`Updated kitchen/electrobun.config.ts version to ${newVersion}`);
70
+
71
+ // Git operations from repo root
72
+ console.log(`Creating commit and tag: ${tagName}`);
73
+
74
+ execSync(`git add package/package.json kitchen/electrobun.config.ts`, {
75
+ cwd: repoRoot,
76
+ stdio: "inherit",
77
+ });
78
+ execSync(`git commit -m "${tagName}"`, { cwd: repoRoot, stdio: "inherit" });
79
+ execSync(`git tag ${tagName}`, { cwd: repoRoot, stdio: "inherit" });
80
+
81
+ console.log(`Pushing to origin...`);
82
+ execSync(`git push origin main --tags`, { cwd: repoRoot, stdio: "inherit" });
83
+
84
+ console.log(`\n✓ Successfully pushed ${tagName}`);
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Checks GitHub for the latest stable Bun release and compares it
5
+ * with the version in src/shared/bun-version.ts.
6
+ *
7
+ * When a newer version exists:
8
+ * - Overwrites src/shared/bun-version.ts with the new version
9
+ * - Sets has_update=true in $GITHUB_OUTPUT
10
+ *
11
+ * Always outputs version info to $GITHUB_OUTPUT and a human-readable
12
+ * summary to $GITHUB_STEP_SUMMARY.
13
+ */
14
+
15
+ import { BUN_VERSION } from "../src/shared/bun-version";
16
+ import { appendFileSync, writeFileSync } from "fs";
17
+ import { resolve } from "path";
18
+
19
+ const BUN_RELEASES_URL =
20
+ "https://api.github.com/repos/oven-sh/bun/releases/latest";
21
+
22
+ async function getLatestStableBunVersion(): Promise<string> {
23
+ const headers: Record<string, string> = {
24
+ Accept: "application/vnd.github+json",
25
+ "X-GitHub-Api-Version": "2022-11-28",
26
+ };
27
+ const token = process.env["GITHUB_TOKEN"];
28
+ if (token) {
29
+ headers["Authorization"] = `Bearer ${token}`;
30
+ }
31
+
32
+ const response = await fetch(BUN_RELEASES_URL, { headers });
33
+ if (!response.ok) {
34
+ throw new Error(
35
+ `Failed to fetch Bun latest release: HTTP ${response.status}`,
36
+ );
37
+ }
38
+
39
+ const data = (await response.json()) as { tag_name?: string };
40
+ if (!data.tag_name) {
41
+ throw new Error("No tag_name in Bun latest release response");
42
+ }
43
+
44
+ // Bun release tags look like "bun-v1.3.11" — strip the prefix.
45
+ const match = /^bun-v(.+)$/.exec(data.tag_name);
46
+ if (!match) {
47
+ throw new Error(`Unexpected Bun release tag format: ${data.tag_name}`);
48
+ }
49
+
50
+ return match[1]!;
51
+ }
52
+
53
+ function setOutput(key: string, value: string) {
54
+ const outputFile = process.env["GITHUB_OUTPUT"];
55
+ if (outputFile) {
56
+ appendFileSync(outputFile, `${key}=${value}\n`);
57
+ }
58
+ }
59
+
60
+ function writeSummary(markdown: string) {
61
+ const summaryFile = process.env["GITHUB_STEP_SUMMARY"];
62
+ if (summaryFile) {
63
+ appendFileSync(summaryFile, markdown + "\n");
64
+ }
65
+ }
66
+
67
+ async function main() {
68
+ const currentBun = BUN_VERSION;
69
+ console.log(`Current: Bun ${currentBun}`);
70
+
71
+ const latest = await getLatestStableBunVersion();
72
+ console.log(`Latest: Bun ${latest}`);
73
+
74
+ const hasUpdate = currentBun !== latest;
75
+
76
+ setOutput("current_bun_version", currentBun);
77
+ setOutput("latest_bun_version", latest);
78
+ setOutput("has_update", hasUpdate ? "true" : "false");
79
+
80
+ if (hasUpdate) {
81
+ console.log("Version mismatch — updating src/shared/bun-version.ts");
82
+
83
+ const bunVersionPath = resolve(
84
+ import.meta.dir,
85
+ "../src/shared/bun-version.ts",
86
+ );
87
+ const newContent = [
88
+ "// Default Bun version shipped with this Electrobun release.",
89
+ "// All platforms use the same version. Update this when bumping Bun.",
90
+ `export const BUN_VERSION = "${latest}";`,
91
+ "",
92
+ ].join("\n");
93
+ writeFileSync(bunVersionPath, newContent);
94
+ console.log(`Wrote ${bunVersionPath}`);
95
+ } else {
96
+ console.log("Bun version is up to date.");
97
+ }
98
+
99
+ const summary = hasUpdate
100
+ ? [
101
+ "## Bun Compatibility Check",
102
+ "",
103
+ `| | Bun |`,
104
+ `|---|---|`,
105
+ `| **Current** | \`${currentBun}\` |`,
106
+ `| **Latest** | \`${latest}\` |`,
107
+ "",
108
+ "New version detected — build step will run.",
109
+ ].join("\n")
110
+ : [
111
+ "## Bun Compatibility Check",
112
+ "",
113
+ `Bun \`${currentBun}\` is the latest stable version. No build needed.`,
114
+ ].join("\n");
115
+
116
+ writeSummary(summary);
117
+ }
118
+
119
+ main().catch((err) => {
120
+ console.error("Error checking Bun version:", err);
121
+ process.exit(1);
122
+ });
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Checks Spotify CDN for the latest stable CEF version and compares it
5
+ * with the version in src/shared/cef-version.ts.
6
+ *
7
+ * When a newer version exists:
8
+ * - Overwrites src/shared/cef-version.ts with the new version pair
9
+ * - Sets has_update=true in $GITHUB_OUTPUT
10
+ *
11
+ * Always outputs version info to $GITHUB_OUTPUT and a human-readable
12
+ * summary to $GITHUB_STEP_SUMMARY.
13
+ */
14
+
15
+ import { CEF_VERSION, CHROMIUM_VERSION } from "../src/shared/cef-version";
16
+ import { appendFileSync, writeFileSync } from "fs";
17
+ import { resolve } from "path";
18
+
19
+ const CEF_INDEX_URL =
20
+ "https://cef-builds.spotifycdn.com/index.json";
21
+
22
+ interface StableVersion {
23
+ cef_version: string;
24
+ chromium_version: string;
25
+ }
26
+
27
+ async function getLatestStableCEFVersion(): Promise<StableVersion> {
28
+ const response = await fetch(CEF_INDEX_URL);
29
+ if (!response.ok) {
30
+ throw new Error(
31
+ `Failed to fetch CEF builds index: HTTP ${response.status}`,
32
+ );
33
+ }
34
+
35
+ const data = (await response.json()) as {
36
+ linux64: {
37
+ versions: Array<{
38
+ cef_version: string;
39
+ chromium_version: string;
40
+ channel: string;
41
+ }>;
42
+ };
43
+ };
44
+
45
+ const versions = data.linux64?.versions;
46
+ if (!versions || versions.length === 0) {
47
+ throw new Error("No versions found in CEF builds index");
48
+ }
49
+
50
+ const stable = versions.find((v) => v.channel === "stable");
51
+ if (!stable) {
52
+ throw new Error("No stable CEF version found in builds index");
53
+ }
54
+
55
+ // The CDN's cef_version includes "+chromium-..." suffix, but cef-version.ts
56
+ // stores just the CEF part (e.g. "144.0.11+ge135be2").
57
+ const cefOnly = stable.cef_version.replace(/\+chromium-.*$/, "");
58
+
59
+ return {
60
+ cef_version: cefOnly,
61
+ chromium_version: stable.chromium_version,
62
+ };
63
+ }
64
+
65
+ function setOutput(key: string, value: string) {
66
+ const outputFile = process.env.GITHUB_OUTPUT;
67
+ if (outputFile) {
68
+ appendFileSync(outputFile, `${key}=${value}\n`);
69
+ }
70
+ }
71
+
72
+ function writeSummary(markdown: string) {
73
+ const summaryFile = process.env.GITHUB_STEP_SUMMARY;
74
+ if (summaryFile) {
75
+ appendFileSync(summaryFile, markdown + "\n");
76
+ }
77
+ }
78
+
79
+ async function main() {
80
+ const currentCef = CEF_VERSION;
81
+ const currentChromium = CHROMIUM_VERSION;
82
+ console.log(`Current: CEF ${currentCef} Chromium ${currentChromium}`);
83
+
84
+ const latest = await getLatestStableCEFVersion();
85
+ console.log(
86
+ `Latest: CEF ${latest.cef_version} Chromium ${latest.chromium_version}`,
87
+ );
88
+
89
+ const hasUpdate =
90
+ currentCef !== latest.cef_version ||
91
+ currentChromium !== latest.chromium_version;
92
+
93
+ // Always emit version outputs
94
+ setOutput("current_cef_version", currentCef);
95
+ setOutput("current_chromium_version", currentChromium);
96
+ setOutput("latest_cef_version", latest.cef_version);
97
+ setOutput("latest_chromium_version", latest.chromium_version);
98
+ setOutput("has_update", hasUpdate ? "true" : "false");
99
+
100
+ if (hasUpdate) {
101
+ console.log("Version mismatch — updating src/shared/cef-version.ts");
102
+
103
+ const cefVersionPath = resolve(
104
+ import.meta.dir,
105
+ "../src/shared/cef-version.ts",
106
+ );
107
+ const newContent = [
108
+ "// Default CEF version shipped with this Electrobun release.",
109
+ "// All platforms use the same version. Update this single pair when bumping CEF.",
110
+ `export const CEF_VERSION = \`${latest.cef_version}\`;`,
111
+ `export const CHROMIUM_VERSION = \`${latest.chromium_version}\`;`,
112
+ "export const DEFAULT_CEF_VERSION_STRING = `${CEF_VERSION}+chromium-${CHROMIUM_VERSION}`;",
113
+ "",
114
+ ].join("\n");
115
+ writeFileSync(cefVersionPath, newContent);
116
+ console.log(`Wrote ${cefVersionPath}`);
117
+ } else {
118
+ console.log("CEF version is up to date.");
119
+ }
120
+
121
+ // Step summary
122
+ const summary = hasUpdate
123
+ ? [
124
+ "## CEF Compatibility Check",
125
+ "",
126
+ `| | CEF | Chromium |`,
127
+ `|---|---|---|`,
128
+ `| **Current** | \`${currentCef}\` | \`${currentChromium}\` |`,
129
+ `| **Latest** | \`${latest.cef_version}\` | \`${latest.chromium_version}\` |`,
130
+ "",
131
+ "New version detected — build step will run.",
132
+ ].join("\n")
133
+ : [
134
+ "## CEF Compatibility Check",
135
+ "",
136
+ `CEF \`${currentCef}\` is the latest stable version. No build needed.`,
137
+ ].join("\n");
138
+
139
+ writeSummary(summary);
140
+ }
141
+
142
+ main().catch((err) => {
143
+ console.error("Error checking CEF version:", err);
144
+ process.exit(1);
145
+ });
@@ -0,0 +1,19 @@
1
+ // consider just makeing a shared types file
2
+
3
+ export type BuiltinBunToWebviewSchema = {
4
+ requests: {
5
+ evaluateJavascriptWithResponse: {
6
+ params: { script: string };
7
+ response: any;
8
+ };
9
+ };
10
+ };
11
+
12
+ export type BuiltinWebviewToBunSchema = {
13
+ requests: {
14
+ webviewTagInit: {
15
+ params: {};
16
+ response: any;
17
+ };
18
+ };
19
+ };
@@ -0,0 +1,36 @@
1
+ // Global type declarations for SparkBun browser environment
2
+
3
+ interface SparkBunEncryptResult {
4
+ encryptedData: string;
5
+ iv: string;
6
+ tag: string;
7
+ }
8
+
9
+ interface SparkBunBridge {
10
+ receiveMessageFromHost: (msg: unknown) => void;
11
+ receiveInternalMessageFromHost: (msg: unknown) => void;
12
+ receiveMessageFromBun: (msg: unknown) => void;
13
+ receiveInternalMessageFromBun: (msg: unknown) => void;
14
+ }
15
+
16
+ interface MessageHandler {
17
+ postMessage: (msg: string) => void;
18
+ }
19
+
20
+ declare global {
21
+ interface Window {
22
+ __sparkbunWebviewId: number;
23
+ __sparkbunWindowId: number;
24
+ __sparkbunRpcSocketPort: number;
25
+ __sparkbunHostSocketPort?: number;
26
+ __sparkbun?: SparkBunBridge;
27
+ __sparkbunPendingHostMessages?: unknown[];
28
+ __sparkbun_encrypt: (msg: string) => Promise<SparkBunEncryptResult>;
29
+ __sparkbun_decrypt: (encryptedData: string, iv: string, tag: string) => Promise<string>;
30
+ __sparkbunInternalBridge?: MessageHandler;
31
+ __sparkbunHostBridge?: MessageHandler;
32
+ __sparkbunBunBridge?: MessageHandler;
33
+ }
34
+ }
35
+
36
+ export {};