electrobun 0.0.2 → 0.0.4
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/.colab.json +1 -0
- package/README.md +14 -12
- package/bun.lockb +0 -0
- package/dist/bsdiff +0 -0
- package/dist/bspatch +0 -0
- package/dist/webview +0 -0
- package/docs-old/architecture.md +46 -0
- package/documentation/README.md +41 -0
- package/documentation/babel.config.js +3 -0
- package/documentation/blog/2024-08-20-electrobun.md +22 -0
- package/documentation/blog/authors.yml +8 -0
- package/documentation/blog/tags.yml +0 -0
- package/documentation/docs/apis/Application Icons.md +9 -0
- package/documentation/docs/apis/Bundled Assets.md +95 -0
- package/documentation/docs/apis/browser/DraggableRegions.md +36 -0
- package/documentation/docs/apis/browser/Electrobun Webview Tag.md +200 -0
- package/documentation/docs/apis/browser/Electroview Class.md +158 -0
- package/documentation/docs/apis/browser/GlobalProperties.md +11 -0
- package/documentation/docs/apis/browser/index.md +25 -0
- package/documentation/docs/apis/bun/ApplicationMenu.md +141 -0
- package/documentation/docs/apis/bun/BrowserView.md +513 -0
- package/documentation/docs/apis/bun/BrowserWindow.md +423 -0
- package/documentation/docs/apis/bun/ContextMenu.md +50 -0
- package/documentation/docs/apis/bun/Events.md +50 -0
- package/documentation/docs/apis/bun/PATHS.md +17 -0
- package/documentation/docs/apis/bun/Tray.md +115 -0
- package/documentation/docs/apis/bun/Updater.md +74 -0
- package/documentation/docs/apis/bun/Utils.md +51 -0
- package/documentation/docs/apis/bun/index.md +26 -0
- package/documentation/docs/apis/cli/Electrobun.config.md +97 -0
- package/documentation/docs/apis/cli/cli args.md +76 -0
- package/documentation/docs/guides/Architecture/Events.md +19 -0
- package/documentation/docs/guides/Architecture/IPC and Isolation.md +20 -0
- package/documentation/docs/guides/Architecture/Overview.md +140 -0
- package/documentation/docs/guides/Architecture/Updates.md +7 -0
- package/documentation/docs/guides/Architecture/Webview Tag.md +5 -0
- package/documentation/docs/guides/Compatability.md +8 -0
- package/documentation/docs/guides/Getting Started/Creating UI.md +147 -0
- package/documentation/docs/guides/Getting Started/Distributing.md +116 -0
- package/documentation/docs/guides/Getting Started/Getting Started.md +7 -0
- package/documentation/docs/guides/Getting Started/Hello World.md +93 -0
- package/documentation/docs/guides/Getting Started/What is Electrobun.md +39 -0
- package/documentation/docs/guides/Guides/Build UI with React +0 -0
- package/documentation/docs/guides/Guides/Build UI with Solidjs +0 -0
- package/documentation/docs/guides/Guides/Build a Web Browser +0 -0
- package/documentation/docs/guides/Guides/Bun <-> Browser RPC +0 -0
- package/documentation/docs/guides/Guides/Using Tailwind +0 -0
- package/documentation/docusaurus.config.ts +153 -0
- package/documentation/package-lock.json +14530 -0
- package/documentation/package.json +47 -0
- package/documentation/sidebars.ts +32 -0
- package/documentation/src/components/HomepageFeatures/index.tsx +70 -0
- package/documentation/src/components/HomepageFeatures/styles.module.css +11 -0
- package/documentation/src/css/custom.css +30 -0
- package/documentation/src/pages/index.module.css +23 -0
- package/documentation/src/pages/index.tsx +137 -0
- package/documentation/static/.nojekyll +0 -0
- package/documentation/static/img/electrobun-logo-256.png +0 -0
- package/documentation/static/img/electrobun-logo-32.png +0 -0
- package/documentation/tsconfig.json +7 -0
- package/package.json +11 -6
- package/src/browser/index.ts +7 -2
- package/src/browser/webviewtag.ts +149 -17
- package/src/bun/core/BrowserView.ts +19 -2
- package/src/bun/proc/zig.ts +1 -0
- package/src/cli/build/electrobun +0 -0
- package/src/cli/index.ts +3 -1
- package/src/extractor/zig-out/bin/extractor +0 -0
- package/src/launcher/zig-out/bin/launcher +0 -0
- package/docs/architecture.md +0 -84
- /package/{docs → docs-old}/api/bun-api.md +0 -0
- /package/{docs → docs-old}/api/view-api.md +0 -0
- /package/{docs → docs-old}/electrobun-config.md +0 -0
- /package/{docs → docs-old}/getting-started.md +0 -0
- /package/{docs → docs-old}/node_modules/.cache/webpack/client-development-en/0.pack +0 -0
- /package/{docs → docs-old}/node_modules/.cache/webpack/client-development-en/index.pack +0 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
> Electrobun's built-in update mechanism for your app
|
|
2
|
+
|
|
3
|
+
```typescript title="/src/bun/index.ts"
|
|
4
|
+
import { Updator } from "electrobun/bun";
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
```json title="/electrobun.config"
|
|
8
|
+
{
|
|
9
|
+
...
|
|
10
|
+
|
|
11
|
+
"release": {
|
|
12
|
+
"bucketUrl": "https://s3-url"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Updating Electrobun Apps
|
|
18
|
+
|
|
19
|
+
Electrobun ships with a built-in update mechanism that lets you ship updates to your app as small as 14KB so you can ship often. All you need to do is specify a url where your artifacts are stored in your `electrobun.config` file. A static file host like S3 + cloudfront is more than enough, most likely your app will stay well within the free tier.
|
|
20
|
+
|
|
21
|
+
The electrobun `cli` will automatically generate an `artifacts` folder for each non-dev build (typically `canary` and `stable`), just upload those folders to S3 and set the bucketUrl, then use the api to check for and install updates when your app launches and on an interval or in response to a system tray menu to check for updates whenever a user initiates it.
|
|
22
|
+
|
|
23
|
+
## Methods
|
|
24
|
+
|
|
25
|
+
### getLocalInfo
|
|
26
|
+
|
|
27
|
+
Get the local version info for display in your app or other logic. This will read the `version.json` file bundled with your app.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
const localInfo = await Electrobun.Updator.getLocal;
|
|
31
|
+
|
|
32
|
+
localInfo: {
|
|
33
|
+
version: string;
|
|
34
|
+
hash: string;
|
|
35
|
+
bucketUrl: string;
|
|
36
|
+
channel: string;
|
|
37
|
+
name: string;
|
|
38
|
+
identifier: string;
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### checkForUpdate
|
|
43
|
+
|
|
44
|
+
Checks for an update by reading the update.json file at the url specified in the s3 subfolder for the current channel.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
const updateInfo = await Electrobun.Updater.checkForUpdate();
|
|
48
|
+
|
|
49
|
+
updateInfo: {
|
|
50
|
+
version: string;
|
|
51
|
+
hash: string;
|
|
52
|
+
updateAvailable: boolean;
|
|
53
|
+
updateReady: boolean;
|
|
54
|
+
error: string;
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### downloadUpdate
|
|
59
|
+
|
|
60
|
+
This will initiate a process where it attempts to download patch files and apply them until the patched app matches the current version. If something goes wrong like there isn't a trail of patch files from the user's version to current it will download the latest full version of the app directly.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
await Electrobun.Updater.downloadUpdate();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### applyUpdate
|
|
67
|
+
|
|
68
|
+
Once the latest version is either patched or downloaded and ready to install you can call `applyUpdate` to quit the current app, replace it with the latest version, and relaunch.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
if (Electrobun.Updater.updateInfo()?.updateReady) {
|
|
72
|
+
await Electrobun.Updater.applyUpdate();
|
|
73
|
+
}
|
|
74
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
> Various utilities for Electrobun apps.
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
import {Utils} from "electrobun/bun";
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
## moveToTrash
|
|
9
|
+
|
|
10
|
+
Move a file or folder on your system to the Trash (recycle bin).
|
|
11
|
+
|
|
12
|
+
:::warning
|
|
13
|
+
On MacOS when you move something to trash from the finder you can open the trash can and see a "restore" button that will put the files/folders back where they were deleted from
|
|
14
|
+
|
|
15
|
+
When using moveToTrash in Electrobun it moves it to the trash can but does not enable the "restore" button. To restore you will need to manually drag the files and folders back to their originating folder
|
|
16
|
+
:::
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Utils.moveToTrash(absolutePath)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## showItemInFolder
|
|
23
|
+
|
|
24
|
+
Open the finder to the specified path
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Utils.showItemInFolder(absolutePath)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## openFileDialog
|
|
31
|
+
|
|
32
|
+
Open a file dialogue to let the user specify a file or folder and return the path to your app. Typically you would have an event handler in the browser context like clicking an "open" button, this would trigger an rpc call to bun, which would call `openFileDialog()` and then optionally pass the response back to the browser context via rpc after the user has made their selection
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
// To simplify this example we'll just show a dialogue after a 2 second timeout
|
|
36
|
+
|
|
37
|
+
setTimeout(async () => {
|
|
38
|
+
|
|
39
|
+
const chosenPaths = await Utils.openFileDialog({
|
|
40
|
+
startingFolder: join(homedir(), "Desktop"),
|
|
41
|
+
allowedFileTypes: "*",
|
|
42
|
+
// allowedFileTypes: "png,jpg",
|
|
43
|
+
canChooseFiles: true,
|
|
44
|
+
canChooseDirectory: false,
|
|
45
|
+
allowsMultipleSelection: true,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
console.log("chosen paths", chosenPaths);
|
|
49
|
+
}, 2000);
|
|
50
|
+
|
|
51
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 1
|
|
3
|
+
title: "Bun API"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
These are apis you can use in the main bun process. Electrobun is just an npm dependency in your bun project. If you're just starting to look around take a look at the [Getting Started Guide](/docs/guides/Getting%20Started/) first to learn how to set up your first project.
|
|
7
|
+
|
|
8
|
+
In Electrobun you simply write Typescript for the main process, when your app is all bundled up it will ship with a version of the bun runtime and it'll execute your main bun process with it, so any bun-compatible typescript is valid.
|
|
9
|
+
|
|
10
|
+
You should explicitely import the `electrobun/bun` api for the main process:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import Electrobun from "electrobun/bun";
|
|
14
|
+
|
|
15
|
+
const win = new Electrobun.BrowserWindow(/*...*/);
|
|
16
|
+
|
|
17
|
+
// or
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
BrowserWindow,
|
|
21
|
+
ApplicationMenu,
|
|
22
|
+
// other specified imports
|
|
23
|
+
} from "electrobun/bun";
|
|
24
|
+
|
|
25
|
+
const win = new BrowserWindow(/*...*/);
|
|
26
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
## Electrobun Configuration (`electrobun.config`)
|
|
2
|
+
|
|
3
|
+
This document provides detailed descriptions of the `electrobun.config` file, outlining how to configure your Electrobun application's build, deployment, and operational settings. This file tells the Electrobun CLI how to build and configure your app.
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
{
|
|
7
|
+
// This section sets the core application metadata.
|
|
8
|
+
"app": {
|
|
9
|
+
// Your application name, spaces and some special characters are allowed.
|
|
10
|
+
// Your App distributables will use this and it's the name displayed in the
|
|
11
|
+
// Mac application menu when your app is focused.
|
|
12
|
+
"name": "Electrobun (Playground)",
|
|
13
|
+
// A unique identifier for the application, typically using reverse domain name
|
|
14
|
+
// notation. This should match the identifier for this app in your Apple Developer
|
|
15
|
+
// account
|
|
16
|
+
"identifier": "dev.electrobun.playground",
|
|
17
|
+
// The version of your app
|
|
18
|
+
"version": "0.0.1"
|
|
19
|
+
},
|
|
20
|
+
// Defines the settings and paths for the application's build process.
|
|
21
|
+
"build": {
|
|
22
|
+
// Configure the `bun build <entrypoint>` command that gets run
|
|
23
|
+
// to build the main bun process
|
|
24
|
+
"bun": {
|
|
25
|
+
// entrypoint should point to your typescript entrypoint for
|
|
26
|
+
// the main bun process
|
|
27
|
+
"entrypoint": "src/bun/index.ts",
|
|
28
|
+
// List any dependencies that should be treated as external
|
|
29
|
+
"external": []
|
|
30
|
+
},
|
|
31
|
+
// Configure the `bun build <entrypoint>` command that gets
|
|
32
|
+
// run to transpile typescript for the browser.
|
|
33
|
+
"views": {
|
|
34
|
+
// you can use any folder-safe name "mainview"
|
|
35
|
+
// will transpile the entrypoint into /Resources/app/views/mainview/index.js
|
|
36
|
+
// in the MacOS bundle
|
|
37
|
+
"mainview": {
|
|
38
|
+
"entrypoint": "src/mainview/index.ts",
|
|
39
|
+
"external": []
|
|
40
|
+
},
|
|
41
|
+
"myextension": {
|
|
42
|
+
"entrypoint": "src/myextension/preload.ts",
|
|
43
|
+
"external": []
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
// Copy files or folders from your src repo into the bundle. On MacOS
|
|
47
|
+
// the to paths are relative to the Resources/app/ folder. While the main
|
|
48
|
+
// bun process can access resources anywhere in the bundle BrowserViews
|
|
49
|
+
"copy": {
|
|
50
|
+
// can use the views:// scheme urls to load bundled resources.
|
|
51
|
+
// the views://mainview/index.html url maps to the views/mainview/index.html
|
|
52
|
+
"src/mainview/index.html": "views/mainview/index.html",
|
|
53
|
+
// It's useful to group your source code and bundled files by the name
|
|
54
|
+
// of the view they're for but that's not necessary, you can organize
|
|
55
|
+
// them however you like.
|
|
56
|
+
"src/mainview/index.css": "views/mainview/index.css"
|
|
57
|
+
},
|
|
58
|
+
// Mac specific configuration
|
|
59
|
+
"mac": {
|
|
60
|
+
// Fill a folder with different sized pngs that will be used as your App's icon.
|
|
61
|
+
// (https://developer.apple.com/documentation/xcode/configuring-your-app-icon)
|
|
62
|
+
// You can use a single 1024x1024 image or multiple images at different sizes. Name the folder icon.iconset and specify the path here.
|
|
63
|
+
"icons": "icon.iconset",
|
|
64
|
+
// Toggle code signing and notarization for non-dev builds on and off
|
|
65
|
+
"codesign": true,
|
|
66
|
+
"notarize": true,
|
|
67
|
+
// Specify a list of entitlements.
|
|
68
|
+
|
|
69
|
+
"entitlements": {
|
|
70
|
+
// The "com.apple.security.cs.allow-jit": true is enabled by default
|
|
71
|
+
// as it's required for hardened runtime macos applications, which is
|
|
72
|
+
// required for notarization.
|
|
73
|
+
// https://developer.apple.com/documentation/bundleresources/entitlements
|
|
74
|
+
|
|
75
|
+
// You will likely also have to enable some entitlements in your
|
|
76
|
+
// Apple Developer account for the corresponding app.
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Script hooks to run custom code during the build process. These are Typescript
|
|
81
|
+
// files executed with the bun runtime.
|
|
82
|
+
"scripts": {
|
|
83
|
+
// postBuild is executed after the mac app bundle is created, but before codeSigning.
|
|
84
|
+
// A good time to run tailwind, copy extra assets into the bundle, or other
|
|
85
|
+
// custom build steps.
|
|
86
|
+
"postBuild": "./buildScript.ts"
|
|
87
|
+
},
|
|
88
|
+
"release": {
|
|
89
|
+
// The only thing you need for updates to work is a static file host like S3.
|
|
90
|
+
// Specify the main bucket url. Electrobun will append the channel name internally
|
|
91
|
+
// to find the files it needs for updating. When building non-dev channels
|
|
92
|
+
// like canary and stable Electrobun will generate an artifacts folder
|
|
93
|
+
// with subfolders for each channel that you can upload direcly to the bucketUrl
|
|
94
|
+
"bucketUrl": "https://storage.googleapis.com/somebucket/bucket-subfolder/"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
## CLI Tool Integration
|
|
2
|
+
|
|
3
|
+
When you execute `bun install electrobun`, it installs the Electrobun CLI tool into the `node_modules/bin` folder. This setup enables your npm scripts to simply invoke `electrobun <args>` directly, utilizing the CLI seamlessly.
|
|
4
|
+
|
|
5
|
+
The CLI leverages the `electrobun.config` file to manage commands and handle processes associated with building and running the application efficiently.
|
|
6
|
+
|
|
7
|
+
### Installation
|
|
8
|
+
|
|
9
|
+
To install the CLI tool, use the following command:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun install electrobun
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This command integrates the Electrobun CLI into your project's `node_modules` directory, making it accessible for npm scripts or direct command-line usage within the project environment.
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
### init
|
|
20
|
+
|
|
21
|
+
**Description**: Initializes a new Electrobun project structure.
|
|
22
|
+
**Status**: Not yet implemented.
|
|
23
|
+
|
|
24
|
+
### build
|
|
25
|
+
|
|
26
|
+
**Description**: Compiles the project according to configurations specified in the `electrobun.config`.
|
|
27
|
+
|
|
28
|
+
### dev
|
|
29
|
+
|
|
30
|
+
**Description**: Facilitates the project running in a development environment with live reloading, providing real-time feedback during development phases.
|
|
31
|
+
|
|
32
|
+
### launcher
|
|
33
|
+
|
|
34
|
+
**Description**: Manages application launching, adapting to different settings for development and production environments to ensure appropriate resource utilization.
|
|
35
|
+
|
|
36
|
+
## Environments
|
|
37
|
+
|
|
38
|
+
### env
|
|
39
|
+
|
|
40
|
+
**Description**: Specifies the build environment, which can be set to `dev`, `canary`, or `stable`. Non-dev environments like `canary` and `stable` lead to the generation of an `artifacts` folder, containing all necessary distribution files. These files can be hosted on static file services for application distribution.
|
|
41
|
+
|
|
42
|
+
## Example Build Scripts
|
|
43
|
+
|
|
44
|
+
Incorporating Electrobun into your `package.json` scripts can streamline both development and build processes:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build:dev": "electrobun build",
|
|
49
|
+
"start:dev": "electrobun dev",
|
|
50
|
+
"dev": "bun install && npm run build:dev && npm run start:dev",
|
|
51
|
+
"build:canary": "electrobun build env=canary",
|
|
52
|
+
"build:stable": "electrobun build env=stable"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Development vs. Production Builds
|
|
57
|
+
|
|
58
|
+
### Development Build (`dev`)
|
|
59
|
+
|
|
60
|
+
In the development environment, the build configuration is designed to output logs and errors directly to the terminal window, ensuring immediate feedback and error reporting for enhanced developer intervention.
|
|
61
|
+
|
|
62
|
+
### Canary and Stable Builds
|
|
63
|
+
|
|
64
|
+
For environments marked as `canary` and `stable`, the CLI employs an optimized launcher binary better suited for production deployments. This launcher is optimized for performance and stability, ensuring efficient application execution.
|
|
65
|
+
|
|
66
|
+
#### Canary
|
|
67
|
+
|
|
68
|
+
Typically utilized for pre-release versions or testing new features in conditions that closely mimic production.
|
|
69
|
+
|
|
70
|
+
#### Stable
|
|
71
|
+
|
|
72
|
+
Used for releasing final, production-ready builds that are distributed to end-users.
|
|
73
|
+
|
|
74
|
+
### Optimized Launcher Binary
|
|
75
|
+
|
|
76
|
+
The optimized launcher binary is not merely for launching the application; it is also engineered to handle updates, system integration, and other critical runtime operations more reliably than the development-based launcher. This optimization ensures peak performance in environments where direct developer oversight is minimized.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
`Electrobun.events` is a custom event emitter in the [Bun api](/docs/apis/bun/Events).
|
|
2
|
+
|
|
3
|
+
Some events happen entirely within bun process, some happen in a BrowserView and make their way through zig into bun, and others originate in the native code layer (objc on MacOS) through zig into bun and then back to objc. Let's look at how the 'will-navigate' event works.
|
|
4
|
+
|
|
5
|
+
1. Objc event is fired on a BrowserView and handled by zig
|
|
6
|
+
1. zig sends json rpc request to decide navigation over the main bun named pipe with a url and a webviewid
|
|
7
|
+
1. zig pauses the main thread simulating a promise-like behaviour while listening on a separate named pipe listener thread
|
|
8
|
+
1. bun parses the json rpc and sees it's a 'will navigate' request
|
|
9
|
+
1. bun creates a new Electrobun.events.webview.willNavigate event with the data (url and webviewid).
|
|
10
|
+
1. bun then emits the event globally `('will-navigate')` that could be listened to with `Electrobun.events.on('will-navigate', handlerFn)`
|
|
11
|
+
1. bun then passes the same event to a specific event `('will-navigate-<webviewId>'` eg: `will-navigate-1` for the webview with id 1).
|
|
12
|
+
1. you could also listen to this globally via `Electrobun.events.on('will-navigate-1', handlerFn)` if you wanted to. Since ids are incremented deterministically this allows for some interesting patterns like handling navigation for the first window created.
|
|
13
|
+
1. you can also listen on the webview with `myWebview.on('will-navigate', handlerFn)`. Webview extends a "event emitter class' that essentially provides `on`, `off`, `appendEventListener`, etc. but instead of being an event listener it modifies the event name to include its id, and subscribes the handler to the main event emitter. So it basically does `Electrobun.events.on('will-navigate-1')` for you without you having to think about the webview's id and providing other lifecycle handling for you.
|
|
14
|
+
1. the event object has a `response` getter/setter and a `clearResponse` method that allows any handler to respond with a value as well as a `responseWasSet` flag. so in any handler you can both check if another handler set a response, and if you want override or modify the response.
|
|
15
|
+
1. the response is then serialized as an rpc response and sent back to zig which is listening on another thread, zig unfreezes the main thread returning the value to objc.
|
|
16
|
+
|
|
17
|
+
:::note
|
|
18
|
+
Global events are always called before specific events.
|
|
19
|
+
:::
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## IPC
|
|
2
|
+
|
|
3
|
+
Bun spawns the zig bindings as a separate process. GUI applications require the main thread of a process to run a blocking event loop, so this is separate to the bun process.
|
|
4
|
+
|
|
5
|
+
There are two categories of named pipes for IPC.
|
|
6
|
+
|
|
7
|
+
1. bun \<-> zig. This is used for communicating with zig. ie: creating windows and webviews, and binding native handlers that need a response from bun like will-navigate.
|
|
8
|
+
2. bun \<-> webview. Each webview gets its own pair of named pipes for communicating with bun.
|
|
9
|
+
|
|
10
|
+
### bun \<-> zig
|
|
11
|
+
|
|
12
|
+
There is a primary named pipe used to send rpc-anywhere encoded json messages between bun and zig on this pipe. There is a minimal zig implementation of rpc-anywhere that also implements a promise-like api in zig (freezes the main thread while waiting and unfreezes it returning a value).
|
|
13
|
+
|
|
14
|
+
In order to simulate something promise-like in zig we send the request to bun and pause the main zig thread. We have a pipe listener on another thread waiting for a reply, when it gets a response it unfreezes the main thread and returns the value back to the function that was waiting.
|
|
15
|
+
|
|
16
|
+
In general (whether receiving rpc requests, responses, and messages from bun) there is a performant loop in zig listening on another thread. We use native functions to group named pipe into a kqueue and let the process subscribe to events that continue the loop so it isn't busy waiting. For any gui-related rpc whe have to pass messages to the main thread to be executed.
|
|
17
|
+
|
|
18
|
+
### bun \<-> webview
|
|
19
|
+
|
|
20
|
+
When creating a webview a new named pipe pair is created. zig creates a bridge between the named pipe and the webview that passes anything between the named pipe and the webview so it's never deserialized in zig. We also have code in the webview for handling the other end of the RPC anywhere bun\<->webview communication. By using a named pipe for each webview we eliminate the need for the zig bridge having to double wrap or partially de/serialize json messages to route them to the right webview which makes bun \<-> webview communciation significantly faster.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 1
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Application Bundles
|
|
6
|
+
|
|
7
|
+
### MacOS
|
|
8
|
+
|
|
9
|
+
#### Your Installed App
|
|
10
|
+
|
|
11
|
+
On MacOS an application bundle is really just a folder with a .app file extension. The key subfolders inside are
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
// electrobun places several binaries here
|
|
15
|
+
/Contents/MacOS
|
|
16
|
+
|
|
17
|
+
// An optimized zig implementation of bspatch used to generate and apply diffs during updates
|
|
18
|
+
/Contents/MacOS/bspatch
|
|
19
|
+
|
|
20
|
+
// The bun runtime
|
|
21
|
+
/Contents/MacOS/bun
|
|
22
|
+
|
|
23
|
+
// An optimized zig binary that typically just calls `bun index.js` with the included runtime
|
|
24
|
+
// to run your compiled bun entrypoint file.
|
|
25
|
+
/Contents/MacOS/launcher
|
|
26
|
+
|
|
27
|
+
// A folder containing native code layer for the platform, on MacOS this these are
|
|
28
|
+
// objc binaries for interfacing with MacOS apis like NSWindow and WKWebkit
|
|
29
|
+
/Contents/MacOS/native/
|
|
30
|
+
|
|
31
|
+
// electrobun compiles your application's custom code here
|
|
32
|
+
/Contents/MacOS/Resources
|
|
33
|
+
|
|
34
|
+
// Your application icons
|
|
35
|
+
/Contents/MacOS/Resources/AppIcon.icns
|
|
36
|
+
|
|
37
|
+
// Local version info that `Electrobun.Updater` reads
|
|
38
|
+
/Contents/MacOS/Resources/version.json
|
|
39
|
+
|
|
40
|
+
// Folder containing the bundled javascript code for the main bun process.
|
|
41
|
+
// Use electrobun.config to tell Electrobun where your ts entrypoing is and
|
|
42
|
+
// define external dependencies
|
|
43
|
+
/Contents/MacOS/Resources/app/bun/
|
|
44
|
+
|
|
45
|
+
// This is where your views defined in electrobun.config are transpiled to
|
|
46
|
+
// Browserviews can also use the views:// url schema anywhere urls are loaded
|
|
47
|
+
// to load bundled static content from here.
|
|
48
|
+
/Contents/MacOS/Resources/app/views
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### IPC
|
|
52
|
+
|
|
53
|
+
In order to communicate between bun, zig, and browser contexts Electrobun has several mechanisms for establishing IPC between the processes involved. For the most part Electrobun uses efficient named pipes and serializes json rpc over the pipes.
|
|
54
|
+
|
|
55
|
+
#### Self-Extracting Bundle
|
|
56
|
+
|
|
57
|
+
Because zip file compression is not the best and we want apps you build with Electrobun to be as tiny as possible Electron automatically bundles your application into a self-extracting bundle. Electrobun takes your entire app bundle, tars it, compresses it with zlib which is fast best-in-class modern compression and creates a second app bundle for distribution.
|
|
58
|
+
|
|
59
|
+
:::info
|
|
60
|
+
The current Electrobun Playground app is **50.4MB** in size (most of this is the bun runtime), but when compressed and distributed as the self-extracting bundle it's only **13.1MB which is almost 5 times smaller**.
|
|
61
|
+
|
|
62
|
+
_Meaning almost 5 times as many users can download your app for the same cost in Storage and Network fees._
|
|
63
|
+
:::
|
|
64
|
+
|
|
65
|
+
The self-extracting bundle looks like this:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
// This is different from the regular launcher binary. It's a zig binary that uses zlip to decompress your actual app bundle
|
|
69
|
+
/Contents/MacOS/launcher
|
|
70
|
+
|
|
71
|
+
// App icons are actually stored again so the self-extractor looks just like your extracted bundled app.
|
|
72
|
+
/Contents/Resources/AppIcons.icns
|
|
73
|
+
|
|
74
|
+
// Your actual app bundled, tarred, and compressed with the name set to the hash
|
|
75
|
+
/Contents/Resources/23fajlkj2.tar.zst
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
A user can install the self-extracting bundle the same as any other application in the `/Applications/` folder or run it from any folder on your machine. When your end-user double clicks to open it, it will transparently self-extract and replace itself with your full application and then launch the full application. To your user it just looks like the first time opening your app takes 1 or 2 seconds longer.
|
|
79
|
+
|
|
80
|
+
The self-extraction process only happens on first install and is entirely local and self-contained using only a designated application support folder for your app for the extraction and verification.
|
|
81
|
+
|
|
82
|
+
#### DMG
|
|
83
|
+
|
|
84
|
+
Finally electrobun will automatically generate a DMG with the self-extracting bundle inside.
|
|
85
|
+
|
|
86
|
+
## Code Signing and Notarization
|
|
87
|
+
|
|
88
|
+
Electrobun will automatically code sign and notarize your application for you.
|
|
89
|
+
|
|
90
|
+
### MacOS
|
|
91
|
+
|
|
92
|
+
There is a prerequesite to register for an Apple Developer account and create an app id as well as download your code signing certificate. We'll have a guide that walks you through this process. There is no need to have any private keys in your code repo but you do need to set `codesigning` and `notarization` flags to `true` in your `electrobun.config` file and make some credentials available in your env.
|
|
93
|
+
|
|
94
|
+
On MacOS Electrobun will code sign and notarize both your app bundle **and** the self-extracting bundle so your end-users can be confident that what their installing is legitimately from you and has been scanned by Apple.
|
|
95
|
+
|
|
96
|
+
While code signing is generally very fast, notarization requires uploading a zip file to Apple's servers and waiting for them to scan and verify your app's code which typically takes about 1-2 minutes. The notarization is then stapled to your app bundle.
|
|
97
|
+
|
|
98
|
+
Because notarization can take time, in cases where a bug only exists on non-dev builds you can simply turn off code signing and/or notarization in your `electrobun.config` while debugging to speed up the build process.
|
|
99
|
+
|
|
100
|
+
Any notarization issues will be shown to you in the terminal so you can address them. This typically involves setting certain entitlements for your application so that your app declares what it uses to Apple and your end-users.
|
|
101
|
+
|
|
102
|
+
## Updating
|
|
103
|
+
|
|
104
|
+
Electrobun has a [built-in update mechanism](/docs/apis/bun/Updater) that optimizes updates for file-size and efficiency.
|
|
105
|
+
|
|
106
|
+
:::info
|
|
107
|
+
Ship updates to your users as small as 14KB. This lets your ship often without paying huge storage and network fees.
|
|
108
|
+
|
|
109
|
+
No server required, all you need is a static file host like S3 which you can put behind a CDN like Cloudfront. Most apps will fall well within AWS's free tier even if you ship updates often to many users.
|
|
110
|
+
:::
|
|
111
|
+
|
|
112
|
+
### How does it work
|
|
113
|
+
|
|
114
|
+
Using the [Electrobun Updater api](/docs/apis/bun/Updater) you can check for updates and automatically download, and install them. The flow looks something like:
|
|
115
|
+
|
|
116
|
+
1. Check the local version.json hash against the hosted update.json hash of the latest version.
|
|
117
|
+
2. If it's different download the tiny patch file that matches the hash you have (generated with BSDIFF) and apply it to the current bundle.
|
|
118
|
+
3. Generate a hash of the patched bundle. If it matches the latest hash then replace the running application with the latest version of the app and relaunch (you can control when with the api and let the user trigger this manually when they're ready)
|
|
119
|
+
4. If the hash does not match the latest look for another patch file and keep patching until it does.
|
|
120
|
+
5. If for some reason the algorithm can't patch its way to the latest version it will download a zlib compressed bundle from your static host and complete the update that way.
|
|
121
|
+
|
|
122
|
+
:::info
|
|
123
|
+
Whenever you build a non-dev build of your app the electrobun cli will automatically generate a patch from the current hosted version to the newly built version.
|
|
124
|
+
|
|
125
|
+
It's completely up to you how many patches you make available on your static host.
|
|
126
|
+
:::
|
|
127
|
+
|
|
128
|
+
## CLI and development builds
|
|
129
|
+
|
|
130
|
+
The Electrobun cli is automatically installed locally to your project when you `bun install electrobun`. You can then add npm scripts and an `electrobun.config` file to build your app.
|
|
131
|
+
|
|
132
|
+
### Development Builds
|
|
133
|
+
|
|
134
|
+
When building a `dev` build of your app instead of the optimized `launcher` binary the cli uses a special dev launcher binary which routes any bun, zig, and native output to your terminal.
|
|
135
|
+
|
|
136
|
+
Dev builds are not meant to be distributed and so the cli does not generate artifacts for dev builds.
|
|
137
|
+
|
|
138
|
+
### Distribution
|
|
139
|
+
|
|
140
|
+
Whne building `canary` and `stable` builds of your app Electrobun will generate an `artifacts` folder that contains everything you need to upload to a static host for distribution and updates.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## Introduction
|
|
2
|
+
|
|
3
|
+
We've implemented a batteries included update mechanism. All you need is to bring your own static file host like S3.
|
|
4
|
+
|
|
5
|
+
- [Update API](/docs/apis/bun/Updater) to check for, download, and update your apps.
|
|
6
|
+
- [CLI](/docs/apis/cli/cli%20args) to build your app bundle, codesign, and generate artifacts.
|
|
7
|
+
- A custom BSDIFF implementation in zig that lets you distribute updates as small as 14KB
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## Dependencies and Versions
|
|
2
|
+
|
|
3
|
+
| Dependency | Version | Notes |
|
|
4
|
+
| -------------------------- | ----------- | --------------------------------------------------------- |
|
|
5
|
+
| Bun | 1.8 | We will be upgrading to the latest version of bun soon |
|
|
6
|
+
| Zig | 0.8 | We will be upgrading to zig 0.13.0 soon |
|
|
7
|
+
| Building Electrobun apps | MacOS (arm) | No near-term plans to support building on other platforms |
|
|
8
|
+
| Distribute Electrobun apps | MacOS (arm) | Linux and Windows support coming soon |
|