Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions content/docs/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ These commands require `remote.*` settings in your [config](/docs/configuration)

### `wvb upload [BUNDLE] [VERSION]`

Upload a packed bundle to the remote, optionally computing integrity, signing it, and deploying.
Pack (by default) and upload a bundle to the remote, optionally computing integrity, signing it, and
deploying.

```sh
wvb upload # uses config defaults
Expand All @@ -85,15 +86,16 @@ wvb upload app 1.2.0 --deploy --channel beta
wvb upload --file ./dist/app.wvb --force
```

| Option | Description |
| ------------------- | ------------------------------------------------------------ |
| `BUNDLE`, `VERSION` | Bundle name and version (else from config / `package.json`). |
| `--file, -F` | Path to the `.wvb` to upload. |
| `--force` | Overwrite if the version already exists. |
| `--deploy` | Deploy after upload. Default `true`. |
| `--channel` | Channel to deploy to (with `--deploy`). |
| `--skip-integrity` | Don't compute an integrity hash. |
| `--skip-signature` | Don't sign the bundle. |
| Option | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------- |
| `BUNDLE`, `VERSION` | Bundle name and version (else from config / `package.json`). |
| `--file, -F` | Path to the `.wvb` to upload. |
| `--pack, -P` | Pack from `pack.srcDir` before uploading. Default `true` (pass `--no-pack` to upload an existing `.wvb`). |
| `--force` | Overwrite if the version already exists. |
| `--deploy` | Deploy after upload. Default `true`. |
| `--channel` | Channel to deploy to (with `--deploy`). |
| `--skip-integrity` | Don't compute an integrity hash. |
| `--skip-signature` | Don't sign the bundle. |

### `wvb deploy [BUNDLE] VERSION`

Expand All @@ -111,7 +113,7 @@ Download a bundle from the remote and (by default) save it to disk.
```sh
wvb download app --endpoint https://updates.example.com
wvb download app 1.2.0 --out ./bundles/app.wvb --overwrite
wvb download app --skip-write # fetch + print info only
wvb download app --no-write # fetch + print info only
```

