electrobun 0.0.19-beta.70 → 0.0.19-beta.71
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/debug.js +5 -0
- package/dist/api/bun/core/Updater.ts +11 -6
- package/dist/api/shared/platform.ts +48 -0
- package/package.json +1 -1
- package/src/cli/index.ts +66 -55
- package/templates/hello-world/README.md +57 -0
- package/templates/hello-world/bun.lock +63 -0
- package/templates/hello-world/electrobun.config +17 -0
- package/templates/hello-world/package.json +16 -0
- package/templates/hello-world/src/bun/index.ts +15 -0
- package/templates/hello-world/src/mainview/index.css +124 -0
- package/templates/hello-world/src/mainview/index.html +47 -0
- package/templates/hello-world/src/mainview/index.ts +5 -0
package/debug.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
console.log('process.argv:', process.argv);
|
|
2
|
+
const indexOfElectrobun = process.argv.findIndex((arg) => arg.includes('electrobun'));
|
|
3
|
+
console.log('indexOfElectrobun:', indexOfElectrobun);
|
|
4
|
+
const commandArg = process.argv[indexOfElectrobun + 1] || 'build';
|
|
5
|
+
console.log('commandArg:', commandArg);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { join, dirname, resolve } from "path";
|
|
2
|
-
import { homedir
|
|
2
|
+
import { homedir } from "os";
|
|
3
3
|
import { renameSync, unlinkSync, mkdirSync, rmdirSync, statSync } from "fs";
|
|
4
4
|
import tar from "tar";
|
|
5
5
|
import { ZstdInit } from "@oneidentity/zstd-js/wasm";
|
|
6
|
+
import { OS as currentOS, ARCH as currentArch } from '../../shared/platform';
|
|
6
7
|
|
|
7
8
|
const appSupportDir = join(homedir(), "Library", "Application Support");
|
|
8
9
|
|
|
@@ -46,7 +47,8 @@ const Updater = {
|
|
|
46
47
|
|
|
47
48
|
const channelBucketUrl = await Updater.channelBucketUrl();
|
|
48
49
|
const cacheBuster = Math.random().toString(36).substring(7);
|
|
49
|
-
const
|
|
50
|
+
const platformFolder = `${localInfo.channel}-${currentOS}-${currentArch}`;
|
|
51
|
+
const updateInfoUrl = join(localInfo.bucketUrl, platformFolder, `update.json?${cacheBuster}`);
|
|
50
52
|
|
|
51
53
|
try {
|
|
52
54
|
const updateInfoResponse = await fetch(updateInfoUrl);
|
|
@@ -113,8 +115,9 @@ const Updater = {
|
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
// check if there's a patch file for it
|
|
118
|
+
const platformFolder = `${localInfo.channel}-${currentOS}-${currentArch}`;
|
|
116
119
|
const patchResponse = await fetch(
|
|
117
|
-
join(
|
|
120
|
+
join(localInfo.bucketUrl, platformFolder, `${currentHash}.patch`)
|
|
118
121
|
);
|
|
119
122
|
|
|
120
123
|
if (!patchResponse.ok) {
|
|
@@ -210,8 +213,10 @@ const Updater = {
|
|
|
210
213
|
// then just download it and unpack it
|
|
211
214
|
if (currentHash !== latestHash) {
|
|
212
215
|
const cacheBuster = Math.random().toString(36).substring(7);
|
|
216
|
+
const platformFolder = `${localInfo.channel}-${currentOS}-${currentArch}`;
|
|
213
217
|
const urlToLatestTarball = join(
|
|
214
|
-
|
|
218
|
+
localInfo.bucketUrl,
|
|
219
|
+
platformFolder,
|
|
215
220
|
`${appFileName}.app.tar.zst`
|
|
216
221
|
);
|
|
217
222
|
const prevVersionCompressedTarballPath = join(
|
|
@@ -337,8 +342,8 @@ const Updater = {
|
|
|
337
342
|
|
|
338
343
|
channelBucketUrl: async () => {
|
|
339
344
|
await Updater.getLocallocalInfo();
|
|
340
|
-
|
|
341
|
-
return join(localInfo.bucketUrl,
|
|
345
|
+
const platformFolder = `${localInfo.channel}-${currentOS}-${currentArch}`;
|
|
346
|
+
return join(localInfo.bucketUrl, platformFolder);
|
|
342
347
|
},
|
|
343
348
|
|
|
344
349
|
appDataFolder: async () => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { platform, arch } from 'os';
|
|
2
|
+
|
|
3
|
+
export type SupportedOS = 'macos' | 'win' | 'linux';
|
|
4
|
+
export type SupportedArch = 'arm64' | 'x64';
|
|
5
|
+
|
|
6
|
+
// Cache platform() result to avoid multiple system calls
|
|
7
|
+
const platformName = platform();
|
|
8
|
+
const archName = arch();
|
|
9
|
+
|
|
10
|
+
// Determine OS once
|
|
11
|
+
export const OS: SupportedOS = (() => {
|
|
12
|
+
switch (platformName) {
|
|
13
|
+
case "win32":
|
|
14
|
+
return 'win';
|
|
15
|
+
case "darwin":
|
|
16
|
+
return 'macos';
|
|
17
|
+
case 'linux':
|
|
18
|
+
return 'linux';
|
|
19
|
+
default:
|
|
20
|
+
throw new Error(`Unsupported platform: ${platformName}`);
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
|
|
24
|
+
// Determine ARCH once, with Windows override
|
|
25
|
+
export const ARCH: SupportedArch = (() => {
|
|
26
|
+
// Always use x64 for Windows since we only build x64 Windows binaries
|
|
27
|
+
if (OS === 'win') {
|
|
28
|
+
return 'x64';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (archName) {
|
|
32
|
+
case "arm64":
|
|
33
|
+
return 'arm64';
|
|
34
|
+
case "x64":
|
|
35
|
+
return 'x64';
|
|
36
|
+
default:
|
|
37
|
+
throw new Error(`Unsupported architecture: ${archName}`);
|
|
38
|
+
}
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
// Export functions for backwards compatibility if needed
|
|
42
|
+
export function getPlatformOS(): SupportedOS {
|
|
43
|
+
return OS;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getPlatformArch(): SupportedArch {
|
|
47
|
+
return ARCH;
|
|
48
|
+
}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { join, dirname, basename } from "path";
|
|
|
2
2
|
import {
|
|
3
3
|
existsSync,
|
|
4
4
|
readFileSync,
|
|
5
|
+
writeFileSync,
|
|
5
6
|
cpSync,
|
|
6
7
|
rmdirSync,
|
|
7
8
|
mkdirSync,
|
|
@@ -12,40 +13,12 @@ import {
|
|
|
12
13
|
import { execSync } from "child_process";
|
|
13
14
|
import tar from "tar";
|
|
14
15
|
import { ZstdInit } from "@oneidentity/zstd-js/wasm";
|
|
15
|
-
import {
|
|
16
|
+
import { OS, ARCH } from '../shared/platform';
|
|
17
|
+
import { getTemplate, getTemplateNames } from './templates/embedded';
|
|
16
18
|
// import { loadBsdiff, loadBspatch } from 'bsdiff-wasm';
|
|
17
19
|
// MacOS named pipes hang at around 4KB
|
|
18
20
|
const MAX_CHUNK_SIZE = 1024 * 2;
|
|
19
21
|
|
|
20
|
-
// TODO: dedup with built.ts
|
|
21
|
-
const OS: 'win' | 'linux' | 'macos' = getPlatform();
|
|
22
|
-
// Always use x64 for Windows since we only build x64 Windows binaries
|
|
23
|
-
const ARCH: 'arm64' | 'x64' = OS === 'win' ? 'x64' : getArch();
|
|
24
|
-
|
|
25
|
-
function getPlatform() {
|
|
26
|
-
switch (platform()) {
|
|
27
|
-
case "win32":
|
|
28
|
-
return 'win';
|
|
29
|
-
case "darwin":
|
|
30
|
-
return 'macos';
|
|
31
|
-
case 'linux':
|
|
32
|
-
return 'linux';
|
|
33
|
-
default:
|
|
34
|
-
throw 'unsupported platform';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function getArch() {
|
|
39
|
-
switch (arch()) {
|
|
40
|
-
case "arm64":
|
|
41
|
-
return 'arm64';
|
|
42
|
-
case "x64":
|
|
43
|
-
return 'x64';
|
|
44
|
-
default:
|
|
45
|
-
throw 'unsupported arch'
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
22
|
|
|
50
23
|
const binExt = OS === 'win' ? '.exe' : '';
|
|
51
24
|
|
|
@@ -711,8 +684,57 @@ const bundleFileName = targetOS === 'macos' ? `${appFileName}.app` : appFileName
|
|
|
711
684
|
let proc = null;
|
|
712
685
|
|
|
713
686
|
if (commandArg === "init") {
|
|
714
|
-
|
|
715
|
-
|
|
687
|
+
const projectName = process.argv[indexOfElectrobun + 2] || "my-electrobun-app";
|
|
688
|
+
const templateName = process.argv.find(arg => arg.startsWith("--template="))?.split("=")[1] || "hello-world";
|
|
689
|
+
|
|
690
|
+
console.log(`🚀 Initializing Electrobun project: ${projectName}`);
|
|
691
|
+
|
|
692
|
+
// Validate template name
|
|
693
|
+
const availableTemplates = getTemplateNames();
|
|
694
|
+
if (!availableTemplates.includes(templateName)) {
|
|
695
|
+
console.error(`❌ Template "${templateName}" not found.`);
|
|
696
|
+
console.log(`Available templates: ${availableTemplates.join(", ")}`);
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
const template = getTemplate(templateName);
|
|
701
|
+
if (!template) {
|
|
702
|
+
console.error(`❌ Could not load template "${templateName}"`);
|
|
703
|
+
process.exit(1);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Create project directory
|
|
707
|
+
const projectPath = join(process.cwd(), projectName);
|
|
708
|
+
if (existsSync(projectPath)) {
|
|
709
|
+
console.error(`❌ Directory "${projectName}" already exists.`);
|
|
710
|
+
process.exit(1);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
mkdirSync(projectPath, { recursive: true });
|
|
714
|
+
|
|
715
|
+
// Extract template files
|
|
716
|
+
let fileCount = 0;
|
|
717
|
+
for (const [relativePath, content] of Object.entries(template.files)) {
|
|
718
|
+
const fullPath = join(projectPath, relativePath);
|
|
719
|
+
const dir = dirname(fullPath);
|
|
720
|
+
|
|
721
|
+
// Create directory if it doesn't exist
|
|
722
|
+
mkdirSync(dir, { recursive: true });
|
|
723
|
+
|
|
724
|
+
// Write file
|
|
725
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
726
|
+
fileCount++;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
console.log(`✅ Created ${fileCount} files from "${templateName}" template`);
|
|
730
|
+
console.log(`📁 Project created at: ${projectPath}`);
|
|
731
|
+
console.log("");
|
|
732
|
+
console.log("📦 Next steps:");
|
|
733
|
+
console.log(` cd ${projectName}`);
|
|
734
|
+
console.log(" bun install");
|
|
735
|
+
console.log(" bunx electrobun dev");
|
|
736
|
+
console.log("");
|
|
737
|
+
console.log("🎉 Happy building with Electrobun!");
|
|
716
738
|
} else if (commandArg === "build") {
|
|
717
739
|
// Ensure core binaries are available for the target platform before starting build
|
|
718
740
|
await ensureCoreDependencies(currentTarget.os, currentTarget.arch);
|
|
@@ -1306,7 +1328,7 @@ if (commandArg === "init") {
|
|
|
1306
1328
|
// 6.5. code sign and notarize the dmg
|
|
1307
1329
|
// 7. copy artifacts to directory [self-extractor dmg, zstd app bundle, bsdiff patch, update.json]
|
|
1308
1330
|
|
|
1309
|
-
//
|
|
1331
|
+
// Platform suffix is only used for folder names, not file names
|
|
1310
1332
|
const platformSuffix = `-${targetOS}-${targetARCH}`;
|
|
1311
1333
|
const tarPath = `${appBundleFolderPath}.tar`;
|
|
1312
1334
|
|
|
@@ -1331,8 +1353,7 @@ if (commandArg === "init") {
|
|
|
1331
1353
|
// than saving 1 more MB of space/bandwidth.
|
|
1332
1354
|
|
|
1333
1355
|
const compressedTarPath = `${tarPath}.zst`;
|
|
1334
|
-
|
|
1335
|
-
artifactsToUpload.push(platformCompressedTarPath);
|
|
1356
|
+
artifactsToUpload.push(compressedTarPath);
|
|
1336
1357
|
|
|
1337
1358
|
// zstd compress tarball
|
|
1338
1359
|
// todo (yoav): consider using c bindings for zstd for speed instead of wasm
|
|
@@ -1361,8 +1382,6 @@ if (commandArg === "init") {
|
|
|
1361
1382
|
);
|
|
1362
1383
|
|
|
1363
1384
|
await Bun.write(compressedTarPath, compressedData);
|
|
1364
|
-
// Copy to platform-specific filename for upload
|
|
1365
|
-
cpSync(compressedTarPath, platformCompressedTarPath);
|
|
1366
1385
|
}
|
|
1367
1386
|
});
|
|
1368
1387
|
|
|
@@ -1416,8 +1435,7 @@ if (commandArg === "init") {
|
|
|
1416
1435
|
console.log("creating dmg...");
|
|
1417
1436
|
// make a dmg
|
|
1418
1437
|
const dmgPath = join(buildFolder, `${appFileName}.dmg`);
|
|
1419
|
-
|
|
1420
|
-
artifactsToUpload.push(platformDmgPath);
|
|
1438
|
+
artifactsToUpload.push(dmgPath);
|
|
1421
1439
|
// hdiutil create -volname "YourAppName" -srcfolder /path/to/YourApp.app -ov -format UDZO YourAppName.dmg
|
|
1422
1440
|
// Note: use ULFO (lzfse) for better compatibility with large CEF frameworks and modern macOS
|
|
1423
1441
|
execSync(
|
|
@@ -1437,9 +1455,6 @@ if (commandArg === "init") {
|
|
|
1437
1455
|
} else {
|
|
1438
1456
|
console.log("skipping notarization");
|
|
1439
1457
|
}
|
|
1440
|
-
|
|
1441
|
-
// Copy to platform-specific filename
|
|
1442
|
-
cpSync(dmgPath, platformDmgPath);
|
|
1443
1458
|
} else {
|
|
1444
1459
|
// For Windows and Linux, add the self-extracting bundle directly
|
|
1445
1460
|
const platformBundlePath = join(buildFolder, `${appFileName}${platformSuffix}${targetOS === 'win' ? '.exe' : ''}`);
|
|
@@ -1447,10 +1462,10 @@ if (commandArg === "init") {
|
|
|
1447
1462
|
if (targetOS === 'win') {
|
|
1448
1463
|
// On Windows, create a self-extracting exe
|
|
1449
1464
|
// For now, just copy the bundle folder
|
|
1450
|
-
artifactsToUpload.push(compressedTarPath
|
|
1465
|
+
artifactsToUpload.push(compressedTarPath);
|
|
1451
1466
|
} else if (targetOS === 'linux') {
|
|
1452
1467
|
// On Linux, create a tar.gz of the bundle
|
|
1453
|
-
const linuxTarPath = join(buildFolder, `${appFileName}
|
|
1468
|
+
const linuxTarPath = join(buildFolder, `${appFileName}.tar.gz`);
|
|
1454
1469
|
execSync(`tar -czf ${escapePathForTerminal(linuxTarPath)} -C ${escapePathForTerminal(buildFolder)} ${escapePathForTerminal(basename(appBundleFolderPath))}`);
|
|
1455
1470
|
artifactsToUpload.push(linuxTarPath);
|
|
1456
1471
|
}
|
|
@@ -1478,9 +1493,8 @@ if (commandArg === "init") {
|
|
|
1478
1493
|
// bucketUrl: config.release.bucketUrl
|
|
1479
1494
|
});
|
|
1480
1495
|
|
|
1481
|
-
//
|
|
1482
|
-
|
|
1483
|
-
await Bun.write(join(artifactFolder, platformUpdateJsonName), updateJsonContent);
|
|
1496
|
+
// update.json (no platform suffix in filename, platform is in folder name)
|
|
1497
|
+
await Bun.write(join(artifactFolder, 'update.json'), updateJsonContent);
|
|
1484
1498
|
|
|
1485
1499
|
// generate bsdiff
|
|
1486
1500
|
// https://storage.googleapis.com/eggbun-static/electrobun-playground/canary/ElectrobunPlayground-canary.app.tar.zst
|
|
@@ -1495,8 +1509,8 @@ if (commandArg === "init") {
|
|
|
1495
1509
|
} else {
|
|
1496
1510
|
const urlToPrevUpdateJson = join(
|
|
1497
1511
|
config.release.bucketUrl,
|
|
1498
|
-
|
|
1499
|
-
|
|
1512
|
+
buildSubFolder,
|
|
1513
|
+
'update.json'
|
|
1500
1514
|
);
|
|
1501
1515
|
const cacheBuster = Math.random().toString(36).substring(7);
|
|
1502
1516
|
const updateJsonResponse = await fetch(
|
|
@@ -1507,8 +1521,8 @@ if (commandArg === "init") {
|
|
|
1507
1521
|
|
|
1508
1522
|
const urlToLatestTarball = join(
|
|
1509
1523
|
config.release.bucketUrl,
|
|
1510
|
-
|
|
1511
|
-
`${appFileName}.app
|
|
1524
|
+
buildSubFolder,
|
|
1525
|
+
`${appFileName}.app.tar.zst`
|
|
1512
1526
|
);
|
|
1513
1527
|
|
|
1514
1528
|
|
|
@@ -1555,8 +1569,7 @@ if (commandArg === "init") {
|
|
|
1555
1569
|
// especially for creating multiple diffs in parallel
|
|
1556
1570
|
const bsdiffpath = targetPaths.BSDIFF;
|
|
1557
1571
|
const patchFilePath = join(buildFolder, `${prevHash}.patch`);
|
|
1558
|
-
|
|
1559
|
-
artifactsToUpload.push(platformPatchFilePath);
|
|
1572
|
+
artifactsToUpload.push(patchFilePath);
|
|
1560
1573
|
const result = Bun.spawnSync(
|
|
1561
1574
|
[bsdiffpath, prevTarballPath, tarPath, patchFilePath, "--use-zstd"],
|
|
1562
1575
|
{ cwd: buildFolder }
|
|
@@ -1566,8 +1579,6 @@ if (commandArg === "init") {
|
|
|
1566
1579
|
result.stdout.toString(),
|
|
1567
1580
|
result.stderr.toString()
|
|
1568
1581
|
);
|
|
1569
|
-
// Copy to platform-specific filename
|
|
1570
|
-
cpSync(patchFilePath, platformPatchFilePath);
|
|
1571
1582
|
}
|
|
1572
1583
|
} else {
|
|
1573
1584
|
console.log("prevoius version not found at: ", urlToLatestTarball);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Electrobun Hello World
|
|
2
|
+
|
|
3
|
+
A simple Electrobun app to get you started with the framework.
|
|
4
|
+
|
|
5
|
+
## What You'll See
|
|
6
|
+
|
|
7
|
+
This hello world app demonstrates:
|
|
8
|
+
- **Native Window**: A cross-platform desktop window
|
|
9
|
+
- **Web-based UI**: Modern HTML, CSS, and JavaScript interface
|
|
10
|
+
- **Simple Architecture**: Clean separation between Bun process and UI
|
|
11
|
+
|
|
12
|
+
## Getting Started
|
|
13
|
+
|
|
14
|
+
1. Install dependencies:
|
|
15
|
+
```bash
|
|
16
|
+
bun install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Run in development mode:
|
|
20
|
+
```bash
|
|
21
|
+
bun run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. Build for production:
|
|
25
|
+
```bash
|
|
26
|
+
bun run build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Project Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
src/
|
|
33
|
+
├── bun/
|
|
34
|
+
│ └── index.ts # Main process - creates and manages windows
|
|
35
|
+
└── mainview/
|
|
36
|
+
├── index.html # Your app's UI
|
|
37
|
+
├── index.css # Styles
|
|
38
|
+
└── index.ts # View logic
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Next Steps
|
|
42
|
+
|
|
43
|
+
Ready to build something more complex? Check out:
|
|
44
|
+
|
|
45
|
+
- **[Documentation](https://docs.electrobun.dev)** - Learn about all Electrobun features
|
|
46
|
+
- **[Examples](https://github.com/blackboardsh/electrobun/tree/main/playground)** - See advanced features like RPC, menus, and system tray
|
|
47
|
+
- **[GitHub](https://github.com/blackboardsh/electrobun)** - Star the repo and join the community
|
|
48
|
+
|
|
49
|
+
### Add More Features
|
|
50
|
+
|
|
51
|
+
Want to extend this app? Try adding:
|
|
52
|
+
- RPC communication between Bun and webview
|
|
53
|
+
- Native menus and system tray
|
|
54
|
+
- File dialogs and system integration
|
|
55
|
+
- Multiple windows and views
|
|
56
|
+
|
|
57
|
+
Happy building! 🚀
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "electrobun-hello-world",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"electrobun": "latest",
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "latest",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
"packages": {
|
|
15
|
+
"@oneidentity/zstd-js": ["@oneidentity/zstd-js@1.0.3", "", { "dependencies": { "@types/emscripten": "^1.39.4" } }, "sha512-Jm6sawqxLzBrjC4sg2BeXToa33yPzUmq20CKsehKY2++D/gHb/oSwVjNgT+RH4vys+r8FynrgcNzGwhZWMLzfQ=="],
|
|
16
|
+
|
|
17
|
+
"@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
|
|
18
|
+
|
|
19
|
+
"@types/emscripten": ["@types/emscripten@1.40.1", "", {}, "sha512-sr53lnYkQNhjHNN0oJDdUm5564biioI5DuOpycufDVK7D3y+GR3oUswe2rlwY1nPNyusHbrJ9WoTyIHl4/Bpwg=="],
|
|
20
|
+
|
|
21
|
+
"@types/filesystem": ["@types/filesystem@0.0.36", "", { "dependencies": { "@types/filewriter": "*" } }, "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA=="],
|
|
22
|
+
|
|
23
|
+
"@types/filewriter": ["@types/filewriter@0.0.33", "", {}, "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g=="],
|
|
24
|
+
|
|
25
|
+
"@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
|
|
26
|
+
|
|
27
|
+
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
|
|
28
|
+
|
|
29
|
+
"@types/react": ["@types/react@19.1.9", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA=="],
|
|
30
|
+
|
|
31
|
+
"@types/webextension-polyfill": ["@types/webextension-polyfill@0.12.3", "", {}, "sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg=="],
|
|
32
|
+
|
|
33
|
+
"browser-namespace": ["browser-namespace@1.4.0", "", { "dependencies": { "@types/filesystem": "*", "@types/har-format": "*", "@types/webextension-polyfill": "*" } }, "sha512-9b4yNTNs+8HVPssSq8RSZMRunf+G4cVQ2PMtOTn+uEVFOW5C0Uo+eGXuJ5LfxS1UDph5oAdWj92thPyxVhpqXg=="],
|
|
34
|
+
|
|
35
|
+
"bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
|
|
36
|
+
|
|
37
|
+
"chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
|
38
|
+
|
|
39
|
+
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
40
|
+
|
|
41
|
+
"electrobun": ["electrobun@0.0.18", "", { "dependencies": { "@oneidentity/zstd-js": "^1.0.3", "rpc-anywhere": "1.5.0", "tar": "^6.2.1" }, "bin": { "electrobun": "dist/electrobun" } }, "sha512-RyMNGcAaHklicZlJToGfN3fVZGKHpxZv6o8S96TK9tHSY/SRze5bNPIGUnY9wr/BbWuQW5gGUGaVIWWqa5NSZQ=="],
|
|
42
|
+
|
|
43
|
+
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
|
44
|
+
|
|
45
|
+
"minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
|
46
|
+
|
|
47
|
+
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
|
48
|
+
|
|
49
|
+
"mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
|
50
|
+
|
|
51
|
+
"rpc-anywhere": ["rpc-anywhere@1.5.0", "", { "dependencies": { "browser-namespace": "^1.4.0" } }, "sha512-ZYrB0foAM4oE7oBnUH3BL7LwtW9d6+RkzL/rFnjj8GCaFt5c81Rbw6oVl6u9AMsGONsKeJX0mL62TpbPXSO6og=="],
|
|
52
|
+
|
|
53
|
+
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
|
54
|
+
|
|
55
|
+
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
|
56
|
+
|
|
57
|
+
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
|
58
|
+
|
|
59
|
+
"fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
60
|
+
|
|
61
|
+
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "HelloWorld",
|
|
3
|
+
"id": "com.example.helloworld",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": "Your Name",
|
|
6
|
+
"description": "A simple Electrobun hello world app",
|
|
7
|
+
"main": "src/bun/index.ts",
|
|
8
|
+
"views": {
|
|
9
|
+
"main": {
|
|
10
|
+
"html": "src/mainview/index.html",
|
|
11
|
+
"preload": "src/mainview/index.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"build": {
|
|
15
|
+
"placeholderIcon": true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "electrobun-hello-world",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple Electrobun app showcasing core features",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "electrobun dev",
|
|
7
|
+
"build": "electrobun build",
|
|
8
|
+
"start": "bun run build && bun run dev"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"electrobun": "latest"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "latest"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BrowserWindow } from "electrobun/bun";
|
|
2
|
+
|
|
3
|
+
// Create the main application window
|
|
4
|
+
const mainWindow = new BrowserWindow({
|
|
5
|
+
title: "Hello Electrobun!",
|
|
6
|
+
url: "views://main/index.html",
|
|
7
|
+
frame: {
|
|
8
|
+
width: 800,
|
|
9
|
+
height: 600,
|
|
10
|
+
x: 200,
|
|
11
|
+
y: 200,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
console.log("Hello Electrobun app started!");
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
* {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
body {
|
|
6
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
7
|
+
margin: 0;
|
|
8
|
+
padding: 0;
|
|
9
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
10
|
+
color: #333;
|
|
11
|
+
min-height: 100vh;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.container {
|
|
15
|
+
max-width: 800px;
|
|
16
|
+
margin: 0 auto;
|
|
17
|
+
padding: 40px 20px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h1 {
|
|
21
|
+
color: white;
|
|
22
|
+
font-size: 3rem;
|
|
23
|
+
text-align: center;
|
|
24
|
+
margin-bottom: 8px;
|
|
25
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.subtitle {
|
|
29
|
+
color: rgba(255, 255, 255, 0.9);
|
|
30
|
+
font-size: 1.25rem;
|
|
31
|
+
text-align: center;
|
|
32
|
+
margin-top: 0;
|
|
33
|
+
margin-bottom: 40px;
|
|
34
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.welcome-section {
|
|
38
|
+
background: white;
|
|
39
|
+
border-radius: 12px;
|
|
40
|
+
padding: 30px;
|
|
41
|
+
margin: 30px 0;
|
|
42
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
|
43
|
+
line-height: 1.6;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
h2 {
|
|
47
|
+
color: #2563eb;
|
|
48
|
+
margin-top: 30px;
|
|
49
|
+
margin-bottom: 15px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
ul {
|
|
53
|
+
margin: 20px 0;
|
|
54
|
+
padding-left: 20px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
li {
|
|
58
|
+
margin: 8px 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.links {
|
|
62
|
+
display: flex;
|
|
63
|
+
gap: 15px;
|
|
64
|
+
margin: 25px 0;
|
|
65
|
+
flex-wrap: wrap;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.doc-link {
|
|
69
|
+
display: inline-block;
|
|
70
|
+
background: #2563eb;
|
|
71
|
+
color: white;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
padding: 12px 20px;
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
transition: all 0.2s ease;
|
|
77
|
+
box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.doc-link:hover {
|
|
81
|
+
background: #1d4ed8;
|
|
82
|
+
transform: translateY(-1px);
|
|
83
|
+
box-shadow: 0 4px 8px rgba(37, 99, 235, 0.3);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
code {
|
|
87
|
+
background: #f1f5f9;
|
|
88
|
+
color: #475569;
|
|
89
|
+
padding: 2px 6px;
|
|
90
|
+
border-radius: 4px;
|
|
91
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
92
|
+
font-size: 0.9em;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.footer {
|
|
96
|
+
text-align: center;
|
|
97
|
+
color: rgba(255, 255, 255, 0.8);
|
|
98
|
+
margin-top: 40px;
|
|
99
|
+
padding: 20px;
|
|
100
|
+
background: rgba(255, 255, 255, 0.1);
|
|
101
|
+
border-radius: 8px;
|
|
102
|
+
backdrop-filter: blur(10px);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.footer p {
|
|
106
|
+
margin: 8px 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Dark mode support */
|
|
110
|
+
@media (prefers-color-scheme: dark) {
|
|
111
|
+
.welcome-section {
|
|
112
|
+
background: #1f2937;
|
|
113
|
+
color: #f3f4f6;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
h2 {
|
|
117
|
+
color: #60a5fa;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
code {
|
|
121
|
+
background: #374151;
|
|
122
|
+
color: #d1d5db;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Hello Electrobun!</title>
|
|
7
|
+
<link rel="stylesheet" href="index.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="container">
|
|
11
|
+
<h1>Hello Electrobun! 🎉</h1>
|
|
12
|
+
<p class="subtitle">A fast, cross-platform desktop app framework</p>
|
|
13
|
+
|
|
14
|
+
<div class="welcome-section">
|
|
15
|
+
<p>Welcome to your first Electrobun app! This framework combines the power of Bun with native desktop capabilities.</p>
|
|
16
|
+
|
|
17
|
+
<h2>What is Electrobun?</h2>
|
|
18
|
+
<ul>
|
|
19
|
+
<li><strong>Fast:</strong> Built on Bun's lightning-fast JavaScript runtime</li>
|
|
20
|
+
<li><strong>Native:</strong> Access to system APIs like menus, trays, and file dialogs</li>
|
|
21
|
+
<li><strong>Cross-platform:</strong> Works on macOS, Windows, and Linux</li>
|
|
22
|
+
<li><strong>Web-based UI:</strong> Use familiar HTML, CSS, and JavaScript for your interface</li>
|
|
23
|
+
</ul>
|
|
24
|
+
|
|
25
|
+
<h2>Get Started</h2>
|
|
26
|
+
<p>Ready to build something amazing? Check out the documentation and examples:</p>
|
|
27
|
+
|
|
28
|
+
<div class="links">
|
|
29
|
+
<a href="https://docs.electrobun.dev" target="_blank" class="doc-link">
|
|
30
|
+
📚 Documentation
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://github.com/blackboardsh/electrobun" target="_blank" class="doc-link">
|
|
33
|
+
🐙 GitHub Repository
|
|
34
|
+
</a>
|
|
35
|
+
<a href="https://docs.electrobun.dev/examples" target="_blank" class="doc-link">
|
|
36
|
+
💡 Examples
|
|
37
|
+
</a>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="footer">
|
|
42
|
+
<p>Edit <code>src/bun/index.ts</code> and <code>src/mainview/</code> to customize your app</p>
|
|
43
|
+
<p>Press F12 to open DevTools</p>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|