Skip to content

Commit

Permalink
feat: added support for wasm2js
Browse files Browse the repository at this point in the history
This is *extremely* preliminary, and Perseus provides almost no support
for this. This just makes the server integrations host a
`bundle.wasm.js` file, there is no inbuilt facility for transpiling from
Wasm to JS.
  • Loading branch information
arctic-hen7 committed Jan 24, 2022
1 parent 51422ed commit ce07134
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 0 deletions.
2 changes: 2 additions & 0 deletions examples/basic/.perseus/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ fn get_props(is_standalone: bool) -> ServerProps<impl MutableStore, impl Transla
js_bundle: "dist/pkg/perseus_engine.js".to_string(),
// Our crate has the same name, so this will be predictable
wasm_bundle: "dist/pkg/perseus_engine_bg.wasm".to_string(),
// This probably won't exist, but on the off chance that the user needs to support older browsers, we'll provide it anyway
wasm_js_bundle: "dist/pkg/perseus_engine_bg.wasm.js".to_string(),
// It's a nightmare to get the templates map to take plugins, so we use a self-contained version
// TODO reduce allocations here
templates_map: get_templates_map_atomic_contained(),
Expand Down
4 changes: 4 additions & 0 deletions packages/perseus-actix-web/src/configurer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ async fn js_bundle(opts: web::Data<Rc<ServerOptions>>) -> std::io::Result<NamedF
async fn wasm_bundle(opts: web::Data<Rc<ServerOptions>>) -> std::io::Result<NamedFile> {
NamedFile::open(&opts.wasm_bundle)
}
async fn wasm_js_bundle(opts: web::Data<Rc<ServerOptions>>) -> std::io::Result<NamedFile> {
NamedFile::open(&opts.wasm_js_bundle)
}
async fn static_alias(
opts: web::Data<Rc<ServerOptions>>,
req: HttpRequest,
Expand Down Expand Up @@ -79,6 +82,7 @@ pub async fn configurer<M: MutableStore + 'static, T: TranslationsManager + 'sta
// This contains everything in the spirit of a pseudo-SPA
.route("/.perseus/bundle.js", web::get().to(js_bundle))
.route("/.perseus/bundle.wasm", web::get().to(wasm_bundle))
.route("/.perseus/bundle.wasm.js", web::get().to(wasm_js_bundle))
// This allows getting the static HTML/JSON of a page
// We stream both together in a single JSON object so SSR works (otherwise we'd have request IDs and weird caching...)
// A request to this should also provide the template name (routing should only be done once on the client) as a query parameter
Expand Down
4 changes: 4 additions & 0 deletions packages/perseus-warp/src/perseus_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub async fn perseus_routes<M: MutableStore + 'static, T: TranslationsManager +
let wasm_bundle = warp::path!(".perseus" / "bundle.wasm")
.and(warp::path::end())
.and(warp::fs::file(opts.wasm_bundle.clone()));
let wasm_js_bundle = warp::path!(".perseus" / "bundle.wasm.js")
.and(warp::path::end())
.and(warp::fs::file(opts.wasm_js_bundle.clone()));
// Handle JS interop snippets (which need to be served as separate files)
let snippets = warp::path!(".perseus" / "snippets").and(warp::fs::dir(opts.snippets.clone()));
// Handle static content in the user-set directories (this will all be under `/.perseus/static`)
Expand Down Expand Up @@ -121,6 +124,7 @@ pub async fn perseus_routes<M: MutableStore + 'static, T: TranslationsManager +
// Now put all those routes together in the final thing (the user will add this to an existing Warp server)
js_bundle
.or(wasm_bundle)
.or(wasm_js_bundle)
.or(snippets)
.or(static_dir)
.or(static_aliases)
Expand Down
14 changes: 14 additions & 0 deletions packages/perseus/src/server/html_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ impl<'a> HtmlShell<'a> {
}

// Define the script that will load the Wasm bundle (inlined to avoid unnecessary extra requests)
// If we're using the `wasm2js` feature, this will try to load a JS version instead (expected to be at `/.perseus/bundle.wasm.js`)
#[cfg(not(feature = "wasm2js"))]
let load_wasm_bundle = format!(
r#"
import init, {{ run }} from "{path_prefix}/.perseus/bundle.js";
Expand All @@ -72,6 +74,18 @@ impl<'a> HtmlShell<'a> {
"#,
path_prefix = path_prefix
);
#[cfg(feature = "wasm2js")]
let load_wasm_bundle = format!(
r#"
import init, {{ run }} from "{path_prefix}/.perseus/bundle.js";
async function main() {{
await init("{path_prefix}/.perseus/bundle.wasm.js");
run();
}}
main();
"#,
path_prefix = path_prefix
);
scripts_before_boundary.push(load_wasm_bundle.into());

// Add in the `<base>` element at the very top so that it applies to everything in the HTML shell
Expand Down
2 changes: 2 additions & 0 deletions packages/perseus/src/server/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub struct ServerOptions {
pub js_bundle: String,
/// The location on the filesystem of your Wasm bundle.
pub wasm_bundle: String,
/// The location on the filesystem of your JS bundle converted from your Wasm bundle. This isn't required, and if you haven't generated this, you should provide a fake path.
pub wasm_js_bundle: String,
/// The location on the filesystem of your `index.html` file.
// TODO Should this actually be a raw string of HTML so plugins can inject efficiently?
pub index: String,
Expand Down

0 comments on commit ce07134

Please sign in to comment.