| Option | Description |
Expand Down
4 changes: 2 additions & 2 deletions content/docs/concepts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ A Webview Bundle is a single file with three parts laid out back to back:
one-byte format version, a `u32` index size, and a checksum.
- **Index** — a map from each file path (e.g. `/index.html`) to where its bytes live in the data
section, plus its content type and any HTTP headers to replay when served.
- **Data** — each file's bytes compressed with [LZ4](https://github.com/lz4/lz4), each block
followed by an [xxHash-32](https://github.com/Cyan4973/xxHash) checksum.
- **Data** — each file's bytes are compressed with [LZ4](https://github.com/lz4/lz4) and followed by
an [xxHash-32](https://github.com/Cyan4973/xxHash) checksum.

Every section is checksummed, so a truncated or corrupted archive is detected before its contents
are trusted. The full byte-level specification is in the
Expand Down
31 changes: 16 additions & 15 deletions content/docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,22 @@ export default defineConfig(async () => ({
```ts
pack: {
srcDir: './dist',
outFile: 'app', // → app.wvb
outFileName: 'app', // → app.wvb
outDir: '.wvb',
ignore: ['*.map'],
headers: { '*.html': { 'cache-control': 'max-age=3600' } },
overwrite: true,
}
```

| Field | Type | Description |
| ----------- | ------------------------------------------------------------------------------- | ---------------------------------------------- |
| `srcDir` | `string` | Directory to pack. |
| `outFile` | `string` | Output file name (`.wvb` appended if missing). |
| `outDir` | `string` | Output directory. Default `.wvb`. |
| `ignore` | `Array<string \| RegExp> \| ((file) => boolean)` | Patterns/predicate to exclude files. |
| `headers` | `Record<glob, HeadersInit> \| [glob, HeadersInit][] \| ((file) => HeadersInit)` | HTTP headers to attach to matching files. |
| `overwrite` | `boolean` | Overwrite an existing output. Default `true`. |
| Field | Type | Description |
| ------------- | ------------------------------------------------------------------------------- | ---------------------------------------------- |
| `srcDir` | `string` | Directory to pack. |
| `outFileName` | `string` | Output file name (`.wvb` appended if missing). |
| `outDir` | `string` | Output directory. Default `.wvb`. |
| `ignore` | `Array<string \| RegExp> \| ((file) => boolean)` | Patterns/predicate to exclude files. |
| `headers` | `Record<glob, HeadersInit> \| [glob, HeadersInit][] \| ((file) => HeadersInit)` | HTTP headers to attach to matching files. |
| `overwrite` | `boolean` | Overwrite an existing output. Default `true`. |

## `remote`

Expand Down Expand Up @@ -166,9 +166,10 @@ builtin: {
}
```

| Field | Type | Description |
| ---------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------- |
| `outDir` | `string` | Where to write downloaded builtin bundles. Default `.wvb/builtin/bundles`. |
| `include` / `exclude` | `string \| RegExp \| Array<…> \| ((info) => boolean)` | Match remote bundles by name/version. |
| `clean` | `boolean` | Clear `outDir` before downloading. Default `true`. |
| `download.concurrency` | `number` | Parallel downloads. |
| Field | Type | Description |
| ----------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------- |
| `outDir` | `string` | Where to write downloaded builtin bundles. Default `.wvb/builtin/bundles`. |
| `target` | `BuiltinTarget` | Where to install from. Default `{ type: 'remote' }`. |
| `include` / `exclude` | `string \| RegExp \| Array<…> \| ((info) => boolean)` | Match remote bundles by name/version. |
| `clean` | `boolean` | Clear `outDir` before downloading. Default `true`. |
| `target.download.concurrency` | `number` | Parallel downloads (remote target). |
2 changes: 1 addition & 1 deletion content/docs/guides/android.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ val source = BundleSource(

// Query what's available:
val version = source.loadVersion("app") // current version (remote wins over builtin)
val bundle = source.fetch("app") // load a bundle into memory
val bundle = source.fetchBundle("app") // load a bundle into memory
val html = bundle.getData("/index.html") // ByteArray? — file bytes, or null
```

Expand Down
5 changes: 3 additions & 2 deletions content/docs/guides/electron.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ const version = await source.loadVersion('app');
// Is a newer version deployed?
const info = await updater.getUpdate('app');
if (info.isAvailable) {
await updater.downloadUpdate('app'); // downloads, verifies, installs
const downloaded = await updater.download('app'); // downloads + verifies, stages into the remote source
await updater.install('app', downloaded.version); // activates the downloaded version
// reload the window to pick up the new bundle
}
```
Expand Down Expand Up @@ -179,7 +180,7 @@ const config: ForgeConfig = {
`source` accepts `builtinDir` (shipped, read-only) and `remoteDir` (downloaded updates). A good
default is to ship `builtinDir` under `process.resourcesPath` and let `remoteDir` default to a
writable app-data location. Downloaded versions always take priority over builtin ones, so an
installed update is served automatically after `updater.downloadUpdate(...)`.
installed update is served automatically after `updater.download(...)` + `updater.install(...)`.

## Troubleshooting

Expand Down
2 changes: 1 addition & 1 deletion content/docs/guides/ios.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ let source = BundleSource(config: BundleSourceConfig(
))

// Query what's available:
let bundle = try await source.fetch(bundleName: "app") // load into memory
let bundle = try await source.fetchBundle(bundleName: "app") // load into memory
let html = try bundle.getData(path: "/index.html") // Data? — bytes or nil
```

Expand Down
29 changes: 16 additions & 13 deletions content/docs/guides/tauri.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ Point your app window at the custom scheme. The simplest approach is to set the
window to `bundle://app/` (production) or your dev server (development).

Make sure your capabilities allow the plugin's commands if you call them from the frontend. Add the
`wvb` permissions to `src-tauri/capabilities/default.json` as needed (the plugin namespace is
`wvb`).
`wvb-tauri` permissions to `src-tauri/capabilities/default.json` as needed (the plugin namespace is
`wvb-tauri`).

## 3. Pack and ship bundles

Expand All @@ -94,23 +94,25 @@ Config::new()
.remote(Remote::new("https://updates.example.com"));
```

The plugin then exposes these commands to the frontend via `invoke` (all under the `wvb` plugin
The plugin then exposes these commands to the frontend via `invoke` (all under the `wvb-tauri` plugin
namespace):

| Command | Arguments | Returns |
| ------------------------------------- | ------------------------ | ------------------------- |
| `plugin:wvb\|updater_get_update` | `bundleName` | update availability info |
| `plugin:wvb\|updater_download_update` | `bundleName`, `version?` | installed bundle metadata |
| `plugin:wvb\|source_load_version` | `bundleName` | active local version |
| `plugin:wvb\|source_list_bundles` | — | local bundles |
| `plugin:wvb\|remote_get_info` | `bundleName`, `channel?` | current remote metadata |
| Command | Arguments | Returns |
| --------------------------------------- | ------------------------ | ------------------------------ |
| `plugin:wvb-tauri\|updater_get_update` | `bundleName` | update availability info |
| `plugin:wvb-tauri\|updater_download` | `bundleName`, `version?` | downloaded bundle metadata |
| `plugin:wvb-tauri\|updater_install` | `bundleName`, `version` | activates a downloaded version |
| `plugin:wvb-tauri\|source_load_version` | `bundleName` | active local version |
| `plugin:wvb-tauri\|source_list_bundles` | — | local bundles |
| `plugin:wvb-tauri\|remote_get_info` | `bundleName`, `channel?` | current remote metadata |

```ts
import { invoke } from '@tauri-apps/api/core';

const update = await invoke('plugin:wvb|updater_get_update', { bundleName: 'app' });
const update = await invoke('plugin:wvb-tauri|updater_get_update', { bundleName: 'app' });
if (update.isAvailable) {
await invoke('plugin:wvb|updater_download_update', { bundleName: 'app' });
const info = await invoke('plugin:wvb-tauri|updater_download', { bundleName: 'app' });
await invoke('plugin:wvb-tauri|updater_install', { bundleName: 'app', version: info.version });
// reload the webview to pick up the new bundle
}
```
Expand All @@ -130,7 +132,8 @@ use wvb_tauri::WebviewBundleExtra;
let wvb = app.wvb();
let bundles = wvb.source().list_bundles().await?;
if let Some(updater) = wvb.updater() {
updater.download_update("app", None).await?;
let info = updater.download("app", None).await?; // download + verify, stage into the remote source
updater.install("app", info.version).await?; // activate the downloaded version
}
```

Expand Down
28 changes: 14 additions & 14 deletions content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ through a custom URL scheme — and can update over the air without an app-store
release required.
- **Integrity & authenticity.** Every bundle carries checksums, and downloads can be verified with
SHA-3 integrity hashes and digital signatures (ECDSA, Ed25519, RSA).
- **One format, every platform.** The same `.wvb` archive works in Electron, Tauri, Android, and
iOS via a shared Rust core.
- **One format, every platform.** The same `.wvb` archive runs in Electron and Tauri today via a
shared Rust core, with Android and iOS support planned.

## Start here

Expand Down Expand Up @@ -73,27 +73,27 @@ Then pick your platform guide:
<Card
title="Android"
href="/docs/guides/android"
description="Serve a WebView from a bundle with the Kotlin bindings."
description="Serve a WebView from a bundle with the Kotlin bindings (planned — under development)."
/>
<Card
title="iOS"
href="/docs/guides/ios"
description="Serve a WKWebView from a bundle with the Swift bindings."
description="Serve a WKWebView from a bundle with the Swift bindings (planned — under development)."
/>
</Cards>

## Packages

| Package | What it is | Where it runs |
| ---------------------------- | --------------------------------------------------------------------------------- | ---------------------- |
| [`wvb`](https://docs.rs/wvb) | Rust core: bundle format, source, remote, updater, protocol, integrity, signature | everywhere (library) |
| `@wvb/cli` (`wvb`) | Command-line tool: pack, serve, upload, deploy, download, local remote | your machine / CI |
| `@wvb/config` | `defineConfig` for `wvb.config.ts` | build tooling |
| `@wvb/node` | N-API bindings to the core | Node.js |
| `@wvb/electron` | Electron integration (protocols, IPC, updater) | Electron main/renderer |
| `wvb-tauri` | Tauri plugin (protocols, commands, updater) | Tauri app |
| `wvb-ffi` | UniFFI bindings (Kotlin/Swift) | Android / iOS |
| `@wvb/remote-*` | Remote server providers (local, AWS, Cloudflare) | your update backend |
| Package | What it is | Where it runs |
| ---------------------------- | --------------------------------------------------------------------------------- | ----------------------- |
| [`wvb`](https://docs.rs/wvb) | Rust core: bundle format, source, remote, updater, protocol, integrity, signature | everywhere (library) |
| `@wvb/cli` (`wvb`) | Command-line tool: pack, serve, upload, deploy, download, local remote | your machine / CI |
| `@wvb/config` | `defineConfig` for `wvb.config.ts` | build tooling |
| `@wvb/node` | N-API bindings to the core | Node.js |
| `@wvb/electron` | Electron integration (protocols, IPC, updater) | Electron main/renderer |
| `wvb-tauri` | Tauri plugin (protocols, commands, updater) | Tauri app |
| `wvb-ffi` | UniFFI bindings (Kotlin/Swift) | Android / iOS (planned) |
| `@wvb/remote-*` | Remote server providers (local, AWS, Cloudflare) | your update backend |

## The bundle format in one line

Expand Down
Loading