From 5d46749b074631c9e9680c6ae9972c1ab3cd70cd Mon Sep 17 00:00:00 2001 From: zenith391 <39484230+zenith391@users.noreply.github.com> Date: Sun, 10 Nov 2024 10:58:04 +0100 Subject: [PATCH] build(wasm): embed HTML files in the builder The `prefix` path had stopped working following the latest Zig update, which means an alternative had to be found that doesn't depend on `@src().file` (which now only returns paths relative to the module root). For now, the best solution I've found is to embed the files in the WebServerStep. --- build_capy.zig | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/build_capy.zig b/build_capy.zig index a57fa16..889f207 100644 --- a/build_capy.zig +++ b/build_capy.zig @@ -91,7 +91,6 @@ const WebServerStep = struct { fn handler(self: *WebServerStep, build: *std.Build, res: *Server) !void { const allocator = build.allocator; - const prefix = (comptime std.fs.path.dirname(@src().file) orelse "./") ++ std.fs.path.sep_str; var req = try res.receiveHead(); var arena = std.heap.ArenaAllocator.init(allocator); @@ -100,10 +99,17 @@ const WebServerStep = struct { const path = req.head.target; var file_path: []const u8 = ""; + var file_content: ?[]const u8 = null; var content_type: []const u8 = "text/html"; if (std.mem.eql(u8, path, "/")) { - file_path = try std.fs.path.join(req_allocator, &.{ prefix, "src/backends/wasm/index.html" }); + file_content = @embedFile("src/backends/wasm/index.html"); content_type = "text/html"; + } else if (std.mem.eql(u8, path, "/capy.js")) { + file_content = @embedFile("src/backends/wasm/capy.js"); + content_type = "application/javascript"; + } else if (std.mem.eql(u8, path, "/capy-worker.js")) { + file_content = @embedFile("src/backends/wasm/capy-worker.js"); + content_type = "application/javascript"; } else if (std.mem.eql(u8, path, "/zig-app.wasm")) { file_path = self.exe.getEmittedBin().getPath2(build, &self.step); content_type = "application/wasm"; @@ -113,28 +119,34 @@ const WebServerStep = struct { content_type = "application/javascript"; } } else { - file_path = try std.fs.path.join(req_allocator, &.{ prefix, "src/backends/wasm", path }); + // else try the HTML files supplied by the application (in the 'html' project relative + // to the project root) + file_path = try std.fs.path.join(req_allocator, &.{ "html", path }); content_type = "application/javascript"; } if (self.options.wasm_debug_requests) { std.log.debug("{s} -> {s}", .{ path, file_path }); } - const file: ?std.fs.File = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| blk: { - switch (err) { - error.FileNotFound => break :blk null, - else => return err, - } - }; var status: std.http.Status = .ok; const content = blk: { - if (file) |f| { - defer f.close(); - break :blk try f.readToEndAlloc(req_allocator, std.math.maxInt(usize)); + if (file_content) |presupplied_content| { + break :blk presupplied_content; } else { - status = .not_found; - break :blk "404 Not Found"; + const file: ?std.fs.File = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| blk2: { + switch (err) { + error.FileNotFound => break :blk2 null, + else => return err, + } + }; + if (file) |f| { + defer f.close(); + break :blk try f.readToEndAlloc(req_allocator, std.math.maxInt(usize)); + } else { + status = .not_found; + break :blk "404 Not Found"; + } } };