Skip to content

Commit

Permalink
Dynamically pull down binary (#28)
Browse files Browse the repository at this point in the history
* Dynamically pull down binary

Pull the binary from GitHub releases unless the WEBVIEW_BIN env var is provided.

* Bump cargo version

* Delete misc file

* Add mechanism to automatically upgrade version
  • Loading branch information
zephraph authored Sep 21, 2024
1 parent 89256bb commit 2de97a4
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"editor.semanticHighlighting.enabled": true,
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"[json]": {
"editor.defaultFormatter": "denoland.vscode-deno"
}
}
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deno-webview"
version = "0.1.3"
version = "0.1.4"
edition = "2021"

[profile.release]
Expand Down
24 changes: 0 additions & 24 deletions ClientEvent.json

This file was deleted.

2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"tasks": {
"dev": "deno run --watch main.ts",
"gen": "cargo test && deno run -A scripts/generate-zod.ts",
"gen": "cargo test && deno run -A scripts/generate-zod.ts && deno run -A scripts/sync-versions.ts",
"build": "deno task gen && cargo build -F transparent",
"example:simple": "deno run -A examples/simple.ts"
}
Expand Down
23 changes: 23 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions examples/simple.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebView } from "../src/lib.ts";
import { createWebView } from "../src/lib.ts";

const webview = new WebView({
using webview = await createWebView({
title: "Simple",
html: "<h1>Hello, World!</h1>",
});
Expand Down
25 changes: 25 additions & 0 deletions scripts/sync-versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Keeps the version of the WebView binary in sync with the version in Cargo.toml.
*/

import { parse } from "jsr:@std/toml";

const latestVersion = await Deno
.readTextFile("./Cargo.toml").then((text) =>
parse(text) as { package: { version: string } }
).then((config) => config.package.version);

// Read the content of src/lib.ts
const libPath = "./src/lib.ts";
const libContent = await Deno.readTextFile(libPath);

// Replace the version in the URL
const updatedContent = libContent.replace(
/releases\/download\/v\d+\.\d+\.\d+\/deno-webview/,
`releases/download/v${latestVersion}/deno-webview`,
);

// Write the updated content back to src/lib.ts
await Deno.writeTextFile(libPath, updatedContent);

console.log(`Updated WebView binary version to ${latestVersion} in src/lib.ts`);
84 changes: 81 additions & 3 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
} from "./schemas.ts";
import { monotonicUlid as ulid } from "jsr:@std/ulid";
import type { Except } from "npm:type-fest";
import { join } from "jsr:@std/path";
import { ensureDir } from "jsr:@std/fs";
import { exists } from "jsr:@std/fs";

type JSON =
| string
Expand Down Expand Up @@ -68,7 +71,82 @@ const returnAck = (result: WebViewResponse) => {
}
};

export class WebView implements Disposable {
async function getWebViewBin(options: WebViewOptions) {
if (Deno.permissions.querySync({ name: "env" }).state === "granted") {
const binPath = Deno.env.get("WEBVIEW_BIN");
if (binPath) return binPath;
}

const flags = options.devtools
? "-devtools"
: options.transparent && Deno.build.os === "darwin"
? "-transparent"
: "";

const cacheDir = getCacheDir();
const fileName = `deno-webview${flags}${
Deno.build.os === "windows" ? ".exe" : ""
}`;
const filePath = join(cacheDir, fileName);

// Check if the file already exists in cache
if (await exists(filePath)) {
return filePath;
}

// If not in cache, download it
let url =
"https://github.com/zephraph/webview/releases/download/v0.1.4/deno-webview";
switch (Deno.build.os) {
case "darwin": {
url += "-mac" + flags;
break;
}
case "linux": {
url += "-linux" + flags;
break;
}
case "windows": {
url += "-windows" + flags + ".exe";
break;
}
default:
throw new Error("unsupported OS");
}

const res = await fetch(url);

// Ensure the cache directory exists
await ensureDir(cacheDir);

// Write the binary to disk
await Deno.writeFile(filePath, new Uint8Array(await res.arrayBuffer()), {
mode: 0o755,
});

return filePath;
}

// Helper function to get the OS-specific cache directory
function getCacheDir(): string {
switch (Deno.build.os) {
case "darwin":
return join(Deno.env.get("HOME")!, "Library", "Caches", "deno-webview");
case "linux":
return join(Deno.env.get("HOME")!, ".cache", "deno-webview");
case "windows":
return join(Deno.env.get("LOCALAPPDATA")!, "deno-webview", "Cache");
default:
throw new Error("Unsupported OS");
}
}

export async function createWebView(options: WebViewOptions) {
const binPath = await getWebViewBin(options);
return new WebView(options, binPath);
}

class WebView implements Disposable {
#process: Deno.ChildProcess;
#stdin: WritableStreamDefaultWriter;
#stdout: ReadableStreamDefaultReader;
Expand All @@ -77,8 +155,8 @@ export class WebView implements Disposable {
#externalEvent = new EventEmitter();
#messageLoop: Promise<void>;

constructor(options: WebViewOptions) {
this.#process = new Deno.Command("./target/debug/deno-webview", {
constructor(options: WebViewOptions, binPath: string) {
this.#process = new Deno.Command(binPath, {
args: [JSON.stringify(options)],
stdin: "piped",
stdout: "piped",
Expand Down
3 changes: 0 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ fn main() -> wry::Result<()> {
}
let window = window_builder.build(&event_loop).unwrap();

eprintln!("transparent: {:?}", webview_options.transparent);

let webview_builder = match webview_options.target {
WebViewTarget::Url(url) => WebViewBuilder::new(&window).with_url(url),
WebViewTarget::Html(html) => WebViewBuilder::new(&window).with_html(html),
Expand Down Expand Up @@ -171,7 +169,6 @@ fn main() -> wry::Result<()> {
let mut stdout_lock = stdout.lock();

while let Ok(event) = to_deno.recv() {
eprintln!("Sending event: {:?}", event);
match serde_json::to_string(&event) {
Ok(json) => {
let mut buffer = json.replace("\0", "").into_bytes();
Expand Down

0 comments on commit 2de97a4

Please sign in to comment.