aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--src/api/schema.peechy1
-rw-r--r--src/api/schema.zig2925
-rw-r--r--src/bundler.zig573
-rw-r--r--src/fs.zig16
-rw-r--r--src/hash_map_v2.zig6
-rw-r--r--src/import_record.zig2
-rw-r--r--src/javascript/jsc/bindings/bindings.zig2
-rw-r--r--src/javascript/jsc/bindings/exports.zig12
-rw-r--r--src/javascript/jsc/javascript.zig30
-rw-r--r--src/js_parser/js_parser.zig104
-rw-r--r--src/js_printer.zig202
-rw-r--r--src/linker.zig161
-rw-r--r--src/node_module_bundle.zig2
-rw-r--r--src/options.zig102
-rw-r--r--src/panic_handler.zig2
-rw-r--r--src/query_string_map.zig23
-rw-r--r--src/resolver/package_json.zig55
-rw-r--r--src/resolver/resolver.zig89
-rw-r--r--src/runtime.js10
-rw-r--r--src/runtime.version2
-rw-r--r--src/string_immutable.zig16
-rw-r--r--src/test/fixtures/browsermap-false.ts3
-rw-r--r--src/test/fixtures/main-field.ts3
-rw-r--r--src/test/fixtures/package.json7
-rw-r--r--src/test/fixtures/type-only-import.ts33
-rw-r--r--src/test/project.zig139
27 files changed, 2556 insertions, 1968 deletions
diff --git a/README.md b/README.md
index c1cc2c847..b285dc635 100644
--- a/README.md
+++ b/README.md
@@ -102,6 +102,10 @@ bun build ./routes --outdir=./out
Unlike many other bundlers, `Bun` only bundles `node_modules`. This is great for development, where most people add/update packages much less frequently than app code (which is also great for caching in browsers). To make that distinction clear, the filename defaults to `node_modules.bun`. We recommend storing `node_modules.bun` in your git repository. Since it's a binary file, it shouldn't clutter your git history and it will make your entire frontend development team move faster if they don't have to re-bundle dependencies.
+# Not implemented yet
+
+
+
# Building from source
Estimated: 30-60 minutes :(
diff --git a/src/api/schema.peechy b/src/api/schema.peechy
index f296b6452..fd0b81fd2 100644
--- a/src/api/schema.peechy
+++ b/src/api/schema.peechy
@@ -90,7 +90,6 @@ struct JavascriptBundle {
// generated by hashing all ${name}@${version} in sorted order
byte[] app_package_json_dependencies_hash;
-
byte[] import_from_name;
// This is what StringPointer refers to
diff --git a/src/api/schema.zig b/src/api/schema.zig
index 3e542b035..639eeae98 100644
--- a/src/api/schema.zig
+++ b/src/api/schema.zig
@@ -1,4 +1,3 @@
-
const std = @import("std");
pub const Reader = struct {
@@ -282,1872 +281,1762 @@ pub fn Writer(comptime WritableStream: type) type {
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,
+ /// jsx
+ jsx,
+ /// js
+ js,
+ /// ts
+ ts,
-pub const Api = struct {
-
-pub const Loader = enum(u8) {
-
-_none,
- /// jsx
- jsx,
-
- /// js
- js,
-
- /// ts
- ts,
-
- /// tsx
- tsx,
-
- /// css
- css,
-
- /// file
- file,
-
- /// json
- json,
-
-_,
-
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
-
-
-};
-
-pub const ResolveMode = enum(u8) {
-
-_none,
- /// disable
- disable,
+ /// tsx
+ tsx,
- /// lazy
- lazy,
+ /// css
+ css,
- /// dev
- dev,
-
- /// bundle
- bundle,
-
-_,
-
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
-
-
-};
-
-pub const Platform = enum(u8) {
-
-_none,
- /// browser
- browser,
-
- /// node
- node,
-
- /// bun
- bun,
-
-_,
-
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
-
-
-};
+ /// file
+ file,
-pub const CssInJsBehavior = enum(u8) {
+ /// json
+ json,
-_none,
- /// facade
- facade,
+ _,
- /// facade_onimportcss
- facade_onimportcss,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
- /// auto_onimportcss
- auto_onimportcss,
+ pub const ResolveMode = enum(u8) {
+ _none,
+ /// disable
+ disable,
-_,
+ /// lazy
+ lazy,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ /// dev
+ dev,
-
-};
+ /// bundle
+ bundle,
-pub const JsxRuntime = enum(u8) {
+ _,
-_none,
- /// automatic
- automatic,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
- /// classic
- classic,
+ pub const Platform = enum(u8) {
+ _none,
+ /// browser
+ browser,
-_,
+ /// node
+ node,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ /// bun
+ bun,
-
-};
+ _,
-pub const Jsx = struct {
-/// factory
-factory: []const u8,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-/// runtime
-runtime: JsxRuntime,
+ pub const CssInJsBehavior = enum(u8) {
+ _none,
+ /// facade
+ facade,
-/// fragment
-fragment: []const u8,
+ /// facade_onimportcss
+ facade_onimportcss,
-/// development
-development: bool = false,
+ /// auto_onimportcss
+ auto_onimportcss,
-/// import_source
-import_source: []const u8,
+ _,
-/// react_fast_refresh
-react_fast_refresh: bool = false,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
+ pub const JsxRuntime = enum(u8) {
+ _none,
+ /// automatic
+ automatic,
-pub fn decode(reader: anytype) anyerror!Jsx {
- var this = std.mem.zeroes(Jsx);
+ /// classic
+ classic,
- 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;
-}
+ _,
-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 fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-};
+ pub const Jsx = struct {
+ /// factory
+ factory: []const u8,
-pub const StringPointer = packed struct {
-/// offset
-offset: u32 = 0,
+ /// runtime
+ runtime: JsxRuntime,
-/// length
-length: u32 = 0,
+ /// fragment
+ fragment: []const u8,
+ /// development
+ development: bool = false,
-pub fn decode(reader: anytype) anyerror!StringPointer {
- var this = std.mem.zeroes(StringPointer);
+ /// import_source
+ import_source: []const u8,
- this.offset = try reader.readValue(u32);
- this.length = try reader.readValue(u32);
- return this;
-}
+ /// react_fast_refresh
+ react_fast_refresh: bool = false,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.offset);
- try writer.writeInt(this.length);
-}
+ pub fn decode(reader: anytype) anyerror!Jsx {
+ var this = std.mem.zeroes(Jsx);
-};
+ 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;
+ }
-pub const JavascriptBundledModule = struct {
-/// path
-path: StringPointer,
+ 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)));
+ }
+ };
-/// code
-code: StringPointer,
+ pub const StringPointer = packed struct {
+ /// offset
+ offset: u32 = 0,
-/// package_id
-package_id: u32 = 0,
+ /// length
+ length: u32 = 0,
-/// id
-id: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!StringPointer {
+ var this = std.mem.zeroes(StringPointer);
-/// path_extname_length
-path_extname_length: u8 = 0,
+ this.offset = try reader.readValue(u32);
+ this.length = try reader.readValue(u32);
+ return this;
+ }
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.offset);
+ try writer.writeInt(this.length);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!JavascriptBundledModule {
- var this = std.mem.zeroes(JavascriptBundledModule);
+ pub const JavascriptBundledModule = struct {
+ /// path
+ path: StringPointer,
- this.path = try reader.readValue(StringPointer);
- this.code = try reader.readValue(StringPointer);
- this.package_id = try reader.readValue(u32);
- this.id = try reader.readValue(u32);
- this.path_extname_length = try reader.readValue(u8);
- return this;
-}
+ /// code
+ code: StringPointer,
-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);
- try writer.writeInt(this.id);
- try writer.writeInt(this.path_extname_length);
-}
+ /// package_id
+ package_id: u32 = 0,
-};
+ /// id
+ id: u32 = 0,
-pub const JavascriptBundledPackage = struct {
-/// name
-name: StringPointer,
+ /// path_extname_length
+ path_extname_length: u8 = 0,
-/// version
-version: StringPointer,
+ pub fn decode(reader: anytype) anyerror!JavascriptBundledModule {
+ var this = std.mem.zeroes(JavascriptBundledModule);
-/// hash
-hash: u32 = 0,
+ this.path = try reader.readValue(StringPointer);
+ this.code = try reader.readValue(StringPointer);
+ this.package_id = try reader.readValue(u32);
+ this.id = try reader.readValue(u32);
+ this.path_extname_length = try reader.readValue(u8);
+ return this;
+ }
-/// modules_offset
-modules_offset: u32 = 0,
+ 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);
+ try writer.writeInt(this.id);
+ try writer.writeInt(this.path_extname_length);
+ }
+ };
-/// modules_length
-modules_length: u32 = 0,
+ pub const JavascriptBundledPackage = struct {
+ /// name
+ name: StringPointer,
+ /// version
+ version: StringPointer,
-pub fn decode(reader: anytype) anyerror!JavascriptBundledPackage {
- var this = std.mem.zeroes(JavascriptBundledPackage);
+ /// hash
+ hash: u32 = 0,
- 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;
-}
+ /// modules_offset
+ modules_offset: u32 = 0,
-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);
-}
+ /// modules_length
+ modules_length: u32 = 0,
-};
+ pub fn decode(reader: anytype) anyerror!JavascriptBundledPackage {
+ var this = std.mem.zeroes(JavascriptBundledPackage);
-pub const JavascriptBundle = struct {
-/// modules
-modules: []const JavascriptBundledModule,
+ 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;
+ }
-/// packages
-packages: []const JavascriptBundledPackage,
+ 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);
+ }
+ };
-/// etag
-etag: []const u8,
+ pub const JavascriptBundle = struct {
+ /// modules
+ modules: []const JavascriptBundledModule,
-/// generated_at
-generated_at: u32 = 0,
+ /// packages
+ packages: []const JavascriptBundledPackage,
-/// app_package_json_dependencies_hash
-app_package_json_dependencies_hash: []const u8,
+ /// etag
+ etag: []const u8,
-/// import_from_name
-import_from_name: []const u8,
+ /// generated_at
+ generated_at: u32 = 0,
-/// manifest_string
-manifest_string: []const u8,
+ /// app_package_json_dependencies_hash
+ app_package_json_dependencies_hash: []const u8,
+ /// import_from_name
+ import_from_name: []const u8,
-pub fn decode(reader: anytype) anyerror!JavascriptBundle {
- var this = std.mem.zeroes(JavascriptBundle);
+ /// manifest_string
+ manifest_string: []const u8,
- 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;
-}
+ pub fn decode(reader: anytype) anyerror!JavascriptBundle {
+ var this = std.mem.zeroes(JavascriptBundle);
-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);
-}
+ 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;
+ }
-};
+ 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);
+ }
+ };
-pub const JavascriptBundleContainer = struct {
-/// bundle_format_version
-bundle_format_version: ?u32 = null,
-
-/// routes
-routes: ?LoadedRouteConfig = null,
-
-/// framework
-framework: ?LoadedFramework = null,
-
-/// bundle
-bundle: ?JavascriptBundle = null,
-
-/// code_length
-code_length: ?u32 = null,
-
-
-pub fn decode(reader: anytype) anyerror!JavascriptBundleContainer {
- var this = std.mem.zeroes(JavascriptBundleContainer);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.bundle_format_version = try reader.readValue(u32);
-},
- 2 => {
- this.routes = try reader.readValue(LoadedRouteConfig);
-},
- 3 => {
- this.framework = try reader.readValue(LoadedFramework);
-},
- 4 => {
- this.bundle = try reader.readValue(JavascriptBundle);
-},
- 5 => {
- this.code_length = try reader.readValue(u32);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
+ pub const JavascriptBundleContainer = struct {
+ /// bundle_format_version
+ bundle_format_version: ?u32 = null,
-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 (this.routes) |routes| {
- try writer.writeFieldID(2);
- try writer.writeValue(routes);
-}
-if (this.framework) |framework| {
- try writer.writeFieldID(3);
- try writer.writeValue(framework);
-}
-if (this.bundle) |bundle| {
- try writer.writeFieldID(4);
- try writer.writeValue(bundle);
-}
-if (this.code_length) |code_length| {
- try writer.writeFieldID(5);
- try writer.writeInt(code_length);
-}
-try writer.endMessage();
-}
+ /// routes
+ routes: ?LoadedRouteConfig = null,
-};
+ /// framework
+ framework: ?LoadedFramework = null,
-pub const ScanDependencyMode = enum(u8) {
+ /// bundle
+ bundle: ?JavascriptBundle = null,
-_none,
- /// app
- app,
+ /// code_length
+ code_length: ?u32 = null,
- /// all
- all,
+ pub fn decode(reader: anytype) anyerror!JavascriptBundleContainer {
+ var this = std.mem.zeroes(JavascriptBundleContainer);
-_,
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
+ 1 => {
+ this.bundle_format_version = try reader.readValue(u32);
+ },
+ 2 => {
+ this.routes = try reader.readValue(LoadedRouteConfig);
+ },
+ 3 => {
+ this.framework = try reader.readValue(LoadedFramework);
+ },
+ 4 => {
+ this.bundle = try reader.readValue(JavascriptBundle);
+ },
+ 5 => {
+ this.code_length = try reader.readValue(u32);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
}
+ }
+ unreachable;
+ }
-
-};
-
-pub const ModuleImportType = enum(u8) {
-
-_none,
- /// import
- import,
+ 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 (this.routes) |routes| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(routes);
+ }
+ if (this.framework) |framework| {
+ try writer.writeFieldID(3);
+ try writer.writeValue(framework);
+ }
+ if (this.bundle) |bundle| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(bundle);
+ }
+ if (this.code_length) |code_length| {
+ try writer.writeFieldID(5);
+ try writer.writeInt(code_length);
+ }
+ try writer.endMessage();
+ }
+ };
- /// require
- require,
+ pub const ScanDependencyMode = enum(u8) {
+ _none,
+ /// app
+ app,
-_,
+ /// all
+ all,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ _,
-
-};
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-pub const ModuleImportRecord = struct {
-/// kind
-kind: ModuleImportType,
+ pub const ModuleImportType = enum(u8) {
+ _none,
+ /// import
+ import,
-/// path
-path: []const u8,
+ /// require
+ require,
-/// dynamic
-dynamic: bool = false,
+ _,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!ModuleImportRecord {
- var this = std.mem.zeroes(ModuleImportRecord);
+ pub const ModuleImportRecord = struct {
+ /// kind
+ kind: ModuleImportType,
- this.kind = try reader.readValue(ModuleImportType);
- this.path = try reader.readValue([]const u8);
- this.dynamic = try reader.readValue(bool);
- return this;
-}
+ /// path
+ path: []const u8,
-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)));
-}
+ /// dynamic
+ dynamic: bool = false,
-};
+ pub fn decode(reader: anytype) anyerror!ModuleImportRecord {
+ var this = std.mem.zeroes(ModuleImportRecord);
-pub const Module = struct {
-/// path
-path: []const u8,
+ this.kind = try reader.readValue(ModuleImportType);
+ this.path = try reader.readValue([]const u8);
+ this.dynamic = try reader.readValue(bool);
+ return this;
+ }
-/// imports
-imports: []const ModuleImportRecord,
+ 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)));
+ }
+ };
+ pub const Module = struct {
+ /// path
+ path: []const u8,
-pub fn decode(reader: anytype) anyerror!Module {
- var this = std.mem.zeroes(Module);
+ /// imports
+ imports: []const ModuleImportRecord,
- this.path = try reader.readValue([]const u8);
- this.imports = try reader.readArray(ModuleImportRecord);
- return this;
-}
+ pub fn decode(reader: anytype) anyerror!Module {
+ var this = std.mem.zeroes(Module);
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeValue(this.path);
- try writer.writeArray(ModuleImportRecord, this.imports);
-}
+ this.path = try reader.readValue([]const u8);
+ this.imports = try reader.readArray(ModuleImportRecord);
+ return this;
+ }
-};
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.path);
+ try writer.writeArray(ModuleImportRecord, this.imports);
+ }
+ };
-pub const StringMap = struct {
-/// keys
-keys: []const []const u8,
+ pub const StringMap = struct {
+ /// keys
+ keys: []const []const u8,
-/// values
-values: []const []const u8,
+ /// values
+ values: []const []const u8,
+ pub fn decode(reader: anytype) anyerror!StringMap {
+ var this = std.mem.zeroes(StringMap);
-pub fn decode(reader: anytype) anyerror!StringMap {
- var this = std.mem.zeroes(StringMap);
+ this.keys = try reader.readArray([]const u8);
+ this.values = try reader.readArray([]const u8);
+ return this;
+ }
- this.keys = try reader.readArray([]const u8);
- this.values = try reader.readArray([]const u8);
- return this;
-}
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray([]const u8, this.keys);
+ try writer.writeArray([]const u8, this.values);
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray([]const u8, this.keys);
- try writer.writeArray([]const u8, this.values);
-}
+ pub const LoaderMap = struct {
+ /// extensions
+ extensions: []const []const u8,
-};
+ /// loaders
+ loaders: []const Loader,
-pub const LoaderMap = struct {
-/// extensions
-extensions: []const []const u8,
+ pub fn decode(reader: anytype) anyerror!LoaderMap {
+ var this = std.mem.zeroes(LoaderMap);
-/// loaders
-loaders: []const Loader,
+ this.extensions = try reader.readArray([]const u8);
+ this.loaders = try reader.readArray(Loader);
+ return this;
+ }
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray([]const u8, this.extensions);
+ try writer.writeArray(Loader, this.loaders);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!LoaderMap {
- var this = std.mem.zeroes(LoaderMap);
+ pub const DotEnvBehavior = enum(u32) {
+ _none,
+ /// disable
+ disable,
- this.extensions = try reader.readArray([]const u8);
- this.loaders = try reader.readArray(Loader);
- return this;
-}
+ /// prefix
+ prefix,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray([]const u8, this.extensions);
- try writer.writeArray(Loader, this.loaders);
-}
+ /// load_all
+ load_all,
-};
+ _,
-pub const DotEnvBehavior = enum(u32) {
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-_none,
- /// disable
- disable,
+ pub const EnvConfig = struct {
+ /// prefix
+ prefix: ?[]const u8 = null,
- /// prefix
- prefix,
+ /// defaults
+ defaults: ?StringMap = null,
- /// load_all
- load_all,
+ pub fn decode(reader: anytype) anyerror!EnvConfig {
+ var this = std.mem.zeroes(EnvConfig);
-_,
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
+ 1 => {
+ this.prefix = try reader.readValue([]const u8);
+ },
+ 2 => {
+ this.defaults = try reader.readValue(StringMap);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
}
+ }
+ unreachable;
+ }
-
-};
-
-pub const EnvConfig = struct {
-/// prefix
-prefix: ?[]const u8 = null,
-
-/// defaults
-defaults: ?StringMap = null,
-
-
-pub fn decode(reader: anytype) anyerror!EnvConfig {
- var this = std.mem.zeroes(EnvConfig);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.prefix = try reader.readValue([]const u8);
-},
- 2 => {
- this.defaults = try reader.readValue(StringMap);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
-
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.prefix) |prefix| {
- try writer.writeFieldID(1);
- try writer.writeValue(prefix);
-}
-if (this.defaults) |defaults| {
- try writer.writeFieldID(2);
- try writer.writeValue(defaults);
-}
-try writer.endMessage();
-}
-
-};
-
-pub const LoadedEnvConfig = struct {
-/// dotenv
-dotenv: DotEnvBehavior,
-
-/// defaults
-defaults: StringMap,
-
-/// prefix
-prefix: []const u8,
-
-
-pub fn decode(reader: anytype) anyerror!LoadedEnvConfig {
- var this = std.mem.zeroes(LoadedEnvConfig);
-
- this.dotenv = try reader.readValue(DotEnvBehavior);
- this.defaults = try reader.readValue(StringMap);
- this.prefix = try reader.readValue([]const u8);
- return this;
-}
-
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeEnum(this.dotenv);
- try writer.writeValue(this.defaults);
- try writer.writeValue(this.prefix);
-}
-
-};
-
-pub const FrameworkConfig = struct {
-/// package
-package: ?[]const u8 = null,
-
-/// client
-client: ?[]const u8 = null,
-
-/// server
-server: ?[]const u8 = null,
-
-/// development
-development: ?bool = null,
-
-/// client_env
-client_env: ?EnvConfig = null,
-
-/// server_env
-server_env: ?EnvConfig = null,
-
-/// client_css_in_js
-client_css_in_js: ?CssInJsBehavior = null,
-
-
-pub fn decode(reader: anytype) anyerror!FrameworkConfig {
- var this = std.mem.zeroes(FrameworkConfig);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.package = try reader.readValue([]const u8);
-},
- 2 => {
- this.client = try reader.readValue([]const u8);
-},
- 3 => {
- this.server = try reader.readValue([]const u8);
-},
- 4 => {
- this.development = try reader.readValue(bool);
-},
- 5 => {
- this.client_env = try reader.readValue(EnvConfig);
-},
- 6 => {
- this.server_env = try reader.readValue(EnvConfig);
-},
- 7 => {
- this.client_css_in_js = try reader.readValue(CssInJsBehavior);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
-
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.package) |package| {
- try writer.writeFieldID(1);
- try writer.writeValue(package);
-}
-if (this.client) |client| {
- try writer.writeFieldID(2);
- try writer.writeValue(client);
-}
-if (this.server) |server| {
- try writer.writeFieldID(3);
- try writer.writeValue(server);
-}
-if (this.development) |development| {
- try writer.writeFieldID(4);
- try writer.writeInt(@intCast(u8, @boolToInt(development)));
-}
-if (this.client_env) |client_env| {
- try writer.writeFieldID(5);
- try writer.writeValue(client_env);
-}
-if (this.server_env) |server_env| {
- try writer.writeFieldID(6);
- try writer.writeValue(server_env);
-}
-if (this.client_css_in_js) |client_css_in_js| {
- try writer.writeFieldID(7);
- try writer.writeEnum(client_css_in_js);
-}
-try writer.endMessage();
-}
-
-};
-
-pub const LoadedFramework = struct {
-/// entry_point
-entry_point: []const u8,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.prefix) |prefix| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(prefix);
+ }
+ if (this.defaults) |defaults| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(defaults);
+ }
+ try writer.endMessage();
+ }
+ };
-/// package
-package: []const u8,
+ pub const LoadedEnvConfig = struct {
+ /// dotenv
+ dotenv: DotEnvBehavior,
-/// development
-development: bool = false,
+ /// defaults
+ defaults: StringMap,
-/// client
-client: bool = false,
+ /// prefix
+ prefix: []const u8,
-/// env
-env: LoadedEnvConfig,
+ pub fn decode(reader: anytype) anyerror!LoadedEnvConfig {
+ var this = std.mem.zeroes(LoadedEnvConfig);
-/// client_css_in_js
-client_css_in_js: CssInJsBehavior,
+ this.dotenv = try reader.readValue(DotEnvBehavior);
+ this.defaults = try reader.readValue(StringMap);
+ this.prefix = try reader.readValue([]const u8);
+ return this;
+ }
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.dotenv);
+ try writer.writeValue(this.defaults);
+ try writer.writeValue(this.prefix);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!LoadedFramework {
- var this = std.mem.zeroes(LoadedFramework);
+ pub const FrameworkConfig = struct {
+ /// package
+ package: ?[]const u8 = null,
- this.entry_point = try reader.readValue([]const u8);
- this.package = try reader.readValue([]const u8);
- this.development = try reader.readValue(bool);
- this.client = try reader.readValue(bool);
- this.env = try reader.readValue(LoadedEnvConfig);
- this.client_css_in_js = try reader.readValue(CssInJsBehavior);
- return this;
-}
+ /// client
+ client: ?[]const u8 = null,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeValue(this.entry_point);
- try writer.writeValue(this.package);
- try writer.writeInt(@intCast(u8, @boolToInt(this.development)));
- try writer.writeInt(@intCast(u8, @boolToInt(this.client)));
- try writer.writeValue(this.env);
- try writer.writeEnum(this.client_css_in_js);
-}
+ /// server
+ server: ?[]const u8 = null,
-};
+ /// development
+ development: ?bool = null,
-pub const LoadedRouteConfig = struct {
-/// dir
-dir: []const u8,
+ /// client_env
+ client_env: ?EnvConfig = null,
-/// extensions
-extensions: []const []const u8,
+ /// server_env
+ server_env: ?EnvConfig = null,
-/// static_dir
-static_dir: []const u8,
+ /// client_css_in_js
+ client_css_in_js: ?CssInJsBehavior = null,
-/// asset_prefix
-asset_prefix: []const u8,
+ pub fn decode(reader: anytype) anyerror!FrameworkConfig {
+ var this = std.mem.zeroes(FrameworkConfig);
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
-pub fn decode(reader: anytype) anyerror!LoadedRouteConfig {
- var this = std.mem.zeroes(LoadedRouteConfig);
+ 1 => {
+ this.package = try reader.readValue([]const u8);
+ },
+ 2 => {
+ this.client = try reader.readValue([]const u8);
+ },
+ 3 => {
+ this.server = try reader.readValue([]const u8);
+ },
+ 4 => {
+ this.development = try reader.readValue(bool);
+ },
+ 5 => {
+ this.client_env = try reader.readValue(EnvConfig);
+ },
+ 6 => {
+ this.server_env = try reader.readValue(EnvConfig);
+ },
+ 7 => {
+ this.client_css_in_js = try reader.readValue(CssInJsBehavior);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+ unreachable;
+ }
- this.dir = try reader.readValue([]const u8);
- this.extensions = try reader.readArray([]const u8);
- this.static_dir = try reader.readValue([]const u8);
- this.asset_prefix = try reader.readValue([]const u8);
- return this;
-}
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.package) |package| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(package);
+ }
+ if (this.client) |client| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(client);
+ }
+ if (this.server) |server| {
+ try writer.writeFieldID(3);
+ try writer.writeValue(server);
+ }
+ if (this.development) |development| {
+ try writer.writeFieldID(4);
+ try writer.writeInt(@intCast(u8, @boolToInt(development)));
+ }
+ if (this.client_env) |client_env| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(client_env);
+ }
+ if (this.server_env) |server_env| {
+ try writer.writeFieldID(6);
+ try writer.writeValue(server_env);
+ }
+ if (this.client_css_in_js) |client_css_in_js| {
+ try writer.writeFieldID(7);
+ try writer.writeEnum(client_css_in_js);
+ }
+ try writer.endMessage();
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeValue(this.dir);
- try writer.writeArray([]const u8, this.extensions);
- try writer.writeValue(this.static_dir);
- try writer.writeValue(this.asset_prefix);
-}
+ pub const LoadedFramework = struct {
+ /// entry_point
+ entry_point: []const u8,
-};
+ /// package
+ package: []const u8,
-pub const RouteConfig = struct {
-/// dir
-dir: []const []const u8,
-
-/// extensions
-extensions: []const []const u8,
-
-/// static_dir
-static_dir: ?[]const u8 = null,
-
-/// asset_prefix
-asset_prefix: ?[]const u8 = null,
-
-
-pub fn decode(reader: anytype) anyerror!RouteConfig {
- var this = std.mem.zeroes(RouteConfig);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.dir = try reader.readArray([]const u8);
-},
- 2 => {
- this.extensions = try reader.readArray([]const u8);
-},
- 3 => {
- this.static_dir = try reader.readValue([]const u8);
-},
- 4 => {
- this.asset_prefix = try reader.readValue([]const u8);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
+ /// development
+ development: bool = false,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.dir) |dir| {
- try writer.writeFieldID(1);
- try writer.writeArray([]const u8, dir);
-}
-if (this.extensions) |extensions| {
- try writer.writeFieldID(2);
- try writer.writeArray([]const u8, extensions);
-}
-if (this.static_dir) |static_dir| {
- try writer.writeFieldID(3);
- try writer.writeValue(static_dir);
-}
-if (this.asset_prefix) |asset_prefix| {
- try writer.writeFieldID(4);
- try writer.writeValue(asset_prefix);
-}
-try writer.endMessage();
-}
+ /// client
+ client: bool = false,
-};
+ /// env
+ env: LoadedEnvConfig,
-pub const TransformOptions = struct {
-/// jsx
-jsx: ?Jsx = null,
+ /// client_css_in_js
+ client_css_in_js: CssInJsBehavior,
-/// tsconfig_override
-tsconfig_override: ?[]const u8 = null,
+ pub fn decode(reader: anytype) anyerror!LoadedFramework {
+ var this = std.mem.zeroes(LoadedFramework);
-/// resolve
-resolve: ?ResolveMode = null,
+ this.entry_point = try reader.readValue([]const u8);
+ this.package = try reader.readValue([]const u8);
+ this.development = try reader.readValue(bool);
+ this.client = try reader.readValue(bool);
+ this.env = try reader.readValue(LoadedEnvConfig);
+ this.client_css_in_js = try reader.readValue(CssInJsBehavior);
+ return this;
+ }
-/// origin
-origin: ?[]const u8 = null,
-
-/// absolute_working_dir
-absolute_working_dir: ?[]const u8 = null,
-
-/// define
-define: ?StringMap = null,
-
-/// preserve_symlinks
-preserve_symlinks: ?bool = null,
-
-/// entry_points
-entry_points: []const []const u8,
-
-/// write
-write: ?bool = null,
-
-/// inject
-inject: []const []const u8,
-
-/// output_dir
-output_dir: ?[]const u8 = null,
-
-/// external
-external: []const []const u8,
-
-/// loaders
-loaders: ?LoaderMap = null,
-
-/// main_fields
-main_fields: []const []const u8,
-
-/// platform
-platform: ?Platform = null,
-
-/// serve
-serve: ?bool = null,
-
-/// extension_order
-extension_order: []const []const u8,
-
-/// generate_node_module_bundle
-generate_node_module_bundle: ?bool = null,
-
-/// node_modules_bundle_path
-node_modules_bundle_path: ?[]const u8 = null,
-
-/// node_modules_bundle_path_server
-node_modules_bundle_path_server: ?[]const u8 = null,
-
-/// framework
-framework: ?FrameworkConfig = null,
-
-/// router
-router: ?RouteConfig = null,
-
-/// no_summary
-no_summary: ?bool = null,
-
-
-pub fn decode(reader: anytype) anyerror!TransformOptions {
- var this = std.mem.zeroes(TransformOptions);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.jsx = try reader.readValue(Jsx);
-},
- 2 => {
- this.tsconfig_override = try reader.readValue([]const u8);
-},
- 3 => {
- this.resolve = try reader.readValue(ResolveMode);
-},
- 4 => {
- this.origin = try reader.readValue([]const u8);
-},
- 5 => {
- this.absolute_working_dir = try reader.readValue([]const u8);
-},
- 6 => {
- this.define = try reader.readValue(StringMap);
-},
- 7 => {
- this.preserve_symlinks = try reader.readValue(bool);
-},
- 8 => {
- this.entry_points = try reader.readArray([]const u8);
-},
- 9 => {
- this.write = try reader.readValue(bool);
-},
- 10 => {
- this.inject = try reader.readArray([]const u8);
-},
- 11 => {
- this.output_dir = try reader.readValue([]const u8);
-},
- 12 => {
- this.external = try reader.readArray([]const u8);
-},
- 13 => {
- this.loaders = try reader.readValue(LoaderMap);
-},
- 14 => {
- this.main_fields = try reader.readArray([]const u8);
-},
- 15 => {
- this.platform = try reader.readValue(Platform);
-},
- 16 => {
- this.serve = try reader.readValue(bool);
-},
- 17 => {
- this.extension_order = try reader.readArray([]const u8);
-},
- 18 => {
- this.generate_node_module_bundle = try reader.readValue(bool);
-},
- 19 => {
- this.node_modules_bundle_path = try reader.readValue([]const u8);
-},
- 20 => {
- this.node_modules_bundle_path_server = try reader.readValue([]const u8);
-},
- 21 => {
- this.framework = try reader.readValue(FrameworkConfig);
-},
- 22 => {
- this.router = try reader.readValue(RouteConfig);
-},
- 23 => {
- this.no_summary = try reader.readValue(bool);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.entry_point);
+ try writer.writeValue(this.package);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.development)));
+ try writer.writeInt(@intCast(u8, @boolToInt(this.client)));
+ try writer.writeValue(this.env);
+ try writer.writeEnum(this.client_css_in_js);
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.jsx) |jsx| {
- try writer.writeFieldID(1);
- try writer.writeValue(jsx);
-}
-if (this.tsconfig_override) |tsconfig_override| {
- try writer.writeFieldID(2);
- try writer.writeValue(tsconfig_override);
-}
-if (this.resolve) |resolve| {
- try writer.writeFieldID(3);
- try writer.writeEnum(resolve);
-}
-if (this.origin) |origin| {
- try writer.writeFieldID(4);
- try writer.writeValue(origin);
-}
-if (this.absolute_working_dir) |absolute_working_dir| {
- try writer.writeFieldID(5);
- try writer.writeValue(absolute_working_dir);
-}
-if (this.define) |define| {
- try writer.writeFieldID(6);
- try writer.writeValue(define);
-}
-if (this.preserve_symlinks) |preserve_symlinks| {
- try writer.writeFieldID(7);
- try writer.writeInt(@intCast(u8, @boolToInt(preserve_symlinks)));
-}
-if (this.entry_points) |entry_points| {
- try writer.writeFieldID(8);
- try writer.writeArray([]const u8, entry_points);
-}
-if (this.write) |write| {
- try writer.writeFieldID(9);
- try writer.writeInt(@intCast(u8, @boolToInt(write)));
-}
-if (this.inject) |inject| {
- try writer.writeFieldID(10);
- try writer.writeArray([]const u8, inject);
-}
-if (this.output_dir) |output_dir| {
- try writer.writeFieldID(11);
- try writer.writeValue(output_dir);
-}
-if (this.external) |external| {
- try writer.writeFieldID(12);
- try writer.writeArray([]const u8, external);
-}
-if (this.loaders) |loaders| {
- try writer.writeFieldID(13);
- try writer.writeValue(loaders);
-}
-if (this.main_fields) |main_fields| {
- try writer.writeFieldID(14);
- try writer.writeArray([]const u8, main_fields);
-}
-if (this.platform) |platform| {
- try writer.writeFieldID(15);
- try writer.writeEnum(platform);
-}
-if (this.serve) |serve| {
- try writer.writeFieldID(16);
- try writer.writeInt(@intCast(u8, @boolToInt(serve)));
-}
-if (this.extension_order) |extension_order| {
- try writer.writeFieldID(17);
- try writer.writeArray([]const u8, extension_order);
-}
-if (this.generate_node_module_bundle) |generate_node_module_bundle| {
- try writer.writeFieldID(18);
- try writer.writeInt(@intCast(u8, @boolToInt(generate_node_module_bundle)));
-}
-if (this.node_modules_bundle_path) |node_modules_bundle_path| {
- try writer.writeFieldID(19);
- try writer.writeValue(node_modules_bundle_path);
-}
-if (this.node_modules_bundle_path_server) |node_modules_bundle_path_server| {
- try writer.writeFieldID(20);
- try writer.writeValue(node_modules_bundle_path_server);
-}
-if (this.framework) |framework| {
- try writer.writeFieldID(21);
- try writer.writeValue(framework);
-}
-if (this.router) |router| {
- try writer.writeFieldID(22);
- try writer.writeValue(router);
-}
-if (this.no_summary) |no_summary| {
- try writer.writeFieldID(23);
- try writer.writeInt(@intCast(u8, @boolToInt(no_summary)));
-}
-try writer.endMessage();
-}
+ pub const LoadedRouteConfig = struct {
+ /// dir
+ dir: []const u8,
-};
+ /// extensions
+ extensions: []const []const u8,
-pub const FileHandle = struct {
-/// path
-path: []const u8,
+ /// static_dir
+ static_dir: []const u8,
-/// size
-size: u32 = 0,
+ /// asset_prefix
+ asset_prefix: []const u8,
-/// fd
-fd: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!LoadedRouteConfig {
+ var this = std.mem.zeroes(LoadedRouteConfig);
+ this.dir = try reader.readValue([]const u8);
+ this.extensions = try reader.readArray([]const u8);
+ this.static_dir = try reader.readValue([]const u8);
+ this.asset_prefix = try reader.readValue([]const u8);
+ return this;
+ }
-pub fn decode(reader: anytype) anyerror!FileHandle {
- var this = std.mem.zeroes(FileHandle);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.dir);
+ try writer.writeArray([]const u8, this.extensions);
+ try writer.writeValue(this.static_dir);
+ try writer.writeValue(this.asset_prefix);
+ }
+ };
- this.path = try reader.readValue([]const u8);
- this.size = try reader.readValue(u32);
- this.fd = try reader.readValue(u32);
- return this;
-}
+ pub const RouteConfig = struct {
+ /// dir
+ dir: []const []const u8,
-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);
-}
+ /// extensions
+ extensions: []const []const u8,
-};
+ /// static_dir
+ static_dir: ?[]const u8 = null,
-pub const Transform = struct {
-/// handle
-handle: ?FileHandle = null,
-
-/// path
-path: ?[]const u8 = null,
-
-/// contents
-contents: []const u8,
-
-/// loader
-loader: ?Loader = null,
-
-/// options
-options: ?TransformOptions = null,
-
-
-pub fn decode(reader: anytype) anyerror!Transform {
- var this = std.mem.zeroes(Transform);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.handle = try reader.readValue(FileHandle);
-},
- 2 => {
- this.path = try reader.readValue([]const u8);
-},
- 3 => {
- this.contents = try reader.readArray(u8);
-},
- 4 => {
- this.loader = try reader.readValue(Loader);
-},
- 5 => {
- this.options = try reader.readValue(TransformOptions);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
+ /// asset_prefix
+ asset_prefix: ?[]const u8 = null,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.handle) |handle| {
- try writer.writeFieldID(1);
- try writer.writeValue(handle);
-}
-if (this.path) |path| {
- try writer.writeFieldID(2);
- try writer.writeValue(path);
-}
-if (this.contents) |contents| {
- try writer.writeFieldID(3);
- try writer.writeArray(u8, contents);
-}
-if (this.loader) |loader| {
- try writer.writeFieldID(4);
- try writer.writeEnum(loader);
-}
-if (this.options) |options| {
- try writer.writeFieldID(5);
- try writer.writeValue(options);
-}
-try writer.endMessage();
-}
+ pub fn decode(reader: anytype) anyerror!RouteConfig {
+ var this = std.mem.zeroes(RouteConfig);
-};
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
-pub const TransformResponseStatus = enum(u32) {
+ 1 => {
+ this.dir = try reader.readArray([]const u8);
+ },
+ 2 => {
+ this.extensions = try reader.readArray([]const u8);
+ },
+ 3 => {
+ this.static_dir = try reader.readValue([]const u8);
+ },
+ 4 => {
+ this.asset_prefix = try reader.readValue([]const u8);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+ unreachable;
+ }
-_none,
- /// success
- success,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.dir) |dir| {
+ try writer.writeFieldID(1);
+ try writer.writeArray([]const u8, dir);
+ }
+ if (this.extensions) |extensions| {
+ try writer.writeFieldID(2);
+ try writer.writeArray([]const u8, extensions);
+ }
+ if (this.static_dir) |static_dir| {
+ try writer.writeFieldID(3);
+ try writer.writeValue(static_dir);
+ }
+ if (this.asset_prefix) |asset_prefix| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(asset_prefix);
+ }
+ try writer.endMessage();
+ }
+ };
- /// fail
- fail,
+ pub const TransformOptions = struct {
+ /// jsx
+ jsx: ?Jsx = null,
-_,
+ /// tsconfig_override
+ tsconfig_override: ?[]const u8 = null,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ /// resolve
+ resolve: ?ResolveMode = null,
-
-};
+ /// origin
+ origin: ?[]const u8 = null,
-pub const OutputFile = struct {
-/// data
-data: []const u8,
+ /// absolute_working_dir
+ absolute_working_dir: ?[]const u8 = null,
-/// path
-path: []const u8,
+ /// define
+ define: ?StringMap = null,
+ /// preserve_symlinks
+ preserve_symlinks: ?bool = null,
-pub fn decode(reader: anytype) anyerror!OutputFile {
- var this = std.mem.zeroes(OutputFile);
+ /// entry_points
+ entry_points: []const []const u8,
- this.data = try reader.readArray(u8);
- this.path = try reader.readValue([]const u8);
- return this;
-}
+ /// write
+ write: ?bool = null,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u8, this.data);
- try writer.writeValue(this.path);
-}
+ /// inject
+ inject: []const []const u8,
-};
+ /// output_dir
+ output_dir: ?[]const u8 = null,
-pub const TransformResponse = struct {
-/// status
-status: TransformResponseStatus,
+ /// external
+ external: []const []const u8,
-/// files
-files: []const OutputFile,
+ /// loaders
+ loaders: ?LoaderMap = null,
-/// errors
-errors: []const Message,
+ /// main_fields
+ main_fields: []const []const u8,
+ /// platform
+ platform: ?Platform = null,
-pub fn decode(reader: anytype) anyerror!TransformResponse {
- var this = std.mem.zeroes(TransformResponse);
+ /// serve
+ serve: ?bool = null,
- this.status = try reader.readValue(TransformResponseStatus);
- this.files = try reader.readArray(OutputFile);
- this.errors = try reader.readArray(Message);
- return this;
-}
+ /// extension_order
+ extension_order: []const []const u8,
-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);
-}
+ /// generate_node_module_bundle
+ generate_node_module_bundle: ?bool = null,
-};
+ /// node_modules_bundle_path
+ node_modules_bundle_path: ?[]const u8 = null,
-pub const MessageKind = enum(u32) {
+ /// node_modules_bundle_path_server
+ node_modules_bundle_path_server: ?[]const u8 = null,
-_none,
- /// err
- err,
+ /// framework
+ framework: ?FrameworkConfig = null,
- /// warn
- warn,
+ /// router
+ router: ?RouteConfig = null,
- /// note
- note,
+ /// no_summary
+ no_summary: ?bool = null,
- /// debug
- debug,
+ pub fn decode(reader: anytype) anyerror!TransformOptions {
+ var this = std.mem.zeroes(TransformOptions);
-_,
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
+ 1 => {
+ this.jsx = try reader.readValue(Jsx);
+ },
+ 2 => {
+ this.tsconfig_override = try reader.readValue([]const u8);
+ },
+ 3 => {
+ this.resolve = try reader.readValue(ResolveMode);
+ },
+ 4 => {
+ this.origin = try reader.readValue([]const u8);
+ },
+ 5 => {
+ this.absolute_working_dir = try reader.readValue([]const u8);
+ },
+ 6 => {
+ this.define = try reader.readValue(StringMap);
+ },
+ 7 => {
+ this.preserve_symlinks = try reader.readValue(bool);
+ },
+ 8 => {
+ this.entry_points = try reader.readArray([]const u8);
+ },
+ 9 => {
+ this.write = try reader.readValue(bool);
+ },
+ 10 => {
+ this.inject = try reader.readArray([]const u8);
+ },
+ 11 => {
+ this.output_dir = try reader.readValue([]const u8);
+ },
+ 12 => {
+ this.external = try reader.readArray([]const u8);
+ },
+ 13 => {
+ this.loaders = try reader.readValue(LoaderMap);
+ },
+ 14 => {
+ this.main_fields = try reader.readArray([]const u8);
+ },
+ 15 => {
+ this.platform = try reader.readValue(Platform);
+ },
+ 16 => {
+ this.serve = try reader.readValue(bool);
+ },
+ 17 => {
+ this.extension_order = try reader.readArray([]const u8);
+ },
+ 18 => {
+ this.generate_node_module_bundle = try reader.readValue(bool);
+ },
+ 19 => {
+ this.node_modules_bundle_path = try reader.readValue([]const u8);
+ },
+ 20 => {
+ this.node_modules_bundle_path_server = try reader.readValue([]const u8);
+ },
+ 21 => {
+ this.framework = try reader.readValue(FrameworkConfig);
+ },
+ 22 => {
+ this.router = try reader.readValue(RouteConfig);
+ },
+ 23 => {
+ this.no_summary = try reader.readValue(bool);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
}
+ }
+ unreachable;
+ }
-
-};
-
-pub const Location = struct {
-/// file
-file: []const u8,
-
-/// namespace
-namespace: []const u8,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.jsx) |jsx| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(jsx);
+ }
+ if (this.tsconfig_override) |tsconfig_override| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(tsconfig_override);
+ }
+ if (this.resolve) |resolve| {
+ try writer.writeFieldID(3);
+ try writer.writeEnum(resolve);
+ }
+ if (this.origin) |origin| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(origin);
+ }
+ if (this.absolute_working_dir) |absolute_working_dir| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(absolute_working_dir);
+ }
+ if (this.define) |define| {
+ try writer.writeFieldID(6);
+ try writer.writeValue(define);
+ }
+ if (this.preserve_symlinks) |preserve_symlinks| {
+ try writer.writeFieldID(7);
+ try writer.writeInt(@intCast(u8, @boolToInt(preserve_symlinks)));
+ }
+ if (this.entry_points) |entry_points| {
+ try writer.writeFieldID(8);
+ try writer.writeArray([]const u8, entry_points);
+ }
+ if (this.write) |write| {
+ try writer.writeFieldID(9);
+ try writer.writeInt(@intCast(u8, @boolToInt(write)));
+ }
+ if (this.inject) |inject| {
+ try writer.writeFieldID(10);
+ try writer.writeArray([]const u8, inject);
+ }
+ if (this.output_dir) |output_dir| {
+ try writer.writeFieldID(11);
+ try writer.writeValue(output_dir);
+ }
+ if (this.external) |external| {
+ try writer.writeFieldID(12);
+ try writer.writeArray([]const u8, external);
+ }
+ if (this.loaders) |loaders| {
+ try writer.writeFieldID(13);
+ try writer.writeValue(loaders);
+ }
+ if (this.main_fields) |main_fields| {
+ try writer.writeFieldID(14);
+ try writer.writeArray([]const u8, main_fields);
+ }
+ if (this.platform) |platform| {
+ try writer.writeFieldID(15);
+ try writer.writeEnum(platform);
+ }
+ if (this.serve) |serve| {
+ try writer.writeFieldID(16);
+ try writer.writeInt(@intCast(u8, @boolToInt(serve)));
+ }
+ if (this.extension_order) |extension_order| {
+ try writer.writeFieldID(17);
+ try writer.writeArray([]const u8, extension_order);
+ }
+ if (this.generate_node_module_bundle) |generate_node_module_bundle| {
+ try writer.writeFieldID(18);
+ try writer.writeInt(@intCast(u8, @boolToInt(generate_node_module_bundle)));
+ }
+ if (this.node_modules_bundle_path) |node_modules_bundle_path| {
+ try writer.writeFieldID(19);
+ try writer.writeValue(node_modules_bundle_path);
+ }
+ if (this.node_modules_bundle_path_server) |node_modules_bundle_path_server| {
+ try writer.writeFieldID(20);
+ try writer.writeValue(node_modules_bundle_path_server);
+ }
+ if (this.framework) |framework| {
+ try writer.writeFieldID(21);
+ try writer.writeValue(framework);
+ }
+ if (this.router) |router| {
+ try writer.writeFieldID(22);
+ try writer.writeValue(router);
+ }
+ if (this.no_summary) |no_summary| {
+ try writer.writeFieldID(23);
+ try writer.writeInt(@intCast(u8, @boolToInt(no_summary)));
+ }
+ try writer.endMessage();
+ }
+ };
-/// line
-line: i32 = 0,
+ pub const FileHandle = struct {
+ /// path
+ path: []const u8,
-/// column
-column: i32 = 0,
+ /// size
+ size: u32 = 0,
-/// line_text
-line_text: []const u8,
+ /// fd
+ fd: u32 = 0,
-/// suggestion
-suggestion: []const u8,
+ pub fn decode(reader: anytype) anyerror!FileHandle {
+ var this = std.mem.zeroes(FileHandle);
-/// offset
-offset: u32 = 0,
+ this.path = try reader.readValue([]const u8);
+ this.size = try reader.readValue(u32);
+ this.fd = try reader.readValue(u32);
+ return this;
+ }
+ 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);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!Location {
- var this = std.mem.zeroes(Location);
+ pub const Transform = struct {
+ /// handle
+ handle: ?FileHandle = null,
- 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;
-}
+ /// path
+ path: ?[]const u8 = null,
-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);
-}
+ /// contents
+ contents: []const u8,
-};
+ /// loader
+ loader: ?Loader = null,
-pub const MessageData = struct {
-/// text
-text: ?[]const u8 = null,
-
-/// location
-location: ?Location = null,
-
-
-pub fn decode(reader: anytype) anyerror!MessageData {
- var this = std.mem.zeroes(MessageData);
-
- while(true) {
- switch (try reader.readByte()) {
- 0 => { return this; },
-
- 1 => {
- this.text = try reader.readValue([]const u8);
-},
- 2 => {
- this.location = try reader.readValue(Location);
-},
- else => {
- return error.InvalidMessage;
- },
- }
- }
-unreachable;
-}
+ /// options
+ options: ?TransformOptions = null,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
-if (this.text) |text| {
- try writer.writeFieldID(1);
- try writer.writeValue(text);
-}
-if (this.location) |location| {
- try writer.writeFieldID(2);
- try writer.writeValue(location);
-}
-try writer.endMessage();
-}
+ pub fn decode(reader: anytype) anyerror!Transform {
+ var this = std.mem.zeroes(Transform);
-};
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
-pub const Message = struct {
-/// kind
-kind: MessageKind,
+ 1 => {
+ this.handle = try reader.readValue(FileHandle);
+ },
+ 2 => {
+ this.path = try reader.readValue([]const u8);
+ },
+ 3 => {
+ this.contents = try reader.readArray(u8);
+ },
+ 4 => {
+ this.loader = try reader.readValue(Loader);
+ },
+ 5 => {
+ this.options = try reader.readValue(TransformOptions);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+ unreachable;
+ }
-/// data
-data: MessageData,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.handle) |handle| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(handle);
+ }
+ if (this.path) |path| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(path);
+ }
+ if (this.contents) |contents| {
+ try writer.writeFieldID(3);
+ try writer.writeArray(u8, contents);
+ }
+ if (this.loader) |loader| {
+ try writer.writeFieldID(4);
+ try writer.writeEnum(loader);
+ }
+ if (this.options) |options| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(options);
+ }
+ try writer.endMessage();
+ }
+ };
-/// notes
-notes: []const MessageData,
+ pub const TransformResponseStatus = enum(u32) {
+ _none,
+ /// success
+ success,
+ /// fail
+ fail,
-pub fn decode(reader: anytype) anyerror!Message {
- var this = std.mem.zeroes(Message);
+ _,
- this.kind = try reader.readValue(MessageKind);
- this.data = try reader.readValue(MessageData);
- this.notes = try reader.readArray(MessageData);
- return this;
-}
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-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);
-}
+ pub const OutputFile = struct {
+ /// data
+ data: []const u8,
-};
+ /// path
+ path: []const u8,
-pub const Log = struct {
-/// warnings
-warnings: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!OutputFile {
+ var this = std.mem.zeroes(OutputFile);
-/// errors
-errors: u32 = 0,
+ this.data = try reader.readArray(u8);
+ this.path = try reader.readValue([]const u8);
+ return this;
+ }
-/// msgs
-msgs: []const Message,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u8, this.data);
+ try writer.writeValue(this.path);
+ }
+ };
+ pub const TransformResponse = struct {
+ /// status
+ status: TransformResponseStatus,
-pub fn decode(reader: anytype) anyerror!Log {
- var this = std.mem.zeroes(Log);
+ /// files
+ files: []const OutputFile,
- this.warnings = try reader.readValue(u32);
- this.errors = try reader.readValue(u32);
- this.msgs = try reader.readArray(Message);
- return this;
-}
+ /// errors
+ errors: []const Message,
-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);
-}
+ pub fn decode(reader: anytype) anyerror!TransformResponse {
+ var this = std.mem.zeroes(TransformResponse);
-};
+ this.status = try reader.readValue(TransformResponseStatus);
+ this.files = try reader.readArray(OutputFile);
+ this.errors = try reader.readArray(Message);
+ return this;
+ }
-pub const Reloader = enum(u8) {
+ 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);
+ }
+ };
-_none,
- /// disable
- disable,
+ pub const MessageKind = enum(u32) {
+ _none,
+ /// err
+ err,
- /// live
- live,
+ /// warn
+ warn,
- /// fast_refresh
- fast_refresh,
+ /// note
+ note,
-_,
+ /// debug
+ debug,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ _,
-
-};
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-pub const WebsocketMessageKind = enum(u8) {
+ pub const Location = struct {
+ /// file
+ file: []const u8,
-_none,
- /// welcome
- welcome,
+ /// namespace
+ namespace: []const u8,
- /// file_change_notification
- file_change_notification,
+ /// line
+ line: i32 = 0,
- /// build_success
- build_success,
+ /// column
+ column: i32 = 0,
- /// build_fail
- build_fail,
+ /// line_text
+ line_text: []const u8,
- /// manifest_success
- manifest_success,
+ /// suggestion
+ suggestion: []const u8,
- /// manifest_fail
- manifest_fail,
+ /// offset
+ offset: u32 = 0,
-_,
+ pub fn decode(reader: anytype) anyerror!Location {
+ var this = std.mem.zeroes(Location);
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
+ 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 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);
+ }
+ };
-pub const WebsocketCommandKind = enum(u8) {
+ pub const MessageData = struct {
+ /// text
+ text: ?[]const u8 = null,
-_none,
- /// build
- build,
+ /// location
+ location: ?Location = null,
- /// manifest
- manifest,
+ pub fn decode(reader: anytype) anyerror!MessageData {
+ var this = std.mem.zeroes(MessageData);
-_,
+ while (true) {
+ switch (try reader.readByte()) {
+ 0 => {
+ return this;
+ },
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
+ 1 => {
+ this.text = try reader.readValue([]const u8);
+ },
+ 2 => {
+ this.location = try reader.readValue(Location);
+ },
+ else => {
+ return error.InvalidMessage;
+ },
}
+ }
+ unreachable;
+ }
-
-};
-
-pub const WebsocketMessage = struct {
-/// timestamp
-timestamp: u32 = 0,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ if (this.text) |text| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(text);
+ }
+ if (this.location) |location| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(location);
+ }
+ try writer.endMessage();
+ }
+ };
-/// kind
-kind: WebsocketMessageKind,
+ pub const Message = struct {
+ /// kind
+ kind: MessageKind,
+ /// data
+ data: MessageData,
-pub fn decode(reader: anytype) anyerror!WebsocketMessage {
- var this = std.mem.zeroes(WebsocketMessage);
+ /// notes
+ notes: []const MessageData,
- this.timestamp = try reader.readValue(u32);
- this.kind = try reader.readValue(WebsocketMessageKind);
- return this;
-}
+ pub fn decode(reader: anytype) anyerror!Message {
+ var this = std.mem.zeroes(Message);
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.timestamp);
- try writer.writeEnum(this.kind);
-}
+ this.kind = try reader.readValue(MessageKind);
+ this.data = try reader.readValue(MessageData);
+ this.notes = try reader.readArray(MessageData);
+ return this;
+ }
-};
+ 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);
+ }
+ };
-pub const WebsocketMessageWelcome = struct {
-/// epoch
-epoch: u32 = 0,
+ pub const Log = struct {
+ /// warnings
+ warnings: u32 = 0,
-/// javascriptReloader
-javascript_reloader: Reloader,
+ /// errors
+ errors: u32 = 0,
+ /// msgs
+ msgs: []const Message,
-pub fn decode(reader: anytype) anyerror!WebsocketMessageWelcome {
- var this = std.mem.zeroes(WebsocketMessageWelcome);
+ pub fn decode(reader: anytype) anyerror!Log {
+ var this = std.mem.zeroes(Log);
- this.epoch = try reader.readValue(u32);
- this.javascript_reloader = try reader.readValue(Reloader);
- return this;
-}
+ this.warnings = try reader.readValue(u32);
+ this.errors = try reader.readValue(u32);
+ this.msgs = try reader.readArray(Message);
+ return this;
+ }
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.epoch);
- try writer.writeEnum(this.javascript_reloader);
-}
+ 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);
+ }
+ };
-};
+ pub const Reloader = enum(u8) {
+ _none,
+ /// disable
+ disable,
-pub const WebsocketMessageFileChangeNotification = struct {
-/// id
-id: u32 = 0,
+ /// live
+ live,
-/// loader
-loader: Loader,
+ /// fast_refresh
+ fast_refresh,
+ _,
-pub fn decode(reader: anytype) anyerror!WebsocketMessageFileChangeNotification {
- var this = std.mem.zeroes(WebsocketMessageFileChangeNotification);
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
- this.id = try reader.readValue(u32);
- this.loader = try reader.readValue(Loader);
- return this;
-}
+ pub const WebsocketMessageKind = enum(u8) {
+ _none,
+ /// welcome
+ welcome,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- try writer.writeEnum(this.loader);
-}
+ /// file_change_notification
+ file_change_notification,
-};
+ /// build_success
+ build_success,
-pub const WebsocketCommand = struct {
-/// kind
-kind: WebsocketCommandKind,
+ /// build_fail
+ build_fail,
-/// timestamp
-timestamp: u32 = 0,
+ /// manifest_success
+ manifest_success,
+ /// manifest_fail
+ manifest_fail,
-pub fn decode(reader: anytype) anyerror!WebsocketCommand {
- var this = std.mem.zeroes(WebsocketCommand);
+ _,
- this.kind = try reader.readValue(WebsocketCommandKind);
- this.timestamp = try reader.readValue(u32);
- return this;
-}
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeEnum(this.kind);
- try writer.writeInt(this.timestamp);
-}
+ pub const WebsocketCommandKind = enum(u8) {
+ _none,
+ /// build
+ build,
-};
+ /// manifest
+ manifest,
-pub const WebsocketCommandBuild = packed struct {
-/// id
-id: u32 = 0,
+ _,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!WebsocketCommandBuild {
- var this = std.mem.zeroes(WebsocketCommandBuild);
+ pub const WebsocketMessage = struct {
+ /// timestamp
+ timestamp: u32 = 0,
- this.id = try reader.readValue(u32);
- return this;
-}
+ /// kind
+ kind: WebsocketMessageKind,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketMessage {
+ var this = std.mem.zeroes(WebsocketMessage);
-};
+ this.timestamp = try reader.readValue(u32);
+ this.kind = try reader.readValue(WebsocketMessageKind);
+ return this;
+ }
-pub const WebsocketCommandManifest = packed struct {
-/// id
-id: u32 = 0,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.timestamp);
+ try writer.writeEnum(this.kind);
+ }
+ };
+ pub const WebsocketMessageWelcome = struct {
+ /// epoch
+ epoch: u32 = 0,
-pub fn decode(reader: anytype) anyerror!WebsocketCommandManifest {
- var this = std.mem.zeroes(WebsocketCommandManifest);
+ /// javascriptReloader
+ javascript_reloader: Reloader,
- this.id = try reader.readValue(u32);
- return this;
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageWelcome {
+ var this = std.mem.zeroes(WebsocketMessageWelcome);
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
-}
+ this.epoch = try reader.readValue(u32);
+ this.javascript_reloader = try reader.readValue(Reloader);
+ return this;
+ }
-};
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.epoch);
+ try writer.writeEnum(this.javascript_reloader);
+ }
+ };
-pub const WebsocketMessageBuildSuccess = struct {
-/// id
-id: u32 = 0,
+ pub const WebsocketMessageFileChangeNotification = struct {
+ /// id
+ id: u32 = 0,
-/// from_timestamp
-from_timestamp: u32 = 0,
+ /// loader
+ loader: Loader,
-/// loader
-loader: Loader,
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageFileChangeNotification {
+ var this = std.mem.zeroes(WebsocketMessageFileChangeNotification);
-/// module_path
-module_path: []const u8,
+ this.id = try reader.readValue(u32);
+ this.loader = try reader.readValue(Loader);
+ return this;
+ }
-/// blob_length
-blob_length: u32 = 0,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeEnum(this.loader);
+ }
+ };
+ pub const WebsocketCommand = struct {
+ /// kind
+ kind: WebsocketCommandKind,
-pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildSuccess {
- var this = std.mem.zeroes(WebsocketMessageBuildSuccess);
+ /// timestamp
+ timestamp: u32 = 0,
- this.id = try reader.readValue(u32);
- this.from_timestamp = try reader.readValue(u32);
- this.loader = try reader.readValue(Loader);
- this.module_path = try reader.readValue([]const u8);
- this.blob_length = try reader.readValue(u32);
- return this;
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketCommand {
+ var this = std.mem.zeroes(WebsocketCommand);
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- try writer.writeInt(this.from_timestamp);
- try writer.writeEnum(this.loader);
- try writer.writeValue(this.module_path);
- try writer.writeInt(this.blob_length);
-}
+ this.kind = try reader.readValue(WebsocketCommandKind);
+ this.timestamp = try reader.readValue(u32);
+ return this;
+ }
-};
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.kind);
+ try writer.writeInt(this.timestamp);
+ }
+ };
-pub const WebsocketMessageBuildFailure = struct {
-/// id
-id: u32 = 0,
+ pub const WebsocketCommandBuild = packed struct {
+ /// id
+ id: u32 = 0,
-/// from_timestamp
-from_timestamp: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!WebsocketCommandBuild {
+ var this = std.mem.zeroes(WebsocketCommandBuild);
-/// loader
-loader: Loader,
+ this.id = try reader.readValue(u32);
+ return this;
+ }
-/// module_path
-module_path: []const u8,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ }
+ };
-/// log
-log: Log,
+ pub const WebsocketCommandManifest = packed struct {
+ /// id
+ id: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!WebsocketCommandManifest {
+ var this = std.mem.zeroes(WebsocketCommandManifest);
-pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildFailure {
- var this = std.mem.zeroes(WebsocketMessageBuildFailure);
+ this.id = try reader.readValue(u32);
+ return this;
+ }
- this.id = try reader.readValue(u32);
- this.from_timestamp = try reader.readValue(u32);
- this.loader = try reader.readValue(Loader);
- this.module_path = try reader.readValue([]const u8);
- this.log = try reader.readValue(Log);
- return this;
-}
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- try writer.writeInt(this.from_timestamp);
- try writer.writeEnum(this.loader);
- try writer.writeValue(this.module_path);
- try writer.writeValue(this.log);
-}
+ pub const WebsocketMessageBuildSuccess = struct {
+ /// id
+ id: u32 = 0,
-};
+ /// from_timestamp
+ from_timestamp: u32 = 0,
-pub const DependencyManifest = struct {
-/// ids
-ids: []const u32,
+ /// loader
+ loader: Loader,
+ /// module_path
+ module_path: []const u8,
-pub fn decode(reader: anytype) anyerror!DependencyManifest {
- var this = std.mem.zeroes(DependencyManifest);
+ /// blob_length
+ blob_length: u32 = 0,
- this.ids = try reader.readArray(u32);
- return this;
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildSuccess {
+ var this = std.mem.zeroes(WebsocketMessageBuildSuccess);
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u32, this.ids);
-}
+ this.id = try reader.readValue(u32);
+ this.from_timestamp = try reader.readValue(u32);
+ this.loader = try reader.readValue(Loader);
+ this.module_path = try reader.readValue([]const u8);
+ this.blob_length = try reader.readValue(u32);
+ return this;
+ }
-};
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeInt(this.from_timestamp);
+ try writer.writeEnum(this.loader);
+ try writer.writeValue(this.module_path);
+ try writer.writeInt(this.blob_length);
+ }
+ };
-pub const FileList = struct {
-/// ptrs
-ptrs: []const StringPointer,
+ pub const WebsocketMessageBuildFailure = struct {
+ /// id
+ id: u32 = 0,
-/// files
-files: []const u8,
+ /// from_timestamp
+ from_timestamp: u32 = 0,
+ /// loader
+ loader: Loader,
-pub fn decode(reader: anytype) anyerror!FileList {
- var this = std.mem.zeroes(FileList);
+ /// module_path
+ module_path: []const u8,
- this.ptrs = try reader.readArray(StringPointer);
- this.files = try reader.readValue([]const u8);
- return this;
-}
+ /// log
+ log: Log,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(StringPointer, this.ptrs);
- try writer.writeValue(this.files);
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildFailure {
+ var this = std.mem.zeroes(WebsocketMessageBuildFailure);
-};
+ this.id = try reader.readValue(u32);
+ this.from_timestamp = try reader.readValue(u32);
+ this.loader = try reader.readValue(Loader);
+ this.module_path = try reader.readValue([]const u8);
+ this.log = try reader.readValue(Log);
+ return this;
+ }
-pub const WebsocketMessageResolveIDs = struct {
-/// id
-id: []const u32,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeInt(this.from_timestamp);
+ try writer.writeEnum(this.loader);
+ try writer.writeValue(this.module_path);
+ try writer.writeValue(this.log);
+ }
+ };
-/// list
-list: FileList,
+ pub const DependencyManifest = struct {
+ /// ids
+ ids: []const u32,
+ pub fn decode(reader: anytype) anyerror!DependencyManifest {
+ var this = std.mem.zeroes(DependencyManifest);
-pub fn decode(reader: anytype) anyerror!WebsocketMessageResolveIDs {
- var this = std.mem.zeroes(WebsocketMessageResolveIDs);
+ this.ids = try reader.readArray(u32);
+ return this;
+ }
- this.id = try reader.readArray(u32);
- this.list = try reader.readValue(FileList);
- return this;
-}
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u32, this.ids);
+ }
+ };
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u32, this.id);
- try writer.writeValue(this.list);
-}
+ pub const FileList = struct {
+ /// ptrs
+ ptrs: []const StringPointer,
-};
+ /// files
+ files: []const u8,
-pub const WebsocketCommandResolveIDs = struct {
-/// ptrs
-ptrs: []const StringPointer,
+ pub fn decode(reader: anytype) anyerror!FileList {
+ var this = std.mem.zeroes(FileList);
-/// files
-files: []const u8,
+ this.ptrs = try reader.readArray(StringPointer);
+ this.files = try reader.readValue([]const u8);
+ return this;
+ }
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(StringPointer, this.ptrs);
+ try writer.writeValue(this.files);
+ }
+ };
-pub fn decode(reader: anytype) anyerror!WebsocketCommandResolveIDs {
- var this = std.mem.zeroes(WebsocketCommandResolveIDs);
+ pub const WebsocketMessageResolveIDs = struct {
+ /// id
+ id: []const u32,
- this.ptrs = try reader.readArray(StringPointer);
- this.files = try reader.readValue([]const u8);
- return this;
-}
+ /// list
+ list: FileList,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(StringPointer, this.ptrs);
- try writer.writeValue(this.files);
-}
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageResolveIDs {
+ var this = std.mem.zeroes(WebsocketMessageResolveIDs);
-};
+ this.id = try reader.readArray(u32);
+ this.list = try reader.readValue(FileList);
+ return this;
+ }
-pub const WebsocketMessageManifestSuccess = struct {
-/// id
-id: u32 = 0,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u32, this.id);
+ try writer.writeValue(this.list);
+ }
+ };
-/// module_path
-module_path: []const u8,
+ pub const WebsocketCommandResolveIDs = struct {
+ /// ptrs
+ ptrs: []const StringPointer,
-/// loader
-loader: Loader,
+ /// files
+ files: []const u8,
-/// manifest
-manifest: DependencyManifest,
+ pub fn decode(reader: anytype) anyerror!WebsocketCommandResolveIDs {
+ var this = std.mem.zeroes(WebsocketCommandResolveIDs);
+ this.ptrs = try reader.readArray(StringPointer);
+ this.files = try reader.readValue([]const u8);
+ return this;
+ }
-pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestSuccess {
- var this = std.mem.zeroes(WebsocketMessageManifestSuccess);
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(StringPointer, this.ptrs);
+ try writer.writeValue(this.files);
+ }
+ };
- this.id = try reader.readValue(u32);
- this.module_path = try reader.readValue([]const u8);
- this.loader = try reader.readValue(Loader);
- this.manifest = try reader.readValue(DependencyManifest);
- return this;
-}
+ pub const WebsocketMessageManifestSuccess = struct {
+ /// id
+ id: u32 = 0,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- try writer.writeValue(this.module_path);
- try writer.writeEnum(this.loader);
- try writer.writeValue(this.manifest);
-}
+ /// module_path
+ module_path: []const u8,
-};
+ /// loader
+ loader: Loader,
-pub const WebsocketMessageManifestFailure = struct {
-/// id
-id: u32 = 0,
+ /// manifest
+ manifest: DependencyManifest,
-/// from_timestamp
-from_timestamp: u32 = 0,
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestSuccess {
+ var this = std.mem.zeroes(WebsocketMessageManifestSuccess);
-/// loader
-loader: Loader,
+ this.id = try reader.readValue(u32);
+ this.module_path = try reader.readValue([]const u8);
+ this.loader = try reader.readValue(Loader);
+ this.manifest = try reader.readValue(DependencyManifest);
+ return this;
+ }
-/// log
-log: Log,
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeValue(this.module_path);
+ try writer.writeEnum(this.loader);
+ try writer.writeValue(this.manifest);
+ }
+ };
+ pub const WebsocketMessageManifestFailure = struct {
+ /// id
+ id: u32 = 0,
-pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestFailure {
- var this = std.mem.zeroes(WebsocketMessageManifestFailure);
+ /// from_timestamp
+ from_timestamp: u32 = 0,
- this.id = try reader.readValue(u32);
- this.from_timestamp = try reader.readValue(u32);
- this.loader = try reader.readValue(Loader);
- this.log = try reader.readValue(Log);
- return this;
-}
+ /// loader
+ loader: Loader,
-pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- try writer.writeInt(this.from_timestamp);
- try writer.writeEnum(this.loader);
- try writer.writeValue(this.log);
-}
+ /// log
+ log: Log,
-};
+ pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestFailure {
+ var this = std.mem.zeroes(WebsocketMessageManifestFailure);
+ this.id = try reader.readValue(u32);
+ this.from_timestamp = try reader.readValue(u32);
+ this.loader = try reader.readValue(Loader);
+ this.log = try reader.readValue(Log);
+ return this;
+ }
+ pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeInt(this.from_timestamp);
+ try writer.writeEnum(this.loader);
+ try writer.writeValue(this.log);
+ }
+ };
};
-
const ExamplePackedStruct = packed struct {
len: u32 = 0,
offset: u32 = 0,
diff --git a/src/bundler.zig b/src/bundler.zig
index ca4db463f..483b5d09b 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -465,8 +465,6 @@ pub fn NewBundler(cache_files: bool) type {
pub const WorkerData = struct {
shared_buffer: MutableString = undefined,
scan_pass_result: js_parser.ScanPassResult = undefined,
- templist: [100]_resolver.Result = undefined,
- templist_used: u8 = 0,
pub fn deinit(this: *WorkerData, allocator: *std.mem.Allocator) void {
this.shared_buffer.deinit();
@@ -544,6 +542,7 @@ pub fn NewBundler(cache_files: bool) type {
module_list: std.ArrayList(Api.JavascriptBundledModule),
package_list: std.ArrayList(Api.JavascriptBundledPackage),
header_string_buffer: MutableString,
+
// Just need to know if we've already enqueued this one
package_list_map: std.AutoHashMap(u64, u32),
queue: *BunQueue,
@@ -560,15 +559,23 @@ pub fn NewBundler(cache_files: bool) type {
list_lock: Lock = Lock.init(),
pub const current_version: u32 = 1;
+ const dist_index_js_string_pointer = Api.StringPointer{ .length = "dist/index.js".len };
+ const index_js_string_pointer = Api.StringPointer{ .length = "index.js".len, .offset = "dist/".len };
pub fn enqueueItem(this: *GenerateNodeModuleBundle, resolve: _resolver.Result) !void {
- const loader = this.bundler.options.loaders.get(resolve.path_pair.primary.name.ext) orelse .file;
- if (!loader.isJavaScriptLike()) return;
-
var result = resolve;
- result.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, resolve.path_pair.primary.text)));
+ var path = result.path() orelse return;
+ const loader = this.bundler.options.loaders.get(path.name.ext) orelse .file;
+ if (!loader.isJavaScriptLikeOrJSON()) return;
+ if (BundledModuleData.get(this, &result)) |mod| {
+ path.* = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, path.text)));
+
+ try this.queue.upsert(mod.module_id, result);
+ } else {
+ path.* = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, path.text)));
- try this.queue.upsert(result.hash(loader), result);
+ try this.queue.upsert(result.hash(this.bundler.fs.top_level_dir, loader), result);
+ }
}
// The Bun Bundle Format
@@ -612,6 +619,14 @@ pub fn NewBundler(cache_files: bool) type {
// The specifics of the metadata is not documented here. You can find it in src/api/schema.peechy.
pub fn appendHeaderString(generator: *GenerateNodeModuleBundle, str: string) !Api.StringPointer {
+ // This is so common we might as well just reuse it
+ // Plus this is one machine word so it's a quick comparison
+ if (strings.eqlComptime(str, "index.js")) {
+ return index_js_string_pointer;
+ } else if (strings.eqlComptime(str, "dist/index.js")) {
+ return dist_index_js_string_pointer;
+ }
+
var offset = generator.header_string_buffer.list.items.len;
try generator.header_string_buffer.append(str);
return Api.StringPointer{
@@ -639,13 +654,19 @@ pub fn NewBundler(cache_files: bool) type {
);
var tmpfile = try tmpdir.createFileZ(tmpname, .{ .read = isDebug, .exclusive = true });
+
+ errdefer {
+ tmpfile.close();
+ tmpdir.deleteFile(std.mem.span(tmpname)) catch {};
+ }
+
var generator = try allocator.create(GenerateNodeModuleBundle);
var queue = try BunQueue.init(allocator);
defer allocator.destroy(generator);
generator.* = GenerateNodeModuleBundle{
.module_list = std.ArrayList(Api.JavascriptBundledModule).init(allocator),
.package_list = std.ArrayList(Api.JavascriptBundledPackage).init(allocator),
- .header_string_buffer = try MutableString.init(allocator, 0),
+ .header_string_buffer = try MutableString.init(allocator, "dist/index.js".len),
.allocator = allocator,
.queue = queue,
// .resolve_queue = queue,
@@ -656,6 +677,9 @@ pub fn NewBundler(cache_files: bool) type {
.pool = undefined,
.write_lock = Lock.init(),
};
+ // dist/index.js appears more common than /index.js
+ // but this means we can store both "dist/index.js" and "index.js" in one.
+ try generator.header_string_buffer.append("dist/index.js");
try generator.package_list_map.ensureTotalCapacity(128);
var pool = try allocator.create(ThreadPool);
pool.* = ThreadPool{};
@@ -696,6 +720,7 @@ pub fn NewBundler(cache_files: bool) type {
} else {}
for (bundler.options.entry_points) |entry_point| {
+ if (bundler.options.platform == .bun) continue;
defer this.bundler.resetStore();
const entry_point_path = bundler.normalizeEntryPointPath(entry_point);
@@ -750,9 +775,11 @@ pub fn NewBundler(cache_files: bool) type {
this.bundler.resetStore();
try this.pool.start(this);
- this.pool.wait(this);
+ try this.pool.wait(this);
if (this.log.errors > 0) {
+ tmpfile.close();
+ tmpdir.deleteFile(std.mem.span(tmpname)) catch {};
// We stop here because if there are errors we don't know if the bundle is valid
// This manifests as a crash when sorting through the module list because we may have added files to the bundle which were never actually finished being added.
return null;
@@ -896,8 +923,38 @@ pub fn NewBundler(cache_files: bool) type {
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
+ // Since we trim the prefixes, we must also compare the package name and version
pub fn sortJavascriptModuleByPath(ctx: *GenerateNodeModuleBundle, a: Api.JavascriptBundledModule, b: Api.JavascriptBundledModule) bool {
+ if (comptime isDebug) {
+ const a_pkg: Api.JavascriptBundledPackage = ctx.package_list.items[a.package_id];
+ const b_pkg: Api.JavascriptBundledPackage = ctx.package_list.items[b.package_id];
+ const a_name = ctx.metadataStringPointer(a_pkg.name);
+ const b_name = ctx.metadataStringPointer(b_pkg.name);
+ const a_version = ctx.metadataStringPointer(a_pkg.version);
+ const b_version = ctx.metadataStringPointer(b_pkg.version);
+ const a_path = ctx.metadataStringPointer(a.path);
+ const b_path = ctx.metadataStringPointer(b.path);
+
+ std.debug.assert(a_name.len > 0);
+ std.debug.assert(b_name.len > 0);
+ std.debug.assert(a_version.len > 0);
+ std.debug.assert(b_version.len > 0);
+ std.debug.assert(a_path.len > 0);
+ std.debug.assert(b_path.len > 0);
+
+ if (strings.eql(a_name, b_name)) {
+ if (strings.eql(a_version, b_version)) {
+ std.debug.assert(a_pkg.hash == b_pkg.hash); // hash collision
+ std.debug.assert(a.package_id == b.package_id); // duplicate package
+ std.debug.assert(!strings.eql(a_path, b_path)); // duplicate module
+ } else {
+ std.debug.assert(a_pkg.hash != b_pkg.hash); // incorrectly generated hash
+ }
+ } else {
+ std.debug.assert(a_pkg.hash != b_pkg.hash); // incorrectly generated hash
+ }
+ }
+
return switch (std.mem.order(
u8,
ctx.metadataStringPointer(
@@ -907,11 +964,23 @@ pub fn NewBundler(cache_files: bool) type {
ctx.package_list.items[b.package_id].name,
),
)) {
- .eq => std.mem.order(
+ .eq => switch (std.mem.order(
u8,
- ctx.metadataStringPointer(a.path),
- ctx.metadataStringPointer(b.path),
- ) == .lt,
+ ctx.metadataStringPointer(
+ ctx.package_list.items[a.package_id].version,
+ ),
+ ctx.metadataStringPointer(
+ ctx.package_list.items[b.package_id].version,
+ ),
+ )) {
+ .eq => std.mem.order(
+ u8,
+ ctx.metadataStringPointer(a.path),
+ ctx.metadataStringPointer(b.path),
+ ) == .lt,
+ .lt => true,
+ else => false,
+ },
.lt => true,
else => false,
};
@@ -933,19 +1002,17 @@ pub fn NewBundler(cache_files: bool) type {
module_id: u32,
pub fn get(this: *GenerateNodeModuleBundle, resolve_result: *const _resolver.Result) ?BundledModuleData {
+ var path = resolve_result.pathConst() orelse return null;
const package_json: *const PackageJSON = this.bundler.resolver.rootNodeModulePackageJSON(resolve_result) orelse return null;
const package_base_path = package_json.source.path.name.dirWithTrailingSlash();
- const import_path = resolve_result.path_pair.primary.text[package_base_path.len..];
- const package_path = resolve_result.path_pair.primary.text[package_base_path.len - package_json.name.len - 1 ..];
- var hasher = std.hash.Wyhash.init(0);
- hasher.update(import_path);
- hasher.update(std.mem.asBytes(&package_json.hash));
+ const import_path = path.text[package_base_path.len..];
+ const package_path = path.text[package_base_path.len - package_json.name.len - 1 ..];
return BundledModuleData{
.import_path = import_path,
.package_path = package_path,
.package = package_json,
- .module_id = @truncate(u32, hasher.final()),
+ .module_id = package_json.hashModule(package_path),
};
}
};
@@ -953,22 +1020,20 @@ pub fn NewBundler(cache_files: bool) type {
fn processImportRecord(this: *GenerateNodeModuleBundle, import_record: ImportRecord) !void {}
pub fn processFile(this: *GenerateNodeModuleBundle, worker: *ThreadPool.Worker, _resolve: _resolver.Result) !void {
- var resolve = _resolve;
+ const resolve = _resolve;
if (resolve.is_external) return;
var shared_buffer = &worker.data.shared_buffer;
var scan_pass_result = &worker.data.scan_pass_result;
const is_from_node_modules = resolve.isLikelyNodeModule();
- const loader = this.bundler.options.loaders.get(resolve.path_pair.primary.name.ext) orelse .file;
+ var file_path = (resolve.pathConst() orelse unreachable).*;
+
+ const loader = this.bundler.options.loader(file_path.name.ext);
var bundler = this.bundler;
defer scan_pass_result.reset();
defer shared_buffer.reset();
defer this.bundler.resetStore();
- var file_path = resolve.path_pair.primary;
- var hasher = std.hash.Wyhash.init(0);
-
- var module_data: BundledModuleData = undefined;
// If we're in a node_module, build that almost normally
if (is_from_node_modules) {
@@ -978,6 +1043,9 @@ pub fn NewBundler(cache_files: bool) type {
.js,
.ts,
=> {
+ var written: usize = undefined;
+ var code_offset: u32 = 0;
+
const entry = try bundler.resolver.caches.fs.readFileShared(
bundler.fs,
file_path.text,
@@ -985,26 +1053,58 @@ pub fn NewBundler(cache_files: bool) type {
null,
shared_buffer,
);
- const source = logger.Source.initRecycledFile(Fs.File{ .path = file_path, .contents = entry.contents }, bundler.allocator) catch return null;
- const source_dir = file_path.name.dirWithTrailingSlash();
- var jsx = bundler.options.jsx;
- jsx.parse = loader.isJSX();
-
- var opts = js_parser.Parser.Options.init(jsx, loader);
- opts.transform_require_to_import = false;
- opts.enable_bundling = true;
- opts.warn_about_unbundled_modules = false;
-
- var ast: js_ast.Ast = (try bundler.resolver.caches.js.parse(
- bundler.allocator,
- opts,
- bundler.options.define,
- this.log,
- &source,
- )) orelse return;
- if (ast.import_records.len > 0) {
- {
+ const module_data = BundledModuleData.get(this, &resolve) orelse return error.ResolveError;
+ const module_id = module_data.module_id;
+ const package = module_data.package;
+ const package_relative_path = module_data.import_path;
+ file_path.pretty = module_data.package_path;
+
+ // Handle empty files
+ // We can't just ignore them. Sometimes code will try to import it. Often because of TypeScript types.
+ // So we just say it's an empty object. Empty object mimicks what "browser": false does as well.
+ // TODO: optimize this so that all the exports for these are done in one line instead of writing repeatedly
+ if (entry.contents.len == 0 or (entry.contents.len < 33 and strings.trim(entry.contents, " \n\r").len == 0)) {
+ this.write_lock.lock();
+ defer this.write_lock.unlock();
+ code_offset = @truncate(u32, try this.tmpfile.getPos());
+ var writer = this.tmpfile.writer();
+ var buffered = std.io.bufferedWriter(writer);
+
+ var bufwriter = buffered.writer();
+ try bufwriter.writeAll("// ");
+ try bufwriter.writeAll(package_relative_path);
+ try bufwriter.writeAll("\nexport var $");
+ std.fmt.formatInt(module_id, 16, .lower, .{}, bufwriter) catch unreachable;
+ try bufwriter.writeAll(" = () => ({});\n");
+ try buffered.flush();
+ this.tmpfile_byte_offset = @truncate(u32, try this.tmpfile.getPos());
+ } else {
+ const source = logger.Source.initRecycledFile(
+ Fs.File{
+ .path = file_path,
+ .contents = entry.contents,
+ },
+ bundler.allocator,
+ ) catch return null;
+ const source_dir = file_path.name.dirWithTrailingSlash();
+
+ var jsx = bundler.options.jsx;
+ jsx.parse = loader.isJSX();
+
+ var opts = js_parser.Parser.Options.init(jsx, loader);
+ opts.transform_require_to_import = false;
+ opts.enable_bundling = true;
+ opts.warn_about_unbundled_modules = false;
+
+ var ast: js_ast.Ast = (try bundler.resolver.caches.js.parse(
+ bundler.allocator,
+ opts,
+ bundler.options.define,
+ this.log,
+ &source,
+ )) orelse return;
+ if (ast.import_records.len > 0) {
for (ast.import_records) |*import_record, record_id| {
// Don't resolve the runtime
@@ -1016,18 +1116,31 @@ pub fn NewBundler(cache_files: bool) type {
if (_resolved_import.is_external) {
continue;
}
- _resolved_import.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, _resolved_import.path_pair.primary.text)));
+ var path = _resolved_import.path() orelse {
+ import_record.path.is_disabled = true;
+ import_record.is_bundled = true;
+ continue;
+ };
- const resolved_import: *const _resolver.Result = _resolved_import;
+ const loader_ = bundler.options.loader(path.name.ext);
- const absolute_path = resolved_import.path_pair.primary.text;
+ if (!loader_.isJavaScriptLikeOrJSON()) {
+ import_record.path.is_disabled = true;
+ import_record.is_bundled = true;
+ continue;
+ }
- module_data = BundledModuleData.get(this, resolved_import) orelse continue;
- import_record.module_id = module_data.module_id;
+ const resolved_import: *const _resolver.Result = _resolved_import;
+
+ const _module_data = BundledModuleData.get(this, resolved_import) orelse continue;
+ import_record.module_id = _module_data.module_id;
import_record.is_bundled = true;
- import_record.path = Fs.Path.init(module_data.import_path);
+ path.* = Fs.Path.init(this.allocator.dupeZ(u8, path.text) catch unreachable);
+
+ import_record.path = path.*;
+
try this.queue.upsert(
- _resolved_import.hash(this.bundler.options.loaders.get(resolved_import.path_pair.primary.name.ext) orelse .file),
+ _module_data.module_id,
_resolved_import.*,
);
} else |err| {
@@ -1080,157 +1193,161 @@ pub fn NewBundler(cache_files: bool) type {
}
}
}
- }
-
- module_data = BundledModuleData.get(this, &_resolve) orelse return error.ResolveError;
- const module_id = module_data.module_id;
- const package = module_data.package;
- const package_relative_path = module_data.import_path;
- // const load_from_symbol_ref = ast.runtime_imports.$$r.?;
- // const reexport_ref = ast.runtime_imports.__reExport.?;
- const register_ref = ast.runtime_imports.register.?;
- const E = js_ast.E;
- const Expr = js_ast.Expr;
- const Stmt = js_ast.Stmt;
-
- var prepend_part: js_ast.Part = undefined;
- var needs_prepend_part = false;
- if (ast.parts.len > 1) {
- for (ast.parts) |part| {
- if (part.tag != .none and part.stmts.len > 0) {
- prepend_part = part;
- needs_prepend_part = true;
- break;
+ // const load_from_symbol_ref = ast.runtime_imports.$$r.?;
+ // const reexport_ref = ast.runtime_imports.__reExport.?;
+ const register_ref = ast.runtime_imports.register.?;
+ const E = js_ast.E;
+ const Expr = js_ast.Expr;
+ const Stmt = js_ast.Stmt;
+
+ var prepend_part: js_ast.Part = undefined;
+ var needs_prepend_part = false;
+ if (ast.parts.len > 1) {
+ for (ast.parts) |part| {
+ if (part.tag != .none and part.stmts.len > 0) {
+ prepend_part = part;
+ needs_prepend_part = true;
+ break;
+ }
}
}
- }
- if (ast.parts.len == 0) {
- if (comptime isDebug) {
- Output.prettyErrorln("Missing AST for file: {s}", .{file_path.text});
- Output.flush();
+ if (ast.parts.len == 0) {
+ if (comptime isDebug) {
+ Output.prettyErrorln("Missing AST for file: {s}", .{file_path.text});
+ Output.flush();
+ }
}
- }
- var part = &ast.parts[ast.parts.len - 1];
- var new_stmts: [1]Stmt = undefined;
- var register_args: [3]Expr = undefined;
-
- var package_json_string = E.String{ .utf8 = package.name };
- var module_path_string = E.String{ .utf8 = module_data.import_path };
- var target_identifier = E.Identifier{ .ref = register_ref };
- var cjs_args: [2]js_ast.G.Arg = undefined;
- var module_binding = js_ast.B.Identifier{ .ref = ast.module_ref.? };
- var exports_binding = js_ast.B.Identifier{ .ref = ast.exports_ref.? };
-
- // if (!ast.uses_module_ref) {
- // var symbol = &ast.symbols[ast.module_ref.?.inner_index];
- // symbol.original_name = "_$$";
- // }
-
- cjs_args[0] = js_ast.G.Arg{
- .binding = js_ast.Binding{
- .loc = logger.Loc.Empty,
- .data = .{ .b_identifier = &module_binding },
- },
- };
- cjs_args[1] = js_ast.G.Arg{
- .binding = js_ast.Binding{
- .loc = logger.Loc.Empty,
- .data = .{ .b_identifier = &exports_binding },
- },
- };
+ var part = &ast.parts[ast.parts.len - 1];
+ var new_stmts: [1]Stmt = undefined;
+ var register_args: [3]Expr = undefined;
+
+ var package_json_string = E.String{ .utf8 = package.name };
+ var module_path_string = E.String{ .utf8 = module_data.import_path };
+ var target_identifier = E.Identifier{ .ref = register_ref };
+ var cjs_args: [2]js_ast.G.Arg = undefined;
+ var module_binding = js_ast.B.Identifier{ .ref = ast.module_ref.? };
+ var exports_binding = js_ast.B.Identifier{ .ref = ast.exports_ref.? };
+
+ // if (!ast.uses_module_ref) {
+ // var symbol = &ast.symbols[ast.module_ref.?.inner_index];
+ // symbol.original_name = "_$$";
+ // }
+
+ cjs_args[0] = js_ast.G.Arg{
+ .binding = js_ast.Binding{
+ .loc = logger.Loc.Empty,
+ .data = .{ .b_identifier = &module_binding },
+ },
+ };
+ cjs_args[1] = js_ast.G.Arg{
+ .binding = js_ast.Binding{
+ .loc = logger.Loc.Empty,
+ .data = .{ .b_identifier = &exports_binding },
+ },
+ };
- var closure = E.Arrow{
- .args = &cjs_args,
- .body = .{
- .loc = logger.Loc.Empty,
- .stmts = part.stmts,
- },
- };
+ var closure = E.Arrow{
+ .args = &cjs_args,
+ .body = .{
+ .loc = logger.Loc.Empty,
+ .stmts = part.stmts,
+ },
+ };
- // $$m(12345, "react", "index.js", function(module, exports) {
+ // $$m(12345, "react", "index.js", function(module, exports) {
- // })
- register_args[0] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &package_json_string } };
- register_args[1] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &module_path_string } };
- register_args[2] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_arrow = &closure } };
+ // })
+ register_args[0] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &package_json_string } };
+ register_args[1] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &module_path_string } };
+ register_args[2] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_arrow = &closure } };
- var call_register = E.Call{
- .target = Expr{
- .data = .{ .e_identifier = &target_identifier },
- .loc = logger.Loc{ .start = 0 },
- },
- .args = &register_args,
- };
- var register_expr = Expr{ .loc = call_register.target.loc, .data = .{ .e_call = &call_register } };
- var decls: [1]js_ast.G.Decl = undefined;
- var bundle_export_binding = js_ast.B.Identifier{ .ref = ast.bundle_export_ref.? };
- var binding = js_ast.Binding{
- .loc = register_expr.loc,
- .data = .{ .b_identifier = &bundle_export_binding },
- };
- decls[0] = js_ast.G.Decl{
- .value = register_expr,
- .binding = binding,
- };
- var export_var = js_ast.S.Local{
- .decls = &decls,
- .is_export = true,
- };
- new_stmts[0] = Stmt{ .loc = register_expr.loc, .data = .{ .s_local = &export_var } };
- part.stmts = &new_stmts;
+ var call_register = E.Call{
+ .target = Expr{
+ .data = .{ .e_identifier = &target_identifier },
+ .loc = logger.Loc{ .start = 0 },
+ },
+ .args = &register_args,
+ };
+ var register_expr = Expr{ .loc = call_register.target.loc, .data = .{ .e_call = &call_register } };
+ var decls: [1]js_ast.G.Decl = undefined;
+ var bundle_export_binding = js_ast.B.Identifier{ .ref = ast.bundle_export_ref.? };
+ var binding = js_ast.Binding{
+ .loc = register_expr.loc,
+ .data = .{ .b_identifier = &bundle_export_binding },
+ };
+ decls[0] = js_ast.G.Decl{
+ .value = register_expr,
+ .binding = binding,
+ };
+ var export_var = js_ast.S.Local{
+ .decls = &decls,
+ .is_export = true,
+ };
+ new_stmts[0] = Stmt{ .loc = register_expr.loc, .data = .{ .s_local = &export_var } };
+ part.stmts = &new_stmts;
+
+ var writer = js_printer.NewFileWriter(this.tmpfile);
+ var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols});
+
+ // It should only have one part.
+ ast.parts = ast.parts[ast.parts.len - 1 ..];
+
+ const write_result =
+ try js_printer.printCommonJSThreaded(
+ @TypeOf(writer),
+ writer,
+ ast,
+ js_ast.Symbol.Map.initList(symbols),
+ &source,
+ false,
+ js_printer.Options{
+ .to_module_ref = Ref.RuntimeRef,
+ .bundle_export_ref = ast.bundle_export_ref.?,
+ .source_path = file_path,
+ .externals = ast.externals,
+ .indent = 0,
+ .module_hash = module_id,
+ .runtime_imports = ast.runtime_imports,
+ .prepend_part_value = &prepend_part,
+ .prepend_part_key = if (needs_prepend_part) closure.body.stmts.ptr else null,
+ },
+ Linker,
+ &bundler.linker,
+ &this.write_lock,
+ std.fs.File,
+ this.tmpfile,
+ std.fs.File.getPos,
+ );
- var writer = js_printer.NewFileWriter(this.tmpfile);
- var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols});
+ code_offset = write_result.off;
+ written = write_result.len;
- // It should only have one part.
- ast.parts = ast.parts[ast.parts.len - 1 ..];
- var written: usize = undefined;
- var code_offset: u32 = 0;
- const write_result =
- try js_printer.printCommonJSThreaded(
- @TypeOf(writer),
- writer,
- ast,
- js_ast.Symbol.Map.initList(symbols),
- &source,
- false,
- js_printer.Options{
- .to_module_ref = Ref.RuntimeRef,
- .bundle_export_ref = ast.bundle_export_ref.?,
- .source_path = file_path,
- .externals = ast.externals,
- .indent = 0,
- .module_hash = module_id,
- .runtime_imports = ast.runtime_imports,
- .prepend_part_value = &prepend_part,
- .prepend_part_key = if (needs_prepend_part) closure.body.stmts.ptr else null,
- },
- Linker,
- &bundler.linker,
- &this.write_lock,
- std.fs.File,
- this.tmpfile,
- std.fs.File.getPos,
- );
+ // Faster to _not_ do the syscall
+ // But there's some off-by-one error somewhere and more reliable to just do the lseek
+ this.tmpfile_byte_offset = write_result.end_off;
+ }
if (comptime isDebug) {
- Output.prettyln("{s}/{s} \n", .{ package.name, package_relative_path });
+ Output.prettyln("{s}@{s}/{s} - {d}:{d} \n", .{ package.name, package.version, package_relative_path, package.hash, module_id });
Output.flush();
+ std.debug.assert(package_relative_path.len > 0);
}
this.list_lock.lock();
defer this.list_lock.unlock();
- code_offset = write_result.off;
- written = write_result.len;
- // Faster to _not_ do the syscall
- // But there's some off-by-one error somewhere and more reliable to just do the lseek
- this.tmpfile_byte_offset = write_result.end_off;
const code_length = this.tmpfile_byte_offset - code_offset;
- // std.debug.assert(code_length == written);
+
+ if (comptime isDebug) {
+ std.debug.assert(code_length > 0);
+ std.debug.assert(package.hash != 0);
+ std.debug.assert(package.version.len > 0);
+ std.debug.assert(package.name.len > 0);
+ std.debug.assert(module_id > 0);
+ }
var package_get_or_put_entry = try this.package_list_map.getOrPut(package.hash);
@@ -1279,6 +1396,7 @@ pub fn NewBundler(cache_files: bool) type {
null,
shared_buffer,
) catch return;
+ if (entry.contents.len == 0 or (entry.contents.len < 33 and strings.trim(entry.contents, " \n\r").len == 0)) return;
const source = logger.Source.initRecycledFile(Fs.File{ .path = file_path, .contents = entry.contents }, bundler.allocator) catch return null;
const source_dir = file_path.name.dirWithTrailingSlash();
@@ -1307,13 +1425,26 @@ pub fn NewBundler(cache_files: bool) type {
continue;
}
- _resolved_import.path_pair.primary = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, _resolved_import.path_pair.primary.text)));
- try this.queue.upsert(
- _resolved_import.hash(
- this.bundler.options.loaders.get(_resolved_import.path_pair.primary.name.ext) orelse .file,
- ),
- _resolved_import.*,
- );
+ var path = _resolved_import.path() orelse continue;
+
+ const loader_ = this.bundler.options.loader(path.name.ext);
+ if (!loader_.isJavaScriptLikeOrJSON()) continue;
+ path.* = Fs.Path.init(std.mem.span(try this.allocator.dupeZ(u8, path.text)));
+
+ if (BundledModuleData.get(this, _resolved_import)) |mod| {
+ try this.queue.upsert(
+ mod.module_id,
+ _resolved_import.*,
+ );
+ } else {
+ try this.queue.upsert(
+ _resolved_import.hash(
+ this.bundler.fs.top_level_dir,
+ loader_,
+ ),
+ _resolved_import.*,
+ );
+ }
} else |err| {
switch (err) {
error.ModuleNotFound => {
@@ -1393,7 +1524,12 @@ pub fn NewBundler(cache_files: bool) type {
errdefer bundler.resetStore();
- var file_path = resolve_result.path_pair.primary;
+ var file_path = (resolve_result.pathConst() orelse {
+ return BuildResolveResultPair{
+ .written = 0,
+ .input_fd = null,
+ };
+ }).*;
if (strings.indexOf(file_path.text, bundler.fs.top_level_dir)) |i| {
file_path.pretty = file_path.text[i + bundler.fs.top_level_dir.len ..];
@@ -1401,12 +1537,7 @@ pub fn NewBundler(cache_files: bool) type {
file_path.pretty = allocator.dupe(u8, bundler.fs.relativeTo(file_path.text)) catch unreachable;
}
- var old_bundler_allocator = bundler.allocator;
- bundler.allocator = allocator;
- defer bundler.allocator = old_bundler_allocator;
- var old_linker_allocator = bundler.linker.allocator;
- defer bundler.linker.allocator = old_linker_allocator;
- bundler.linker.allocator = allocator;
+ bundler.setAllocator(allocator);
switch (loader) {
.css => {
@@ -1432,7 +1563,7 @@ pub fn NewBundler(cache_files: bool) type {
.written = brk: {
if (bundler.options.hot_module_reloading) {
break :brk (try CSSBundlerHMR.bundle(
- resolve_result.path_pair.primary.text,
+ file_path.text,
bundler.fs,
writer,
watcher,
@@ -1445,7 +1576,7 @@ pub fn NewBundler(cache_files: bool) type {
)).written;
} else {
break :brk (try CSSBundler.bundle(
- resolve_result.path_pair.primary.text,
+ file_path.text,
bundler.fs,
writer,
watcher,
@@ -1462,6 +1593,8 @@ pub fn NewBundler(cache_files: bool) type {
};
},
else => {
+ var old_allocator = bundler.allocator;
+ bundler.setAllocator(allocator);
var result = bundler.parse(
allocator,
file_path,
@@ -1471,12 +1604,14 @@ pub fn NewBundler(cache_files: bool) type {
filepath_hash,
client_entry_point,
) orelse {
+ bundler.setAllocator(old_allocator);
bundler.resetStore();
return BuildResolveResultPair{
.written = 0,
.input_fd = null,
};
};
+ bundler.setAllocator(old_allocator);
try bundler.linker.link(file_path, &result, import_path_format, false);
@@ -1505,9 +1640,10 @@ pub fn NewBundler(cache_files: bool) type {
return null;
}
+ var file_path = (resolve_result.pathConst() orelse return null).*;
+
// Step 1. Parse & scan
- const loader = bundler.options.loaders.get(resolve_result.path_pair.primary.name.ext) orelse .file;
- var file_path = resolve_result.path_pair.primary;
+ const loader = bundler.options.loader(file_path.name.ext);
if (client_entry_point_) |client_entry_point| {
file_path = client_entry_point.source.path;
@@ -1796,15 +1932,11 @@ pub fn NewBundler(cache_files: bool) type {
comptime client_entry_point_enabled: bool,
) !ServeResult {
var extension = _extension;
- var original_resolver_logger = bundler.resolver.log;
- var original_bundler_logger = bundler.log;
-
- defer bundler.log = original_bundler_logger;
- defer bundler.resolver.log = original_resolver_logger;
- bundler.log = log;
- bundler.linker.allocator = allocator;
+ var old_log = bundler.log;
+ var old_allocator = bundler.allocator;
- bundler.resolver.log = log;
+ bundler.setLog(log);
+ defer bundler.setLog(old_log);
if (strings.eqlComptime(relative_path, "__runtime.js")) {
return ServeResult{
@@ -1862,8 +1994,10 @@ pub fn NewBundler(cache_files: bool) type {
break :brk (try bundler.resolver.resolve(bundler.fs.top_level_dir, absolute_path, .stmt));
};
- const loader = bundler.options.loader(resolved.path_pair.primary.name.ext);
- const mime_type_ext = bundler.options.out_extensions.get(resolved.path_pair.primary.name.ext) orelse resolved.path_pair.primary.name.ext;
+ const path = (resolved.pathConst() orelse return error.ModuleNotFound);
+
+ const loader = bundler.options.loader(path.name.ext);
+ const mime_type_ext = bundler.options.out_extensions.get(path.name.ext) orelse path.name.ext;
switch (loader) {
.js, .jsx, .ts, .tsx, .css => {
@@ -1882,7 +2016,7 @@ pub fn NewBundler(cache_files: bool) type {
};
},
else => {
- var abs_path = resolved.path_pair.primary.text;
+ var abs_path = path.text;
const file = try std.fs.openFileAbsolute(abs_path, .{ .read = true });
var stat = try file.stat();
return ServeResult{
@@ -1941,10 +2075,17 @@ pub fn NewBundler(cache_files: bool) type {
}
const result = bundler.resolver.resolve(bundler.fs.top_level_dir, entry, .entry_point) catch |err| {
- Output.printError("Error resolving \"{s}\": {s}\n", .{ entry, @errorName(err) });
+ Output.prettyError("Error resolving \"{s}\": {s}\n", .{ entry, @errorName(err) });
continue;
};
+ if (result.pathConst() == null) {
+ Output.prettyError("\"{s}\" is disabled due to \"browser\" field in package.json.\n", .{
+ entry,
+ });
+ continue;
+ }
+
if (bundler.linker.enqueueResolveResult(&result) catch unreachable) {
entry_points[entry_point_i] = result;
entry_point_i += 1;
@@ -2098,12 +2239,13 @@ pub fn NewBundler(cache_files: bool) type {
// defer count += 1;
if (comptime wrap_entry_point) {
- const loader = bundler.options.loaders.get(item.path_pair.primary.name.ext) orelse .file;
+ var path = item.pathConst() orelse unreachable;
+ const loader = bundler.options.loader(path.name.ext);
if (item.import_kind == .entry_point and loader.supportsClientEntryPoint()) {
var client_entry_point = try bundler.allocator.create(ClientEntryPoint);
client_entry_point.* = ClientEntryPoint{};
- try client_entry_point.generate(ThisBundler, bundler, item.path_pair.primary.name, bundler.options.framework.?.client);
+ try client_entry_point.generate(ThisBundler, bundler, path.name, bundler.options.framework.?.client);
try bundler.virtual_modules.append(client_entry_point);
const entry_point_output_file = bundler.buildWithResolveResultEager(
@@ -2602,6 +2744,9 @@ pub const ServerEntryPoint = struct {
\\//Auto-generated file
\\import * as start from '{s}{s}';
\\export * from '{s}{s}';
+ \\if ('default' in start && typeof start.default == 'function') {{
+ \\ start.default();
+ \\}}
,
.{
dir_to_use,
diff --git a/src/fs.zig b/src/fs.zig
index 3936ea933..e59d24b6f 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -16,7 +16,7 @@ const hash_map = @import("hash_map.zig");
pub const Preallocate = struct {
pub const Counts = struct {
pub const dir_entry: usize = 512;
- pub const files: usize = 1024;
+ pub const files: usize = 4096;
};
};
@@ -810,7 +810,7 @@ pub const FileSystem = struct {
) !File {
FileSystem.setMaxFd(file.handle);
- if (FeatureFlags.disable_filesystem_cache) {
+ if (comptime FeatureFlags.disable_filesystem_cache) {
_ = std.os.fcntl(file.handle, std.os.F_NOCACHE, 1) catch 0;
}
@@ -820,6 +820,18 @@ pub const FileSystem = struct {
return err;
});
+ // Skip the pread call for empty files
+ // Otherwise will get out of bounds errors
+ // plus it's an unnecessary syscall
+ if (size == 0) {
+ if (comptime use_shared_buffer) {
+ shared_buffer.reset();
+ return File{ .path = Path.init(path), .contents = shared_buffer.list.items };
+ } else {
+ return File{ .path = Path.init(path), .contents = "" };
+ }
+ }
+
var file_contents: []u8 = undefined;
// When we're serving a JavaScript-like file over HTTP, we do not want to cache the contents in memory
diff --git a/src/hash_map_v2.zig b/src/hash_map_v2.zig
index cad4bd36c..e0b84fcd5 100644
--- a/src/hash_map_v2.zig
+++ b/src/hash_map_v2.zig
@@ -48,6 +48,10 @@ pub fn getAutoHashFn(comptime K: type, comptime Context: type) (fn (Context, K)
pub fn getAutoEqlFn(comptime K: type, comptime Context: type) (fn (Context, K, K) bool) {
return struct {
fn eql(ctx: Context, a: K, b: K) bool {
+ if (comptime @typeInfo(K) == .Struct and @hasDecl(K, "eql")) {
+ return a.eql(b);
+ }
+
return meta.eql(a, b);
}
}.eql;
@@ -965,7 +969,7 @@ pub fn HashMapUnmanaged(
/// fuse the basic blocks after the branch to the basic blocks
/// from this function. To encourage that, this function is
/// marked as inline.
- fn getIndex(self: Self, key: anytype, ctx: anytype) callconv(.Inline) ?usize {
+ inline fn getIndex(self: Self, key: anytype, ctx: anytype) ?usize {
comptime verifyContext(@TypeOf(ctx), @TypeOf(key), K, Hash);
if (self.size == 0) {
diff --git a/src/import_record.zig b/src/import_record.zig
index ae09f8d2f..adb6ea625 100644
--- a/src/import_record.zig
+++ b/src/import_record.zig
@@ -65,6 +65,8 @@ pub const ImportRecord = struct {
is_internal: bool = false,
+ // This tells the printer that we should print as export var $moduleID = ...
+ // Instead of using the path.
is_bundled: bool = false,
// Sometimes the parser creates an import record and decides it isn't needed.
diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig
index b01690f2a..65a8bef94 100644
--- a/src/javascript/jsc/bindings/bindings.zig
+++ b/src/javascript/jsc/bindings/bindings.zig
@@ -92,7 +92,7 @@ pub const ZigString = extern struct {
pub fn fromStringPointer(ptr: StringPointer, buf: string, to: *ZigString) void {
to.* = ZigString{
.len = ptr.length,
- .ptr = buf[ptr.offset..ptr.length].ptr,
+ .ptr = buf[ptr.offset..][0..ptr.length].ptr,
};
}
diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig
index d58435785..6a8c6328b 100644
--- a/src/javascript/jsc/bindings/exports.zig
+++ b/src/javascript/jsc/bindings/exports.zig
@@ -4,6 +4,7 @@ const Fs = @import("../../../fs.zig");
const CAPI = @import("../JavaScriptCore.zig");
const JS = @import("../javascript.zig");
const JSBase = @import("../base.zig");
+const ZigURL = @import("../../../query_string_map.zig").URL;
const Handler = struct {
pub export fn global_signal_handler_fn(sig: i32, info: *const std.os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) void {
var stdout = std.io.getStdOut();
@@ -347,8 +348,15 @@ pub const ZigStackFrame = extern struct {
source_url: ZigString,
position: ZigStackFramePosition,
enable_color: bool,
+ origin: *const ZigURL,
pub fn format(this: SourceURLFormatter, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
+ try writer.writeAll(this.origin.displayProtocol());
+ try writer.writeAll("://");
+ try writer.writeAll(this.origin.displayHostname());
+ try writer.writeAll(":");
+ try writer.writeAll(this.origin.port);
+ try writer.writeAll("/blob:");
try writer.writeAll(this.source_url.slice());
if (this.position.line > -1 and this.position.column_start > -1) {
try std.fmt.format(writer, ":{d}:{d}", .{ this.position.line + 1, this.position.column_start });
@@ -416,8 +424,8 @@ pub const ZigStackFrame = extern struct {
return NameFormatter{ .function_name = this.function_name, .code_type = this.code_type, .enable_color = enable_color };
}
- pub fn sourceURLFormatter(this: *const ZigStackFrame, comptime enable_color: bool) SourceURLFormatter {
- return SourceURLFormatter{ .source_url = this.source_url, .position = this.position, .enable_color = enable_color };
+ pub fn sourceURLFormatter(this: *const ZigStackFrame, origin: *const ZigURL, comptime enable_color: bool) SourceURLFormatter {
+ return SourceURLFormatter{ .source_url = this.source_url, .origin = origin, .position = this.position, .enable_color = enable_color };
}
};
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index 4a3c19964..fa942e4a2 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -34,6 +34,7 @@ pub const GlobalClasses = [_]type{
ResolveError.Class,
Bun.Class,
};
+const Blob = @import("../../blob.zig");
pub const Bun = struct {
threadlocal var css_imports_list_strings: [512]ZigString = undefined;
@@ -345,10 +346,12 @@ pub const VirtualMachine = struct {
event_listeners: EventListenerMixin.Map,
main: string = "",
process: js.JSObjectRef = null,
-
+ blobs: *Blob.Group = undefined,
flush_list: std.ArrayList(string),
entry_point: ServerEntryPoint = undefined,
+ has_loaded: bool = false,
+
pub var vm_loaded = false;
pub var vm: *VirtualMachine = undefined;
@@ -387,6 +390,7 @@ pub const VirtualMachine = struct {
.node_modules = bundler.options.node_modules_bundle,
.log = log,
.flush_list = std.ArrayList(string).init(allocator),
+ .blobs = try Blob.Group.init(allocator),
};
VirtualMachine.vm.bundler.configureLinker();
@@ -418,6 +422,11 @@ pub const VirtualMachine = struct {
threadlocal var source_code_printer: js_printer.BufferPrinter = undefined;
threadlocal var source_code_printer_loaded: bool = false;
+ pub fn preflush(this: *VirtualMachine) void {
+ // We flush on the next tick so that if there were any errors you can still see them
+ this.blobs.temporary.reset() catch {};
+ }
+
pub fn flush(this: *VirtualMachine) void {
for (this.flush_list.items) |item| {
this.allocator.free(item);
@@ -650,6 +659,7 @@ pub const VirtualMachine = struct {
.stmt,
);
ret.result = result;
+ const result_path = result.pathConst() orelse return error.ModuleNotFound;
if (vm.node_modules != null and result.isLikelyNodeModule()) {
const node_modules_bundle = vm.node_modules.?;
@@ -682,7 +692,7 @@ pub const VirtualMachine = struct {
const package_relative_path = vm.bundler.fs.relative(
package_json.source.path.name.dirWithTrailingSlash(),
- result.path_pair.primary.text,
+ result_path.text,
);
if (node_modules_bundle.findModuleIDInPackage(package, package_relative_path) == null) break :node_module_checker;
@@ -693,7 +703,7 @@ pub const VirtualMachine = struct {
}
}
- ret.path = result.path_pair.primary.text;
+ ret.path = result_path.text;
}
pub fn resolve(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString) void {
@@ -751,6 +761,11 @@ pub const VirtualMachine = struct {
return slice;
}
+ pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
+ VirtualMachine.vm.defaultErrorHandler(promise.result(global.vm()));
+ return JSValue.jsUndefined();
+ }
+
const main_file_name: string = "bun:main";
threadlocal var errors_stack: [256]*c_void = undefined;
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) void {
@@ -775,6 +790,13 @@ pub const VirtualMachine = struct {
}
ret.result.value = result;
+
+ if (vm.has_loaded) {
+ vm.blobs.temporary.put(specifier.slice(), .{ .ptr = result.source_code.ptr, .len = result.source_code.len }) catch {};
+ } else {
+ vm.blobs.persistent.put(specifier.slice(), .{ .ptr = result.source_code.ptr, .len = result.source_code.len }) catch {};
+ }
+
ret.success = true;
}
@@ -977,7 +999,7 @@ pub const VirtualMachine = struct {
"<r> <d>at <r>{any} <d>(<r>{any}<d>)<r>\n",
allow_ansi_colors,
),
- .{ frame.nameFormatter(allow_ansi_colors), frame.sourceURLFormatter(allow_ansi_colors) },
+ .{ frame.nameFormatter(allow_ansi_colors), frame.sourceURLFormatter(&vm.bundler.options.origin, allow_ansi_colors) },
);
// if (!frame.position.isInvalid()) {
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 760d3ec2b..83a1b0127 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -130,7 +130,7 @@ pub const ImportScanner = struct {
//
// const keep_unused_imports = !p.options.trim_unused_imports;
var did_remove_star_loc = false;
- const keep_unused_imports = false;
+ const keep_unused_imports = !p.options.ts;
// TypeScript always trims unused imports. This is important for
// correctness since some imports might be fake (only in the type
@@ -205,11 +205,7 @@ pub const ImportScanner = struct {
}
}
- if (items_end < st.items.len - 1) {
- var list = List(js_ast.ClauseItem).fromOwnedSlice(p.allocator, st.items);
- list.shrinkAndFree(items_end);
- st.items = list.toOwnedSlice();
- }
+ st.items = st.items[0..items_end];
}
// -- Original Comment --
@@ -285,7 +281,7 @@ pub const ImportScanner = struct {
// it's really stupid to import all 1,000 components from that design system
// when you just want <Button />
const namespace_ref = st.namespace_ref;
- const convert_star_to_clause = !p.options.can_import_from_bundle and p.symbols.items[namespace_ref.inner_index].use_count_estimate == 0;
+ const convert_star_to_clause = !p.options.enable_bundling and !p.options.can_import_from_bundle and p.symbols.items[namespace_ref.inner_index].use_count_estimate == 0;
if (convert_star_to_clause and !keep_unused_imports) {
st.star_name_loc = null;
@@ -1643,19 +1639,27 @@ const PropertyOpts = struct {
};
pub const ScanPassResult = struct {
+ pub const ParsePassSymbolUse = struct { ref: Ref, used: bool = false, import_record_index: u32 };
+ pub const NamespaceCounter = struct { count: u16, import_record_index: u32 };
+ pub const ParsePassSymbolUsageMap = std.StringArrayHashMap(ParsePassSymbolUse);
import_records: List(ImportRecord),
named_imports: js_ast.Ast.NamedImports,
+ used_symbols: ParsePassSymbolUsageMap,
+ import_records_to_keep: List(u32),
pub fn init(allocator: *std.mem.Allocator) ScanPassResult {
return .{
.import_records = List(ImportRecord).init(allocator),
.named_imports = js_ast.Ast.NamedImports.init(allocator),
+ .used_symbols = ParsePassSymbolUsageMap.init(allocator),
+ .import_records_to_keep = List(u32).init(allocator),
};
}
pub fn reset(scan_pass: *ScanPassResult) void {
scan_pass.named_imports.clearRetainingCapacity();
scan_pass.import_records.shrinkRetainingCapacity(0);
+ scan_pass.used_symbols.clearRetainingCapacity();
}
};
@@ -1714,9 +1718,21 @@ pub const Parser = struct {
fn _scanImports(self: *Parser, comptime ParserType: type, scan_pass: *ScanPassResult) !void {
var p: ParserType = undefined;
+
try ParserType.init(self.allocator, self.log, self.source, self.define, self.lexer, self.options, &p);
p.import_records = &scan_pass.import_records;
p.named_imports = &scan_pass.named_imports;
+
+ // The problem with our scan pass approach is type-only imports.
+ // We don't have accurate symbol counts.
+ // So we don't have a good way to distuingish between a type-only import and not.
+ switch (comptime ParserType) {
+ TSXImportScanner, TypeScriptImportScanner => {
+ p.parse_pass_symbol_uses = &scan_pass.used_symbols;
+ },
+ else => {},
+ }
+
// Parse the file in the first pass, but do not bind symbols
var opts = ParseStatementOptions{ .is_module_scope = true };
debugl("<p.parseStmtsUpTo>");
@@ -1727,6 +1743,33 @@ pub const Parser = struct {
// June 4: "Rest of this took: 8003000"
_ = try p.parseStmtsUpTo(js_lexer.T.t_end_of_file, &opts);
+ //
+ switch (comptime ParserType) {
+ TSXImportScanner, TypeScriptImportScanner => {
+ for (scan_pass.import_records.items) |*import_record| {
+ // Mark everything as unused
+ // Except:
+ // - export * as ns from 'foo';
+ // - export * from 'foo';
+ // - import 'foo';
+ // - import("foo")
+ // - require("foo")
+ import_record.is_unused = import_record.kind == .stmt and
+ !import_record.was_originally_bare_import and
+ !import_record.calls_run_time_re_export_fn;
+ }
+
+ var iter = scan_pass.used_symbols.iterator();
+ while (iter.next()) |entry| {
+ const val = entry.value_ptr;
+ if (val.used) {
+ scan_pass.import_records.items[val.import_record_index].is_unused = false;
+ }
+ }
+ },
+ else => {},
+ }
+
// Symbol use counts are unavailable
// So we say "did we parse any JSX?"
// if yes, just automatically add the import so that .bun knows to include the file.
@@ -2500,7 +2543,7 @@ pub fn NewParser(
const ImportRecordList = if (only_scan_imports_and_do_not_visit) *std.ArrayList(ImportRecord) else std.ArrayList(ImportRecord);
const NamedImportsType = if (only_scan_imports_and_do_not_visit) *js_ast.Ast.NamedImports else js_ast.Ast.NamedImports;
const NeedsJSXType = if (only_scan_imports_and_do_not_visit) bool else void;
-
+ const ParsePassSymbolUsageType = if (only_scan_imports_and_do_not_visit and is_typescript_enabled) *ScanPassResult.ParsePassSymbolUsageMap else void;
// P is for Parser!
// public only because of Binding.ToExpr
return struct {
@@ -2552,6 +2595,8 @@ pub fn NewParser(
symbol_uses: SymbolUseMap,
declared_symbols: List(js_ast.DeclaredSymbol),
runtime_imports: RuntimeImports = RuntimeImports{},
+
+ parse_pass_symbol_uses: ParsePassSymbolUsageType = undefined,
// duplicate_case_checker: void,
// non_bmp_identifiers: StringBoolMap,
// legacy_octal_literals: void,
@@ -5186,6 +5231,12 @@ pub fn NewParser(
// TODO: import assertions
// path.assertions
);
+
+ if (comptime ParsePassSymbolUsageType != void) {
+ // In the scan pass, we need _some_ way of knowing *not* to mark as unused
+ p.import_records.items[import_record_index].calls_run_time_re_export_fn = true;
+ }
+
try p.lexer.expectOrInsertSemicolon();
return p.s(S.ExportStar{
.namespace_ref = namespace_ref,
@@ -5207,6 +5258,12 @@ pub fn NewParser(
var path_name = fs.PathName.init(strings.append(p.allocator, "import_", parsedPath.text) catch unreachable);
const namespace_ref = p.storeNameInRef(path_name.nonUniqueNameString(p.allocator) catch unreachable) catch unreachable;
try p.lexer.expectOrInsertSemicolon();
+
+ if (comptime ParsePassSymbolUsageType != void) {
+ // In the scan pass, we need _some_ way of knowing *not* to mark as unused
+ p.import_records.items[import_record_index].calls_run_time_re_export_fn = true;
+ }
+
return p.s(S.ExportFrom{ .items = export_clause.clauses, .is_single_line = export_clause.is_single_line, .namespace_ref = namespace_ref, .import_record_index = import_record_index }, loc);
}
try p.lexer.expectOrInsertSemicolon();
@@ -5820,6 +5877,12 @@ pub fn NewParser(
if (stmt.star_name_loc) |star| {
const name = p.loadNameFromRef(stmt.namespace_ref);
stmt.namespace_ref = try p.declareSymbol(.import, star, name);
+ if (comptime ParsePassSymbolUsageType != void) {
+ p.parse_pass_symbol_uses.put(name, .{
+ .ref = stmt.namespace_ref,
+ .import_record_index = stmt.import_record_index,
+ }) catch unreachable;
+ }
} else {
var path_name = fs.PathName.init(strings.append(p.allocator, "import_", path.text) catch unreachable);
const name = try path_name.nonUniqueNameString(p.allocator);
@@ -5836,6 +5899,12 @@ pub fn NewParser(
const ref = try p.declareSymbol(.import, name_loc.loc, name);
try p.is_import_item.put(ref, true);
name_loc.ref = ref;
+ if (comptime ParsePassSymbolUsageType != void) {
+ p.parse_pass_symbol_uses.put(name, .{
+ .ref = ref,
+ .import_record_index = stmt.import_record_index,
+ }) catch unreachable;
+ }
}
if (stmt.items.len > 0) {
@@ -5847,11 +5916,19 @@ pub fn NewParser(
try p.is_import_item.put(ref, true);
item.name.ref = ref;
item_refs.putAssumeCapacity(item.alias, LocRef{ .loc = item.name.loc, .ref = ref });
+
+ if (comptime ParsePassSymbolUsageType != void) {
+ p.parse_pass_symbol_uses.put(name, .{
+ .ref = ref,
+ .import_record_index = stmt.import_record_index,
+ }) catch unreachable;
+ }
}
}
// Track the items for this namespace
try p.import_items_for_namespace.put(stmt.namespace_ref, item_refs);
+
return p.s(stmt, loc);
},
.t_break => {
@@ -7293,7 +7370,7 @@ pub fn NewParser(
};
const text = p.lexer.identifier;
- if (text.len > 0 and !strings.eql(text, "arguments")) {
+ if (text.len > 0 and !strings.eqlComptime(text, "arguments")) {
_name.ref = try p.declareSymbol(.hoisted_function, _name.loc, text);
} else {
_name.ref = try p.newSymbol(.hoisted_function, text);
@@ -7425,6 +7502,12 @@ pub fn NewParser(
}
pub fn storeNameInRef(p: *P, name: string) !js_ast.Ref {
+ if (comptime ParsePassSymbolUsageType != void) {
+ if (p.parse_pass_symbol_uses.getPtr(name)) |res| {
+ res.used = true;
+ }
+ }
+
if (@ptrToInt(p.source.contents.ptr) <= @ptrToInt(name.ptr) and (@ptrToInt(name.ptr) + name.len) <= (@ptrToInt(p.source.contents.ptr) + p.source.contents.len)) {
const start = Ref.toInt(@ptrToInt(name.ptr) - @ptrToInt(p.source.contents.ptr));
const end = Ref.toInt(name.len);
@@ -9739,8 +9822,7 @@ pub fn NewParser(
// esbuild's version of this function is much more complicated.
// I'm not sure why defines is strictly relevant for this case
- // and I imagine all the allocations cause some performance
- // guessing it's concurrency-related
+ // do people do <API_URL>?
pub fn jsxStringsToMemberExpression(p: *P, loc: logger.Loc, ref: Ref) Expr {
p.recordUsage(ref);
return p.e(E.Identifier{ .ref = ref }, loc);
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 82c849df9..42af0cd63 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -189,6 +189,8 @@ const ImportVariant = enum {
variant = variant.hasDefault();
}
}
+ } else {
+ variant = variant.hasDefault();
}
if (s_import.items.len > 0) {
@@ -224,6 +226,8 @@ pub fn NewPrinter(
call_target: ?Expr.Data = null,
writer: Writer,
+ has_printed_bundled_import_statement: bool = false,
+
renamer: rename.Renamer,
prev_stmt_tag: Stmt.Tag = .s_empty,
@@ -520,6 +524,12 @@ pub fn NewPrinter(
backtick_cost += 1;
}
},
+ '\r', '\n' => {
+ if (comptime isDebug) {
+ std.debug.assert(allow_backtick);
+ }
+ return '`';
+ },
else => {},
}
i += 1;
@@ -1869,11 +1879,13 @@ pub fn NewPrinter(
// "=" and ":" are not valid
// So we need to check
var needs_quoted = !js_lexer.isIdentifierStart(@intCast(js_lexer.CodePoint, key.utf8[0]));
- var i: usize = 1;
- while (i < key.utf8.len and !needs_quoted) : (i += 1) {
- if (!js_lexer.isIdentifierContinue(@intCast(js_lexer.CodePoint, key.utf8[i]))) {
- needs_quoted = true;
- break;
+ if (!needs_quoted) {
+ var i: usize = 1;
+ while (i < key.utf8.len) : (i += 1) {
+ if (!js_lexer.isIdentifierContinue(@intCast(js_lexer.CodePoint, key.utf8[i]))) {
+ needs_quoted = true;
+ break;
+ }
}
}
@@ -2118,17 +2130,27 @@ pub fn NewPrinter(
if (str.isUTF8()) {
p.addSourceMapping(property.key.loc);
p.printSpaceBeforeIdentifier();
- p.printIdentifier(str.utf8);
-
- // Use a shorthand property if the names are the same
- switch (property.value.data) {
- .b_identifier => |id| {
- if (str.eql(string, p.renamer.nameForSymbol(id.ref))) {
- p.maybePrintDefaultBindingValue(property);
- continue;
- }
- },
- else => {},
+ // Example case:
+ // const Menu = React.memo(function Menu({
+ // aria-label: ariaLabel,
+ // ^
+ // That needs to be:
+ // "aria-label": ariaLabel,
+ if (p.canPrintIdentifier(str.utf8)) {
+ p.printIdentifier(str.utf8);
+
+ // Use a shorthand property if the names are the same
+ switch (property.value.data) {
+ .b_identifier => |id| {
+ if (str.eql(string, p.renamer.nameForSymbol(id.ref))) {
+ p.maybePrintDefaultBindingValue(property);
+ continue;
+ }
+ },
+ else => {},
+ }
+ } else {
+ p.printQuotedUTF8(str.utf8, false);
}
} else if (p.canPrintIdentifierUTF16(str.value)) {
p.addSourceMapping(property.key.loc);
@@ -2245,11 +2267,7 @@ pub fn NewPrinter(
if (rewrite_esm_to_cjs and s.func.flags.is_export) {
p.printIndent();
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".");
- p.printSymbol(nameRef);
- p.print(" = ");
- p.printSymbol(nameRef);
+ p.printBundledExport(p.renamer.nameForSymbol(nameRef), p.renamer.nameForSymbol(nameRef));
p.printSemicolonAfterStatement();
}
},
@@ -2287,11 +2305,7 @@ pub fn NewPrinter(
if (rewrite_esm_to_cjs) {
if (s.is_export) {
p.printIndent();
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".");
- p.printSymbol(nameRef);
- p.print(" = ");
- p.printSymbol(nameRef);
+ p.printBundledExport(p.renamer.nameForSymbol(nameRef), p.renamer.nameForSymbol(nameRef));
p.printSemicolonAfterStatement();
}
}
@@ -2369,10 +2383,7 @@ pub fn NewPrinter(
if (rewrite_esm_to_cjs) {
if (func.func.name) |name| {
p.printIndent();
- p.printSpaceBeforeIdentifier();
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".default = ");
- p.printSymbol(name.ref.?);
+ p.printBundledExport("default", p.renamer.nameForSymbol(name.ref.?));
p.printSemicolonAfterStatement();
}
}
@@ -2408,10 +2419,7 @@ pub fn NewPrinter(
if (class.class.class_name) |name| {
p.printIndent();
- p.printSpaceBeforeIdentifier();
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".default = ");
- p.printSymbol(name.ref.?);
+ p.printBundledExport("default", p.renamer.nameForSymbol(name.ref.?));
p.printSemicolonAfterStatement();
}
} else {
@@ -2432,12 +2440,9 @@ pub fn NewPrinter(
// module.exports.react = $react();
if (s.alias) |alias| {
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".");
- p.printClauseAlias(alias.original_name);
- p.print(" = ");
- p.printLoadFromBundle(s.import_record_index);
+ p.printBundledRexport(alias.original_name, s.import_record_index);
p.printSemicolonAfterStatement();
+
return;
// module.exports = $react();
} else {
@@ -2445,7 +2450,9 @@ pub fn NewPrinter(
p.print("(");
p.printSymbol(p.options.runtime_imports.__export.?);
p.print(",");
+
p.printLoadFromBundle(s.import_record_index);
+
p.print(")");
p.printSemicolonAfterStatement();
return;
@@ -2481,20 +2488,17 @@ pub fn NewPrinter(
switch (s.items.len) {
0 => {},
- // __export.prop1 = prop1;
+ // It unfortunately cannot be so simple as exports.foo = foo;
+ // If we have a lazy re-export and it's read-only...
+ // we have to overwrite it via Object.defineProperty
1 => {
const item = s.items[0];
-
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".");
- const name = p.renamer.nameForSymbol(item.name.ref.?);
- if (!strings.eql(name, item.alias)) {
- p.printClauseAlias(item.alias);
- } else {
- p.printIdentifier(name);
- }
- p.print(" = ");
- p.printIdentifier(name);
+ const identifier = p.renamer.nameForSymbol(item.name.ref.?);
+ const name = if (!strings.eql(identifier, item.alias))
+ item.alias
+ else
+ identifier;
+ p.printBundledExport(name, identifier);
p.printSemicolonAfterStatement();
},
@@ -2978,13 +2982,46 @@ pub fn NewPrinter(
return;
}
} else if (record.is_bundled) {
- p.print("import {");
+ if (!record.path.is_disabled) {
+ if (!p.has_printed_bundled_import_statement) {
+ p.has_printed_bundled_import_statement = true;
+ p.print("import {");
+
+ const last = p.import_records.len - 1;
+ var needs_comma = false;
+ // This might be a determinsim issue
+ // But, it's not random
+ skip: for (p.import_records) |_record, i| {
+ if (!_record.is_bundled or _record.module_id == 0) continue;
- p.printLoadFromBundleWithoutCall(s.import_record_index);
+ if (i < last) {
+ // Prevent importing the same module ID twice
+ // We could use a map but we want to avoid allocating
+ // and this should be pretty quick since it's just comparing a uint32
+ for (p.import_records[i + 1 ..]) |_record2| {
+ if (_record2.is_bundled and _record2.module_id > 0 and _record2.module_id == _record.module_id) {
+ continue :skip;
+ }
+ }
+ }
- p.print("} from ");
- p.printQuotedUTF8(record.path.text, false);
- p.printSemicolonAfterStatement();
+ if (needs_comma) p.print(", ");
+ p.printLoadFromBundleWithoutCall(@truncate(u32, i));
+ needs_comma = true;
+ }
+
+ p.print("} from ");
+
+ p.printQuotedUTF8(record.path.text, false);
+ p.printSemicolonAfterStatement();
+ }
+ } else {
+ p.print("var ");
+
+ p.printLoadFromBundleWithoutCall(s.import_record_index);
+
+ p.print(" = () => ({default: {}});\n");
+ }
if (s.items.len > 0) {
p.printIndent();
@@ -3248,8 +3285,6 @@ pub fn NewPrinter(
.import_items => {
p.print("var {");
- var item_count: usize = 0;
-
for (s.items) |*item, i| {
if (i != 0) {
p.print(",");
@@ -3266,7 +3301,6 @@ pub fn NewPrinter(
p.printSpaceBeforeIdentifier();
p.printIdentifier(name);
}
- item_count += 1;
}
p.print("}");
@@ -3278,12 +3312,20 @@ pub fn NewPrinter(
.import_items_and_default => {
p.print("var {");
- const default_name = s.default_name.?.ref.?;
- p.print("default: ");
- p.printSymbol(default_name);
+ var need_comma = false;
+ if (s.default_name) |default_name| {
+ if (default_name.ref) |ref| {
+ p.print("default: ");
+ p.printSymbol(ref);
+ need_comma = true;
+ }
+ }
for (s.items) |*item, i| {
- p.print(",");
+ if (need_comma)
+ p.print(",");
+
+ defer need_comma = true;
p.printClauseAlias(item.alias);
const name = p.renamer.nameForSymbol(item.name.ref.?);
@@ -3392,6 +3434,27 @@ pub fn NewPrinter(
p.printLoadFromBundle(require.import_record_index);
}
+ pub fn printBundledRexport(p: *Printer, name: string, import_record_index: u32) void {
+ p.print("Object.defineProperty(");
+ p.print("module.exports");
+ p.print(",");
+ p.printQuotedUTF8(name, true);
+
+ p.print(",{get: () => (");
+ p.printLoadFromBundle(import_record_index);
+ p.print("), enumerable: true, configurable: true})");
+ }
+
+ pub fn printBundledExport(p: *Printer, name: string, identifier: string) void {
+ p.print("Object.defineProperty(");
+ p.print("module.exports");
+ p.print(",");
+ p.printQuotedUTF8(name, true);
+ p.print(",{get: () => (");
+ p.printIdentifier(identifier);
+ p.print("), enumerable: true, configurable: true})");
+ }
+
pub fn printForLoopInit(p: *Printer, initSt: Stmt) void {
switch (initSt.data) {
.s_expr => |s| {
@@ -3553,16 +3616,21 @@ pub fn NewPrinter(
if (rewrite_esm_to_cjs and is_export and decls.len > 0) {
p.printIndent();
p.printSpaceBeforeIdentifier();
+ p.print("Object.defineProperties(");
+ p.printSymbol(p.options.runtime_imports.__export.?);
+ p.print(",{");
for (decls) |decl, i| {
- p.printSymbol(p.options.runtime_imports.__export.?);
- p.print(".");
+ p.print("'");
p.printBinding(decl.binding);
- p.print(" = ");
+ p.print("': {get: () => (");
p.printBinding(decl.binding);
+ p.print("), enumerable: true, configurable: true}");
+
if (i < decls.len - 1) {
- p.print(",");
+ p.print(",\n");
}
}
+ p.print("})");
p.printSemicolonAfterStatement();
}
}
diff --git a/src/linker.zig b/src/linker.zig
index 9c0c1d6a1..d6ed3d8fc 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -190,13 +190,14 @@ pub fn NewLinker(comptime BundlerType: type) type {
var externals = std.ArrayList(u32).init(linker.allocator);
var needs_bundle = false;
const process_import_record_path = file_path.text[0..std.math.min(source_dir.len + 1, file_path.text.len)];
+ var first_bundled_index: ?u32 = null;
// Step 1. Resolve imports & requires
switch (result.loader) {
.jsx, .js, .ts, .tsx => {
for (result.ast.import_records) |*import_record, _record_index| {
if (import_record.is_unused) continue;
-
+
const record_index = @truncate(u32, _record_index);
if (comptime !ignore_runtime) {
if (strings.eqlComptime(import_record.path.text, Runtime.Imports.Name)) {
@@ -224,86 +225,97 @@ pub fn NewLinker(comptime BundlerType: type) type {
externals.append(record_index) catch unreachable;
continue;
}
- if (linker.options.node_modules_bundle) |node_modules_bundle| {
- const package_json_ = resolved_import.package_json orelse brk: {
- if (resolved_import.isLikelyNodeModule()) {
- break :brk linker.resolver.packageJSONForResolvedNodeModule(resolved_import);
- }
-
- break :brk null;
- };
- if (package_json_) |package_json| {
- if (strings.contains(package_json.source.path.name.dirWithTrailingSlash(), "node_modules")) {
- if (node_modules_bundle.getPackageIDByName(package_json.name)) |possible_pkg_ids| {
- const pkg_id: u32 = brk: {
- for (possible_pkg_ids) |pkg_id| {
- const pkg = node_modules_bundle.bundle.packages[pkg_id];
- if (pkg.hash == package_json.hash) {
- break :brk pkg_id;
- }
- }
- linker.log.addErrorFmt(
- null,
- logger.Loc.Empty,
- linker.allocator,
- "\"{s}\" version changed, please regenerate the .bun.\nOld version: \"{s}\"\nNew version: \"{s}\"\nRun this command:\nbun bun",
- .{
- package_json.name,
- node_modules_bundle.str(node_modules_bundle.bundle.packages[possible_pkg_ids[0]].version),
- package_json.version,
- },
- ) catch {};
- return error.RebuildJSB;
- };
-
- const package = &node_modules_bundle.bundle.packages[pkg_id];
-
- if (comptime isDebug) {
- std.debug.assert(strings.eql(node_modules_bundle.str(package.name), package_json.name));
+ const path = resolved_import.pathConst() orelse {
+ import_record.path.is_disabled = true;
+ continue;
+ };
+
+ const loader = linker.options.loader(path.name.ext);
+ if (loader.isJavaScriptLikeOrJSON()) {
+ bundled: {
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ const package_json_ = resolved_import.package_json orelse brk: {
+ if (resolved_import.isLikelyNodeModule()) {
+ break :brk linker.resolver.packageJSONForResolvedNodeModule(resolved_import);
}
- const package_relative_path = linker.fs.relative(
- package_json.source.path.name.dirWithTrailingSlash(),
- resolved_import.path_pair.primary.text,
- );
+ break :bundled;
+ };
+ if (package_json_) |package_json| {
+ if (strings.contains(package_json.source.path.name.dirWithTrailingSlash(), "node_modules")) {
+ if (node_modules_bundle.getPackageIDByName(package_json.name)) |possible_pkg_ids| {
+ const pkg_id: u32 = brk: {
+ for (possible_pkg_ids) |pkg_id| {
+ const pkg = node_modules_bundle.bundle.packages[pkg_id];
+ if (pkg.hash == package_json.hash) {
+ break :brk pkg_id;
+ }
+ }
+
+ linker.log.addErrorFmt(
+ null,
+ logger.Loc.Empty,
+ linker.allocator,
+ "\"{s}\" version changed, please regenerate the .bun.\nOld version: \"{s}\"\nNew version: \"{s}\"\nRun this command:\nbun bun",
+ .{
+ package_json.name,
+ node_modules_bundle.str(node_modules_bundle.bundle.packages[possible_pkg_ids[0]].version),
+ package_json.version,
+ },
+ ) catch {};
+ return error.RunBunBun;
+ };
+
+ const package = &node_modules_bundle.bundle.packages[pkg_id];
+
+ if (comptime isDebug) {
+ std.debug.assert(strings.eql(node_modules_bundle.str(package.name), package_json.name));
+ }
- const found_module = node_modules_bundle.findModuleInPackage(package, package_relative_path) orelse {
- linker.log.addErrorFmt(
- null,
- logger.Loc.Empty,
- linker.allocator,
- "New dependency import: \"{s}/{s}\"\nPlease run `bun bun` to update the .bun.",
- .{
- package_json.name,
- package_relative_path,
- },
- ) catch {};
- return error.RebuildJSB;
- };
-
- if (comptime isDebug) {
- const module_path = node_modules_bundle.str(found_module.path);
- std.debug.assert(
- strings.eql(
- module_path,
- package_relative_path,
- ),
- );
- }
+ const package_relative_path = linker.fs.relative(
+ package_json.source.path.name.dirWithTrailingSlash(),
+ path.text,
+ );
+
+ const found_module = node_modules_bundle.findModuleInPackage(package, package_relative_path) orelse {
+ linker.log.addErrorFmt(
+ null,
+ logger.Loc.Empty,
+ linker.allocator,
+ "New dependency import: \"{s}/{s}\"\nPlease run `bun bun` to update the .bun.",
+ .{
+ package_json.name,
+ package_relative_path,
+ },
+ ) catch {};
+ break :bundled;
+ };
+
+ if (comptime isDebug) {
+ const module_path = node_modules_bundle.str(found_module.path);
+ std.debug.assert(
+ strings.eql(
+ module_path,
+ package_relative_path,
+ ),
+ );
+ }
- import_record.is_bundled = true;
- import_record.path.text = linker.nodeModuleBundleImportPath();
- import_record.module_id = found_module.id;
- needs_bundle = true;
- continue;
+ import_record.is_bundled = true;
+ import_record.path.text = linker.nodeModuleBundleImportPath();
+ import_record.module_id = found_module.id;
+ needs_bundle = true;
+ continue;
+ }
+ }
}
}
}
}
linker.processImportRecord(
- linker.options.loader(resolved_import.path_pair.primary.name.ext),
+ loader,
// Include trailing slash
process_import_record_path,
@@ -564,7 +576,7 @@ pub fn NewLinker(comptime BundlerType: type) type {
import_record.path = try linker.generateImportPath(
source_dir,
- resolve_result.path_pair.primary.text,
+ resolve_result.pathConst().?.text,
if (resolve_result.package_json) |package_json| package_json.version else "",
BundlerType.isCacheEnabled and loader == .file,
import_path_format,
@@ -586,11 +598,12 @@ pub fn NewLinker(comptime BundlerType: type) type {
}
pub fn resolveResultHashKey(linker: *ThisLinker, resolve_result: *const Resolver.Result) u64 {
- var hash_key = resolve_result.path_pair.primary.text;
+ const path = resolve_result.pathConst() orelse unreachable;
+ var hash_key = path.text;
// Shorter hash key is faster to hash
- if (strings.startsWith(resolve_result.path_pair.primary.text, linker.fs.top_level_dir)) {
- hash_key = resolve_result.path_pair.primary.text[linker.fs.top_level_dir.len..];
+ if (strings.startsWith(path.text, linker.fs.top_level_dir)) {
+ hash_key = path.text[linker.fs.top_level_dir.len..];
}
return std.hash.Wyhash.hash(0, hash_key);
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig
index 9af0f27de..979c1bba5 100644
--- a/src/node_module_bundle.zig
+++ b/src/node_module_bundle.zig
@@ -122,7 +122,7 @@ pub const NodeModuleBundle = struct {
// Assert we have enough room to add another package
std.debug.assert(end < remaining_names.len);
entry.value_ptr.* = prev_package_ids_for_name.ptr[0..end];
- entry.value_ptr.*[end] = package_id;
+ entry.value_ptr.*[end - 1] = package_id;
} else {
prev_package_ids_for_name = remaining_names[0..1];
prev_package_ids_for_name[0] = package_id;
diff --git a/src/options.zig b/src/options.zig
index 032d2a38b..05a32cc28 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -75,12 +75,23 @@ pub const ExternalModules = struct {
.patterns = &([_]WildcardPattern{}),
};
- if (platform == .node) {
- // TODO: fix this stupid copy
- result.node_modules.hash_map.ensureCapacity(NodeBuiltinPatterns.len) catch unreachable;
- for (NodeBuiltinPatterns) |pattern| {
- result.node_modules.insert(pattern) catch unreachable;
- }
+ switch (platform) {
+ .node => {
+ // TODO: fix this stupid copy
+ result.node_modules.hash_map.ensureCapacity(NodeBuiltinPatterns.len) catch unreachable;
+ for (NodeBuiltinPatterns) |pattern| {
+ result.node_modules.insert(pattern) catch unreachable;
+ }
+ },
+ .bun => {
+
+ // TODO: fix this stupid copy
+ result.node_modules.hash_map.ensureCapacity(BunNodeBuiltinPatternsCompat.len) catch unreachable;
+ for (BunNodeBuiltinPatternsCompat) |pattern| {
+ result.node_modules.insert(pattern) catch unreachable;
+ }
+ },
+ else => {},
}
if (externals.len == 0) {
@@ -176,6 +187,65 @@ pub const ExternalModules = struct {
"zlib",
};
+ pub const BunNodeBuiltinPatternsCompat = [_]string{
+ "_http_agent",
+ "_http_client",
+ "_http_common",
+ "_http_incoming",
+ "_http_outgoing",
+ "_http_server",
+ "_stream_duplex",
+ "_stream_passthrough",
+ "_stream_readable",
+ "_stream_transform",
+ "_stream_wrap",
+ "_stream_writable",
+ "_tls_common",
+ "_tls_wrap",
+ "assert",
+ "async_hooks",
+ // "buffer",
+ "child_process",
+ "cluster",
+ "console",
+ "constants",
+ "crypto",
+ "dgram",
+ "diagnostics_channel",
+ "dns",
+ "domain",
+ "events",
+ "fs",
+ "http",
+ "http2",
+ "https",
+ "inspector",
+ "module",
+ "net",
+ "os",
+ // "path",
+ "perf_hooks",
+ // "process",
+ "punycode",
+ "querystring",
+ "readline",
+ "repl",
+ "stream",
+ "string_decoder",
+ "sys",
+ "timers",
+ "tls",
+ "trace_events",
+ "tty",
+ "url",
+ "util",
+ "v8",
+ "vm",
+ "wasi",
+ "worker_threads",
+ "zlib",
+ };
+
pub const NodeBuiltinsMap = std.ComptimeStringMap(bool, .{
.{ "_http_agent", true },
.{ "_http_client", true },
@@ -260,6 +330,13 @@ pub const Platform = enum {
};
}
+ pub inline fn supportsBrowserField(this: Platform) bool {
+ return switch (this) {
+ .neutral, .browser, .bun => true,
+ else => false,
+ };
+ }
+
const browser_define_value_true = "true";
const browser_define_value_false = "false";
@@ -354,10 +431,12 @@ pub const Platform = enum {
array.set(Platform.browser, &listc);
array.set(Platform.bun, &listc);
+ // Original comment:
// The neutral platform is for people that don't want esbuild to try to
// pick good defaults for their platform. In that case, the list of main
// fields is empty by default. You must explicitly configure it yourself.
- array.set(Platform.neutral, &([_]string{}));
+
+ array.set(Platform.neutral, &listc);
break :brk array;
};
@@ -405,6 +484,13 @@ pub const Loader = enum(u3) {
};
}
+ pub fn isJavaScriptLikeOrJSON(loader: Loader) bool {
+ return switch (loader) {
+ .jsx, .js, .ts, .tsx, .json => true,
+ else => false,
+ };
+ }
+
pub fn forFileName(filename: string, obj: anytype) ?Loader {
const ext = std.fs.path.extension(filename);
if (ext.len == 0 or (ext.len == 1 and ext[0] == '.')) return null;
@@ -1191,7 +1277,7 @@ pub const OutputFile = struct {
pub fn initPending(loader: Loader, pending: resolver.Result) OutputFile {
return .{
.loader = .file,
- .input = pending.path_pair.primary,
+ .input = pending.pathConst().?.*,
.size = 0,
.value = .{ .pending = pending },
};
diff --git a/src/panic_handler.zig b/src/panic_handler.zig
index 3f49bf6ab..84b66d9be 100644
--- a/src/panic_handler.zig
+++ b/src/panic_handler.zig
@@ -3,8 +3,6 @@ const logger = @import("logger.zig");
const root = @import("root");
usingnamespace @import("global.zig");
-const USERLAND_PANIC_MESSAGE = "iNtErNaL sErVeR eRrOr";
-
/// This function is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub fn default_panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
diff --git a/src/query_string_map.zig b/src/query_string_map.zig
index e9e1f2e6d..1bac8f5ce 100644
--- a/src/query_string_map.zig
+++ b/src/query_string_map.zig
@@ -18,9 +18,30 @@ pub const URL = struct {
search: string = "",
searchParams: ?QueryStringMap = null,
username: string = "",
-
port_was_automatically_set: bool = false,
+ pub fn displayProtocol(this: *const URL) string {
+ if (this.protocol.len > 0) {
+ return this.protocol;
+ }
+
+ if (this.getPort()) |port| {
+ if (port == 443) {
+ return "https";
+ }
+ }
+
+ return "http";
+ }
+
+ pub fn displayHostname(this: *const URL) string {
+ if (this.hostname.len > 0) {
+ return this.hostname;
+ }
+
+ return "localhost";
+ }
+
pub fn hasHTTPLikeProtocol(this: *const URL) bool {
return strings.eqlComptime(this.protocol, "http") or strings.eqlComptime(this.protocol, "https");
}
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig
index 346b15371..b3b484a84 100644
--- a/src/resolver/package_json.zig
+++ b/src/resolver/package_json.zig
@@ -9,9 +9,11 @@ const alloc = @import("../alloc.zig");
const fs = @import("../fs.zig");
const resolver = @import("./resolver.zig");
-const MainFieldMap = std.StringHashMap(string);
-const BrowserMap = std.StringHashMap(string);
-threadlocal var hashed_buf: [2048]u8 = undefined;
+// Assume they're not going to have hundreds of main fields or browser map
+// so use an array-backed hash table instead of bucketed
+const MainFieldMap = std.StringArrayHashMap(string);
+const BrowserMap = std.StringArrayHashMap(string);
+threadlocal var hashy: [2048]u8 = undefined;
pub const PackageJSON = struct {
pub const LoadFramework = enum {
@@ -50,7 +52,7 @@ pub const PackageJSON = struct {
main_fields: MainFieldMap,
module_type: options.ModuleType,
version: string = "",
- hash: u32 = 0,
+ hash: u32 = 0xDEADBEEF,
// Present if the "browser" field is present. This field is intended to be
// used by bundlers and lets you redirect the paths of certain 3rd-party
@@ -79,6 +81,10 @@ pub const PackageJSON = struct {
//
browser_map: BrowserMap,
+ pub inline fn isAppPackage(this: *const PackageJSON) bool {
+ return this.hash == 0xDEADBEEF;
+ }
+
fn loadDefineDefaults(
env: *options.Env,
json: *const js_ast.E.Object,
@@ -400,6 +406,9 @@ pub const PackageJSON = struct {
} orelse return null);
var package_json = PackageJSON{
+ .name = "",
+ .version = "",
+ .hash = 0xDEADBEEF,
.source = json_source,
.module_type = .unknown,
.browser_map = BrowserMap.init(r.allocator),
@@ -408,13 +417,17 @@ pub const PackageJSON = struct {
if (json.asProperty("version")) |version_json| {
if (version_json.expr.asString(r.allocator)) |version_str| {
- package_json.version = r.allocator.dupe(u8, version_str) catch unreachable;
+ if (version_str.len > 0) {
+ package_json.version = r.allocator.dupe(u8, version_str) catch unreachable;
+ }
}
}
if (json.asProperty("name")) |version_json| {
if (version_json.expr.asString(r.allocator)) |version_str| {
- package_json.name = r.allocator.dupe(u8, version_str) catch unreachable;
+ if (version_str.len > 0) {
+ package_json.name = r.allocator.dupe(u8, version_str) catch unreachable;
+ }
}
}
@@ -449,14 +462,14 @@ pub const PackageJSON = struct {
if ((expr.asString(r.allocator))) |str| {
if (str.len > 0) {
- package_json.main_fields.put(main, str) catch unreachable;
+ package_json.main_fields.put(main, r.allocator.dupe(u8, str) catch unreachable) catch unreachable;
}
}
}
}
// Read the "browser" property, but only when targeting the browser
- if (r.opts.platform == .browser) {
+ if (r.opts.platform.supportsBrowserField()) {
// We both want the ability to have the option of CJS vs. ESM and the
// option of having node vs. browser. The way to do this is to use the
// object literal form of the "browser" field like this:
@@ -514,13 +527,29 @@ pub const PackageJSON = struct {
// TODO: exports map
if (generate_hash) {
- std.mem.set(u8, &hashed_buf, 0);
- std.mem.copy(u8, &hashed_buf, package_json.name);
- hashed_buf[package_json.name.len + 1] = '@';
- std.mem.copy(u8, hashed_buf[package_json.name.len + 1 ..], package_json.version);
- package_json.hash = @truncate(u32, std.hash.Wyhash.hash(0, hashed_buf[0 .. package_json.name.len + 1 + package_json.version.len]));
+ if (package_json.name.len > 0 and package_json.version.len > 0) {
+ std.mem.set(u8, &hashy, 0);
+ var used: usize = 0;
+ std.mem.copy(u8, &hashy, package_json.name);
+ used = package_json.name.len;
+
+ hashy[used] = '@';
+ used += 1;
+ std.mem.copy(u8, hashy[used..], package_json.version);
+ used += package_json.version.len;
+
+ package_json.hash = std.hash.Murmur3_32.hash(hashy[0..used]);
+ }
}
return package_json;
}
+
+ pub fn hashModule(this: *const PackageJSON, module: string) u32 {
+ var hasher = std.hash.Wyhash.init(0);
+ hasher.update(std.mem.asBytes(&this.hash));
+ hasher.update(module);
+
+ return @truncate(u32, hasher.final());
+ }
};
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 2203ac138..c44608d3b 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -100,6 +100,28 @@ pub const Result = struct {
file_fd: StoredFileDescriptorType = 0,
import_kind: ast.ImportKind = undefined,
+ pub fn path(this: *Result) ?*Path {
+ if (!this.path_pair.primary.is_disabled)
+ return &this.path_pair.primary;
+
+ if (this.path_pair.secondary) |*second| {
+ if (!second.is_disabled) return second;
+ }
+
+ return null;
+ }
+
+ pub fn pathConst(this: *const Result) ?*const Path {
+ if (!this.path_pair.primary.is_disabled)
+ return &this.path_pair.primary;
+
+ if (this.path_pair.secondary) |*second| {
+ if (!second.is_disabled) return second;
+ }
+
+ return null;
+ }
+
// remember: non-node_modules can have package.json
// checking package.json may not be relevant
pub fn isLikelyNodeModule(this: *const Result) bool {
@@ -147,21 +169,16 @@ pub const Result = struct {
}
};
- pub fn hash(this: *const Result, loader: options.Loader) u32 {
- const HashValue = packed struct {
- loader: options.Loader,
- len: u8,
- path_hash: u21,
- };
+ pub fn hash(this: *const Result, root_dir: string, loader: options.Loader) u32 {
+ const module = this.path_pair.primary.text;
+ const node_module_root = std.fs.path.sep_str ++ "node_modules" ++ std.fs.path.sep_str;
+ if (strings.lastIndexOf(module, node_module_root)) |end_| {
+ var end: usize = end_ + node_module_root.len;
- return @bitCast(
- u32,
- HashValue{
- .loader = loader,
- .len = @truncate(u8, this.path_pair.primary.text.len),
- .path_hash = @truncate(u21, std.hash.Wyhash.hash(0, this.path_pair.primary.text)),
- },
- );
+ return @truncate(u32, std.hash.Wyhash.hash(0, module[end..]));
+ }
+
+ return @truncate(u32, std.hash.Wyhash.hash(0, this.path_pair.primary.text));
}
};
@@ -882,14 +899,15 @@ pub fn NewResolver(cache_files: bool) type {
const base_dir_info = ((r.dirInfoCached(dirname) catch null)) orelse continue;
const dir_info = base_dir_info.getEnclosingBrowserScope() orelse continue;
const pkg_json = dir_info.package_json orelse continue;
- const rel_path = r.fs.relative(pkg_json.source.key_path.text, path.text);
+ const rel_path = r.fs.relative(pkg_json.source.path.name.dirWithTrailingSlash(), path.text);
result.module_type = pkg_json.module_type;
result.package_json = result.package_json orelse pkg_json;
if (r.checkBrowserMap(pkg_json, rel_path)) |remapped| {
if (remapped.len == 0) {
path.is_disabled = true;
} else if (r.resolveWithoutRemapping(dir_info, remapped, kind)) |remapped_result| {
- switch (iter.index) {
+ // iter.index is the next one, not the prev
+ switch (iter.index - 1) {
0 => {
result.path_pair.primary = remapped_result.path_pair.primary;
result.dirname_fd = remapped_result.dirname_fd;
@@ -944,7 +962,7 @@ pub fn NewResolver(cache_files: bool) type {
r: *ThisResolver,
result: *const Result,
) ?*const PackageJSON {
- const absolute = result.path_pair.primary.text;
+ const absolute = (result.pathConst() orelse return null).text;
// /foo/node_modules/@babel/standalone/index.js
// ^------------^
var end = strings.lastIndexOf(absolute, node_module_root_string) orelse return null;
@@ -1361,7 +1379,12 @@ pub fn NewResolver(cache_files: bool) type {
}
}
- const dir_info = try r.dirInfoUncached(
+ // We must initialize it as empty so that the result index is correct.
+ // This is important so that browser_scope has a valid index.
+ var dir_info_ptr = try r.dir_cache.put(&queue_top.result, DirInfo{});
+
+ try r.dirInfoUncached(
+ dir_info_ptr,
dir_path,
dir_entries_option,
queue_top.result,
@@ -1371,8 +1394,6 @@ pub fn NewResolver(cache_files: bool) type {
open_dir.fd,
);
- var dir_info_ptr = try r.dir_cache.put(&queue_top.result, dir_info);
-
if (queue_slice.len == 0) {
return dir_info_ptr;
@@ -1834,11 +1855,11 @@ pub fn NewResolver(cache_files: bool) type {
return MatchResult{
.path_pair = .{
- .primary = auto_main_result.path_pair.primary,
- .secondary = _result.path_pair.primary,
+ .primary = _result.path_pair.primary,
+ .secondary = auto_main_result.path_pair.primary,
},
- .diff_case = auto_main_result.diff_case,
- .dirname_fd = auto_main_result.dirname_fd,
+ .diff_case = _result.diff_case,
+ .dirname_fd = _result.dirname_fd,
.package_json = package_json,
};
} else {
@@ -2025,6 +2046,7 @@ pub fn NewResolver(cache_files: bool) type {
fn dirInfoUncached(
r: *ThisResolver,
+ info: *DirInfo,
path: string,
_entries: *Fs.FileSystem.RealFS.EntriesOption,
_result: allocators.Result,
@@ -2032,13 +2054,13 @@ pub fn NewResolver(cache_files: bool) type {
parent: ?*DirInfo,
parent_index: allocators.IndexType,
fd: FileDescriptorType,
- ) anyerror!DirInfo {
+ ) anyerror!void {
var result = _result;
var rfs: *Fs.FileSystem.RealFS = &r.fs.fs;
var entries = _entries.entries;
- var info = DirInfo{
+ info.* = DirInfo{
.abs_path = path,
// .abs_real_path = path,
.parent = parent_index,
@@ -2054,7 +2076,6 @@ pub fn NewResolver(cache_files: bool) type {
// if (entries != null) {
if (!strings.eqlComptime(base, "node_modules")) {
if (entries.getComptimeQuery("node_modules")) |entry| {
- // the catch might be wrong!
info.has_node_modules = (entry.entry.kind(rfs)) == .dir;
}
}
@@ -2157,8 +2178,6 @@ pub fn NewResolver(cache_files: bool) type {
if (info.tsconfig_json == null and parent != null) {
info.tsconfig_json = parent.?.tsconfig_json;
}
-
- return info;
}
};
}
@@ -2197,3 +2216,15 @@ const Dirname = struct {
return path[0 .. end_index + 1];
}
};
+
+test "murmur" {
+ var str = try std.heap.c_allocator.alloc(u8, "swiper@6.8.2swiper.cjs.js".len);
+ var str2 = try std.heap.c_allocator.alloc(u8, "swiper@6.8.2swiper.cjs.js".len);
+ std.mem.copy(u8, str, "swiper@6.8.2swiper.cjs.js");
+ std.mem.copy(u8, str2, "swiper@6.8.2swiper.cjs.js");
+
+ try std.testing.expectEqual(
+ std.hash.murmur.Murmur3_32.hash(str),
+ std.hash.murmur.Murmur3_32.hash(str2),
+ );
+}
diff --git a/src/runtime.js b/src/runtime.js
index d3416cbe4..96c1c2d6f 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -7,7 +7,7 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
export var __markAsModule = (target) =>
- __defProp(target, "__esModule", { value: true });
+ __defProp(target, "__esModule", { value: true, configurable: true });
// lazy require to prevent loading one icon from a design system
export var $$lzy = (target, module, props) => {
@@ -16,6 +16,7 @@ export var $$lzy = (target, module, props) => {
__defProp(target, key, {
get: () => module()[props[key]],
enumerable: true,
+ configurable: true,
});
}
return target;
@@ -28,8 +29,8 @@ export var __toModule = (module) => {
module != null ? __create(__getProtoOf(module)) : {},
"default",
module && module.__esModule && "default" in module
- ? { get: () => module.default, enumerable: true }
- : { value: module, enumerable: true }
+ ? { get: () => module.default, enumerable: true, configurable: true }
+ : { value: module, enumerable: true, configurable: true }
)
),
module
@@ -64,6 +65,7 @@ export var __commonJS = (cb, name) => {
return mod.exports;
},
enumerable: true,
+ configurable: true,
});
// If it's a namespace export without .default, pretend .default is the same as mod.exports
} else if (
@@ -79,6 +81,7 @@ export var __commonJS = (cb, name) => {
defaultValue = value;
},
enumerable: true,
+ configurable: true,
});
}
@@ -175,6 +178,7 @@ export var __reExport = (target, module, desc) => {
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, {
get: () => module[key],
+ configurable: true,
enumerable:
!(desc = __getOwnPropDesc(module, key)) || desc.enumerable,
});
diff --git a/src/runtime.version b/src/runtime.version
index e76ed155e..1d355c2cd 100644
--- a/src/runtime.version
+++ b/src/runtime.version
@@ -1 +1 @@
-3b71ea301d8e2123 \ No newline at end of file
+ffa36d1436d2546f \ No newline at end of file
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index bac00ba45..8706f4053 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -305,7 +305,7 @@ pub fn eqlComptime(self: string, comptime alt: anytype) bool {
second == std.mem.readIntNative(u16, self[4..6]);
},
5, 7 => {
- const check = std.mem.readIntNative(u32, alt[0..4]);
+ const check = comptime std.mem.readIntNative(u32, alt[0..4]);
if (self.len != alt.len or std.mem.readIntNative(u32, self[0..4]) != check) {
return false;
}
@@ -316,7 +316,7 @@ pub fn eqlComptime(self: string, comptime alt: anytype) bool {
return true;
},
8 => {
- const check = std.mem.readIntNative(u64, alt[0..alt.len]);
+ const check = comptime std.mem.readIntNative(u64, alt[0..alt.len]);
return self.len == alt.len and std.mem.readIntNative(u64, self[0..8]) == check;
},
9...11 => {
@@ -332,13 +332,13 @@ pub fn eqlComptime(self: string, comptime alt: anytype) bool {
return true;
},
12 => {
- const first = std.mem.readIntNative(u64, alt[0..8]);
- const second = std.mem.readIntNative(u32, alt[8..12]);
+ const first = comptime std.mem.readIntNative(u64, alt[0..8]);
+ const second = comptime std.mem.readIntNative(u32, alt[8..12]);
return (self.len == alt.len) and first == std.mem.readIntNative(u64, self[0..8]) and second == std.mem.readIntNative(u32, self[8..12]);
},
13...15 => {
- const first = std.mem.readIntNative(u64, alt[0..8]);
- const second = std.mem.readIntNative(u32, alt[8..12]);
+ const first = comptime std.mem.readIntNative(u64, alt[0..8]);
+ const second = comptime std.mem.readIntNative(u32, alt[8..12]);
if (self.len != alt.len or first != std.mem.readIntNative(u64, self[0..8]) or second != std.mem.readIntNative(u32, self[8..12])) {
return false;
@@ -351,8 +351,8 @@ pub fn eqlComptime(self: string, comptime alt: anytype) bool {
return true;
},
16 => {
- const first = std.mem.readIntNative(u64, alt[0..8]);
- const second = std.mem.readIntNative(u64, alt[8..15]);
+ const first = comptime std.mem.readIntNative(u64, alt[0..8]);
+ const second = comptime std.mem.readIntNative(u64, alt[8..15]);
return (self.len == alt.len) and first == std.mem.readIntNative(u64, self[0..8]) and second == std.mem.readIntNative(u64, self[8..16]);
},
else => {
diff --git a/src/test/fixtures/browsermap-false.ts b/src/test/fixtures/browsermap-false.ts
new file mode 100644
index 000000000..aac72e325
--- /dev/null
+++ b/src/test/fixtures/browsermap-false.ts
@@ -0,0 +1,3 @@
+import { Foo } from "browsermap";
+
+console.log(Foo);
diff --git a/src/test/fixtures/main-field.ts b/src/test/fixtures/main-field.ts
new file mode 100644
index 000000000..5f69721c8
--- /dev/null
+++ b/src/test/fixtures/main-field.ts
@@ -0,0 +1,3 @@
+import Algolia from "algoliasearch/lite";
+
+console.log(Algolia);
diff --git a/src/test/fixtures/package.json b/src/test/fixtures/package.json
deleted file mode 100644
index 8555c8500..000000000
--- a/src/test/fixtures/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "repo",
- "dependencies": {
- "react": "^16.8.4",
- "react-dom": "^16.8.4"
- }
-}
diff --git a/src/test/fixtures/type-only-import.ts b/src/test/fixtures/type-only-import.ts
new file mode 100644
index 000000000..af7c11a12
--- /dev/null
+++ b/src/test/fixtures/type-only-import.ts
@@ -0,0 +1,33 @@
+import { Foo } from "bacon";
+import React from "react";
+import * as Boom from "react";
+import { createElement } from "react";
+export const hello: Foo = React.createElement("div");
+
+export const bacon: (foo: (what: Foo) => (the: Foo) => Foo) => Foo = (
+ foo: Foo
+) => {
+ return createElement(true);
+};
+
+export function funcBacon(foo: (what: Foo) => (the: Foo) => void) {
+ this.Foo = foo;
+ Boom();
+}
+
+export abstract class Bar implements Foo {
+ bacon: Foo;
+ what: Foo;
+}
+
+export class Broke implements Foo {
+ bacon: Foo;
+ what: Foo;
+}
+export interface Baz extends Foo {
+ foo: Foo;
+ bar: Foo;
+ boop: Foo;
+ Foo: Foo;
+}
+export interface Baz extends Foo {}
diff --git a/src/test/project.zig b/src/test/project.zig
index 5715778c1..26dadbc94 100644
--- a/src/test/project.zig
+++ b/src/test/project.zig
@@ -1464,3 +1464,142 @@ pub const three = [_][]const u8{
"/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js",
"/project/node_modules/three/src/extras/curves/SplineCurve.js",
};
+
+pub const next = [_][]const u8{
+ "next@11.1.0/app.js - 3424158524:2890943422",
+ "next@11.1.0/app.js - 3424158524:2890943422",
+ "next@11.1.0/dist/client/head-manager.js - 3424158524:2201168507",
+ "next@11.1.0/dist/client/head-manager.js - 3424158524:2201168507",
+ "next@11.1.0/dist/client/link.js - 3424158524:3978876338",
+ "next@11.1.0/dist/client/link.js - 3424158524:3978876338",
+ "next@11.1.0/dist/client/normalize-trailing-slash.js - 3424158524:3949960510",
+ "next@11.1.0/dist/client/normalize-trailing-slash.js - 3424158524:3949960510",
+ "next@11.1.0/dist/client/page-loader.js - 3424158524:3974401562",
+ "next@11.1.0/dist/client/request-idle-callback.js - 3424158524:2155089364",
+ "next@11.1.0/dist/client/request-idle-callback.js - 3424158524:2155089364",
+ "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608",
+ "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608",
+ "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608",
+ "next@11.1.0/dist/client/router.js - 3424158524:60654157",
+ "next@11.1.0/dist/client/router.js - 3424158524:60654157",
+ "next@11.1.0/dist/client/router.js - 3424158524:60654157",
+ "next@11.1.0/dist/client/script.js - 3424158524:2971760940",
+ "next@11.1.0/dist/client/use-intersection.js - 3424158524:1893142411",
+ "next@11.1.0/dist/client/use-intersection.js - 3424158524:1893142411",
+ "next@11.1.0/dist/client/with-router.js - 3424158524:3574523301",
+ "next@11.1.0/dist/client/with-router.js - 3424158524:3574523301",
+ "next@11.1.0/dist/compiled/path-to-regexp/index.js - 3424158524:4292453228",
+ "next@11.1.0/dist/compiled/path-to-regexp/index.js - 3424158524:4292453228",
+ "next@11.1.0/dist/pages/_app.js - 3424158524:1831562171",
+ "next@11.1.0/dist/pages/_app.js - 3424158524:1831562171",
+ "next@11.1.0/dist/pages/_document.js - 3424158524:1843055786",
+ "next@11.1.0/dist/server/denormalize-page-path.js - 3424158524:2078268279",
+ "next@11.1.0/dist/server/denormalize-page-path.js - 3424158524:2078268279",
+ "next@11.1.0/dist/server/get-page-files.js - 3424158524:3103205117",
+ "next@11.1.0/dist/server/htmlescape.js - 3424158524:3619675719",
+ "next@11.1.0/dist/server/normalize-page-path.js - 3424158524:79382061",
+ "next@11.1.0/dist/server/utils.js - 3424158524:3170288217",
+ "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210",
+ "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210",
+ "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210",
+ "next@11.1.0/dist/shared/lib/amp.js - 3424158524:3972854680",
+ "next@11.1.0/dist/shared/lib/amp.js - 3424158524:3972854680",
+ "next@11.1.0/dist/shared/lib/constants.js - 3424158524:3766949957",
+ "next@11.1.0/dist/shared/lib/document-context.js - 3424158524:3503028665",
+ "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170",
+ "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170",
+ "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170",
+ "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170",
+ "next@11.1.0/dist/shared/lib/head.js - 3424158524:1660462722",
+ "next@11.1.0/dist/shared/lib/head.js - 3424158524:1660462722",
+ "next@11.1.0/dist/shared/lib/i18n/detect-domain-locale.js - 3424158524:2360522531",
+ "next@11.1.0/dist/shared/lib/i18n/normalize-locale-path.js - 3424158524:2987178093",
+ "next@11.1.0/dist/shared/lib/i18n/normalize-locale-path.js - 3424158524:2987178093",
+ "next@11.1.0/dist/shared/lib/loadable-context.js - 3424158524:3504182001",
+ "next@11.1.0/dist/shared/lib/loadable-context.js - 3424158524:3504182001",
+ "next@11.1.0/dist/shared/lib/loadable.js - 3424158524:3055601316",
+ "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371",
+ "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371",
+ "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371",
+ "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782",
+ "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782",
+ "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782",
+ "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782",
+ "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930",
+ "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930",
+ "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930",
+ "next@11.1.0/dist/shared/lib/router/utils/format-url.js - 3424158524:2249819031",
+ "next@11.1.0/dist/shared/lib/router/utils/format-url.js - 3424158524:2249819031",
+ "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198",
+ "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198",
+ "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198",
+ "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346",
+ "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346",
+ "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346",
+ "next@11.1.0/dist/shared/lib/router/utils/parse-relative-url.js - 3424158524:84921275",
+ "next@11.1.0/dist/shared/lib/router/utils/parse-relative-url.js - 3424158524:84921275",
+ "next@11.1.0/dist/shared/lib/router/utils/parse-url.js - 3424158524:2943870410",
+ "next@11.1.0/dist/shared/lib/router/utils/parse-url.js - 3424158524:2943870410",
+ "next@11.1.0/dist/shared/lib/router/utils/path-match.js - 3424158524:1335539408",
+ "next@11.1.0/dist/shared/lib/router/utils/path-match.js - 3424158524:1335539408",
+ "next@11.1.0/dist/shared/lib/router/utils/prepare-destination.js - 3424158524:2905198601",
+ "next@11.1.0/dist/shared/lib/router/utils/prepare-destination.js - 3424158524:2905198601",
+ "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157",
+ "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157",
+ "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157",
+ "next@11.1.0/dist/shared/lib/router/utils/resolve-rewrites.js - 3424158524:2049321565",
+ "next@11.1.0/dist/shared/lib/router/utils/resolve-rewrites.js - 3424158524:2049321565",
+ "next@11.1.0/dist/shared/lib/router/utils/route-matcher.js - 3424158524:3388378419",
+ "next@11.1.0/dist/shared/lib/router/utils/route-matcher.js - 3424158524:3388378419",
+ "next@11.1.0/dist/shared/lib/router/utils/route-regex.js - 3424158524:1570670727",
+ "next@11.1.0/dist/shared/lib/router/utils/route-regex.js - 3424158524:1570670727",
+ "next@11.1.0/dist/shared/lib/runtime-config.js - 3424158524:4205818429",
+ "next@11.1.0/dist/shared/lib/side-effect.js - 3424158524:3871282960",
+ "next@11.1.0/dist/shared/lib/side-effect.js - 3424158524:3871282960",
+ "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793",
+ "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793",
+ "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793",
+ "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793",
+ "next@11.1.0/document.js - 3424158524:761357561",
+ "next@11.1.0/head.js - 3424158524:4027675732",
+ "next@11.1.0/head.js - 3424158524:4027675732",
+ "next@11.1.0/link.js - 3424158524:3847679594",
+ "next@11.1.0/link.js - 3424158524:3847679594",
+ "next@11.1.0/router.js - 3424158524:2467530242",
+ "next@11.1.0/router.js - 3424158524:2467530242",
+ "object-assign@4.1.1/index.js - 1106322050:1257305923",
+ "object-assign@4.1.1/index.js - 1106322050:1257305923",
+ "react-dom@17.0.2/cjs/react-dom-server.browser.development.js - 2917057216:4251258747",
+ "react-dom@17.0.2/cjs/react-dom.development.js - 2917057216:2729826485",
+ "react-dom@17.0.2/index.js - 2917057216:4152798548",
+ "react-dom@17.0.2/server.browser.js - 2917057216:2336742101",
+ "react-is@17.0.2/cjs/react-is.development.js - 1177198225:1925584658",
+ "react-is@17.0.2/cjs/react-is.development.js - 1177198225:1925584658",
+ "react-is@17.0.2/index.js - 1177198225:3919220786",
+ "react-is@17.0.2/index.js - 1177198225:3919220786",
+ "react-is@17.0.2/index.js - 1177198225:3919220786",
+ "react-refresh@0.8.3/cjs/react-refresh-runtime.development.js - 1106322050:2742290347",
+ "react-refresh@0.8.3/runtime.js - 1106322050:1039122438",
+ "react@17.0.2/cjs/react-jsx-dev-runtime.development.js - 2465707714:1705570593",
+ "react@17.0.2/cjs/react-jsx-dev-runtime.development.js - 2465707714:1705570593",
+ "react@17.0.2/cjs/react.development.js - 2465707714:1390143369",
+ "react@17.0.2/cjs/react.development.js - 2465707714:1390143369",
+ "react@17.0.2/index.js - 2465707714:1063423392",
+ "react@17.0.2/index.js - 2465707714:1063423392",
+ "react@17.0.2/index.js - 2465707714:1063423392",
+ "react@17.0.2/index.js - 2465707714:1063423392",
+ "react@17.0.2/jsx-dev-runtime.js - 2465707714:3464951857",
+ "react@17.0.2/jsx-dev-runtime.js - 2465707714:3464951857",
+ "scheduler@0.20.2/cjs/scheduler-tracing.development.js - 2917057216:1128698082",
+ "scheduler@0.20.2/cjs/scheduler.development.js - 2917057216:4082470097",
+ "scheduler@0.20.2/index.js - 2917057216:3977196876",
+ "scheduler@0.20.2/tracing.js - 2917057216:2401030364",
+ "string-hash@1.1.3/index.js - 2958931479:1647663124",
+ "styled-jsx@4.0.0/dist/lib/stylesheet.js - 2917057216:205078822",
+ "styled-jsx@4.0.0/dist/server.js - 2917057216:2807236644",
+ "styled-jsx@4.0.0/dist/style.js - 2917057216:3820693621",
+ "styled-jsx@4.0.0/dist/stylesheet-registry.js - 2917057216:2283650446",
+ "styled-jsx@4.0.0/server.js - 2917057216:3921567966",
+ "use-subscription@1.5.1/cjs/use-subscription.development.js - 1836582978:3015515293",
+ "use-subscription@1.5.1/index.js - 1836582978:2982917928",
+};