aboutsummaryrefslogtreecommitdiff
path: root/src/node_module_bundle.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-06 18:34:01 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-06 18:34:01 -0700
commitd49e0a5fa129152c27b70a57d1cc7a2af770577c (patch)
tree1ac581bda71fec5dfd09a6ab508a1adfca80b358 /src/node_module_bundle.zig
parente66466cc1a453db1370a199a32729441747761bb (diff)
downloadbun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.tar.gz
bun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.tar.zst
bun-d49e0a5fa129152c27b70a57d1cc7a2af770577c.zip
WIP node module bundles
Former-commit-id: 797b2ff557542e9d318c953b840b102695711888
Diffstat (limited to 'src/node_module_bundle.zig')
-rw-r--r--src/node_module_bundle.zig69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig
new file mode 100644
index 000000000..11150f376
--- /dev/null
+++ b/src/node_module_bundle.zig
@@ -0,0 +1,69 @@
+const Api = @import("./api/schema.zig").Api;
+const std = @import("std");
+usingnamespace @import("global.zig");
+
+pub const NodeModuleBundle = struct {
+ container: *Api.JavascriptBundleContainer,
+ bundle: *Api.JavascriptBundle,
+ allocator: *std.mem.Allocator,
+ fd: FileDescriptorType = 0,
+
+ pub const magic_bytes = "#!/usr/bin/env speedy\n\n";
+ threadlocal var jsbundle_prefix: [magic_bytes.len + 5]u8 = undefined;
+
+ pub fn getCodeEndPosition(stream: anytype, comptime needs_seek: bool) !u32 {
+ if (needs_seek) try stream.seekTo(0);
+
+ const read_bytes = try stream.read(&jsbundle_prefix);
+ if (read_bytes != jsbundle_prefix.len) {
+ return error.JSBundleBadHeaderTooShort;
+ }
+
+ return std.mem.readIntNative(u32, jsbundle_prefix[magic_bytes.len .. magic_bytes.len + 4]);
+ }
+
+ pub fn loadBundle(allocator: *std.mem.Allocator, stream: anytype) !NodeModuleBundle {
+ const end = try getCodeEndPosition(stream);
+ try stream.seekTo(end + 1);
+ var reader = stream.reader();
+ var container = try Api.JavascriptBundleContainer.decode(allocator, reader);
+ return NodeModuleBundle{
+ .allocator = allocator,
+ .container = container,
+ .bundle = container.bundle,
+ .fd = if (std.meta.trait.hasField("handle")(stream)) stream.handle else 0,
+ };
+ }
+
+ pub fn printBundle(
+ comptime StreamType: type,
+ input: StreamType,
+ comptime DestinationStreamType: type,
+ output: DestinationStreamType,
+ ) !void {
+ const BufferStreamContext = struct {
+ pub fn run(in: StreamType, out: DestinationStreamType, end_at: u32) !void {
+ var buf: [4096]u8 = undefined;
+ var remain = @intCast(i64, end_at);
+ var read_amount: i64 = @intCast(i64, in.read(&buf) catch 0);
+ while (remain > 0 and read_amount > 0) {
+ remain -= @intCast(i64, try out.write(buf[0..@intCast(usize, std.math.min(read_amount, remain))]));
+ read_amount = @intCast(i64, in.read(&buf) catch 0);
+ }
+
+ _ = try out.write(buf[0..@intCast(usize, remain + 1)]);
+ }
+ };
+ if (isMac) {
+ // darwin only allows reading ahead on/off, not specific amount
+ _ = std.os.fcntl(input.handle, std.os.F_RDAHEAD, 1) catch 0;
+ }
+ const end = try getCodeEndPosition(input, false);
+
+ try BufferStreamContext.run(
+ input,
+ output,
+ end,
+ );
+ }
+};