aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/schema.zig1644
-rw-r--r--src/bundler.zig135
-rw-r--r--src/cli.zig34
-rw-r--r--src/darwin_c.zig7
-rw-r--r--src/deps/zig-clap/clap/streaming.zig2
-rw-r--r--src/global.zig161
-rw-r--r--src/main.zig3
-rw-r--r--src/node_module_bundle.zig136
8 files changed, 1194 insertions, 928 deletions
diff --git a/src/api/schema.zig b/src/api/schema.zig
index 54f854db6..0e7cb6fcc 100644
--- a/src/api/schema.zig
+++ b/src/api/schema.zig
@@ -1,5 +1,279 @@
const std = @import("std");
+pub const Reader = struct {
+ const Self = @This();
+ pub const ReadError = error{EOF};
+
+ buf: []u8,
+ remain: []u8,
+ allocator: *std.mem.Allocator,
+
+ pub fn init(buf: []u8, allocator: *std.mem.Allocator) Reader {
+ return Reader{
+ .buf = buf,
+ .remain = buf,
+ .allocator = allocator,
+ };
+ }
+
+ pub fn read(this: *Self, count: usize) ![]u8 {
+ const read_count = std.math.min(count, this.remain.len);
+ if (read_count < count) {
+ return error.EOF;
+ }
+
+ var slice = this.remain[0..read_count];
+
+ this.remain = this.remain[read_count..];
+
+ return slice;
+ }
+
+ pub fn readAs(this: *Self, comptime T: type) !T {
+ if (!std.meta.trait.hasUniqueRepresentation(T)) {
+ @compileError(@typeName(T) ++ " must have unique representation.");
+ }
+
+ return std.mem.bytesAsValue(T, try this.read(@sizeOf(T)));
+ }
+
+ pub fn readByte(this: *Self) !u8 {
+ return (try this.read(1))[0];
+ }
+
+ pub fn readEnum(this: *Self, comptime Enum: type) !Enum {
+ const E = error{
+ /// An integer was read, but it did not match any of the tags in the supplied enum.
+ InvalidValue,
+ };
+ const type_info = @typeInfo(Enum).Enum;
+ const tag = try this.readInt(type_info.tag_type);
+
+ inline for (std.meta.fields(Enum)) |field| {
+ if (tag == field.value) {
+ return @field(Enum, field.name);
+ }
+ }
+
+ return E.InvalidValue;
+ }
+
+ pub fn readArray(this: *Self, comptime T: type) ![]T {
+ const length = try this.readInt(u32);
+ if (length == 0) {
+ return &([_]T{});
+ }
+
+ switch (T) {
+ u8 => {
+ return try this.read(length);
+ },
+ u16, u32, i8, i16, i32 => {
+ return std.mem.readIntSliceNative(T, this.read(length * @sizeOf(T)));
+ },
+ []const u8 => {
+ var i: u32 = 0;
+ var array = try this.allocator.alloc([]const u8, length);
+ while (i < length) : (i += 1) {
+ array[i] = try this.readArray(u8);
+ }
+ return array;
+ },
+ else => {
+ switch (@typeInfo(T)) {
+ .Struct => |Struct| {
+ switch (Struct.layout) {
+ .Packed => {
+ const sizeof = @sizeOf(T);
+ var slice = try this.read(sizeof * length);
+ return std.mem.bytesAsSlice(T, slice);
+ },
+ else => {},
+ }
+ },
+ .Enum => |type_info| {
+ return std.meta.cast([]T, std.mem.readIntSliceNative(type_info.tag_type, try this.read(length * @sizeOf(type_info.tag_type))));
+ },
+ else => {},
+ }
+
+ var i: u32 = 0;
+ var array = try this.allocator.alloc(T, length);
+ while (i < length) : (i += 1) {
+ array[i] = try this.readValue(T);
+ }
+
+ return array;
+ },
+ }
+ }
+
+ pub fn readByteArray(this: *Self) ![]u8 {
+ const length = try this.readInt(u32);
+ if (length == 0) {
+ return &([_]u8{});
+ }
+
+ return try this.read(@intCast(usize, length));
+ }
+
+ pub fn readInt(this: *Self, comptime T: type) !T {
+ var slice = try this.read(@sizeOf(T));
+
+ return std.mem.readIntSliceNative(T, slice);
+ }
+
+ pub fn readBool(this: *Self) !bool {
+ return (try this.readByte()) > 0;
+ }
+
+ pub fn readValue(this: *Self, comptime T: type) !T {
+ switch (T) {
+ bool => {
+ return try this.readBool();
+ },
+ u8 => {
+ return try this.readByte();
+ },
+ []const u8 => {
+ return try this.readArray([]const u8);
+ },
+ []u8 => {
+ return try this.readArray([]u8);
+ },
+ u16, u32, i8, i16, i32 => {
+ return std.mem.readIntSliceNative(T, try this.read(@sizeOf(T)));
+ },
+ else => {
+ switch (@typeInfo(T)) {
+ .Struct => |Struct| {
+ switch (Struct.layout) {
+ .Packed => {
+ const sizeof = @sizeOf(T);
+ var slice = try this.read(sizeof);
+ return @ptrCast(*T, slice[0..sizeof]).*;
+ },
+ else => {},
+ }
+ },
+ .Enum => |type_info| {
+ return try this.readEnum(T);
+ },
+ else => {},
+ }
+
+ return try T.decode(this);
+ },
+ }
+
+ @compileError("Invalid type passed to readValue");
+ }
+};
+
+pub fn Writer(comptime WritableStream: type) type {
+ return struct {
+ const Self = @This();
+ writable: WritableStream,
+
+ pub fn init(writable: WritableStream) Self {
+ return Self{ .writable = writable };
+ }
+
+ pub fn write(this: *Self, bytes: anytype) !void {
+ _ = try this.writable.write(bytes);
+ }
+
+ pub fn writeByte(this: *Self, byte: u8) !void {
+ _ = try this.writable.write(&[1]u8{byte});
+ }
+
+ pub fn writeInt(this: *Self, int: anytype) !void {
+ try this.write(std.mem.asBytes(&int));
+ }
+
+ pub fn writeFieldID(this: *Self, comptime id: comptime_int) !void {
+ try this.writeByte(id);
+ }
+
+ pub fn writeEnum(this: *Self, val: anytype) !void {
+ try this.writeInt(@enumToInt(val));
+ }
+
+ pub fn writeValue(this: *Self, slice: anytype) !void {
+ switch (@TypeOf(slice)) {
+ []u8,
+ []u16,
+ []u32,
+ []i16,
+ []i32,
+ []i8,
+ []const u8,
+ []const u16,
+ []const u32,
+ []const i16,
+ []const i32,
+ []const i8,
+ => {
+ try this.writeArray(@TypeOf(slice), slice);
+ },
+
+ u8 => {
+ try this.write(slice);
+ },
+ u16, u32, i16, i32, i8 => {
+ try this.write(std.mem.asBytes(slice));
+ },
+
+ else => {
+ try slice.encode(this);
+ },
+ }
+ }
+
+ pub fn writeArray(this: *Self, comptime T: type, slice: anytype) !void {
+ try this.writeInt(@truncate(u32, slice.len));
+
+ switch (T) {
+ u8 => {
+ try this.write(slice);
+ },
+ u16, u32, i16, i32, i8 => {
+ try this.write(std.mem.asBytes(slice));
+ },
+ []u8,
+ []u16,
+ []u32,
+ []i16,
+ []i32,
+ []i8,
+ []const u8,
+ []const u16,
+ []const u32,
+ []const i16,
+ []const i32,
+ []const i8,
+ => {
+ for (slice) |num_slice| {
+ try this.writeArray(std.meta.Child(@TypeOf(num_slice)), num_slice);
+ }
+ },
+ else => {
+ for (slice) |val| {
+ try val.encode(this);
+ }
+ },
+ }
+ }
+
+ pub fn endMessage(this: *Self) !void {
+ try this.writeByte(0);
+ }
+ };
+}
+
+pub const ByteWriter = Writer(std.io.FixedBufferStream([]u8));
+pub const FileWriter = Writer(std.fs.File);
+
pub const Api = struct {
pub const Loader = enum(u8) {
_none,
@@ -101,76 +375,46 @@ pub const Api = struct {
/// react_fast_refresh
react_fast_refresh: bool = false,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Jsx {
- var obj = std.mem.zeroes(Jsx);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *Jsx, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = try reader.readIntNative(u32);
- if (result.factory.len != length) {
- result.factory = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.factory);
- result.runtime = try reader.readEnum(JsxRuntime, .Little);
- length = try reader.readIntNative(u32);
- if (result.fragment.len != length) {
- result.fragment = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.fragment);
- result.development = (try reader.readByte()) == @as(u8, 1);
- length = try reader.readIntNative(u32);
- if (result.import_source.len != length) {
- result.import_source = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.import_source);
- result.react_fast_refresh = (try reader.readByte()) == @as(u8, 1);
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(u32, @intCast(u32, result.factory.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.factory));
-
- try writer.writeIntNative(@TypeOf(@enumToInt(result.runtime)), @enumToInt(result.runtime));
-
- try writer.writeIntNative(u32, @intCast(u32, result.fragment.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.fragment));
-
- try writer.writeByte(@boolToInt(result.development));
+ pub fn decode(reader: anytype) anyerror!Jsx {
+ var this = std.mem.zeroes(Jsx);
- try writer.writeIntNative(u32, @intCast(u32, result.import_source.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.import_source));
+ this.factory = try reader.readValue([]const u8);
+ this.runtime = try reader.readValue(JsxRuntime);
+ this.fragment = try reader.readValue([]const u8);
+ this.development = try reader.readValue(bool);
+ this.import_source = try reader.readValue([]const u8);
+ this.react_fast_refresh = try reader.readValue(bool);
+ return this;
+ }
- try writer.writeByte(@boolToInt(result.react_fast_refresh));
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.factory);
+ try writer.writeEnum(this.runtime);
+ try writer.writeValue(this.fragment);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.development)));
+ try writer.writeValue(this.import_source);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.react_fast_refresh)));
}
};
- pub const StringPointer = struct {
+ pub const StringPointer = packed struct {
/// offset
offset: u32 = 0,
/// length
length: u32 = 0,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!StringPointer {
- var obj = std.mem.zeroes(StringPointer);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *StringPointer, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- _ = try reader.readAll(std.mem.asBytes(&result.offset));
- _ = try reader.readAll(std.mem.asBytes(&result.length));
- return;
- }
+ pub fn decode(reader: anytype) anyerror!StringPointer {
+ var this = std.mem.zeroes(StringPointer);
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(u32, result.offset);
+ this.offset = try reader.readValue(u32);
+ this.length = try reader.readValue(u32);
+ return this;
+ }
- try writer.writeIntNative(u32, result.length);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.offset);
+ try writer.writeInt(this.length);
}
};
@@ -184,25 +428,19 @@ pub const Api = struct {
/// package_id
package_id: u32 = 0,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!JavascriptBundledModule {
- var obj = std.mem.zeroes(JavascriptBundledModule);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *JavascriptBundledModule, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- result.path = try StringPointer.decode(allocator, reader);
- result.code = try StringPointer.decode(allocator, reader);
- _ = try reader.readAll(std.mem.asBytes(&result.package_id));
- return;
- }
+ pub fn decode(reader: anytype) anyerror!JavascriptBundledModule {
+ var this = std.mem.zeroes(JavascriptBundledModule);
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try result.path.encode(writer);
-
- try result.code.encode(writer);
+ this.path = try reader.readValue(StringPointer);
+ this.code = try reader.readValue(StringPointer);
+ this.package_id = try reader.readValue(u32);
+ return this;
+ }
- try writer.writeIntNative(u32, result.package_id);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.path);
+ try writer.writeValue(this.code);
+ try writer.writeInt(this.package_id);
}
};
@@ -222,31 +460,23 @@ pub const Api = struct {
/// modules_length
modules_length: u32 = 0,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!JavascriptBundledPackage {
- var obj = std.mem.zeroes(JavascriptBundledPackage);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *JavascriptBundledPackage, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- result.name = try StringPointer.decode(allocator, reader);
- result.version = try StringPointer.decode(allocator, reader);
- _ = try reader.readAll(std.mem.asBytes(&result.hash));
- _ = try reader.readAll(std.mem.asBytes(&result.modules_offset));
- _ = try reader.readAll(std.mem.asBytes(&result.modules_length));
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try result.name.encode(writer);
-
- try result.version.encode(writer);
+ pub fn decode(reader: anytype) anyerror!JavascriptBundledPackage {
+ var this = std.mem.zeroes(JavascriptBundledPackage);
- try writer.writeIntNative(u32, result.hash);
-
- try writer.writeIntNative(u32, result.modules_offset);
+ this.name = try reader.readValue(StringPointer);
+ this.version = try reader.readValue(StringPointer);
+ this.hash = try reader.readValue(u32);
+ this.modules_offset = try reader.readValue(u32);
+ this.modules_length = try reader.readValue(u32);
+ return this;
+ }
- try writer.writeIntNative(u32, result.modules_length);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.name);
+ try writer.writeValue(this.version);
+ try writer.writeInt(this.hash);
+ try writer.writeInt(this.modules_offset);
+ try writer.writeInt(this.modules_length);
}
};
@@ -272,87 +502,27 @@ pub const Api = struct {
/// manifest_string
manifest_string: []const u8,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!JavascriptBundle {
- var obj = std.mem.zeroes(JavascriptBundle);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *JavascriptBundle, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = try reader.readIntNative(u32);
- result.modules = try allocator.alloc(JavascriptBundledModule, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.modules[j] = try JavascriptBundledModule.decode(allocator, reader);
- }
- }
- length = try reader.readIntNative(u32);
- result.packages = try allocator.alloc(JavascriptBundledPackage, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.packages[j] = try JavascriptBundledPackage.decode(allocator, reader);
- }
- }
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.etag != length) {
- result.etag = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.etag);
- _ = try reader.readAll(std.mem.asBytes(&result.generated_at));
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.app_package_json_dependencies_hash != length) {
- result.app_package_json_dependencies_hash = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.app_package_json_dependencies_hash);
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.import_from_name != length) {
- result.import_from_name = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.import_from_name);
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.manifest_string != length) {
- result.manifest_string = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.manifest_string);
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- n = result.modules.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.modules[j].encode(writer);
- }
- }
-
- n = result.packages.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.packages[j].encode(writer);
- }
- }
-
- try writer.writeIntNative(u32, @intCast(u32, result.etag.len));
- try writer.writeAll(result.etag);
-
- try writer.writeIntNative(u32, result.generated_at);
-
- try writer.writeIntNative(u32, @intCast(u32, result.app_package_json_dependencies_hash.len));
- try writer.writeAll(result.app_package_json_dependencies_hash);
-
- try writer.writeIntNative(u32, @intCast(u32, result.import_from_name.len));
- try writer.writeAll(result.import_from_name);
+ pub fn decode(reader: anytype) anyerror!JavascriptBundle {
+ var this = std.mem.zeroes(JavascriptBundle);
+
+ this.modules = try reader.readArray(JavascriptBundledModule);
+ this.packages = try reader.readArray(JavascriptBundledPackage);
+ this.etag = try reader.readArray(u8);
+ this.generated_at = try reader.readValue(u32);
+ this.app_package_json_dependencies_hash = try reader.readArray(u8);
+ this.import_from_name = try reader.readArray(u8);
+ this.manifest_string = try reader.readArray(u8);
+ return this;
+ }
- try writer.writeIntNative(u32, @intCast(u32, result.manifest_string.len));
- try writer.writeAll(result.manifest_string);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(JavascriptBundledModule, this.modules);
+ try writer.writeArray(JavascriptBundledPackage, this.packages);
+ try writer.writeArray(u8, this.etag);
+ try writer.writeInt(this.generated_at);
+ try writer.writeArray(u8, this.app_package_json_dependencies_hash);
+ try writer.writeArray(u8, this.import_from_name);
+ try writer.writeArray(u8, this.manifest_string);
}
};
@@ -366,52 +536,46 @@ pub const Api = struct {
/// code_length
code_length: ?u32 = null,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!JavascriptBundleContainer {
- var obj = std.mem.zeroes(JavascriptBundleContainer);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *JavascriptBundleContainer, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
+ pub fn decode(reader: anytype) anyerror!JavascriptBundleContainer {
+ var this = std.mem.zeroes(JavascriptBundleContainer);
+
while (true) {
- const field_type: u8 = try reader.readByte();
- switch (field_type) {
+ switch (try reader.readByte()) {
0 => {
- return;
+ return this;
},
1 => {
- _ = try reader.readAll(std.mem.asBytes(&result.bundle_format_version));
+ this.bundle_format_version = try reader.readValue(u32);
},
2 => {
- result.bundle = try JavascriptBundle.decode(allocator, reader);
+ this.bundle = try reader.readValue(JavascriptBundle);
},
3 => {
- _ = try reader.readAll(std.mem.asBytes(&result.code_length));
+ this.code_length = try reader.readValue(u32);
},
else => {
return error.InvalidMessage;
},
}
}
+ unreachable;
}
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- if (result.bundle_format_version) |bundle_format_version| {
- try writer.writeByte(1);
- try writer.writeIntNative(u32, bundle_format_version);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.bundle_format_version) |bundle_format_version| {
+ try writer.writeFieldID(1);
+ try writer.writeInt(bundle_format_version);
}
-
- if (result.bundle) |bundle| {
- try writer.writeByte(2);
- try bundle.encode(writer);
+ if (this.bundle) |bundle| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(bundle);
}
-
- if (result.code_length) |code_length| {
- try writer.writeByte(3);
- try writer.writeIntNative(u32, code_length);
+ if (this.code_length) |code_length| {
+ try writer.writeFieldID(3);
+ try writer.writeInt(code_length);
}
- try writer.writeByte(0);
- return;
+ try writer.endMessage();
}
};
@@ -455,31 +619,19 @@ pub const Api = struct {
/// dynamic
dynamic: bool = false,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!ModuleImportRecord {
- var obj = std.mem.zeroes(ModuleImportRecord);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *ModuleImportRecord, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- result.kind = try reader.readEnum(ModuleImportType, .Little);
- length = try reader.readIntNative(u32);
- if (result.path.len != length) {
- result.path = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.path);
- result.dynamic = (try reader.readByte()) == @as(u8, 1);
- return;
- }
+ pub fn decode(reader: anytype) anyerror!ModuleImportRecord {
+ var this = std.mem.zeroes(ModuleImportRecord);
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(@TypeOf(@enumToInt(result.kind)), @enumToInt(result.kind));
-
- try writer.writeIntNative(u32, @intCast(u32, result.path.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.path));
+ this.kind = try reader.readValue(ModuleImportType);
+ this.path = try reader.readValue([]const u8);
+ this.dynamic = try reader.readValue(bool);
+ return this;
+ }
- try writer.writeByte(@boolToInt(result.dynamic));
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.kind);
+ try writer.writeValue(this.path);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.dynamic)));
}
};
@@ -490,43 +642,17 @@ pub const Api = struct {
/// imports
imports: []ModuleImportRecord,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Module {
- var obj = std.mem.zeroes(Module);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *Module, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = try reader.readIntNative(u32);
- if (result.path.len != length) {
- result.path = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.path);
- length = try reader.readIntNative(u32);
- result.imports = try allocator.alloc(ModuleImportRecord, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.imports[j] = try ModuleImportRecord.decode(allocator, reader);
- }
- }
- return;
- }
+ pub fn decode(reader: anytype) anyerror!Module {
+ var this = std.mem.zeroes(Module);
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- try writer.writeIntNative(u32, @intCast(u32, result.path.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.path));
+ this.path = try reader.readValue([]const u8);
+ this.imports = try reader.readArray(ModuleImportRecord);
+ return this;
+ }
- n = result.imports.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.imports[j].encode(writer);
- }
- }
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.path);
+ try writer.writeArray(ModuleImportRecord, this.imports);
}
};
@@ -597,407 +723,179 @@ pub const Api = struct {
/// generate_node_module_bundle
generate_node_module_bundle: ?bool = null,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!TransformOptions {
- var obj = std.mem.zeroes(TransformOptions);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *TransformOptions, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
+ pub fn decode(reader: anytype) anyerror!TransformOptions {
+ var this = std.mem.zeroes(TransformOptions);
+
while (true) {
- const field_type: u8 = try reader.readByte();
- switch (field_type) {
+ switch (try reader.readByte()) {
0 => {
- return;
+ return this;
},
1 => {
- result.jsx = try Jsx.decode(allocator, reader);
+ this.jsx = try reader.readValue(Jsx);
},
2 => {
- length = try reader.readIntNative(u32);
- if ((result.tsconfig_override orelse &([_]u8{})).len != length) {
- result.tsconfig_override = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.tsconfig_override.?);
+ this.tsconfig_override = try reader.readValue([]const u8);
},
3 => {
- result.resolve = try reader.readEnum(ResolveMode, .Little);
+ this.resolve = try reader.readValue(ResolveMode);
},
4 => {
- length = try reader.readIntNative(u32);
- if ((result.public_url orelse &([_]u8{})).len != length) {
- result.public_url = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.public_url.?);
+ this.public_url = try reader.readValue([]const u8);
},
5 => {
- length = try reader.readIntNative(u32);
- if ((result.absolute_working_dir orelse &([_]u8{})).len != length) {
- result.absolute_working_dir = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.absolute_working_dir.?);
+ this.absolute_working_dir = try reader.readValue([]const u8);
},
6 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.define_keys.len) {
- result.define_keys = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.define_keys) |content, j| {
- if (result.define_keys[j].len != length and length > 0) {
- result.define_keys[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.define_keys[j].?);
- }
- }
+ this.define_keys = try reader.readArray([]const u8);
},
7 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.define_values.len) {
- result.define_values = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.define_values) |content, j| {
- if (result.define_values[j].len != length and length > 0) {
- result.define_values[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.define_values[j].?);
- }
- }
+ this.define_values = try reader.readArray([]const u8);
},
8 => {
- result.preserve_symlinks = (try reader.readByte()) == @as(u8, 1);
+ this.preserve_symlinks = try reader.readValue(bool);
},
9 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.entry_points.len) {
- result.entry_points = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.entry_points) |content, j| {
- if (result.entry_points[j].len != length and length > 0) {
- result.entry_points[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.entry_points[j].?);
- }
- }
+ this.entry_points = try reader.readArray([]const u8);
},
10 => {
- result.write = (try reader.readByte()) == @as(u8, 1);
+ this.write = try reader.readValue(bool);
},
11 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.inject.len) {
- result.inject = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.inject) |content, j| {
- if (result.inject[j].len != length and length > 0) {
- result.inject[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.inject[j].?);
- }
- }
+ this.inject = try reader.readArray([]const u8);
},
12 => {
- length = try reader.readIntNative(u32);
- if ((result.output_dir orelse &([_]u8{})).len != length) {
- result.output_dir = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.output_dir.?);
+ this.output_dir = try reader.readValue([]const u8);
},
13 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.external.len) {
- result.external = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.external) |content, j| {
- if (result.external[j].len != length and length > 0) {
- result.external[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.external[j].?);
- }
- }
+ this.external = try reader.readArray([]const u8);
},
14 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.loader_keys.len) {
- result.loader_keys = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.loader_keys) |content, j| {
- if (result.loader_keys[j].len != length and length > 0) {
- result.loader_keys[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.loader_keys[j].?);
- }
- }
+ this.loader_keys = try reader.readArray([]const u8);
},
15 => {
- length = try reader.readIntNative(u32);
- if (result.loader_values != length) {
- result.loader_values = try allocator.alloc(Loader, length);
- }
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.loader_values[j] = try reader.readEnum(Loader, .Little);
- }
- }
+ this.loader_values = try reader.readArray(Loader);
},
16 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.main_fields.len) {
- result.main_fields = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.main_fields) |content, j| {
- if (result.main_fields[j].len != length and length > 0) {
- result.main_fields[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.main_fields[j].?);
- }
- }
+ this.main_fields = try reader.readArray([]const u8);
},
17 => {
- result.platform = try reader.readEnum(Platform, .Little);
+ this.platform = try reader.readValue(Platform);
},
18 => {
- result.serve = (try reader.readByte()) == @as(u8, 1);
+ this.serve = try reader.readValue(bool);
},
19 => {
- {
- var array_count = try reader.readIntNative(u32);
- if (array_count != result.extension_order.len) {
- result.extension_order = try allocator.alloc([]const u8, array_count);
- }
- length = try reader.readIntNative(u32);
- for (result.extension_order) |content, j| {
- if (result.extension_order[j].len != length and length > 0) {
- result.extension_order[j] = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.extension_order[j].?);
- }
- }
+ this.extension_order = try reader.readArray([]const u8);
},
20 => {
- length = try reader.readIntNative(u32);
- if ((result.public_dir orelse &([_]u8{})).len != length) {
- result.public_dir = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.public_dir.?);
+ this.public_dir = try reader.readValue([]const u8);
},
21 => {
- result.only_scan_dependencies = try reader.readEnum(ScanDependencyMode, .Little);
+ this.only_scan_dependencies = try reader.readValue(ScanDependencyMode);
},
22 => {
- result.generate_node_module_bundle = (try reader.readByte()) == @as(u8, 1);
+ this.generate_node_module_bundle = try reader.readValue(bool);
},
else => {
return error.InvalidMessage;
},
}
}
+ unreachable;
}
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- if (result.jsx) |jsx| {
- try writer.writeByte(1);
- try jsx.encode(writer);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.jsx) |jsx| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(jsx);
}
-
- if (result.tsconfig_override) |tsconfig_override| {
- try writer.writeByte(2);
- try writer.writeIntNative(u32, @intCast(u32, tsconfig_override.len));
- try writer.writeAll(std.mem.sliceAsBytes(tsconfig_override));
+ if (this.tsconfig_override) |tsconfig_override| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(tsconfig_override);
}
-
- if (result.resolve) |resolve| {
- try writer.writeByte(3);
- try writer.writeIntNative(@TypeOf(@enumToInt(result.resolve orelse unreachable)), @enumToInt(result.resolve orelse unreachable));
+ if (this.resolve) |resolve| {
+ try writer.writeFieldID(3);
+ try writer.writeEnum(resolve);
}
-
- if (result.public_url) |public_url| {
- try writer.writeByte(4);
- try writer.writeIntNative(u32, @intCast(u32, public_url.len));
- try writer.writeAll(std.mem.sliceAsBytes(public_url));
+ if (this.public_url) |public_url| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(public_url);
}
-
- if (result.absolute_working_dir) |absolute_working_dir| {
- try writer.writeByte(5);
- try writer.writeIntNative(u32, @intCast(u32, absolute_working_dir.len));
- try writer.writeAll(std.mem.sliceAsBytes(absolute_working_dir));
+ if (this.absolute_working_dir) |absolute_working_dir| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(absolute_working_dir);
}
-
- if (result.define_keys) |define_keys| {
- try writer.writeByte(6);
- n = result.define_keys.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.define_keys[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(define_keys[j]));
- }
- }
+ if (this.define_keys) |define_keys| {
+ try writer.writeFieldID(6);
+ try writer.writeArray([]const u8, define_keys);
}
-
- if (result.define_values) |define_values| {
- try writer.writeByte(7);
- n = result.define_values.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.define_values[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(define_values[j]));
- }
- }
+ if (this.define_values) |define_values| {
+ try writer.writeFieldID(7);
+ try writer.writeArray([]const u8, define_values);
}
-
- if (result.preserve_symlinks) |preserve_symlinks| {
- try writer.writeByte(8);
- try writer.writeByte(@boolToInt(preserve_symlinks));
+ if (this.preserve_symlinks) |preserve_symlinks| {
+ try writer.writeFieldID(8);
+ try writer.writeInt(@intCast(u8, @boolToInt(preserve_symlinks)));
}
-
- if (result.entry_points) |entry_points| {
- try writer.writeByte(9);
- n = result.entry_points.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.entry_points[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(entry_points[j]));
- }
- }
+ if (this.entry_points) |entry_points| {
+ try writer.writeFieldID(9);
+ try writer.writeArray([]const u8, entry_points);
}
-
- if (result.write) |write| {
- try writer.writeByte(10);
- try writer.writeByte(@boolToInt(write));
+ if (this.write) |write| {
+ try writer.writeFieldID(10);
+ try writer.writeInt(@intCast(u8, @boolToInt(write)));
}
-
- if (result.inject) |inject| {
- try writer.writeByte(11);
- n = result.inject.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.inject[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(inject[j]));
- }
- }
+ if (this.inject) |inject| {
+ try writer.writeFieldID(11);
+ try writer.writeArray([]const u8, inject);
}
-
- if (result.output_dir) |output_dir| {
- try writer.writeByte(12);
- try writer.writeIntNative(u32, @intCast(u32, output_dir.len));
- try writer.writeAll(std.mem.sliceAsBytes(output_dir));
+ if (this.output_dir) |output_dir| {
+ try writer.writeFieldID(12);
+ try writer.writeValue(output_dir);
}
-
- if (result.external) |external| {
- try writer.writeByte(13);
- n = result.external.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.external[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(external[j]));
- }
- }
+ if (this.external) |external| {
+ try writer.writeFieldID(13);
+ try writer.writeArray([]const u8, external);
}
-
- if (result.loader_keys) |loader_keys| {
- try writer.writeByte(14);
- n = result.loader_keys.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.loader_keys[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(loader_keys[j]));
- }
- }
+ if (this.loader_keys) |loader_keys| {
+ try writer.writeFieldID(14);
+ try writer.writeArray([]const u8, loader_keys);
}
-
- if (result.loader_values) |loader_values| {
- try writer.writeByte(15);
- n = result.loader_values.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try writer.writeByte(@enumToInt(result.loader_values[j] orelse unreachable));
- }
- }
+ if (this.loader_values) |loader_values| {
+ try writer.writeFieldID(15);
+ try writer.writeArray(Loader, loader_values);
}
-
- if (result.main_fields) |main_fields| {
- try writer.writeByte(16);
- n = result.main_fields.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.main_fields[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(main_fields[j]));
- }
- }
+ if (this.main_fields) |main_fields| {
+ try writer.writeFieldID(16);
+ try writer.writeArray([]const u8, main_fields);
}
-
- if (result.platform) |platform| {
- try writer.writeByte(17);
- try writer.writeIntNative(@TypeOf(@enumToInt(result.platform orelse unreachable)), @enumToInt(result.platform orelse unreachable));
+ if (this.platform) |platform| {
+ try writer.writeFieldID(17);
+ try writer.writeEnum(platform);
}
-
- if (result.serve) |serve| {
- try writer.writeByte(18);
- try writer.writeByte(@boolToInt(serve));
+ if (this.serve) |serve| {
+ try writer.writeFieldID(18);
+ try writer.writeInt(@intCast(u8, @boolToInt(serve)));
}
-
- if (result.extension_order) |extension_order| {
- try writer.writeByte(19);
- n = result.extension_order.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- _ = try writer.writeIntNative(u32, @intCast(u32, result.extension_order[j].len));
- try writer.writeAll(std.mem.sliceAsBytes(extension_order[j]));
- }
- }
+ if (this.extension_order) |extension_order| {
+ try writer.writeFieldID(19);
+ try writer.writeArray([]const u8, extension_order);
}
-
- if (result.public_dir) |public_dir| {
- try writer.writeByte(20);
- try writer.writeIntNative(u32, @intCast(u32, public_dir.len));
- try writer.writeAll(std.mem.sliceAsBytes(public_dir));
+ if (this.public_dir) |public_dir| {
+ try writer.writeFieldID(20);
+ try writer.writeValue(public_dir);
}
-
- if (result.only_scan_dependencies) |only_scan_dependencies| {
- try writer.writeByte(21);
- try writer.writeIntNative(@TypeOf(@enumToInt(result.only_scan_dependencies orelse unreachable)), @enumToInt(result.only_scan_dependencies orelse unreachable));
+ if (this.only_scan_dependencies) |only_scan_dependencies| {
+ try writer.writeFieldID(21);
+ try writer.writeEnum(only_scan_dependencies);
}
-
- if (result.generate_node_module_bundle) |generate_node_module_bundle| {
- try writer.writeByte(22);
- try writer.writeByte(@boolToInt(generate_node_module_bundle));
+ if (this.generate_node_module_bundle) |generate_node_module_bundle| {
+ try writer.writeFieldID(22);
+ try writer.writeInt(@intCast(u8, @boolToInt(generate_node_module_bundle)));
}
- try writer.writeByte(0);
- return;
+ try writer.endMessage();
}
};
@@ -1011,31 +909,19 @@ pub const Api = struct {
/// fd
fd: u32 = 0,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!FileHandle {
- var obj = std.mem.zeroes(FileHandle);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *FileHandle, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = try reader.readIntNative(u32);
- if (result.path.len != length) {
- result.path = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.path);
- _ = try reader.readAll(std.mem.asBytes(&result.size));
- _ = try reader.readAll(std.mem.asBytes(&result.fd));
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(u32, @intCast(u32, result.path.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.path));
+ pub fn decode(reader: anytype) anyerror!FileHandle {
+ var this = std.mem.zeroes(FileHandle);
- try writer.writeIntNative(u32, result.size);
+ this.path = try reader.readValue([]const u8);
+ this.size = try reader.readValue(u32);
+ this.fd = try reader.readValue(u32);
+ return this;
+ }
- try writer.writeIntNative(u32, result.fd);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.path);
+ try writer.writeInt(this.size);
+ try writer.writeInt(this.fd);
}
};
@@ -1055,79 +941,60 @@ pub const Api = struct {
/// options
options: ?TransformOptions = null,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Transform {
- var obj = std.mem.zeroes(Transform);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *Transform, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
+ pub fn decode(reader: anytype) anyerror!Transform {
+ var this = std.mem.zeroes(Transform);
+
while (true) {
- const field_type: u8 = try reader.readByte();
- switch (field_type) {
+ switch (try reader.readByte()) {
0 => {
- return;
+ return this;
},
1 => {
- result.handle = try FileHandle.decode(allocator, reader);
+ this.handle = try reader.readValue(FileHandle);
},
2 => {
- length = try reader.readIntNative(u32);
- if ((result.path orelse &([_]u8{})).len != length) {
- result.path = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.path.?);
+ this.path = try reader.readValue([]const u8);
},
3 => {
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.contents != length) {
- result.contents = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.contents);
+ this.contents = try reader.readArray(u8);
},
4 => {
- result.loader = try reader.readEnum(Loader, .Little);
+ this.loader = try reader.readValue(Loader);
},
5 => {
- result.options = try TransformOptions.decode(allocator, reader);
+ this.options = try reader.readValue(TransformOptions);
},
else => {
return error.InvalidMessage;
},
}
}
+ unreachable;
}
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- if (result.handle) |handle| {
- try writer.writeByte(1);
- try handle.encode(writer);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.handle) |handle| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(handle);
}
-
- if (result.path) |path| {
- try writer.writeByte(2);
- try writer.writeIntNative(u32, @intCast(u32, path.len));
- try writer.writeAll(std.mem.sliceAsBytes(path));
+ if (this.path) |path| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(path);
}
-
- if (result.contents) |contents| {
- try writer.writeByte(3);
- try writer.writeIntNative(u32, @intCast(u32, contents.len));
- try writer.writeAll(contents);
+ if (this.contents) |contents| {
+ try writer.writeFieldID(3);
+ try writer.writeArray(u8, contents);
}
-
- if (result.loader) |loader| {
- try writer.writeByte(4);
- try writer.writeIntNative(@TypeOf(@enumToInt(result.loader orelse unreachable)), @enumToInt(result.loader orelse unreachable));
+ if (this.loader) |loader| {
+ try writer.writeFieldID(4);
+ try writer.writeEnum(loader);
}
-
- if (result.options) |options| {
- try writer.writeByte(5);
- try options.encode(writer);
+ if (this.options) |options| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(options);
}
- try writer.writeByte(0);
- return;
+ try writer.endMessage();
}
};
@@ -1153,33 +1020,17 @@ pub const Api = struct {
/// path
path: []const u8,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!OutputFile {
- var obj = std.mem.zeroes(OutputFile);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *OutputFile, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = @intCast(usize, try reader.readIntNative(u32));
- if (result.data != length) {
- result.data = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.data);
- length = try reader.readIntNative(u32);
- if (result.path.len != length) {
- result.path = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.path);
- return;
- }
+ pub fn decode(reader: anytype) anyerror!OutputFile {
+ var this = std.mem.zeroes(OutputFile);
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(u32, @intCast(u32, result.data.len));
- try writer.writeAll(result.data);
+ this.data = try reader.readArray(u8);
+ this.path = try reader.readValue([]const u8);
+ return this;
+ }
- try writer.writeIntNative(u32, @intCast(u32, result.path.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.path));
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u8, this.data);
+ try writer.writeValue(this.path);
}
};
@@ -1193,55 +1044,19 @@ pub const Api = struct {
/// errors
errors: []Message,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!TransformResponse {
- var obj = std.mem.zeroes(TransformResponse);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *TransformResponse, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- result.status = try reader.readEnum(TransformResponseStatus, .Little);
- length = try reader.readIntNative(u32);
- result.files = try allocator.alloc(OutputFile, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.files[j] = try OutputFile.decode(allocator, reader);
- }
- }
- length = try reader.readIntNative(u32);
- result.errors = try allocator.alloc(Message, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.errors[j] = try Message.decode(allocator, reader);
- }
- }
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- try writer.writeIntNative(@TypeOf(@enumToInt(result.status)), @enumToInt(result.status));
+ pub fn decode(reader: anytype) anyerror!TransformResponse {
+ var this = std.mem.zeroes(TransformResponse);
- n = result.files.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.files[j].encode(writer);
- }
- }
+ this.status = try reader.readValue(TransformResponseStatus);
+ this.files = try reader.readArray(OutputFile);
+ this.errors = try reader.readArray(Message);
+ return this;
+ }
- n = result.errors.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.errors[j].encode(writer);
- }
- }
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.status);
+ try writer.writeArray(OutputFile, this.files);
+ try writer.writeArray(Message, this.errors);
}
};
@@ -1288,58 +1103,27 @@ pub const Api = struct {
/// offset
offset: u32 = 0,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Location {
- var obj = std.mem.zeroes(Location);
- try update(&obj, allocator, reader);
- return obj;
+ pub fn decode(reader: anytype) anyerror!Location {
+ var this = std.mem.zeroes(Location);
+
+ this.file = try reader.readValue([]const u8);
+ this.namespace = try reader.readValue([]const u8);
+ this.line = try reader.readValue(i32);
+ this.column = try reader.readValue(i32);
+ this.line_text = try reader.readValue([]const u8);
+ this.suggestion = try reader.readValue([]const u8);
+ this.offset = try reader.readValue(u32);
+ return this;
}
- pub fn update(result: *Location, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- length = try reader.readIntNative(u32);
- if (result.file.len != length) {
- result.file = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.file);
- length = try reader.readIntNative(u32);
- if (result.namespace.len != length) {
- result.namespace = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.namespace);
- _ = try reader.readAll(std.mem.asBytes(&result.line));
- _ = try reader.readAll(std.mem.asBytes(&result.column));
- length = try reader.readIntNative(u32);
- if (result.line_text.len != length) {
- result.line_text = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.line_text);
- length = try reader.readIntNative(u32);
- if (result.suggestion.len != length) {
- result.suggestion = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.suggestion);
- _ = try reader.readAll(std.mem.asBytes(&result.offset));
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- try writer.writeIntNative(u32, @intCast(u32, result.file.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.file));
-
- try writer.writeIntNative(u32, @intCast(u32, result.namespace.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.namespace));
-
- try writer.writeIntNative(i32, result.line);
-
- try writer.writeIntNative(i32, result.column);
- try writer.writeIntNative(u32, @intCast(u32, result.line_text.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.line_text));
-
- try writer.writeIntNative(u32, @intCast(u32, result.suggestion.len));
- try writer.writeAll(std.mem.sliceAsBytes(result.suggestion));
-
- try writer.writeIntNative(u32, result.offset);
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.file);
+ try writer.writeValue(this.namespace);
+ try writer.writeInt(this.line);
+ try writer.writeInt(this.column);
+ try writer.writeValue(this.line_text);
+ try writer.writeValue(this.suggestion);
+ try writer.writeInt(this.offset);
}
};
@@ -1350,50 +1134,39 @@ pub const Api = struct {
/// location
location: ?Location = null,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!MessageData {
- var obj = std.mem.zeroes(MessageData);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *MessageData, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
+ pub fn decode(reader: anytype) anyerror!MessageData {
+ var this = std.mem.zeroes(MessageData);
+
while (true) {
- const field_type: u8 = try reader.readByte();
- switch (field_type) {
+ switch (try reader.readByte()) {
0 => {
- return;
+ return this;
},
1 => {
- length = try reader.readIntNative(u32);
- if ((result.text orelse &([_]u8{})).len != length) {
- result.text = try allocator.alloc(u8, length);
- }
- _ = try reader.readAll(result.text.?);
+ this.text = try reader.readValue([]const u8);
},
2 => {
- result.location = try Location.decode(allocator, reader);
+ this.location = try reader.readValue(Location);
},
else => {
return error.InvalidMessage;
},
}
}
+ unreachable;
}
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- if (result.text) |text| {
- try writer.writeByte(1);
- try writer.writeIntNative(u32, @intCast(u32, text.len));
- try writer.writeAll(std.mem.sliceAsBytes(text));
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.text) |text| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(text);
}
-
- if (result.location) |location| {
- try writer.writeByte(2);
- try location.encode(writer);
+ if (this.location) |location| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(location);
}
- try writer.writeByte(0);
- return;
+ try writer.endMessage();
}
};
@@ -1407,41 +1180,19 @@ pub const Api = struct {
/// notes
notes: []MessageData,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Message {
- var obj = std.mem.zeroes(Message);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *Message, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- result.kind = try reader.readEnum(MessageKind, .Little);
- result.data = try MessageData.decode(allocator, reader);
- length = try reader.readIntNative(u32);
- result.notes = try allocator.alloc(MessageData, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.notes[j] = try MessageData.decode(allocator, reader);
- }
- }
- return;
- }
-
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- try writer.writeIntNative(@TypeOf(@enumToInt(result.kind)), @enumToInt(result.kind));
+ pub fn decode(reader: anytype) anyerror!Message {
+ var this = std.mem.zeroes(Message);
- try result.data.encode(writer);
+ this.kind = try reader.readValue(MessageKind);
+ this.data = try reader.readValue(MessageData);
+ this.notes = try reader.readArray(MessageData);
+ return this;
+ }
- n = result.notes.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.notes[j].encode(writer);
- }
- }
- return;
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.kind);
+ try writer.writeValue(this.data);
+ try writer.writeArray(MessageData, this.notes);
}
};
@@ -1455,41 +1206,198 @@ pub const Api = struct {
/// msgs
msgs: []Message,
- pub fn decode(allocator: *std.mem.Allocator, reader: anytype) anyerror!Log {
- var obj = std.mem.zeroes(Log);
- try update(&obj, allocator, reader);
- return obj;
- }
- pub fn update(result: *Log, allocator: *std.mem.Allocator, reader: anytype) anyerror!void {
- var length: usize = 0;
- _ = try reader.readAll(std.mem.asBytes(&result.warnings));
- _ = try reader.readAll(std.mem.asBytes(&result.errors));
- length = try reader.readIntNative(u32);
- result.msgs = try allocator.alloc(Message, length);
- {
- var j: usize = 0;
- while (j < length) : (j += 1) {
- result.msgs[j] = try Message.decode(allocator, reader);
- }
- }
- return;
+ pub fn decode(reader: anytype) anyerror!Log {
+ var this = std.mem.zeroes(Log);
+
+ this.warnings = try reader.readValue(u32);
+ this.errors = try reader.readValue(u32);
+ this.msgs = try reader.readArray(Message);
+ return this;
}
- pub fn encode(result: *const @This(), writer: anytype) anyerror!void {
- var n: usize = 0;
- try writer.writeIntNative(u32, result.warnings);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.warnings);
+ try writer.writeInt(this.errors);
+ try writer.writeArray(Message, this.msgs);
+ }
+ };
+};
- try writer.writeIntNative(u32, result.errors);
+const ExamplePackedStruct = packed struct {
+ len: u32 = 0,
+ offset: u32 = 0,
- n = result.msgs.len;
- _ = try writer.writeIntNative(u32, @intCast(u32, n));
- {
- var j: usize = 0;
- while (j < n) : (j += 1) {
- try result.msgs[j].encode(writer);
- }
+ pub fn encode(this: *const ExamplePackedStruct, writer: anytype) !void {
+ try writer.write(std.mem.asBytes(this));
+ }
+
+ pub fn decode(reader: anytype) !ExamplePackedStruct {
+ return try reader.readAs(ExamplePackedStruct);
+ }
+};
+
+const ExampleStruct = struct {
+ name: []const u8 = "",
+ age: u32 = 0,
+
+ pub fn encode(this: *const ExampleStruct, writer: anytype) !void {
+ try writer.writeArray(u8, this.name);
+ try writer.writeInt(this.age);
+ }
+
+ pub fn decode(reader: anytype) !ExampleStruct {
+ var this = std.mem.zeroes(ExampleStruct);
+ this.name = try reader.readArray(u8);
+ this.age = try reader.readInt(u32);
+
+ return this;
+ }
+};
+
+const EnumValue = enum(u8) { hey, hi, heyopoo };
+
+const ExampleMessage = struct {
+ examples: ?[]ExampleStruct = &([_]ExampleStruct{}),
+ pack: ?[]ExamplePackedStruct = &([_]ExamplePackedStruct{}),
+ hey: ?u8 = 0,
+ hey16: ?u16 = 0,
+ hey32: ?u16 = 0,
+ heyi32: ?i32 = 0,
+ heyi16: ?i16 = 0,
+ heyi8: ?i8 = 0,
+ boolean: ?bool = null,
+ heyooo: ?EnumValue = null,
+
+ pub fn encode(this: *const ExampleMessage, writer: anytype) !void {
+ if (this.examples) |examples| {
+ try writer.writeFieldID(1);
+ try writer.writeArray(ExampleStruct, examples);
+ }
+
+ if (this.pack) |pack| {
+ try writer.writeFieldID(2);
+ try writer.writeArray(ExamplePackedStruct, pack);
+ }
+
+ if (this.hey) |hey| {
+ try writer.writeFieldID(3);
+ try writer.writeInt(hey);
+ }
+ if (this.hey16) |hey16| {
+ try writer.writeFieldID(4);
+ try writer.writeInt(hey16);
+ }
+ if (this.hey32) |hey32| {
+ try writer.writeFieldID(5);
+ try writer.writeInt(hey32);
+ }
+ if (this.heyi32) |heyi32| {
+ try writer.writeFieldID(6);
+ try writer.writeInt(heyi32);
+ }
+ if (this.heyi16) |heyi16| {
+ try writer.writeFieldID(7);
+ try writer.writeInt(heyi16);
+ }
+ if (this.heyi8) |heyi8| {
+ try writer.writeFieldID(8);
+ try writer.writeInt(heyi8);
+ }
+ if (this.boolean) |boolean| {
+ try writer.writeFieldID(9);
+ try writer.writeInt(boolean);
+ }
+
+ if (this.heyooo) |heyoo| {
+ try writer.writeFieldID(10);
+ try writer.writeEnum(heyoo);
+ }
+
+ try writer.endMessage();
+ }
+
+ pub fn decode(reader: anytype) !ExampleMessage {
+ var this = std.mem.zeroes(ExampleMessage);
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
+
+ 1 => {
+ this.examples = try reader.readArray(std.meta.Child(@TypeOf(this.examples.?)));
+ },
+ 2 => {
+ this.pack = try reader.readArray(std.meta.Child(@TypeOf(this.pack.?)));
+ },
+ 3 => {
+ this.hey = try reader.readValue(@TypeOf(this.hey.?));
+ },
+ 4 => {
+ this.hey16 = try reader.readValue(@TypeOf(this.hey16.?));
+ },
+ 5 => {
+ this.hey32 = try reader.readValue(@TypeOf(this.hey32.?));
+ },
+ 6 => {
+ this.heyi32 = try reader.readValue(@TypeOf(this.heyi32.?));
+ },
+ 7 => {
+ this.heyi16 = try reader.readValue(@TypeOf(this.heyi16.?));
+ },
+ 8 => {
+ this.heyi8 = try reader.readValue(@TypeOf(this.heyi8.?));
+ },
+ 9 => {
+ this.boolean = try reader.readValue(@TypeOf(this.boolean.?));
+ },
+ 10 => {
+ this.heyooo = try reader.readValue(@TypeOf(this.heyooo.?));
+ },
+ else => {
+ return error.InvalidValue;
+ },
}
- return;
}
- };
+
+ return this;
+ }
};
+
+test "ExampleMessage" {
+ var base = std.mem.zeroes(ExampleMessage);
+ base.hey = 1;
+ var buf: [4096]u8 = undefined;
+ var writable = std.io.fixedBufferStream(&buf);
+ var writer = ByteWriter.init(writable);
+ var examples = [_]ExamplePackedStruct{
+ .{ .len = 2, .offset = 5 },
+ .{ .len = 0, .offset = 10 },
+ };
+
+ var more_examples = [_]ExampleStruct{
+ .{ .name = "bacon", .age = 10 },
+ .{ .name = "slime", .age = 300 },
+ };
+ base.examples = &more_examples;
+ base.pack = &examples;
+ base.heyooo = EnumValue.hey;
+ try base.encode(&writer);
+ var reader = Reader.init(&buf, std.heap.c_allocator);
+ var compare = try ExampleMessage.decode(&reader);
+ try std.testing.expectEqual(base.hey orelse 255, 1);
+
+ const cmp_pack = compare.pack.?;
+ for (cmp_pack) |item, id| {
+ try std.testing.expectEqual(item, examples[id]);
+ }
+
+ const cmp_ex = compare.examples.?;
+ for (cmp_ex) |item, id| {
+ try std.testing.expectEqualStrings(item.name, more_examples[id].name);
+ try std.testing.expectEqual(item.age, more_examples[id].age);
+ }
+
+ try std.testing.expectEqual(cmp_pack[0].len, examples[0].len);
+ try std.testing.expectEqual(base.heyooo, compare.heyooo);
+}
diff --git a/src/bundler.zig b/src/bundler.zig
index 708a9d616..9b8ac11b3 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -14,7 +14,8 @@ usingnamespace @import("ast/base.zig");
usingnamespace @import("defines.zig");
const panicky = @import("panic_handler.zig");
const Fs = @import("fs.zig");
-const Api = @import("api/schema.zig").Api;
+const schema = @import("api/schema.zig");
+const Api = schema.Api;
const _resolver = @import("./resolver/resolver.zig");
const sync = @import("sync.zig");
const ThreadPool = sync.ThreadPool;
@@ -264,11 +265,11 @@ pub fn NewBundler(cache_files: bool) type {
};
}
- pub fn generate(bundler: *ThisBundler, allocator: *std.mem.Allocator) !void {
+ pub fn generate(bundler: *ThisBundler, allocator: *std.mem.Allocator, destination: string) !Api.JavascriptBundleContainer {
var tmpdir: std.fs.Dir = bundler.fs.tmpdir();
- const tmpname = try bundler.fs.tmpname(".jsbundle");
+ const tmpname = try bundler.fs.tmpname(".jsb");
- var tmpfile = try tmpdir.createFile(tmpname, .{});
+ var tmpfile = try tmpdir.createFile(tmpname, .{ .read = isDebug });
var generator = GenerateNodeModuleBundle{
.module_list = std.ArrayList(Api.JavascriptBundledModule).init(allocator),
.package_list = std.ArrayList(Api.JavascriptBundledPackage).init(allocator),
@@ -284,7 +285,10 @@ pub fn NewBundler(cache_files: bool) type {
};
var this = &generator;
// Always inline the runtime into the bundle
- try generator.appendBytes(initial_header ++ runtime.SourceContent ++ "\n\n");
+ try generator.appendBytes(&initial_header);
+ // If we try to be smart and rely on .written, it turns out incorrect
+ const code_start_pos = try this.tmpfile.getPos();
+ try generator.appendBytes(runtime.SourceContent ++ "\n\n");
if (bundler.log.level == .verbose) {
bundler.resolver.debug_logs = try DebugLogs.init(allocator);
@@ -303,57 +307,77 @@ pub fn NewBundler(cache_files: bool) type {
// Ensure we never overflow
this.code_end_byte_offset = @truncate(
u32,
- std.math.max(this.tmpfile_byte_offset, @truncate(u32, initial_header.len)) - initial_header.len,
+ // Doing this math ourself seems to not necessarily produce correct results
+ (try this.tmpfile.getPos()),
);
- if (isDebug) {
- Output.print(
- "Wrote {d} bytes of code for {d} modules and {d} packages\n",
- .{ this.code_end_byte_offset - code_start_byte_offset, this.module_list.items.len, this.package_list.items.len },
- );
- }
+
var javascript_bundle_container = std.mem.zeroes(Api.JavascriptBundleContainer);
- std.sort.sort(Api.JavascriptBundledModule, this.module_list.items, this, GenerateNodeModuleBundle.sortJavascriptModuleByPath);
+ std.sort.sort(
+ Api.JavascriptBundledModule,
+ this.module_list.items,
+ this,
+ GenerateNodeModuleBundle.sortJavascriptModuleByPath,
+ );
var hasher = std.hash.Wyhash.init(0);
+ // We want to sort the packages as well as the files
+ // The modules sort the packages already
+ // So can just copy it in the below loop.
+ var sorted_package_list = try allocator.alloc(Api.JavascriptBundledPackage, this.package_list.items.len);
+
+ // At this point, the module_list is sorted.
if (this.module_list.items.len > 0) {
+ var package_id_i: u32 = 0;
var i: usize = 0;
- // Assumption: packages are immutable
+ // Assumption: node_modules are immutable
// Assumption: module files are immutable
- // The etag is the hash of each module's path in sorted order
- // followed by the hash of package-name@version
- // This will allow any unused files to force re-updating the bundle
- // or package version changes
+ // (They're not. But, for our purposes that's okay)
+ // The etag is:
+ // - The hash of each module's path in sorted order
+ // - The hash of each module's code size in sorted order
+ // - hash(hash(package_name, package_version))
+ // If this doesn't prove strong enough, we will do a proper content hash
+ // But I want to avoid that overhead unless proven necessary.
+ // There's a good chance we don't even strictly need an etag here.
+ var bytes: [4]u8 = undefined;
while (i < this.module_list.items.len) {
var current_package_id = this.module_list.items[i].package_id;
+ this.module_list.items[i].package_id = package_id_i;
var offset = @truncate(u32, i);
- hasher.update(this.metadataStringPointer(this.module_list.items[i].path));
i += 1;
while (i < this.module_list.items.len and this.module_list.items[i].package_id == current_package_id) : (i += 1) {
+ this.module_list.items[i].package_id = package_id_i;
+ // Hash the file path
hasher.update(this.metadataStringPointer(this.module_list.items[i].path));
- break;
+ // Then the length of the code
+ std.mem.writeIntNative(u32, &bytes, this.module_list.items[i].code.length);
+ hasher.update(&bytes);
}
this.package_list.items[current_package_id].modules_offset = offset;
this.package_list.items[current_package_id].modules_length = @truncate(u32, i) - offset;
- var bytes: [4]u8 = undefined;
+ // Hash the hash of the package name
+ // it's hash(hash(package_name, package_version))
std.mem.writeIntNative(u32, &bytes, this.package_list.items[current_package_id].hash);
hasher.update(&bytes);
+
+ sorted_package_list[package_id_i] = this.package_list.items[current_package_id];
+ package_id_i += 1;
}
}
var javascript_bundle = std.mem.zeroes(Api.JavascriptBundle);
javascript_bundle.modules = this.module_list.items;
- javascript_bundle.packages = this.package_list.items;
+ javascript_bundle.packages = sorted_package_list;
javascript_bundle.manifest_string = this.header_string_buffer.list.items;
javascript_bundle.generated_at = @truncate(u32, @intCast(u64, std.time.milliTimestamp()));
- var from_name = "node_modules.jsbundle".*;
- javascript_bundle.import_from_name = &from_name;
+ javascript_bundle.import_from_name = destination;
var etag_bytes: [8]u8 = undefined;
std.mem.writeIntNative(u64, &etag_bytes, hasher.final());
@@ -363,30 +387,55 @@ pub fn NewBundler(cache_files: bool) type {
javascript_bundle_container.bundle = javascript_bundle;
javascript_bundle_container.code_length = this.code_end_byte_offset;
- var tmpwriter = this.tmpfile.writer();
- try javascript_bundle_container.encode(tmpwriter);
- try this.tmpfile.seekTo(magic_bytes.len);
+ var start_pos = try this.tmpfile.getPos();
+ var tmpwriter = std.io.bufferedWriter(this.tmpfile.writer());
+ const SchemaWriter = schema.Writer(@TypeOf(tmpwriter.writer()));
+ var schema_file_writer = SchemaWriter.init(tmpwriter.writer());
+ try javascript_bundle_container.encode(&schema_file_writer);
+ try tmpwriter.flush();
+
+ // sanity check
+ if (isDebug) {
+ try this.tmpfile.seekTo(start_pos);
+ var contents = try allocator.alloc(u8, (try this.tmpfile.getEndPos()) - start_pos);
+ var read_bytes = try this.tmpfile.read(contents);
+ var buf = contents[0..read_bytes];
+ var reader = schema.Reader.init(buf, allocator);
+
+ var decoder = try Api.JavascriptBundleContainer.decode(
+ &reader,
+ );
+ std.debug.assert(decoder.code_length.? == javascript_bundle_container.code_length.?);
+ }
+
var code_length_bytes: [4]u8 = undefined;
std.mem.writeIntNative(u32, &code_length_bytes, this.code_end_byte_offset);
- try this.tmpfile.writeAll(&code_length_bytes);
+ _ = try std.os.pwrite(this.tmpfile.handle, &code_length_bytes, magic_bytes.len);
const top_dir = try std.fs.openDirAbsolute(this.bundler.fs.top_level_dir, .{});
- try std.os.renameat(tmpdir.fd, tmpname, top_dir.fd, "node_modules.jsbundle");
+ _ = C.fchmod(
+ this.tmpfile.handle,
+ // chmod 777
+ 0000010 | 0000100 | 0000001 | 0001000 | 0000040 | 0000004 | 0000002 | 0000400 | 0000200 | 0000020,
+ );
+ try std.os.renameat(tmpdir.fd, tmpname, top_dir.fd, destination);
// Print any errors at the end
try this.log.print(Output.errorWriter());
-
- if (isDebug) {
- Output.println("Saved node_modules.jsbundle", .{});
- }
+ return javascript_bundle_container;
}
pub fn metadataStringPointer(this: *GenerateNodeModuleBundle, ptr: Api.StringPointer) string {
return this.header_string_buffer.list.items[ptr.offset .. ptr.offset + ptr.length];
}
+ // Since we trim the prefixes, we must also compare the package name
pub fn sortJavascriptModuleByPath(ctx: *GenerateNodeModuleBundle, a: Api.JavascriptBundledModule, b: Api.JavascriptBundledModule) bool {
- return std.mem.order(u8, ctx.metadataStringPointer(a.path), ctx.metadataStringPointer(b.path)) == .lt;
+ return switch (std.mem.order(u8, ctx.metadataStringPointer(ctx.package_list.items[a.package_id].name), ctx.metadataStringPointer(ctx.package_list.items[b.package_id].name))) {
+ .eq => std.mem.order(u8, ctx.metadataStringPointer(a.path), ctx.metadataStringPointer(b.path)) == .lt,
+ .lt => true,
+ else => false,
+ };
}
// pub fn sortJavascriptPackageByName(ctx: *GenerateNodeModuleBundle, a: Api.JavascriptBundledPackage, b: Api.JavascriptBundledPackage) bool {
@@ -399,11 +448,12 @@ pub fn NewBundler(cache_files: bool) type {
}
fn processImportRecord(this: *GenerateNodeModuleBundle, import_record: ImportRecord) !void {}
+ const node_module_root_string = "node_modules" ++ std.fs.path.sep_str;
threadlocal var package_key_buf: [512]u8 = undefined;
fn processFile(this: *GenerateNodeModuleBundle, _resolve: _resolver.Result) !void {
var resolve = _resolve;
if (resolve.is_external) return;
- const node_module_root_string = comptime "node_modules" ++ std.fs.path.sep_str;
+
resolve.is_from_node_modules = strings.contains(resolve.path_pair.primary.text, node_module_root_string);
const loader = this.bundler.options.loaders.get(resolve.path_pair.primary.name.ext) orelse .file;
var bundler = this.bundler;
@@ -523,11 +573,22 @@ pub fn NewBundler(cache_files: bool) type {
},
);
}
- const node_module_root = strings.indexOf(resolve.path_pair.primary.text, node_module_root_string) orelse unreachable;
+ // trim node_modules/${package.name}/ from the string to save space
+ // This reduces metadata size by about 30% for a large-ish file
+ // A future optimization here could be to reuse the string from the original path
+ var node_module_root = strings.indexOf(resolve.path_pair.primary.text, node_module_root_string) orelse unreachable;
+ // omit package name
+ node_module_root += package.name.len;
+ // omit node_modules
+ node_module_root += node_module_root_string.len;
+ // omit trailing separator
+ node_module_root += 1;
try this.module_list.append(
Api.JavascriptBundledModule{
- .path = try this.appendHeaderString(resolve.path_pair.primary.text[node_module_root + node_module_root_string.len ..]),
+ .path = try this.appendHeaderString(
+ resolve.path_pair.primary.text[node_module_root..],
+ ),
.package_id = package_get_or_put_entry.value_ptr.*,
.code = Api.StringPointer{
.length = @truncate(u32, code_length),
diff --git a/src/cli.zig b/src/cli.zig
index d3fba1608..472c6ac02 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -132,7 +132,7 @@ pub const Cli = struct {
clap.parseParam("--platform <STR> \"browser\" or \"node\". Defaults to \"browser\"") catch unreachable,
clap.parseParam("--main-fields <STR>... Main fields to lookup in package.json. Defaults to --platform dependent") catch unreachable,
clap.parseParam("--scan Instead of bundling or transpiling, print a list of every file imported by an entry point, recursively") catch unreachable,
- clap.parseParam("--jsbundle Generate a new node_modules.jsbundle file from the current node_modules folder and entry point(s)") catch unreachable,
+ clap.parseParam("--jsb Generate a new node_modules.jsb file from node_modules and entry point(s)") catch unreachable,
clap.parseParam("<POS>... Entry points to use") catch unreachable,
};
@@ -279,7 +279,7 @@ pub const Cli = struct {
.main_fields = args.options("--main-fields"),
.platform = platform,
.only_scan_dependencies = if (args.flag("--scan")) Api.ScanDependencyMode.all else Api.ScanDependencyMode._none,
- .generate_node_module_bundle = if (args.flag("--jsbundle")) true else false,
+ .generate_node_module_bundle = if (args.flag("--jsb")) true else false,
};
}
};
@@ -306,10 +306,26 @@ pub const Cli = struct {
MainPanicHandler.Singleton = &panicker;
var args = try Arguments.parse(alloc.static, stdout, stderr);
- if ((args.entry_points.len == 1 and args.entry_points[0].len > ".jsbundle".len and args.entry_points[0][args.entry_points[0].len - ".jsbundle".len] == '.' and strings.eqlComptime(args.entry_points[0][args.entry_points[0].len - "jsbundle".len ..], "jsbundle"))) {
+ if ((args.entry_points.len == 1 and args.entry_points[0].len > ".jsb".len and args.entry_points[0][args.entry_points[0].len - ".jsb".len] == '.' and strings.eqlComptime(args.entry_points[0][args.entry_points[0].len - "jsb".len ..], "jsb"))) {
var out_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var input = try std.fs.openFileAbsolute(try std.os.realpath(args.entry_points[0], &out_buffer), .{ .read = true });
- try NodeModuleBundle.printBundle(std.fs.File, input, @TypeOf(stdout), stdout);
+
+ const params = comptime [_]clap.Param(clap.Help){
+ clap.parseParam("--summary Print a summary") catch unreachable,
+ clap.parseParam("<POS>... ") catch unreachable,
+ };
+
+ var jsBundleArgs = clap.parse(clap.Help, &params, .{}) catch |err| {
+ try NodeModuleBundle.printBundle(std.fs.File, input, @TypeOf(stdout), stdout);
+ return;
+ };
+
+ if (jsBundleArgs.flag("--summary")) {
+ try NodeModuleBundle.printSummaryFromDisk(std.fs.File, input, @TypeOf(stdout), stdout, allocator);
+ } else {
+ try NodeModuleBundle.printBundle(std.fs.File, input, @TypeOf(stdout), stdout);
+ }
+
return;
}
@@ -326,7 +342,15 @@ pub const Cli = struct {
if ((args.generate_node_module_bundle orelse false)) {
var this_bundler = try bundler.ServeBundler.init(allocator, &log, args);
this_bundler.configureLinker();
- try bundler.ServeBundler.GenerateNodeModuleBundle.generate(&this_bundler, allocator);
+ var filepath = "node_modules.jsb";
+ var node_modules = try bundler.ServeBundler.GenerateNodeModuleBundle.generate(&this_bundler, allocator, filepath);
+ var elapsed = @divTrunc(std.time.nanoTimestamp() - start_time, @as(i128, std.time.ns_per_ms));
+ var bundle = NodeModuleBundle.init(node_modules, allocator);
+
+ bundle.printSummary();
+ const indent = comptime " ";
+ Output.prettyln(indent ++ "<d>{d:6}ms elapsed", .{@intCast(u32, elapsed)});
+ Output.prettyln(indent ++ "<r>Saved to ./{s}", .{filepath});
return;
}
diff --git a/src/darwin_c.zig b/src/darwin_c.zig
index 21080ea85..12f61d8ba 100644
--- a/src/darwin_c.zig
+++ b/src/darwin_c.zig
@@ -6,3 +6,10 @@ pub extern "c" fn clonefileat(c_int, [*c]const u8, c_int, [*c]const u8, uint32_t
pub extern "c" fn fclonefileat(c_int, c_int, [*c]const u8, uint32_t: c_int) c_int;
// int clonefile(const char * src, const char * dst, int flags);
pub extern "c" fn clonefile([*c]const u8, [*c]const u8, uint32_t: c_int) c_int;
+
+pub extern "c" fn chmod([*c]const u8, mode_t) c_int;
+pub extern "c" fn fchmod(c_int, mode_t) c_int;
+pub extern "c" fn umask(mode_t) mode_t;
+pub extern "c" fn fchmodat(c_int, [*c]const u8, mode_t, c_int) c_int;
+
+const mode_t = u16;
diff --git a/src/deps/zig-clap/clap/streaming.zig b/src/deps/zig-clap/clap/streaming.zig
index a2a0ca8d5..e7991cb53 100644
--- a/src/deps/zig-clap/clap/streaming.zig
+++ b/src/deps/zig-clap/clap/streaming.zig
@@ -87,7 +87,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
return Arg(Id){ .param = param, .value = value };
}
- return parser.err(arg, .{ .long = name }, error.InvalidArgument);
+ return null;
},
.short => return try parser.chainging(.{
.arg = arg,
diff --git a/src/global.zig b/src/global.zig
index 4cf3ccef0..bc0ab3ee3 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -70,6 +70,11 @@ pub const Output = struct {
// return @TypeOf(std.io.bufferedWriter(stdout.writer()));
}
};
+ const BufferedStream = std.io.BufferedWriter(4096, @typeInfo(@TypeOf(Source.StreamType.writer)).Fn.return_type.?);
+
+ buffered_stream: BufferedStream,
+ buffered_error_stream: BufferedStream,
+
stream: StreamType,
error_stream: StreamType,
out_buffer: []u8 = &([_]u8{}),
@@ -79,13 +84,28 @@ pub const Output = struct {
stream: StreamType,
err: StreamType,
) Source {
- return Source{ .stream = stream, .error_stream = err };
+ return Source{
+ .stream = stream,
+ .error_stream = err,
+ .buffered_stream = BufferedStream{ .unbuffered_writer = stream.writer() },
+ .buffered_error_stream = BufferedStream{ .unbuffered_writer = err.writer() },
+ };
}
pub fn set(_source: *Source) void {
source = _source;
}
};
+ pub var enable_ansi_colors = isNative;
+ pub var enable_buffering = true;
+
+ pub fn enableBuffering() void {
+ enable_buffering = true;
+ }
+
+ pub fn disableBuffering() void {
+ enable_buffering = false;
+ }
pub fn errorWriter() @typeInfo(@TypeOf(Source.StreamType.writer)).Fn.return_type.? {
return source.error_stream.writer();
@@ -97,6 +117,8 @@ pub const Output = struct {
pub fn flush() void {
if (isNative) {
+ source.buffered_stream.flush() catch {};
+ source.buffered_error_stream.flush() catch {};
// source.stream.flush() catch {};
// source.error_stream.flush() catch {};
}
@@ -140,7 +162,142 @@ pub const Output = struct {
const root = @import("root");
root.console_log(root.Uint8Array.fromSlice(source.out_buffer[0..source.stream.pos]));
} else {
- std.fmt.format(source.stream.writer(), fmt, args) catch unreachable;
+ if (enable_buffering) {
+ std.fmt.format(source.buffered_stream.writer(), fmt, args) catch unreachable;
+ } else {
+ std.fmt.format(writer(), fmt, args) catch unreachable;
+ }
+ }
+ }
+
+ // Valid colors:
+ // <black>
+ // <blue>
+ // <cyan>
+ // <green>
+ // <magenta>
+ // <red>
+ // <white>
+ // <yellow>
+ // <b> - bold
+ // <d> - dim
+ // </r> - reset
+ // <r> - reset
+ fn _pretty(comptime fmt: string, args: anytype, comptime printer: anytype, comptime is_enabled: bool) void {
+ comptime var new_fmt: [fmt.len * 4]u8 = undefined;
+ comptime var new_fmt_i: usize = 0;
+ comptime const ED = "\x1b[";
+
+ @setEvalBranchQuota(9999);
+ comptime var i: usize = 0;
+ comptime while (i < fmt.len) {
+ const c = fmt[i];
+ switch (c) {
+ '\\' => {
+ i += 1;
+ if (fmt.len < i) {
+ switch (fmt[i]) {
+ '<', '>' => {
+ i += 1;
+ },
+ else => {
+ new_fmt[new_fmt_i] = '\\';
+ new_fmt_i += 1;
+ new_fmt[new_fmt_i] = fmt[i];
+ new_fmt_i += 1;
+ },
+ }
+ }
+ },
+ '>' => {
+ i += 1;
+ },
+ '{' => {
+ while (fmt.len > i and fmt[i] != '}') {
+ new_fmt[new_fmt_i] = fmt[i];
+ new_fmt_i += 1;
+ i += 1;
+ }
+ },
+ '<' => {
+ i += 1;
+ var is_reset = fmt[i] == '/';
+ if (is_reset) i += 1;
+ var start: usize = i;
+ while (i < fmt.len and fmt[i] != '>') {
+ i += 1;
+ }
+
+ const color_name = fmt[start..i];
+ const color_str = color_picker: {
+ if (std.mem.eql(u8, color_name, "black")) {
+ break :color_picker ED ++ "30m";
+ } else if (std.mem.eql(u8, color_name, "blue")) {
+ break :color_picker ED ++ "34m";
+ } else if (std.mem.eql(u8, color_name, "b")) {
+ break :color_picker ED ++ "1m";
+ } else if (std.mem.eql(u8, color_name, "d")) {
+ break :color_picker ED ++ "2m";
+ } else if (std.mem.eql(u8, color_name, "cyan")) {
+ break :color_picker ED ++ "36m";
+ } else if (std.mem.eql(u8, color_name, "green")) {
+ break :color_picker ED ++ "32m";
+ } else if (std.mem.eql(u8, color_name, "magenta")) {
+ break :color_picker ED ++ "35m";
+ } else if (std.mem.eql(u8, color_name, "red")) {
+ break :color_picker ED ++ "31m";
+ } else if (std.mem.eql(u8, color_name, "white")) {
+ break :color_picker ED ++ "37m";
+ } else if (std.mem.eql(u8, color_name, "yellow")) {
+ break :color_picker ED ++ "33m";
+ } else if (std.mem.eql(u8, color_name, "r")) {
+ is_reset = true;
+ break :color_picker "";
+ } else {
+ @compileError("Invalid color name passed:" ++ color_name);
+ }
+ };
+ var orig = new_fmt_i;
+
+ if (is_enabled) {
+ if (!is_reset) {
+ orig = new_fmt_i;
+ new_fmt_i += color_str.len;
+ std.mem.copy(u8, new_fmt[orig..new_fmt_i], color_str);
+ }
+
+ if (is_reset) {
+ const reset_sequence = "\x1b[0m";
+ orig = new_fmt_i;
+ new_fmt_i += reset_sequence.len;
+ std.mem.copy(u8, new_fmt[orig..new_fmt_i], reset_sequence);
+ }
+ }
+ },
+
+ else => {
+ new_fmt[new_fmt_i] = fmt[i];
+ new_fmt_i += 1;
+ i += 1;
+ },
+ }
+ };
+ printer(new_fmt[0..new_fmt_i], args);
+ }
+
+ pub fn pretty(comptime fmt: string, args: anytype) void {
+ if (enable_ansi_colors) {
+ _pretty(fmt, args, print, true);
+ } else {
+ _pretty(fmt, args, print, false);
+ }
+ }
+
+ pub fn prettyln(comptime fmt: string, args: anytype) void {
+ if (enable_ansi_colors) {
+ _pretty(fmt, args, println, true);
+ } else {
+ _pretty(fmt, args, println, false);
}
}
diff --git a/src/main.zig b/src/main.zig
index e8ad2c282..c54d2cf7f 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -38,6 +38,7 @@ pub fn main() anyerror!void {
// defer stdout.flush() catch {};
// defer stderr.flush() catch {};
Output.Source.set(&output_source);
-
+ Output.enable_ansi_colors = stderr.isTty();
+ defer Output.flush();
try cli.Cli.start(std.heap.c_allocator, stdout, stderr, MainPanicHandler);
}
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig
index 11150f376..ada125e22 100644
--- a/src/node_module_bundle.zig
+++ b/src/node_module_bundle.zig
@@ -1,16 +1,27 @@
-const Api = @import("./api/schema.zig").Api;
+const schema = @import("./api/schema.zig");
+const Api = schema.Api;
const std = @import("std");
usingnamespace @import("global.zig");
pub const NodeModuleBundle = struct {
- container: *Api.JavascriptBundleContainer,
- bundle: *Api.JavascriptBundle,
+ container: Api.JavascriptBundleContainer,
+ bundle: Api.JavascriptBundle,
allocator: *std.mem.Allocator,
+ bytes_ptr: []u8 = undefined,
+ bytes: []u8 = undefined,
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 init(container: Api.JavascriptBundleContainer, allocator: *std.mem.Allocator) NodeModuleBundle {
+ return NodeModuleBundle{
+ .container = container,
+ .bundle = container.bundle.?,
+ .allocator = allocator,
+ };
+ }
+
pub fn getCodeEndPosition(stream: anytype, comptime needs_seek: bool) !u32 {
if (needs_seek) try stream.seekTo(0);
@@ -23,18 +34,117 @@ pub const NodeModuleBundle = struct {
}
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);
+ const end = try getCodeEndPosition(stream, false);
+ try stream.seekTo(end);
+ const file_end = try stream.getEndPos();
+ var file_bytes = try allocator.alloc(u8, file_end - end);
+ var read_count = try stream.read(file_bytes);
+ var read_bytes = file_bytes[0..read_count];
+ var reader = schema.Reader.init(read_bytes, allocator);
+ var container = try Api.JavascriptBundleContainer.decode(&reader);
+
return NodeModuleBundle{
.allocator = allocator,
.container = container,
- .bundle = container.bundle,
- .fd = if (std.meta.trait.hasField("handle")(stream)) stream.handle else 0,
+ .bundle = container.bundle.?,
+ .fd = stream.handle,
+ .bytes = read_bytes,
+ .bytes_ptr = file_bytes,
};
}
+ pub fn str(bundle: *const NodeModuleBundle, pointer: Api.StringPointer) string {
+ return bundle.bundle.manifest_string[pointer.offset .. pointer.offset + pointer.length];
+ }
+
+ pub fn getPackageSize(this: *const NodeModuleBundle, pkg: Api.JavascriptBundledPackage) usize {
+ const modules = this.bundle.modules[pkg.modules_offset .. pkg.modules_offset + pkg.modules_length];
+ var size: usize = 0;
+ for (modules) |module| {
+ size += module.code.length;
+ }
+ return size;
+ }
+
+ pub fn isPackageBigger(
+ this: *const NodeModuleBundle,
+ a: Api.JavascriptBundledPackage,
+ b: Api.JavascriptBundledPackage,
+ ) bool {
+ return this.getPackageSize(a) < this.getPackageSize(b);
+ }
+
+ pub fn printSummary(this: *const NodeModuleBundle) void {
+ const last = this.bundle.packages.len - 1;
+ const indent = comptime " ";
+ for (this.bundle.packages) |pkg, i| {
+ const modules = this.bundle.modules[pkg.modules_offset .. pkg.modules_offset + pkg.modules_length];
+
+ Output.prettyln(
+ "<r><blue><b>{s}</r> v{s}",
+ .{ this.str(pkg.name), this.str(pkg.version) },
+ );
+
+ for (modules) |module| {
+ const size_level = switch (module.code.length) {
+ 0...5_000 => SizeLevel.good,
+ 5_001...74_999 => SizeLevel.neutral,
+ else => SizeLevel.bad,
+ };
+
+ Output.print(indent, .{});
+ prettySize(module.code.length, size_level, ">");
+ Output.prettyln(
+ indent ++ "<d>{s}</r>" ++ std.fs.path.sep_str ++ "{s}\n",
+ .{
+ this.str(pkg.name),
+ this.str(module.path),
+ },
+ );
+ }
+
+ Output.print("\n", .{});
+ }
+ const source_code_size = this.container.code_length.? - @intCast(u32, jsbundle_prefix.len);
+
+ Output.pretty("<b>", .{});
+ prettySize(source_code_size, .neutral, ">");
+ Output.prettyln("<b> JavaScript<r>", .{});
+ Output.prettyln(indent ++ "<b>{d:6} modules", .{this.bundle.modules.len});
+ Output.prettyln(indent ++ "<b>{d:6} packages", .{this.bundle.packages.len});
+ }
+
+ pub fn printSummaryFromDisk(
+ comptime StreamType: type,
+ input: StreamType,
+ comptime DestinationStreamType: type,
+ output: DestinationStreamType,
+ allocator: *std.mem.Allocator,
+ ) !void {
+ const this = try loadBundle(allocator, input);
+ this.printSummary();
+ }
+
+ const SizeLevel = enum { good, neutral, bad };
+ fn prettySize(size: u32, level: SizeLevel, comptime align_char: []const u8) void {
+ switch (size) {
+ 0...1024 * 1024 => {
+ switch (level) {
+ .bad => Output.pretty("<red>{d: " ++ align_char ++ "6.2} KB</r>", .{@intToFloat(f64, size) / 1024.0}),
+ .neutral => Output.pretty("{d: " ++ align_char ++ "6.2} KB</r>", .{@intToFloat(f64, size) / 1024.0}),
+ .good => Output.pretty("<green>{d: " ++ align_char ++ "6.2} KB</r>", .{@intToFloat(f64, size) / 1024.0}),
+ }
+ },
+ else => {
+ switch (level) {
+ .bad => Output.pretty("<red>{d: " ++ align_char ++ "6.2} MB</r>", .{@intToFloat(f64, size) / (1024 * 1024.0)}),
+ .neutral => Output.pretty("{d: " ++ align_char ++ "6.2} MB</r>", .{@intToFloat(f64, size) / (1024 * 1024.0)}),
+ .good => Output.pretty("<green>{d: " ++ align_char ++ "6.2} MB</r>", .{@intToFloat(f64, size) / (1024 * 1024.0)}),
+ }
+ },
+ }
+ }
+
pub fn printBundle(
comptime StreamType: type,
input: StreamType,
@@ -45,20 +155,18 @@ pub const NodeModuleBundle = 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);
+ var read_amount: i64 = 99999;
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);
+ remain -= @intCast(i64, try out.write(buf[0..@intCast(usize, std.math.min(read_amount, remain))]));
}
-
- _ = 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);
+ const end = (try getCodeEndPosition(input, false)) - @intCast(u32, jsbundle_prefix.len);
try BufferStreamContext.run(
input,