aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-31 15:03:40 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-31 15:03:40 -0700
commit6a5f34a6bc0546a8f17b8fc0af7688a831a797ad (patch)
tree8ed040425ccac8a7e4b04a9f12c2d1174b4cb5b5 /src
parentbd9f137b1bfb5bc3b215515ff9305e70a638daf9 (diff)
downloadbun-6a5f34a6bc0546a8f17b8fc0af7688a831a797ad.tar.gz
bun-6a5f34a6bc0546a8f17b8fc0af7688a831a797ad.tar.zst
bun-6a5f34a6bc0546a8f17b8fc0af7688a831a797ad.zip
Fallback, fragments, printer compat, better errors
Former-commit-id: 486e8c9d460eeebea024e96dbabcb7f2bfaffafb
Diffstat (limited to 'src')
-rw-r--r--src/.prettierignore1
-rw-r--r--src/api/schema.d.ts183
-rw-r--r--src/api/schema.js757
-rw-r--r--src/api/schema.peechy132
-rw-r--r--src/api/schema.zig3487
-rw-r--r--src/bundler.zig165
-rw-r--r--src/cli/bun_command.zig4
-rw-r--r--src/fallback.html17
-rw-r--r--src/fallback.ts24
-rw-r--r--src/fallback.version1
-rw-r--r--src/http.zig452
-rw-r--r--src/javascript/jsc/bindings/exports.zig185
-rw-r--r--src/javascript/jsc/javascript.zig169
-rw-r--r--src/javascript/jsc/webcore/response.zig19
-rw-r--r--src/js_ast.zig2
-rw-r--r--src/js_parser/js_parser.zig9
-rw-r--r--src/js_printer.zig20
-rw-r--r--src/lock.zig162
-rw-r--r--src/logger.zig67
-rw-r--r--src/node_module_bundle.zig1
-rw-r--r--src/options.zig213
-rw-r--r--src/resolver/package_json.zig41
-rw-r--r--src/resolver/resolver.zig20
-rw-r--r--src/router.zig2
-rw-r--r--src/runtime.version2
-rw-r--r--src/runtime.zig109
-rw-r--r--src/runtime/hmr.ts2
-rw-r--r--src/test/fixtures/fragment.jsx1
28 files changed, 4319 insertions, 1928 deletions
diff --git a/src/.prettierignore b/src/.prettierignore
new file mode 100644
index 000000000..b50b4c262
--- /dev/null
+++ b/src/.prettierignore
@@ -0,0 +1 @@
+fallback.html \ No newline at end of file
diff --git a/src/api/schema.d.ts b/src/api/schema.d.ts
index fc03c82b0..d7e66820e 100644
--- a/src/api/schema.d.ts
+++ b/src/api/schema.d.ts
@@ -37,6 +37,69 @@ type uint32 = number;
7: "json",
json: "json"
}
+ export enum FrameworkEntryPointType {
+ client = 1,
+ server = 2,
+ fallback = 3
+ }
+ export const FrameworkEntryPointTypeKeys = {
+ 1: "client",
+ client: "client",
+ 2: "server",
+ server: "server",
+ 3: "fallback",
+ fallback: "fallback"
+ }
+ export enum StackFrameScope {
+ Eval = 1,
+ Module = 2,
+ Function = 3,
+ Global = 4,
+ Wasm = 5,
+ Constructor = 6
+ }
+ export const StackFrameScopeKeys = {
+ 1: "Eval",
+ Eval: "Eval",
+ 2: "Module",
+ Module: "Module",
+ 3: "Function",
+ Function: "Function",
+ 4: "Global",
+ Global: "Global",
+ 5: "Wasm",
+ Wasm: "Wasm",
+ 6: "Constructor",
+ Constructor: "Constructor"
+ }
+ export enum FallbackStep {
+ ssr_disabled = 1,
+ create_vm = 2,
+ configure_router = 3,
+ configure_defines = 4,
+ resolve_entry_point = 5,
+ load_entry_point = 6,
+ eval_entry_point = 7,
+ fetch_event_handler = 8
+ }
+ export const FallbackStepKeys = {
+ 1: "ssr_disabled",
+ ssr_disabled: "ssr_disabled",
+ 2: "create_vm",
+ create_vm: "create_vm",
+ 3: "configure_router",
+ configure_router: "configure_router",
+ 4: "configure_defines",
+ configure_defines: "configure_defines",
+ 5: "resolve_entry_point",
+ resolve_entry_point: "resolve_entry_point",
+ 6: "load_entry_point",
+ load_entry_point: "load_entry_point",
+ 7: "eval_entry_point",
+ eval_entry_point: "eval_entry_point",
+ 8: "fetch_event_handler",
+ fetch_event_handler: "fetch_event_handler"
+ }
export enum ResolveMode {
disable = 1,
lazy = 2,
@@ -132,13 +195,13 @@ type uint32 = number;
2: "fail",
fail: "fail"
}
- export enum MessageKind {
+ export enum MessageLevel {
err = 1,
warn = 2,
note = 3,
debug = 4
}
- export const MessageKindKeys = {
+ export const MessageLevelKeys = {
1: "err",
err: "err",
2: "warn",
@@ -193,6 +256,62 @@ type uint32 = number;
2: "manifest",
manifest: "manifest"
}
+ export interface StackFrame {
+ function_name: string;
+ file: string;
+ position: StackFramePosition;
+ scope: StackFrameScope;
+ }
+
+ export interface StackFramePosition {
+ source_offset: int32;
+ line: int32;
+ line_start: int32;
+ line_stop: int32;
+ column_start: int32;
+ column_stop: int32;
+ expression_start: int32;
+ expression_stop: int32;
+ }
+
+ export interface SourceLine {
+ line: int32;
+ text: string;
+ }
+
+ export interface StackTrace {
+ source_lines: SourceLine[];
+ frames: StackFrame[];
+ }
+
+ export interface JSException {
+ name?: string;
+ message?: string;
+ runtime_type?: uint16;
+ code?: uint8;
+ stack?: StackTrace;
+ }
+
+ export interface Problems {
+ code: uint16;
+ name: string;
+ exceptions: JSException[];
+ build: Log;
+ }
+
+ export interface Router {
+ routes: string[];
+ route: int32;
+ params: StringMap;
+ }
+
+ export interface FallbackMessageContainer {
+ message?: string;
+ router?: Router;
+ reason?: FallbackStep;
+ problems?: Problems;
+ }
+
export interface JSX {
factory: string;
runtime: JSXRuntime;
@@ -275,20 +394,34 @@ type uint32 = number;
export interface FrameworkConfig {
package?: string;
- client?: string;
- server?: string;
+ client?: FrameworkEntryPointMessage;
+ server?: FrameworkEntryPointMessage;
+ fallback?: FrameworkEntryPointMessage;
development?: boolean;
- client_env?: EnvConfig;
- server_env?: EnvConfig;
client_css_in_js?: CSSInJSBehavior;
}
+ export interface FrameworkEntryPoint {
+ kind: FrameworkEntryPointType;
+ path: string;
+ env: LoadedEnvConfig;
+ }
+
+ export interface FrameworkEntryPointMap {
+ client?: FrameworkEntryPoint;
+ server?: FrameworkEntryPoint;
+ fallback?: FrameworkEntryPoint;
+ }
+
+ export interface FrameworkEntryPointMessage {
+ path?: string;
+ env?: EnvConfig;
+ }
+
export interface LoadedFramework {
- entry_point: string;
package: string;
development: boolean;
- client: boolean;
- env: LoadedEnvConfig;
+ entry_points: FrameworkEntryPointMap;
client_css_in_js: CSSInJSBehavior;
}
@@ -372,10 +505,16 @@ type uint32 = number;
location?: Location;
}
+ export interface MessageMeta {
+ resolve?: string;
+ build?: boolean;
+ }
+
export interface Message {
- kind: MessageKind;
+ level: MessageLevel;
data: MessageData;
notes: MessageData[];
+ on: MessageMeta;
}
export interface Log {
@@ -461,6 +600,22 @@ type uint32 = number;
log: Log;
}
+ export declare function encodeStackFrame(message: StackFrame, bb: ByteBuffer): void;
+ export declare function decodeStackFrame(buffer: ByteBuffer): StackFrame;
+ export declare function encodeStackFramePosition(message: StackFramePosition, bb: ByteBuffer): void;
+ export declare function decodeStackFramePosition(buffer: ByteBuffer): StackFramePosition;
+ export declare function encodeSourceLine(message: SourceLine, bb: ByteBuffer): void;
+ export declare function decodeSourceLine(buffer: ByteBuffer): SourceLine;
+ export declare function encodeStackTrace(message: StackTrace, bb: ByteBuffer): void;
+ export declare function decodeStackTrace(buffer: ByteBuffer): StackTrace;
+ export declare function encodeJSException(message: JSException, bb: ByteBuffer): void;
+ export declare function decodeJSException(buffer: ByteBuffer): JSException;
+ export declare function encodeProblems(message: Problems, bb: ByteBuffer): void;
+ export declare function decodeProblems(buffer: ByteBuffer): Problems;
+ export declare function encodeRouter(message: Router, bb: ByteBuffer): void;
+ export declare function decodeRouter(buffer: ByteBuffer): Router;
+ export declare function encodeFallbackMessageContainer(message: FallbackMessageContainer, bb: ByteBuffer): void;
+ export declare function decodeFallbackMessageContainer(buffer: ByteBuffer): FallbackMessageContainer;
export declare function encodeJSX(message: JSX, bb: ByteBuffer): void;
export declare function decodeJSX(buffer: ByteBuffer): JSX;
export declare function encodeStringPointer(message: StringPointer, bb: ByteBuffer): void;
@@ -487,6 +642,12 @@ type uint32 = number;
export declare function decodeLoadedEnvConfig(buffer: ByteBuffer): LoadedEnvConfig;
export declare function encodeFrameworkConfig(message: FrameworkConfig, bb: ByteBuffer): void;
export declare function decodeFrameworkConfig(buffer: ByteBuffer): FrameworkConfig;
+ export declare function encodeFrameworkEntryPoint(message: FrameworkEntryPoint, bb: ByteBuffer): void;
+ export declare function decodeFrameworkEntryPoint(buffer: ByteBuffer): FrameworkEntryPoint;
+ export declare function encodeFrameworkEntryPointMap(message: FrameworkEntryPointMap, bb: ByteBuffer): void;
+ export declare function decodeFrameworkEntryPointMap(buffer: ByteBuffer): FrameworkEntryPointMap;
+ export declare function encodeFrameworkEntryPointMessage(message: FrameworkEntryPointMessage, bb: ByteBuffer): void;
+ export declare function decodeFrameworkEntryPointMessage(buffer: ByteBuffer): FrameworkEntryPointMessage;
export declare function encodeLoadedFramework(message: LoadedFramework, bb: ByteBuffer): void;
export declare function decodeLoadedFramework(buffer: ByteBuffer): LoadedFramework;
export declare function encodeLoadedRouteConfig(message: LoadedRouteConfig, bb: ByteBuffer): void;
@@ -507,6 +668,8 @@ type uint32 = number;
export declare function decodeLocation(buffer: ByteBuffer): Location;
export declare function encodeMessageData(message: MessageData, bb: ByteBuffer): void;
export declare function decodeMessageData(buffer: ByteBuffer): MessageData;
+ export declare function encodeMessageMeta(message: MessageMeta, bb: ByteBuffer): void;
+ export declare function decodeMessageMeta(buffer: ByteBuffer): MessageMeta;
export declare function encodeMessage(message: Message, bb: ByteBuffer): void;
export declare function decodeMessage(buffer: ByteBuffer): Message;
export declare function encodeLog(message: Log, bb: ByteBuffer): void;
diff --git a/src/api/schema.js b/src/api/schema.js
index 0ae493e20..73e7e20c7 100644
--- a/src/api/schema.js
+++ b/src/api/schema.js
@@ -30,6 +30,490 @@ const LoaderKeys = {
"file": "file",
"json": "json"
};
+const FrameworkEntryPointType = {
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "client": 1,
+ "server": 2,
+ "fallback": 3
+};
+const FrameworkEntryPointTypeKeys = {
+ "1": "client",
+ "2": "server",
+ "3": "fallback",
+ "client": "client",
+ "server": "server",
+ "fallback": "fallback"
+};
+const StackFrameScope = {
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "5": 5,
+ "6": 6,
+ "Eval": 1,
+ "Module": 2,
+ "Function": 3,
+ "Global": 4,
+ "Wasm": 5,
+ "Constructor": 6
+};
+const StackFrameScopeKeys = {
+ "1": "Eval",
+ "2": "Module",
+ "3": "Function",
+ "4": "Global",
+ "5": "Wasm",
+ "6": "Constructor",
+ "Eval": "Eval",
+ "Module": "Module",
+ "Function": "Function",
+ "Global": "Global",
+ "Wasm": "Wasm",
+ "Constructor": "Constructor"
+};
+
+function decodeStackFrame(bb) {
+ var result = {};
+
+ result["function_name"] = bb.readString();
+ result["file"] = bb.readString();
+ result["position"] = decodeStackFramePosition(bb);
+ result["scope"] = StackFrameScope[bb.readByte()];
+ return result;
+}
+
+function encodeStackFrame(message, bb) {
+
+ var value = message["function_name"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"function_name\"");
+ }
+
+ var value = message["file"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"file\"");
+ }
+
+ var value = message["position"];
+ if (value != null) {
+ encodeStackFramePosition(value, bb);
+ } else {
+ throw new Error("Missing required field \"position\"");
+ }
+
+ var value = message["scope"];
+ if (value != null) {
+ var encoded = StackFrameScope[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"StackFrameScope\"");
+bb.writeByte(encoded);
+ } else {
+ throw new Error("Missing required field \"scope\"");
+ }
+
+}
+
+function decodeStackFramePosition(bb) {
+ var result = {};
+
+ result["source_offset"] = bb.readInt32();
+ result["line"] = bb.readInt32();
+ result["line_start"] = bb.readInt32();
+ result["line_stop"] = bb.readInt32();
+ result["column_start"] = bb.readInt32();
+ result["column_stop"] = bb.readInt32();
+ result["expression_start"] = bb.readInt32();
+ result["expression_stop"] = bb.readInt32();
+ return result;
+}
+
+function encodeStackFramePosition(message, bb) {
+
+ var value = message["source_offset"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"source_offset\"");
+ }
+
+ var value = message["line"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"line\"");
+ }
+
+ var value = message["line_start"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"line_start\"");
+ }
+
+ var value = message["line_stop"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"line_stop\"");
+ }
+
+ var value = message["column_start"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"column_start\"");
+ }
+
+ var value = message["column_stop"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"column_stop\"");
+ }
+
+ var value = message["expression_start"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"expression_start\"");
+ }
+
+ var value = message["expression_stop"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"expression_stop\"");
+ }
+
+}
+
+function decodeSourceLine(bb) {
+ var result = {};
+
+ result["line"] = bb.readInt32();
+ result["text"] = bb.readString();
+ return result;
+}
+
+function encodeSourceLine(message, bb) {
+
+ var value = message["line"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"line\"");
+ }
+
+ var value = message["text"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"text\"");
+ }
+
+}
+
+function decodeStackTrace(bb) {
+ var result = {};
+
+ var length = bb.readVarUint();
+ var values = result["source_lines"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeSourceLine(bb);
+ var length = bb.readVarUint();
+ var values = result["frames"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeStackFrame(bb);
+ return result;
+}
+
+function encodeStackTrace(message, bb) {
+
+ var value = message["source_lines"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeSourceLine(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"source_lines\"");
+ }
+
+ var value = message["frames"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeStackFrame(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"frames\"");
+ }
+
+}
+
+function decodeJSException(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readByte()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["name"] = bb.readString();
+ break;
+
+ case 2:
+ result["message"] = bb.readString();
+ break;
+
+ case 3:
+ result["runtime_type"] = bb.readUint16();
+ break;
+
+ case 4:
+ result["code"] = bb.readByte();
+ break;
+
+ case 5:
+ result["stack"] = decodeStackTrace(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeJSException(message, bb) {
+
+ var value = message["name"];
+ if (value != null) {
+ bb.writeByte(1);
+ bb.writeString(value);
+ }
+
+ var value = message["message"];
+ if (value != null) {
+ bb.writeByte(2);
+ bb.writeString(value);
+ }
+
+ var value = message["runtime_type"];
+ if (value != null) {
+ bb.writeByte(3);
+ bb.writeUint16(value);
+ }
+
+ var value = message["code"];
+ if (value != null) {
+ bb.writeByte(4);
+ bb.writeByte(value);
+ }
+
+ var value = message["stack"];
+ if (value != null) {
+ bb.writeByte(5);
+ encodeStackTrace(value, bb);
+ }
+ bb.writeByte(0);
+
+}
+const FallbackStep = {
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "5": 5,
+ "6": 6,
+ "7": 7,
+ "8": 8,
+ "ssr_disabled": 1,
+ "create_vm": 2,
+ "configure_router": 3,
+ "configure_defines": 4,
+ "resolve_entry_point": 5,
+ "load_entry_point": 6,
+ "eval_entry_point": 7,
+ "fetch_event_handler": 8
+};
+const FallbackStepKeys = {
+ "1": "ssr_disabled",
+ "2": "create_vm",
+ "3": "configure_router",
+ "4": "configure_defines",
+ "5": "resolve_entry_point",
+ "6": "load_entry_point",
+ "7": "eval_entry_point",
+ "8": "fetch_event_handler",
+ "ssr_disabled": "ssr_disabled",
+ "create_vm": "create_vm",
+ "configure_router": "configure_router",
+ "configure_defines": "configure_defines",
+ "resolve_entry_point": "resolve_entry_point",
+ "load_entry_point": "load_entry_point",
+ "eval_entry_point": "eval_entry_point",
+ "fetch_event_handler": "fetch_event_handler"
+};
+
+function decodeProblems(bb) {
+ var result = {};
+
+ result["code"] = bb.readUint16();
+ result["name"] = bb.readString();
+ var length = bb.readVarUint();
+ var values = result["exceptions"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = decodeJSException(bb);
+ result["build"] = decodeLog(bb);
+ return result;
+}
+
+function encodeProblems(message, bb) {
+
+ var value = message["code"];
+ if (value != null) {
+ bb.writeUint16(value);
+ } else {
+ throw new Error("Missing required field \"code\"");
+ }
+
+ var value = message["name"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"name\"");
+ }
+
+ var value = message["exceptions"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ encodeJSException(value, bb);
+ }
+ } else {
+ throw new Error("Missing required field \"exceptions\"");
+ }
+
+ var value = message["build"];
+ if (value != null) {
+ encodeLog(value, bb);
+ } else {
+ throw new Error("Missing required field \"build\"");
+ }
+
+}
+
+function decodeRouter(bb) {
+ var result = {};
+
+ var length = bb.readVarUint();
+ var values = result["routes"] = Array(length);
+ for (var i = 0; i < length; i++) values[i] = bb.readString();
+ result["route"] = bb.readInt32();
+ result["params"] = decodeStringMap(bb);
+ return result;
+}
+
+function encodeRouter(message, bb) {
+
+ var value = message["routes"];
+ if (value != null) {
+ var values = value, n = values.length;
+ bb.writeVarUint(n);
+ for (var i = 0; i < n; i++) {
+ value = values[i];
+ bb.writeString(value);
+ }
+ } else {
+ throw new Error("Missing required field \"routes\"");
+ }
+
+ var value = message["route"];
+ if (value != null) {
+ bb.writeInt32(value);
+ } else {
+ throw new Error("Missing required field \"route\"");
+ }
+
+ var value = message["params"];
+ if (value != null) {
+ encodeStringMap(value, bb);
+ } else {
+ throw new Error("Missing required field \"params\"");
+ }
+
+}
+
+function decodeFallbackMessageContainer(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readByte()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["message"] = bb.readString();
+ break;
+
+ case 2:
+ result["router"] = decodeRouter(bb);
+ break;
+
+ case 3:
+ result["reason"] = FallbackStep[bb.readByte()];
+ break;
+
+ case 4:
+ result["problems"] = decodeProblems(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeFallbackMessageContainer(message, bb) {
+
+ var value = message["message"];
+ if (value != null) {
+ bb.writeByte(1);
+ bb.writeString(value);
+ }
+
+ var value = message["router"];
+ if (value != null) {
+ bb.writeByte(2);
+ encodeRouter(value, bb);
+ }
+
+ var value = message["reason"];
+ if (value != null) {
+ bb.writeByte(3);
+ var encoded = FallbackStep[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"FallbackStep\"");
+bb.writeByte(encoded);
+ }
+
+ var value = message["problems"];
+ if (value != null) {
+ bb.writeByte(4);
+ encodeProblems(value, bb);
+ }
+ bb.writeByte(0);
+
+}
const ResolveMode = {
"1": 1,
"2": 2,
@@ -709,26 +1193,22 @@ function decodeFrameworkConfig(bb) {
break;
case 2:
- result["client"] = bb.readString();
+ result["client"] = decodeFrameworkEntryPointMessage(bb);
break;
case 3:
- result["server"] = bb.readString();
+ result["server"] = decodeFrameworkEntryPointMessage(bb);
break;
case 4:
- result["development"] = !!bb.readByte();
+ result["fallback"] = decodeFrameworkEntryPointMessage(bb);
break;
case 5:
- result["client_env"] = decodeEnvConfig(bb);
+ result["development"] = !!bb.readByte();
break;
case 6:
- result["server_env"] = decodeEnvConfig(bb);
- break;
-
- case 7:
result["client_css_in_js"] = CSSInJSBehavior[bb.readByte()];
break;
@@ -749,36 +1229,30 @@ function encodeFrameworkConfig(message, bb) {
var value = message["client"];
if (value != null) {
bb.writeByte(2);
- bb.writeString(value);
+ encodeFrameworkEntryPointMessage(value, bb);
}
var value = message["server"];
if (value != null) {
bb.writeByte(3);
- bb.writeString(value);
+ encodeFrameworkEntryPointMessage(value, bb);
}
- var value = message["development"];
+ var value = message["fallback"];
if (value != null) {
bb.writeByte(4);
- bb.writeByte(value);
+ encodeFrameworkEntryPointMessage(value, bb);
}
- var value = message["client_env"];
+ var value = message["development"];
if (value != null) {
bb.writeByte(5);
- encodeEnvConfig(value, bb);
- }
-
- var value = message["server_env"];
- if (value != null) {
- bb.writeByte(6);
- encodeEnvConfig(value, bb);
+ bb.writeByte(value);
}
var value = message["client_css_in_js"];
if (value != null) {
- bb.writeByte(7);
+ bb.writeByte(6);
var encoded = CSSInJSBehavior[value];
if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"CSSInJSBehavior\"");
bb.writeByte(encoded);
@@ -787,53 +1261,161 @@ bb.writeByte(encoded);
}
-function decodeLoadedFramework(bb) {
+function decodeFrameworkEntryPoint(bb) {
var result = {};
- result["entry_point"] = bb.readString();
- result["package"] = bb.readString();
- result["development"] = !!bb.readByte();
- result["client"] = !!bb.readByte();
+ result["kind"] = FrameworkEntryPointType[bb.readByte()];
+ result["path"] = bb.readString();
result["env"] = decodeLoadedEnvConfig(bb);
- result["client_css_in_js"] = CSSInJSBehavior[bb.readByte()];
return result;
}
-function encodeLoadedFramework(message, bb) {
+function encodeFrameworkEntryPoint(message, bb) {
- var value = message["entry_point"];
+ var value = message["kind"];
if (value != null) {
- bb.writeString(value);
+ var encoded = FrameworkEntryPointType[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"FrameworkEntryPointType\"");
+bb.writeByte(encoded);
} else {
- throw new Error("Missing required field \"entry_point\"");
+ throw new Error("Missing required field \"kind\"");
}
- var value = message["package"];
+ var value = message["path"];
if (value != null) {
bb.writeString(value);
} else {
- throw new Error("Missing required field \"package\"");
+ throw new Error("Missing required field \"path\"");
}
- var value = message["development"];
+ var value = message["env"];
if (value != null) {
- bb.writeByte(value);
+ encodeLoadedEnvConfig(value, bb);
} else {
- throw new Error("Missing required field \"development\"");
+ throw new Error("Missing required field \"env\"");
+ }
+
+}
+
+function decodeFrameworkEntryPointMap(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readByte()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["client"] = decodeFrameworkEntryPoint(bb);
+ break;
+
+ case 2:
+ result["server"] = decodeFrameworkEntryPoint(bb);
+ break;
+
+ case 3:
+ result["fallback"] = decodeFrameworkEntryPoint(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
}
+}
+
+function encodeFrameworkEntryPointMap(message, bb) {
var value = message["client"];
if (value != null) {
+ bb.writeByte(1);
+ encodeFrameworkEntryPoint(value, bb);
+ }
+
+ var value = message["server"];
+ if (value != null) {
+ bb.writeByte(2);
+ encodeFrameworkEntryPoint(value, bb);
+ }
+
+ var value = message["fallback"];
+ if (value != null) {
+ bb.writeByte(3);
+ encodeFrameworkEntryPoint(value, bb);
+ }
+ bb.writeByte(0);
+
+}
+
+function decodeFrameworkEntryPointMessage(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readByte()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["path"] = bb.readString();
+ break;
+
+ case 2:
+ result["env"] = decodeEnvConfig(bb);
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeFrameworkEntryPointMessage(message, bb) {
+
+ var value = message["path"];
+ if (value != null) {
+ bb.writeByte(1);
+ bb.writeString(value);
+ }
+
+ var value = message["env"];
+ if (value != null) {
+ bb.writeByte(2);
+ encodeEnvConfig(value, bb);
+ }
+ bb.writeByte(0);
+
+}
+
+function decodeLoadedFramework(bb) {
+ var result = {};
+
+ result["package"] = bb.readString();
+ result["development"] = !!bb.readByte();
+ result["entry_points"] = decodeFrameworkEntryPointMap(bb);
+ result["client_css_in_js"] = CSSInJSBehavior[bb.readByte()];
+ return result;
+}
+
+function encodeLoadedFramework(message, bb) {
+
+ var value = message["package"];
+ if (value != null) {
+ bb.writeString(value);
+ } else {
+ throw new Error("Missing required field \"package\"");
+ }
+
+ var value = message["development"];
+ if (value != null) {
bb.writeByte(value);
} else {
- throw new Error("Missing required field \"client\"");
+ throw new Error("Missing required field \"development\"");
}
- var value = message["env"];
+ var value = message["entry_points"];
if (value != null) {
- encodeLoadedEnvConfig(value, bb);
+ encodeFrameworkEntryPointMap(value, bb);
} else {
- throw new Error("Missing required field \"env\"");
+ throw new Error("Missing required field \"entry_points\"");
}
var value = message["client_css_in_js"];
@@ -1449,7 +2031,7 @@ bb.writeVarUint(encoded);
}
}
-const MessageKind = {
+const MessageLevel = {
"1": 1,
"2": 2,
"3": 3,
@@ -1459,7 +2041,7 @@ const MessageKind = {
"note": 3,
"debug": 4
};
-const MessageKindKeys = {
+const MessageLevelKeys = {
"1": "err",
"2": "warn",
"3": "note",
@@ -1575,26 +2157,66 @@ function encodeMessageData(message, bb) {
}
+function decodeMessageMeta(bb) {
+ var result = {};
+
+ while (true) {
+ switch (bb.readByte()) {
+ case 0:
+ return result;
+
+ case 1:
+ result["resolve"] = bb.readString();
+ break;
+
+ case 2:
+ result["build"] = !!bb.readByte();
+ break;
+
+ default:
+ throw new Error("Attempted to parse invalid message");
+ }
+ }
+}
+
+function encodeMessageMeta(message, bb) {
+
+ var value = message["resolve"];
+ if (value != null) {
+ bb.writeByte(1);
+ bb.writeString(value);
+ }
+
+ var value = message["build"];
+ if (value != null) {
+ bb.writeByte(2);
+ bb.writeByte(value);
+ }
+ bb.writeByte(0);
+
+}
+
function decodeMessage(bb) {
var result = {};
- result["kind"] = MessageKind[bb.readVarUint()];
+ result["level"] = MessageLevel[bb.readVarUint()];
result["data"] = decodeMessageData(bb);
var length = bb.readVarUint();
var values = result["notes"] = Array(length);
for (var i = 0; i < length; i++) values[i] = decodeMessageData(bb);
+ result["on"] = decodeMessageMeta(bb);
return result;
}
function encodeMessage(message, bb) {
- var value = message["kind"];
+ var value = message["level"];
if (value != null) {
- var encoded = MessageKind[value];
-if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"MessageKind\"");
+ var encoded = MessageLevel[value];
+if (encoded === void 0) throw new Error("Invalid value " + JSON.stringify(value) + " for enum \"MessageLevel\"");
bb.writeVarUint(encoded);
} else {
- throw new Error("Missing required field \"kind\"");
+ throw new Error("Missing required field \"level\"");
}
var value = message["data"];
@@ -1616,6 +2238,13 @@ bb.writeVarUint(encoded);
throw new Error("Missing required field \"notes\"");
}
+ var value = message["on"];
+ if (value != null) {
+ encodeMessageMeta(value, bb);
+ } else {
+ throw new Error("Missing required field \"on\"");
+ }
+
}
function decodeLog(bb) {
@@ -2167,6 +2796,28 @@ bb.writeByte(encoded);
export { Loader }
export { LoaderKeys }
+export { FrameworkEntryPointType }
+export { FrameworkEntryPointTypeKeys }
+export { StackFrameScope }
+export { StackFrameScopeKeys }
+export { decodeStackFrame }
+export { encodeStackFrame }
+export { decodeStackFramePosition }
+export { encodeStackFramePosition }
+export { decodeSourceLine }
+export { encodeSourceLine }
+export { decodeStackTrace }
+export { encodeStackTrace }
+export { decodeJSException }
+export { encodeJSException }
+export { FallbackStep }
+export { FallbackStepKeys }
+export { decodeProblems }
+export { encodeProblems }
+export { decodeRouter }
+export { encodeRouter }
+export { decodeFallbackMessageContainer }
+export { encodeFallbackMessageContainer }
export { ResolveMode }
export { ResolveModeKeys }
export { Platform }
@@ -2207,6 +2858,12 @@ export { decodeLoadedEnvConfig }
export { encodeLoadedEnvConfig }
export { decodeFrameworkConfig }
export { encodeFrameworkConfig }
+export { decodeFrameworkEntryPoint }
+export { encodeFrameworkEntryPoint }
+export { decodeFrameworkEntryPointMap }
+export { encodeFrameworkEntryPointMap }
+export { decodeFrameworkEntryPointMessage }
+export { encodeFrameworkEntryPointMessage }
export { decodeLoadedFramework }
export { encodeLoadedFramework }
export { decodeLoadedRouteConfig }
@@ -2225,12 +2882,14 @@ export { decodeOutputFile }
export { encodeOutputFile }
export { decodeTransformResponse }
export { encodeTransformResponse }
-export { MessageKind }
-export { MessageKindKeys }
+export { MessageLevel }
+export { MessageLevelKeys }
export { decodeLocation }
export { encodeLocation }
export { decodeMessageData }
export { encodeMessageData }
+export { decodeMessageMeta }
+export { encodeMessageMeta }
export { decodeMessage }
export { encodeMessage }
export { decodeLog }
diff --git a/src/api/schema.peechy b/src/api/schema.peechy
index fd0b81fd2..3b7b2669e 100644
--- a/src/api/schema.peechy
+++ b/src/api/schema.peechy
@@ -10,6 +10,93 @@ smol Loader {
json = 7;
}
+smol FrameworkEntryPointType {
+ client = 1;
+ server = 2;
+ fallback = 3;
+}
+
+smol StackFrameScope {
+ Eval = 1;
+ Module = 2;
+ Function = 3;
+ Global = 4;
+ Wasm = 5;
+ Constructor = 6;
+}
+
+struct StackFrame {
+ string function_name;
+ string file;
+ StackFramePosition position;
+ StackFrameScope scope;
+}
+
+struct StackFramePosition {
+ int32 source_offset;
+ int32 line;
+ int32 line_start;
+ int32 line_stop;
+ int32 column_start;
+ int32 column_stop;
+ int32 expression_start;
+ int32 expression_stop;
+}
+
+struct SourceLine {
+ int32 line;
+ string text;
+}
+
+struct StackTrace {
+ SourceLine[] source_lines;
+ StackFrame[] frames;
+}
+
+
+message JSException {
+ string name = 1;
+ string message = 2;
+
+ uint16 runtime_type = 3;
+ uint8 code = 4;
+
+ StackTrace stack = 5;
+}
+
+smol FallbackStep {
+ ssr_disabled = 1;
+ create_vm = 2;
+ configure_router = 3;
+ configure_defines = 4;
+ resolve_entry_point = 5;
+ load_entry_point = 6;
+ eval_entry_point = 7;
+ fetch_event_handler = 8;
+}
+
+struct Problems {
+ uint16 code;
+ string name;
+
+ JSException[] exceptions;
+ Log build;
+}
+
+struct Router {
+ string[] routes;
+ int32 route;
+ StringMap params;
+}
+
+message FallbackMessageContainer {
+ string message = 1;
+ Router router = 2;
+ FallbackStep reason = 3;
+ Problems problems = 4;
+}
+
+
smol ResolveMode {
disable = 1;
lazy = 2;
@@ -161,22 +248,35 @@ struct LoadedEnvConfig {
message FrameworkConfig {
string package = 1;
- string client = 2;
- string server = 3;
- bool development = 4;
- EnvConfig client_env = 5;
- EnvConfig server_env = 6;
+ FrameworkEntryPointMessage client = 2;
+ FrameworkEntryPointMessage server = 3;
+ FrameworkEntryPointMessage fallback = 4;
+ bool development = 5;
+
+ CSSInJSBehavior client_css_in_js = 6;
+}
- CSSInJSBehavior client_css_in_js = 7;
+struct FrameworkEntryPoint {
+ FrameworkEntryPointType kind;
+ string path;
+ LoadedEnvConfig env;
+}
+
+message FrameworkEntryPointMap {
+ FrameworkEntryPoint client = 1;
+ FrameworkEntryPoint server = 2;
+ FrameworkEntryPoint fallback = 3;
+}
+
+message FrameworkEntryPointMessage {
+ string path = 1;
+ EnvConfig env = 2;
}
struct LoadedFramework {
- string entry_point;
string package;
bool development;
- bool client;
- LoadedEnvConfig env;
-
+ FrameworkEntryPointMap entry_points;
CSSInJSBehavior client_css_in_js;
}
@@ -264,7 +364,7 @@ struct TransformResponse {
Message[] errors;
}
-enum MessageKind {
+enum MessageLevel {
err = 1;
warn =2;
note = 3;
@@ -286,10 +386,18 @@ message MessageData {
Location location = 2;
}
+
+
+message MessageMeta {
+ string resolve = 1;
+ bool build = 2;
+}
+
struct Message {
- MessageKind kind;
+ MessageLevel level;
MessageData data;
MessageData[] notes;
+ MessageMeta on;
}
struct Log {
diff --git a/src/api/schema.zig b/src/api/schema.zig
index 639eeae98..bd0873540 100644
--- a/src/api/schema.zig
+++ b/src/api/schema.zig
@@ -1,3 +1,4 @@
+
const std = @import("std");
pub const Reader = struct {
@@ -281,1762 +282,2440 @@ 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,
- /// tsx
- tsx,
+pub const Api = struct {
- /// css
- css,
+pub const Loader = enum(u8) {
- /// file
- file,
+_none,
+ /// jsx
+ jsx,
- /// json
- json,
+ /// js
+ js,
- _,
+ /// ts
+ ts,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+ /// tsx
+ tsx,
- pub const ResolveMode = enum(u8) {
- _none,
- /// disable
- disable,
+ /// css
+ css,
- /// lazy
- lazy,
+ /// file
+ file,
- /// dev
- dev,
+ /// json
+ json,
- /// bundle
- bundle,
+_,
- _,
+ 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 Platform = enum(u8) {
- _none,
- /// browser
- browser,
+pub const FrameworkEntryPointType = enum(u8) {
- /// node
- node,
+_none,
+ /// client
+ client,
- /// bun
- bun,
+ /// server
+ server,
- _,
+ /// fallback
+ fallback,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+_,
- pub const CssInJsBehavior = enum(u8) {
- _none,
- /// facade
- facade,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
- /// facade_onimportcss
- facade_onimportcss,
+
+};
- /// auto_onimportcss
- auto_onimportcss,
+pub const StackFrameScope = enum(u8) {
- _,
+_none,
+ /// Eval
+ eval,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+ /// Module
+ module,
- pub const JsxRuntime = enum(u8) {
- _none,
- /// automatic
- automatic,
+ /// Function
+ function,
- /// classic
- classic,
+ /// Global
+ global,
- _,
+ /// Wasm
+ wasm,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+ /// Constructor
+ constructor,
- pub const Jsx = struct {
- /// factory
- factory: []const u8,
+_,
- /// runtime
- runtime: JsxRuntime,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
- /// fragment
- fragment: []const u8,
+
+};
- /// development
- development: bool = false,
+pub const StackFrame = struct {
+/// function_name
+function_name: []const u8,
- /// import_source
- import_source: []const u8,
+/// file
+file: []const u8,
- /// react_fast_refresh
- react_fast_refresh: bool = false,
+/// position
+position: StackFramePosition,
- pub fn decode(reader: anytype) anyerror!Jsx {
- var this = std.mem.zeroes(Jsx);
+/// scope
+scope: StackFrameScope,
- 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 decode(reader: anytype) anyerror!StackFrame {
+ var this = std.mem.zeroes(StackFrame);
- pub const StringPointer = packed struct {
- /// offset
- offset: u32 = 0,
+ this.function_name = try reader.readValue([]const u8);
+ this.file = try reader.readValue([]const u8);
+ this.position = try reader.readValue(StackFramePosition);
+ this.scope = try reader.readValue(StackFrameScope);
+ return this;
+}
- /// length
- length: u32 = 0,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.function_name);
+ try writer.writeValue(this.file);
+ try writer.writeValue(this.position);
+ try writer.writeEnum(this.scope);
+}
- pub fn decode(reader: anytype) anyerror!StringPointer {
- var this = std.mem.zeroes(StringPointer);
+};
- this.offset = try reader.readValue(u32);
- this.length = try reader.readValue(u32);
- return this;
- }
+pub const StackFramePosition = packed struct {
+/// source_offset
+source_offset: i32 = 0,
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.offset);
- try writer.writeInt(this.length);
- }
- };
+/// line
+line: i32 = 0,
- pub const JavascriptBundledModule = struct {
- /// path
- path: StringPointer,
+/// line_start
+line_start: i32 = 0,
- /// code
- code: StringPointer,
+/// line_stop
+line_stop: i32 = 0,
- /// package_id
- package_id: u32 = 0,
+/// column_start
+column_start: i32 = 0,
- /// id
- id: u32 = 0,
+/// column_stop
+column_stop: i32 = 0,
- /// path_extname_length
- path_extname_length: u8 = 0,
+/// expression_start
+expression_start: i32 = 0,
- pub fn decode(reader: anytype) anyerror!JavascriptBundledModule {
- var this = std.mem.zeroes(JavascriptBundledModule);
+/// expression_stop
+expression_stop: i32 = 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;
- }
- 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);
- }
- };
+pub fn decode(reader: anytype) anyerror!StackFramePosition {
+ var this = std.mem.zeroes(StackFramePosition);
- pub const JavascriptBundledPackage = struct {
- /// name
- name: StringPointer,
+ this.source_offset = try reader.readValue(i32);
+ this.line = try reader.readValue(i32);
+ this.line_start = try reader.readValue(i32);
+ this.line_stop = try reader.readValue(i32);
+ this.column_start = try reader.readValue(i32);
+ this.column_stop = try reader.readValue(i32);
+ this.expression_start = try reader.readValue(i32);
+ this.expression_stop = try reader.readValue(i32);
+ return this;
+}
- /// version
- version: StringPointer,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.source_offset);
+ try writer.writeInt(this.line);
+ try writer.writeInt(this.line_start);
+ try writer.writeInt(this.line_stop);
+ try writer.writeInt(this.column_start);
+ try writer.writeInt(this.column_stop);
+ try writer.writeInt(this.expression_start);
+ try writer.writeInt(this.expression_stop);
+}
- /// hash
- hash: u32 = 0,
+};
- /// modules_offset
- modules_offset: u32 = 0,
+pub const SourceLine = struct {
+/// line
+line: i32 = 0,
- /// modules_length
- modules_length: u32 = 0,
+/// text
+text: []const u8,
- pub fn decode(reader: anytype) anyerror!JavascriptBundledPackage {
- var this = std.mem.zeroes(JavascriptBundledPackage);
- 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;
- }
+pub fn decode(reader: anytype) anyerror!SourceLine {
+ var this = std.mem.zeroes(SourceLine);
- 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);
- }
- };
+ this.line = try reader.readValue(i32);
+ this.text = try reader.readValue([]const u8);
+ return this;
+}
- pub const JavascriptBundle = struct {
- /// modules
- modules: []const JavascriptBundledModule,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.line);
+ try writer.writeValue(this.text);
+}
- /// packages
- packages: []const JavascriptBundledPackage,
+};
- /// etag
- etag: []const u8,
+pub const StackTrace = struct {
+/// source_lines
+source_lines: []const SourceLine,
- /// generated_at
- generated_at: u32 = 0,
+/// frames
+frames: []const StackFrame,
- /// 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!StackTrace {
+ var this = std.mem.zeroes(StackTrace);
- /// manifest_string
- manifest_string: []const u8,
+ this.source_lines = try reader.readArray(SourceLine);
+ this.frames = try reader.readArray(StackFrame);
+ 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(SourceLine, this.source_lines);
+ try writer.writeArray(StackFrame, this.frames);
+}
- 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 JsException = struct {
+/// name
+name: ?[]const u8 = null,
+
+/// message
+message: ?[]const u8 = null,
+
+/// runtime_type
+runtime_type: ?u16 = null,
+
+/// code
+code: ?u8 = null,
+
+/// stack
+stack: ?StackTrace = null,
+
+
+pub fn decode(reader: anytype) anyerror!JsException {
+ var this = std.mem.zeroes(JsException);
+
+ while(true) {
+ switch (try reader.readByte()) {
+ 0 => { return this; },
+
+ 1 => {
+ this.name = try reader.readValue([]const u8);
+},
+ 2 => {
+ this.message = try reader.readValue([]const u8);
+},
+ 3 => {
+ this.runtime_type = try reader.readValue(u16);
+},
+ 4 => {
+ this.code = try reader.readValue(u8);
+},
+ 5 => {
+ this.stack = try reader.readValue(StackTrace);
+},
+ 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.name) |name| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(name);
+}
+if (this.message) |message| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(message);
+}
+if (this.runtime_type) |runtime_type| {
+ try writer.writeFieldID(3);
+ try writer.writeInt(runtime_type);
+}
+if (this.code) |code| {
+ try writer.writeFieldID(4);
+ try writer.writeInt(code);
+}
+if (this.stack) |stack| {
+ try writer.writeFieldID(5);
+ try writer.writeValue(stack);
+}
+try writer.endMessage();
+}
- /// routes
- routes: ?LoadedRouteConfig = null,
+};
- /// framework
- framework: ?LoadedFramework = null,
+pub const FallbackStep = enum(u8) {
- /// bundle
- bundle: ?JavascriptBundle = null,
+_none,
+ /// ssr_disabled
+ ssr_disabled,
- /// code_length
- code_length: ?u32 = null,
+ /// create_vm
+ create_vm,
- pub fn decode(reader: anytype) anyerror!JavascriptBundleContainer {
- var this = std.mem.zeroes(JavascriptBundleContainer);
+ /// configure_router
+ configure_router,
- while (true) {
- switch (try reader.readByte()) {
- 0 => {
- return this;
- },
+ /// configure_defines
+ configure_defines,
- 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;
- },
+ /// resolve_entry_point
+ resolve_entry_point,
+
+ /// load_entry_point
+ load_entry_point,
+
+ /// eval_entry_point
+ eval_entry_point,
+
+ /// fetch_event_handler
+ fetch_event_handler,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- unreachable;
- }
- 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();
- }
- };
+
+};
- pub const ScanDependencyMode = enum(u8) {
- _none,
- /// app
- app,
+pub const Problems = struct {
+/// code
+code: u16 = 0,
- /// all
- all,
+/// name
+name: []const u8,
- _,
+/// exceptions
+exceptions: []const JsException,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+/// build
+build: Log,
- pub const ModuleImportType = enum(u8) {
- _none,
- /// import
- import,
- /// require
- require,
+pub fn decode(reader: anytype) anyerror!Problems {
+ var this = std.mem.zeroes(Problems);
- _,
+ this.code = try reader.readValue(u16);
+ this.name = try reader.readValue([]const u8);
+ this.exceptions = try reader.readArray(JsException);
+ this.build = try reader.readValue(Log);
+ 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.writeInt(this.code);
+ try writer.writeValue(this.name);
+ try writer.writeArray(JsException, this.exceptions);
+ try writer.writeValue(this.build);
+}
- pub const ModuleImportRecord = struct {
- /// kind
- kind: ModuleImportType,
+};
- /// path
- path: []const u8,
+pub const Router = struct {
+/// routes
+routes: []const []const u8,
- /// dynamic
- dynamic: bool = false,
+/// route
+route: i32 = 0,
- pub fn decode(reader: anytype) anyerror!ModuleImportRecord {
- var this = std.mem.zeroes(ModuleImportRecord);
+/// params
+params: StringMap,
- this.kind = try reader.readValue(ModuleImportType);
- this.path = try reader.readValue([]const u8);
- this.dynamic = try reader.readValue(bool);
- return this;
- }
- 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 fn decode(reader: anytype) anyerror!Router {
+ var this = std.mem.zeroes(Router);
- pub const Module = struct {
- /// path
- path: []const u8,
+ this.routes = try reader.readArray([]const u8);
+ this.route = try reader.readValue(i32);
+ this.params = try reader.readValue(StringMap);
+ return this;
+}
- /// imports
- imports: []const ModuleImportRecord,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray([]const u8, this.routes);
+ try writer.writeInt(this.route);
+ try writer.writeValue(this.params);
+}
- pub fn decode(reader: anytype) anyerror!Module {
- var this = std.mem.zeroes(Module);
+};
- this.path = try reader.readValue([]const u8);
- this.imports = try reader.readArray(ModuleImportRecord);
- return this;
- }
+pub const FallbackMessageContainer = struct {
+/// message
+message: ?[]const u8 = null,
+
+/// router
+router: ?Router = null,
+
+/// reason
+reason: ?FallbackStep = null,
+
+/// problems
+problems: ?Problems = null,
+
+
+pub fn decode(reader: anytype) anyerror!FallbackMessageContainer {
+ var this = std.mem.zeroes(FallbackMessageContainer);
+
+ while(true) {
+ switch (try reader.readByte()) {
+ 0 => { return this; },
+
+ 1 => {
+ this.message = try reader.readValue([]const u8);
+},
+ 2 => {
+ this.router = try reader.readValue(Router);
+},
+ 3 => {
+ this.reason = try reader.readValue(FallbackStep);
+},
+ 4 => {
+ this.problems = try reader.readValue(Problems);
+},
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+unreachable;
+}
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeValue(this.path);
- try writer.writeArray(ModuleImportRecord, this.imports);
- }
- };
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+if (this.message) |message| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(message);
+}
+if (this.router) |router| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(router);
+}
+if (this.reason) |reason| {
+ try writer.writeFieldID(3);
+ try writer.writeEnum(reason);
+}
+if (this.problems) |problems| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(problems);
+}
+try writer.endMessage();
+}
- pub const StringMap = struct {
- /// keys
- keys: []const []const u8,
+};
- /// values
- values: []const []const u8,
+pub const ResolveMode = enum(u8) {
- pub fn decode(reader: anytype) anyerror!StringMap {
- var this = std.mem.zeroes(StringMap);
+_none,
+ /// disable
+ disable,
- this.keys = try reader.readArray([]const u8);
- this.values = try reader.readArray([]const u8);
- return this;
- }
+ /// lazy
+ lazy,
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray([]const u8, this.keys);
- try writer.writeArray([]const u8, this.values);
- }
- };
+ /// dev
+ dev,
- pub const LoaderMap = struct {
- /// extensions
- extensions: []const []const u8,
+ /// bundle
+ bundle,
- /// loaders
- loaders: []const Loader,
+_,
- pub fn decode(reader: anytype) anyerror!LoaderMap {
- var this = std.mem.zeroes(LoaderMap);
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
- 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 const Platform = enum(u8) {
- pub const DotEnvBehavior = enum(u32) {
- _none,
- /// disable
- disable,
+_none,
+ /// browser
+ browser,
- /// prefix
- prefix,
+ /// node
+ node,
- /// load_all
- load_all,
+ /// bun
+ bun,
- _,
+_,
- 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 EnvConfig = struct {
- /// prefix
- prefix: ?[]const u8 = null,
+
+};
- /// defaults
- defaults: ?StringMap = null,
+pub const CssInJsBehavior = enum(u8) {
- pub fn decode(reader: anytype) anyerror!EnvConfig {
- var this = std.mem.zeroes(EnvConfig);
+_none,
+ /// facade
+ facade,
- while (true) {
- switch (try reader.readByte()) {
- 0 => {
- return this;
- },
+ /// facade_onimportcss
+ facade_onimportcss,
- 1 => {
- this.prefix = try reader.readValue([]const u8);
- },
- 2 => {
- this.defaults = try reader.readValue(StringMap);
- },
- else => {
- return error.InvalidMessage;
- },
+ /// auto_onimportcss
+ auto_onimportcss,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- 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,
+pub const JsxRuntime = enum(u8) {
- /// defaults
- defaults: StringMap,
+_none,
+ /// automatic
+ automatic,
- /// prefix
- prefix: []const u8,
+ /// classic
+ classic,
- 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 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.dotenv);
- try writer.writeValue(this.defaults);
- try writer.writeValue(this.prefix);
- }
- };
+
+};
- pub const FrameworkConfig = struct {
- /// package
- package: ?[]const u8 = null,
+pub const Jsx = struct {
+/// factory
+factory: []const u8,
- /// client
- client: ?[]const u8 = null,
+/// runtime
+runtime: JsxRuntime,
- /// server
- server: ?[]const u8 = null,
+/// fragment
+fragment: []const u8,
- /// development
- development: ?bool = null,
+/// development
+development: bool = false,
- /// client_env
- client_env: ?EnvConfig = null,
+/// import_source
+import_source: []const u8,
- /// server_env
- server_env: ?EnvConfig = null,
+/// react_fast_refresh
+react_fast_refresh: bool = false,
- /// client_css_in_js
- client_css_in_js: ?CssInJsBehavior = null,
- pub fn decode(reader: anytype) anyerror!FrameworkConfig {
- var this = std.mem.zeroes(FrameworkConfig);
+pub fn decode(reader: anytype) anyerror!Jsx {
+ var this = std.mem.zeroes(Jsx);
- while (true) {
- switch (try reader.readByte()) {
- 0 => {
- return this;
- },
+ 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;
+}
- 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;
- },
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.factory);
+ try writer.writeEnum(this.runtime);
+ try writer.writeValue(this.fragment);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.development)));
+ try writer.writeValue(this.import_source);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.react_fast_refresh)));
+}
+
+};
+
+pub const StringPointer = packed struct {
+/// offset
+offset: u32 = 0,
+
+/// length
+length: u32 = 0,
+
+
+pub fn decode(reader: anytype) anyerror!StringPointer {
+ var this = std.mem.zeroes(StringPointer);
+
+ 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 const JavascriptBundledModule = struct {
+/// path
+path: StringPointer,
+
+/// code
+code: StringPointer,
+
+/// package_id
+package_id: u32 = 0,
+
+/// id
+id: u32 = 0,
+
+/// path_extname_length
+path_extname_length: u8 = 0,
+
+
+pub fn decode(reader: anytype) anyerror!JavascriptBundledModule {
+ var this = std.mem.zeroes(JavascriptBundledModule);
+
+ 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;
+}
+
+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);
+}
+
+};
+
+pub const JavascriptBundledPackage = struct {
+/// name
+name: StringPointer,
+
+/// version
+version: StringPointer,
+
+/// hash
+hash: u32 = 0,
+
+/// modules_offset
+modules_offset: u32 = 0,
+
+/// modules_length
+modules_length: u32 = 0,
+
+
+pub fn decode(reader: anytype) anyerror!JavascriptBundledPackage {
+ var this = std.mem.zeroes(JavascriptBundledPackage);
+
+ 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;
+}
+
+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);
+}
+
+};
+
+pub const JavascriptBundle = struct {
+/// modules
+modules: []const JavascriptBundledModule,
+
+/// packages
+packages: []const JavascriptBundledPackage,
+
+/// etag
+etag: []const u8,
+
+/// generated_at
+generated_at: u32 = 0,
+
+/// app_package_json_dependencies_hash
+app_package_json_dependencies_hash: []const u8,
+
+/// import_from_name
+import_from_name: []const u8,
+
+/// manifest_string
+manifest_string: []const u8,
+
+
+pub fn decode(reader: anytype) anyerror!JavascriptBundle {
+ var this = std.mem.zeroes(JavascriptBundle);
+
+ this.modules = try reader.readArray(JavascriptBundledModule);
+ this.packages = try reader.readArray(JavascriptBundledPackage);
+ this.etag = try reader.readArray(u8);
+ this.generated_at = try reader.readValue(u32);
+ this.app_package_json_dependencies_hash = try reader.readArray(u8);
+ this.import_from_name = try reader.readArray(u8);
+ this.manifest_string = try reader.readArray(u8);
+ return this;
+}
+
+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 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();
+}
+
+};
+
+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);
}
- }
- 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 const ModuleImportType = enum(u8) {
- /// package
- package: []const u8,
+_none,
+ /// import
+ import,
- /// development
- development: bool = false,
+ /// require
+ require,
- /// client
- client: bool = false,
+_,
- /// env
- env: LoadedEnvConfig,
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
+ }
- /// client_css_in_js
- client_css_in_js: CssInJsBehavior,
+
+};
- pub fn decode(reader: anytype) anyerror!LoadedFramework {
- var this = std.mem.zeroes(LoadedFramework);
+pub const ModuleImportRecord = struct {
+/// kind
+kind: ModuleImportType,
- 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;
- }
+/// path
+path: []const u8,
- 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);
- }
- };
+/// dynamic
+dynamic: bool = false,
- pub const LoadedRouteConfig = struct {
- /// dir
- dir: []const u8,
- /// extensions
- extensions: []const []const u8,
+pub fn decode(reader: anytype) anyerror!ModuleImportRecord {
+ var this = std.mem.zeroes(ModuleImportRecord);
- /// static_dir
- static_dir: []const u8,
+ this.kind = try reader.readValue(ModuleImportType);
+ this.path = try reader.readValue([]const u8);
+ this.dynamic = try reader.readValue(bool);
+ return this;
+}
- /// asset_prefix
- asset_prefix: []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)));
+}
- 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 const Module = struct {
+/// path
+path: []const u8,
- 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);
- }
- };
+/// imports
+imports: []const ModuleImportRecord,
- pub const RouteConfig = struct {
- /// dir
- dir: []const []const u8,
- /// extensions
- extensions: []const []const u8,
+pub fn decode(reader: anytype) anyerror!Module {
+ var this = std.mem.zeroes(Module);
- /// static_dir
- static_dir: ?[]const u8 = null,
+ this.path = try reader.readValue([]const u8);
+ this.imports = try reader.readArray(ModuleImportRecord);
+ return this;
+}
- /// asset_prefix
- asset_prefix: ?[]const u8 = null,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.path);
+ try writer.writeArray(ModuleImportRecord, this.imports);
+}
- pub fn decode(reader: anytype) anyerror!RouteConfig {
- var this = std.mem.zeroes(RouteConfig);
+};
- while (true) {
- switch (try reader.readByte()) {
- 0 => {
- return this;
- },
+pub const StringMap = struct {
+/// keys
+keys: []const []const u8,
- 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;
- },
+/// values
+values: []const []const u8,
+
+
+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;
+}
+
+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 fn decode(reader: anytype) anyerror!LoaderMap {
+ var this = std.mem.zeroes(LoaderMap);
+
+ 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 const DotEnvBehavior = enum(u32) {
+
+_none,
+ /// disable
+ disable,
+
+ /// prefix
+ prefix,
+
+ /// load_all
+ load_all,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- unreachable;
- }
- 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();
- }
- };
+
+};
- pub const TransformOptions = struct {
- /// jsx
- jsx: ?Jsx = null,
+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;
+}
- /// tsconfig_override
- tsconfig_override: ?[]const u8 = null,
+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();
+}
- /// resolve
- resolve: ?ResolveMode = null,
+};
- /// origin
- origin: ?[]const u8 = null,
+pub const LoadedEnvConfig = struct {
+/// dotenv
+dotenv: DotEnvBehavior,
- /// absolute_working_dir
- absolute_working_dir: ?[]const u8 = null,
+/// defaults
+defaults: StringMap,
- /// define
- define: ?StringMap = null,
+/// prefix
+prefix: []const u8,
- /// preserve_symlinks
- preserve_symlinks: ?bool = null,
- /// entry_points
- entry_points: []const []const u8,
+pub fn decode(reader: anytype) anyerror!LoadedEnvConfig {
+ var this = std.mem.zeroes(LoadedEnvConfig);
- /// write
- write: ?bool = null,
+ this.dotenv = try reader.readValue(DotEnvBehavior);
+ this.defaults = try reader.readValue(StringMap);
+ this.prefix = try reader.readValue([]const u8);
+ return this;
+}
- /// inject
- inject: []const []const u8,
+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);
+}
- /// output_dir
- output_dir: ?[]const u8 = null,
+};
- /// external
- external: []const []const u8,
+pub const FrameworkConfig = struct {
+/// package
+package: ?[]const u8 = null,
+
+/// client
+client: ?FrameworkEntryPointMessage = null,
+
+/// server
+server: ?FrameworkEntryPointMessage = null,
+
+/// fallback
+fallback: ?FrameworkEntryPointMessage = null,
+
+/// development
+development: ?bool = 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(FrameworkEntryPointMessage);
+},
+ 3 => {
+ this.server = try reader.readValue(FrameworkEntryPointMessage);
+},
+ 4 => {
+ this.fallback = try reader.readValue(FrameworkEntryPointMessage);
+},
+ 5 => {
+ this.development = try reader.readValue(bool);
+},
+ 6 => {
+ this.client_css_in_js = try reader.readValue(CssInJsBehavior);
+},
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+unreachable;
+}
- /// loaders
- loaders: ?LoaderMap = null,
+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.fallback) |fallback| {
+ try writer.writeFieldID(4);
+ try writer.writeValue(fallback);
+}
+if (this.development) |development| {
+ try writer.writeFieldID(5);
+ try writer.writeInt(@intCast(u8, @boolToInt(development)));
+}
+if (this.client_css_in_js) |client_css_in_js| {
+ try writer.writeFieldID(6);
+ try writer.writeEnum(client_css_in_js);
+}
+try writer.endMessage();
+}
- /// main_fields
- main_fields: []const []const u8,
+};
- /// platform
- platform: ?Platform = null,
+pub const FrameworkEntryPoint = struct {
+/// kind
+kind: FrameworkEntryPointType,
- /// serve
- serve: ?bool = null,
+/// path
+path: []const u8,
- /// extension_order
- extension_order: []const []const u8,
+/// env
+env: LoadedEnvConfig,
- /// generate_node_module_bundle
- generate_node_module_bundle: ?bool = null,
- /// node_modules_bundle_path
- node_modules_bundle_path: ?[]const u8 = null,
+pub fn decode(reader: anytype) anyerror!FrameworkEntryPoint {
+ var this = std.mem.zeroes(FrameworkEntryPoint);
- /// node_modules_bundle_path_server
- node_modules_bundle_path_server: ?[]const u8 = null,
+ this.kind = try reader.readValue(FrameworkEntryPointType);
+ this.path = try reader.readValue([]const u8);
+ this.env = try reader.readValue(LoadedEnvConfig);
+ return this;
+}
- /// framework
- framework: ?FrameworkConfig = null,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.kind);
+ try writer.writeValue(this.path);
+ try writer.writeValue(this.env);
+}
- /// router
- router: ?RouteConfig = null,
+};
- /// no_summary
- no_summary: ?bool = null,
+pub const FrameworkEntryPointMap = struct {
+/// client
+client: ?FrameworkEntryPoint = null,
+
+/// server
+server: ?FrameworkEntryPoint = null,
+
+/// fallback
+fallback: ?FrameworkEntryPoint = null,
+
+
+pub fn decode(reader: anytype) anyerror!FrameworkEntryPointMap {
+ var this = std.mem.zeroes(FrameworkEntryPointMap);
+
+ while(true) {
+ switch (try reader.readByte()) {
+ 0 => { return this; },
+
+ 1 => {
+ this.client = try reader.readValue(FrameworkEntryPoint);
+},
+ 2 => {
+ this.server = try reader.readValue(FrameworkEntryPoint);
+},
+ 3 => {
+ this.fallback = try reader.readValue(FrameworkEntryPoint);
+},
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+unreachable;
+}
- pub fn decode(reader: anytype) anyerror!TransformOptions {
- var this = std.mem.zeroes(TransformOptions);
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+if (this.client) |client| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(client);
+}
+if (this.server) |server| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(server);
+}
+if (this.fallback) |fallback| {
+ try writer.writeFieldID(3);
+ try writer.writeValue(fallback);
+}
+try writer.endMessage();
+}
- 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;
- },
+pub const FrameworkEntryPointMessage = struct {
+/// path
+path: ?[]const u8 = null,
+
+/// env
+env: ?EnvConfig = null,
+
+
+pub fn decode(reader: anytype) anyerror!FrameworkEntryPointMessage {
+ var this = std.mem.zeroes(FrameworkEntryPointMessage);
+
+ while(true) {
+ switch (try reader.readByte()) {
+ 0 => { return this; },
+
+ 1 => {
+ this.path = try reader.readValue([]const u8);
+},
+ 2 => {
+ this.env = try reader.readValue(EnvConfig);
+},
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+unreachable;
+}
+
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+if (this.path) |path| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(path);
+}
+if (this.env) |env| {
+ try writer.writeFieldID(2);
+ try writer.writeValue(env);
+}
+try writer.endMessage();
+}
+
+};
+
+pub const LoadedFramework = struct {
+/// package
+package: []const u8,
+
+/// development
+development: bool = false,
+
+/// entry_points
+entry_points: FrameworkEntryPointMap,
+
+/// client_css_in_js
+client_css_in_js: CssInJsBehavior,
+
+
+pub fn decode(reader: anytype) anyerror!LoadedFramework {
+ var this = std.mem.zeroes(LoadedFramework);
+
+ this.package = try reader.readValue([]const u8);
+ this.development = try reader.readValue(bool);
+ this.entry_points = try reader.readValue(FrameworkEntryPointMap);
+ this.client_css_in_js = try reader.readValue(CssInJsBehavior);
+ return this;
+}
+
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeValue(this.package);
+ try writer.writeInt(@intCast(u8, @boolToInt(this.development)));
+ try writer.writeValue(this.entry_points);
+ try writer.writeEnum(this.client_css_in_js);
+}
+
+};
+
+pub const LoadedRouteConfig = struct {
+/// dir
+dir: []const u8,
+
+/// extensions
+extensions: []const []const u8,
+
+/// static_dir
+static_dir: []const u8,
+
+/// asset_prefix
+asset_prefix: []const u8,
+
+
+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 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 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;
+}
+
+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();
+}
+
+};
+
+pub const TransformOptions = struct {
+/// jsx
+jsx: ?Jsx = null,
+
+/// tsconfig_override
+tsconfig_override: ?[]const u8 = null,
+
+/// resolve
+resolve: ?ResolveMode = null,
+
+/// 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 {
+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 FileHandle = struct {
+/// path
+path: []const u8,
+
+/// size
+size: u32 = 0,
+
+/// fd
+fd: u32 = 0,
+
+
+pub fn decode(reader: anytype) anyerror!FileHandle {
+ var this = std.mem.zeroes(FileHandle);
+
+ 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 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;
+}
+
+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 const TransformResponseStatus = enum(u32) {
+
+_none,
+ /// success
+ success,
+
+ /// fail
+ fail,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- unreachable;
- }
- 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 FileHandle = struct {
- /// path
- path: []const u8,
+pub const OutputFile = struct {
+/// data
+data: []const u8,
- /// size
- size: u32 = 0,
+/// path
+path: []const u8,
- /// fd
- fd: u32 = 0,
- pub fn decode(reader: anytype) anyerror!FileHandle {
- var this = std.mem.zeroes(FileHandle);
+pub fn decode(reader: anytype) anyerror!OutputFile {
+ var this = std.mem.zeroes(OutputFile);
- this.path = try reader.readValue([]const u8);
- this.size = try reader.readValue(u32);
- this.fd = try reader.readValue(u32);
- return this;
- }
+ this.data = try reader.readArray(u8);
+ this.path = try reader.readValue([]const u8);
+ 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 encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u8, this.data);
+ try writer.writeValue(this.path);
+}
- pub const Transform = struct {
- /// handle
- handle: ?FileHandle = null,
+};
- /// path
- path: ?[]const u8 = null,
+pub const TransformResponse = struct {
+/// status
+status: TransformResponseStatus,
- /// contents
- contents: []const u8,
+/// files
+files: []const OutputFile,
- /// loader
- loader: ?Loader = null,
+/// errors
+errors: []const Message,
- /// options
- options: ?TransformOptions = null,
- pub fn decode(reader: anytype) anyerror!Transform {
- var this = std.mem.zeroes(Transform);
+pub fn decode(reader: anytype) anyerror!TransformResponse {
+ var this = std.mem.zeroes(TransformResponse);
- while (true) {
- switch (try reader.readByte()) {
- 0 => {
- return this;
- },
+ this.status = try reader.readValue(TransformResponseStatus);
+ this.files = try reader.readArray(OutputFile);
+ this.errors = try reader.readArray(Message);
+ 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;
- },
+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);
+}
+
+};
+
+pub const MessageLevel = enum(u32) {
+
+_none,
+ /// err
+ err,
+
+ /// warn
+ warn,
+
+ /// note
+ note,
+
+ /// debug
+ debug,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- unreachable;
- }
- 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 const TransformResponseStatus = enum(u32) {
- _none,
- /// success
- success,
+pub const Location = struct {
+/// file
+file: []const u8,
- /// fail
- fail,
+/// namespace
+namespace: []const u8,
- _,
+/// line
+line: i32 = 0,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+/// column
+column: i32 = 0,
- pub const OutputFile = struct {
- /// data
- data: []const u8,
+/// line_text
+line_text: []const u8,
- /// path
- path: []const u8,
+/// suggestion
+suggestion: []const u8,
- pub fn decode(reader: anytype) anyerror!OutputFile {
- var this = std.mem.zeroes(OutputFile);
+/// offset
+offset: u32 = 0,
- this.data = try reader.readArray(u8);
- this.path = try reader.readValue([]const u8);
- return this;
- }
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u8, this.data);
- try writer.writeValue(this.path);
- }
- };
+pub fn decode(reader: anytype) anyerror!Location {
+ var this = std.mem.zeroes(Location);
- pub const TransformResponse = struct {
- /// status
- status: TransformResponseStatus,
+ 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;
+}
- /// files
- files: []const OutputFile,
+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);
+}
- /// errors
- errors: []const Message,
+};
- pub fn decode(reader: anytype) anyerror!TransformResponse {
- var this = std.mem.zeroes(TransformResponse);
+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;
+}
- this.status = try reader.readValue(TransformResponseStatus);
- this.files = try reader.readArray(OutputFile);
- this.errors = try reader.readArray(Message);
- return this;
- }
+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 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);
- }
- };
+};
- pub const MessageKind = enum(u32) {
- _none,
- /// err
- err,
+pub const MessageMeta = struct {
+/// resolve
+resolve: ?[]const u8 = null,
+
+/// build
+build: ?bool = null,
+
+
+pub fn decode(reader: anytype) anyerror!MessageMeta {
+ var this = std.mem.zeroes(MessageMeta);
+
+ while(true) {
+ switch (try reader.readByte()) {
+ 0 => { return this; },
+
+ 1 => {
+ this.resolve = try reader.readValue([]const u8);
+},
+ 2 => {
+ this.build = try reader.readValue(bool);
+},
+ else => {
+ return error.InvalidMessage;
+ },
+ }
+ }
+unreachable;
+}
- /// warn
- warn,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+if (this.resolve) |resolve| {
+ try writer.writeFieldID(1);
+ try writer.writeValue(resolve);
+}
+if (this.build) |build| {
+ try writer.writeFieldID(2);
+ try writer.writeInt(@intCast(u8, @boolToInt(build)));
+}
+try writer.endMessage();
+}
- /// note
- note,
+};
- /// debug
- debug,
+pub const Message = struct {
+/// level
+level: MessageLevel,
- _,
+/// data
+data: MessageData,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+/// notes
+notes: []const MessageData,
- pub const Location = struct {
- /// file
- file: []const u8,
+/// on
+on: MessageMeta,
- /// namespace
- namespace: []const u8,
- /// line
- line: i32 = 0,
+pub fn decode(reader: anytype) anyerror!Message {
+ var this = std.mem.zeroes(Message);
- /// column
- column: i32 = 0,
+ this.level = try reader.readValue(MessageLevel);
+ this.data = try reader.readValue(MessageData);
+ this.notes = try reader.readArray(MessageData);
+ this.on = try reader.readValue(MessageMeta);
+ return this;
+}
- /// line_text
- line_text: []const u8,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.level);
+ try writer.writeValue(this.data);
+ try writer.writeArray(MessageData, this.notes);
+ try writer.writeValue(this.on);
+}
- /// suggestion
- suggestion: []const u8,
+};
- /// offset
- offset: u32 = 0,
+pub const Log = struct {
+/// warnings
+warnings: u32 = 0,
- pub fn decode(reader: anytype) anyerror!Location {
- var this = std.mem.zeroes(Location);
+/// errors
+errors: u32 = 0,
- 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;
- }
+/// msgs
+msgs: []const Message,
- 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 MessageData = struct {
- /// text
- text: ?[]const u8 = null,
+pub fn decode(reader: anytype) anyerror!Log {
+ var this = std.mem.zeroes(Log);
- /// location
- location: ?Location = null,
+ this.warnings = try reader.readValue(u32);
+ this.errors = try reader.readValue(u32);
+ this.msgs = try reader.readArray(Message);
+ return this;
+}
- pub fn decode(reader: anytype) anyerror!MessageData {
- var this = std.mem.zeroes(MessageData);
+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);
+}
- 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;
- },
+pub const Reloader = enum(u8) {
+
+_none,
+ /// disable
+ disable,
+
+ /// live
+ live,
+
+ /// fast_refresh
+ fast_refresh,
+
+_,
+
+ pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
+ return try std.json.stringify(@tagName(self), opts, o);
}
- }
- unreachable;
- }
- 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 const Message = struct {
- /// kind
- kind: MessageKind,
+pub const WebsocketMessageKind = enum(u8) {
- /// data
- data: MessageData,
+_none,
+ /// welcome
+ welcome,
- /// notes
- notes: []const MessageData,
+ /// file_change_notification
+ file_change_notification,
- pub fn decode(reader: anytype) anyerror!Message {
- var this = std.mem.zeroes(Message);
+ /// build_success
+ build_success,
- this.kind = try reader.readValue(MessageKind);
- this.data = try reader.readValue(MessageData);
- this.notes = try reader.readArray(MessageData);
- return this;
- }
+ /// build_fail
+ build_fail,
- 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);
- }
- };
+ /// manifest_success
+ manifest_success,
- pub const Log = struct {
- /// warnings
- warnings: u32 = 0,
+ /// manifest_fail
+ manifest_fail,
- /// errors
- errors: u32 = 0,
+_,
- /// msgs
- msgs: []const Message,
+ 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!Log {
- var this = std.mem.zeroes(Log);
+
+};
- this.warnings = try reader.readValue(u32);
- this.errors = try reader.readValue(u32);
- this.msgs = try reader.readArray(Message);
- return this;
- }
+pub const WebsocketCommandKind = enum(u8) {
- 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);
- }
- };
+_none,
+ /// build
+ build,
- pub const Reloader = enum(u8) {
- _none,
- /// disable
- disable,
+ /// manifest
+ manifest,
- /// live
- live,
+_,
- /// fast_refresh
- fast_refresh,
+ 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 WebsocketMessage = struct {
+/// timestamp
+timestamp: u32 = 0,
- pub const WebsocketMessageKind = enum(u8) {
- _none,
- /// welcome
- welcome,
+/// kind
+kind: WebsocketMessageKind,
- /// file_change_notification
- file_change_notification,
- /// build_success
- build_success,
+pub fn decode(reader: anytype) anyerror!WebsocketMessage {
+ var this = std.mem.zeroes(WebsocketMessage);
- /// build_fail
- build_fail,
+ this.timestamp = try reader.readValue(u32);
+ this.kind = try reader.readValue(WebsocketMessageKind);
+ return this;
+}
- /// manifest_success
- manifest_success,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.timestamp);
+ try writer.writeEnum(this.kind);
+}
- /// manifest_fail
- manifest_fail,
+};
- _,
+pub const WebsocketMessageWelcome = struct {
+/// epoch
+epoch: u32 = 0,
- pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void {
- return try std.json.stringify(@tagName(self), opts, o);
- }
- };
+/// javascriptReloader
+javascript_reloader: Reloader,
- pub const WebsocketCommandKind = enum(u8) {
- _none,
- /// build
- build,
- /// manifest
- manifest,
+pub fn decode(reader: anytype) anyerror!WebsocketMessageWelcome {
+ var this = std.mem.zeroes(WebsocketMessageWelcome);
- _,
+ this.epoch = try reader.readValue(u32);
+ this.javascript_reloader = try reader.readValue(Reloader);
+ 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.writeInt(this.epoch);
+ try writer.writeEnum(this.javascript_reloader);
+}
- pub const WebsocketMessage = struct {
- /// timestamp
- timestamp: u32 = 0,
+};
- /// kind
- kind: WebsocketMessageKind,
+pub const WebsocketMessageFileChangeNotification = struct {
+/// id
+id: u32 = 0,
- pub fn decode(reader: anytype) anyerror!WebsocketMessage {
- var this = std.mem.zeroes(WebsocketMessage);
+/// loader
+loader: Loader,
- this.timestamp = try reader.readValue(u32);
- this.kind = try reader.readValue(WebsocketMessageKind);
- return this;
- }
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.timestamp);
- try writer.writeEnum(this.kind);
- }
- };
+pub fn decode(reader: anytype) anyerror!WebsocketMessageFileChangeNotification {
+ var this = std.mem.zeroes(WebsocketMessageFileChangeNotification);
- pub const WebsocketMessageWelcome = struct {
- /// epoch
- epoch: u32 = 0,
+ this.id = try reader.readValue(u32);
+ this.loader = try reader.readValue(Loader);
+ return this;
+}
- /// javascriptReloader
- javascript_reloader: Reloader,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+ try writer.writeEnum(this.loader);
+}
- pub fn decode(reader: anytype) anyerror!WebsocketMessageWelcome {
- var this = std.mem.zeroes(WebsocketMessageWelcome);
+};
- this.epoch = try reader.readValue(u32);
- this.javascript_reloader = try reader.readValue(Reloader);
- return this;
- }
+pub const WebsocketCommand = struct {
+/// kind
+kind: WebsocketCommandKind,
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.epoch);
- try writer.writeEnum(this.javascript_reloader);
- }
- };
+/// timestamp
+timestamp: u32 = 0,
- pub const WebsocketMessageFileChangeNotification = struct {
- /// id
- id: u32 = 0,
- /// loader
- loader: Loader,
+pub fn decode(reader: anytype) anyerror!WebsocketCommand {
+ var this = std.mem.zeroes(WebsocketCommand);
- pub fn decode(reader: anytype) anyerror!WebsocketMessageFileChangeNotification {
- var this = std.mem.zeroes(WebsocketMessageFileChangeNotification);
+ this.kind = try reader.readValue(WebsocketCommandKind);
+ this.timestamp = try reader.readValue(u32);
+ return this;
+}
- this.id = try reader.readValue(u32);
- this.loader = try reader.readValue(Loader);
- return this;
- }
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeEnum(this.kind);
+ try writer.writeInt(this.timestamp);
+}
- 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 const WebsocketCommandBuild = packed struct {
+/// id
+id: u32 = 0,
- /// timestamp
- timestamp: u32 = 0,
- pub fn decode(reader: anytype) anyerror!WebsocketCommand {
- var this = std.mem.zeroes(WebsocketCommand);
+pub fn decode(reader: anytype) anyerror!WebsocketCommandBuild {
+ var this = std.mem.zeroes(WebsocketCommandBuild);
- this.kind = try reader.readValue(WebsocketCommandKind);
- this.timestamp = try reader.readValue(u32);
- return this;
- }
+ this.id = 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 fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+}
- pub const WebsocketCommandBuild = packed struct {
- /// id
- id: u32 = 0,
+};
- pub fn decode(reader: anytype) anyerror!WebsocketCommandBuild {
- var this = std.mem.zeroes(WebsocketCommandBuild);
+pub const WebsocketCommandManifest = packed struct {
+/// id
+id: u32 = 0,
- this.id = try reader.readValue(u32);
- return this;
- }
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- }
- };
+pub fn decode(reader: anytype) anyerror!WebsocketCommandManifest {
+ var this = std.mem.zeroes(WebsocketCommandManifest);
- pub const WebsocketCommandManifest = packed struct {
- /// id
- id: u32 = 0,
+ this.id = try reader.readValue(u32);
+ return this;
+}
- pub fn decode(reader: anytype) anyerror!WebsocketCommandManifest {
- var this = std.mem.zeroes(WebsocketCommandManifest);
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeInt(this.id);
+}
- this.id = try reader.readValue(u32);
- return this;
- }
+};
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeInt(this.id);
- }
- };
+pub const WebsocketMessageBuildSuccess = struct {
+/// id
+id: u32 = 0,
- pub const WebsocketMessageBuildSuccess = struct {
- /// id
- id: u32 = 0,
+/// from_timestamp
+from_timestamp: u32 = 0,
- /// from_timestamp
- from_timestamp: u32 = 0,
+/// loader
+loader: Loader,
- /// loader
- loader: Loader,
+/// module_path
+module_path: []const u8,
- /// module_path
- module_path: []const u8,
+/// blob_length
+blob_length: u32 = 0,
- /// blob_length
- blob_length: u32 = 0,
- pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildSuccess {
- var this = std.mem.zeroes(WebsocketMessageBuildSuccess);
+pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildSuccess {
+ var this = std.mem.zeroes(WebsocketMessageBuildSuccess);
- 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;
- }
+ 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 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 WebsocketMessageBuildFailure = struct {
- /// id
- id: u32 = 0,
+};
- /// from_timestamp
- from_timestamp: u32 = 0,
+pub const WebsocketMessageBuildFailure = struct {
+/// id
+id: u32 = 0,
- /// loader
- loader: Loader,
+/// from_timestamp
+from_timestamp: u32 = 0,
- /// module_path
- module_path: []const u8,
+/// loader
+loader: Loader,
- /// log
- log: Log,
+/// module_path
+module_path: []const u8,
- pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildFailure {
- var this = std.mem.zeroes(WebsocketMessageBuildFailure);
+/// log
+log: Log,
- 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);
- try writer.writeInt(this.from_timestamp);
- try writer.writeEnum(this.loader);
- try writer.writeValue(this.module_path);
- try writer.writeValue(this.log);
- }
- };
+pub fn decode(reader: anytype) anyerror!WebsocketMessageBuildFailure {
+ var this = std.mem.zeroes(WebsocketMessageBuildFailure);
- pub const DependencyManifest = struct {
- /// ids
- ids: []const u32,
+ 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 decode(reader: anytype) anyerror!DependencyManifest {
- var this = std.mem.zeroes(DependencyManifest);
+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);
+}
- this.ids = try reader.readArray(u32);
- return this;
- }
+};
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u32, this.ids);
- }
- };
+pub const DependencyManifest = struct {
+/// ids
+ids: []const u32,
- pub const FileList = struct {
- /// ptrs
- ptrs: []const StringPointer,
- /// files
- files: []const u8,
+pub fn decode(reader: anytype) anyerror!DependencyManifest {
+ var this = std.mem.zeroes(DependencyManifest);
- pub fn decode(reader: anytype) anyerror!FileList {
- var this = std.mem.zeroes(FileList);
+ this.ids = try reader.readArray(u32);
+ return this;
+}
- 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(u32, this.ids);
+}
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(StringPointer, this.ptrs);
- try writer.writeValue(this.files);
- }
- };
+};
- pub const WebsocketMessageResolveIDs = struct {
- /// id
- id: []const u32,
+pub const FileList = struct {
+/// ptrs
+ptrs: []const StringPointer,
- /// list
- list: FileList,
+/// files
+files: []const u8,
- 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 fn decode(reader: anytype) anyerror!FileList {
+ var this = std.mem.zeroes(FileList);
- pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
- try writer.writeArray(u32, this.id);
- try writer.writeValue(this.list);
- }
- };
+ this.ptrs = try reader.readArray(StringPointer);
+ this.files = try reader.readValue([]const u8);
+ return this;
+}
- pub const WebsocketCommandResolveIDs = struct {
- /// ptrs
- ptrs: []const StringPointer,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(StringPointer, this.ptrs);
+ try writer.writeValue(this.files);
+}
- /// files
- files: []const u8,
+};
- 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 const WebsocketMessageManifestSuccess = struct {
- /// id
- id: u32 = 0,
+pub fn decode(reader: anytype) anyerror!WebsocketMessageResolveIDs {
+ var this = std.mem.zeroes(WebsocketMessageResolveIDs);
- /// module_path
- module_path: []const u8,
+ this.id = try reader.readArray(u32);
+ this.list = try reader.readValue(FileList);
+ return this;
+}
- /// loader
- loader: Loader,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(u32, this.id);
+ try writer.writeValue(this.list);
+}
- /// manifest
- manifest: DependencyManifest,
+};
- pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestSuccess {
- var this = std.mem.zeroes(WebsocketMessageManifestSuccess);
+pub const WebsocketCommandResolveIDs = struct {
+/// ptrs
+ptrs: []const StringPointer,
- 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;
- }
+/// files
+files: []const u8,
- 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!WebsocketCommandResolveIDs {
+ var this = std.mem.zeroes(WebsocketCommandResolveIDs);
- /// from_timestamp
- from_timestamp: u32 = 0,
+ this.ptrs = try reader.readArray(StringPointer);
+ this.files = try reader.readValue([]const u8);
+ return this;
+}
- /// loader
- loader: Loader,
+pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
+ try writer.writeArray(StringPointer, this.ptrs);
+ try writer.writeValue(this.files);
+}
- /// log
- log: Log,
+};
- pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestFailure {
- var this = std.mem.zeroes(WebsocketMessageManifestFailure);
+pub const WebsocketMessageManifestSuccess = struct {
+/// id
+id: 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;
- }
+/// module_path
+module_path: []const u8,
+
+/// loader
+loader: Loader,
+
+/// manifest
+manifest: DependencyManifest,
+
+
+pub fn decode(reader: anytype) anyerror!WebsocketMessageManifestSuccess {
+ var this = std.mem.zeroes(WebsocketMessageManifestSuccess);
+
+ 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 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,
+
+/// from_timestamp
+from_timestamp: u32 = 0,
+
+/// loader
+loader: Loader,
+
+/// 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);
+}
- 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 483b5d09b..f308fc204 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -89,6 +89,7 @@ pub const ParseResult = struct {
loader: options.Loader,
ast: js_ast.Ast,
input_fd: ?StoredFileDescriptorType = null,
+ empty: bool = false,
};
pub fn NewBundler(cache_files: bool) type {
@@ -242,9 +243,9 @@ pub fn NewBundler(cache_files: bool) type {
if (this.options.framework) |framework| {
if (this.options.platform.isClient()) {
- try this.options.loadDefines(this.allocator, this.env, &framework.client_env);
+ try this.options.loadDefines(this.allocator, this.env, &framework.client.env);
} else {
- try this.options.loadDefines(this.allocator, this.env, &framework.server_env);
+ try this.options.loadDefines(this.allocator, this.env, &framework.server.env);
}
} else {
try this.options.loadDefines(this.allocator, this.env, &this.options.env);
@@ -268,9 +269,9 @@ pub fn NewBundler(cache_files: bool) type {
if (this.options.areDefinesUnset()) {
if (this.options.platform.isClient()) {
- this.options.env = framework.client_env;
+ this.options.env = framework.client.env;
} else {
- this.options.env = framework.server_env;
+ this.options.env = framework.server.env;
}
}
@@ -289,11 +290,15 @@ pub fn NewBundler(cache_files: bool) type {
if (this.options.framework != null) {
try this.configureFramework(true);
if (comptime client) {
- if (this.options.framework.?.client.len > 0) {
- return try this.resolver.resolve(this.fs.top_level_dir, this.options.framework.?.client, .stmt);
+ if (this.options.framework.?.client.isEnabled()) {
+ return try this.resolver.resolve(this.fs.top_level_dir, this.options.framework.?.client.path, .stmt);
+ }
+
+ if (this.options.framework.?.fallback.isEnabled()) {
+ return try this.resolver.resolve(this.fs.top_level_dir, this.options.framework.?.fallback.path, .stmt);
}
} else {
- if (this.options.framework.?.server.len > 0) {
+ if (this.options.framework.?.server.isEnabled()) {
return try this.resolver.resolve(this.fs.top_level_dir, this.options.framework.?.server, .stmt);
}
}
@@ -732,20 +737,38 @@ pub fn NewBundler(cache_files: bool) type {
if (framework_config) |conf| {
defer this.bundler.resetStore();
- if (conf.client) {
- if (bundler.configureFrameworkWithResolveResult(true)) |result_| {
- if (result_) |result| {
- try this.enqueueItem(result);
+ try this.bundler.configureFramework(true);
+ if (bundler.options.framework) |framework| {
+ if (bundler.options.platform == .bun) {
+ if (framework.server.isEnabled()) {
+ const resolved = try bundler.linker.resolver.resolve(
+ bundler.fs.top_level_dir,
+ framework.server.path,
+ .entry_point,
+ );
+ try this.enqueueItem(resolved);
}
- } else |err| {}
- } else {
- if (bundler.configureFrameworkWithResolveResult(false)) |result_| {
- if (result_) |result| {
- try this.enqueueItem(result);
+ } else {
+ if (framework.client.isEnabled()) {
+ const resolved = try bundler.linker.resolver.resolve(
+ bundler.fs.top_level_dir,
+ framework.client.path,
+ .entry_point,
+ );
+ try this.enqueueItem(resolved);
}
- } else |err| {}
+
+ if (framework.fallback.isEnabled()) {
+ const resolved = try bundler.linker.resolver.resolve(
+ bundler.fs.top_level_dir,
+ framework.fallback.path,
+ .entry_point,
+ );
+ try this.enqueueItem(resolved);
+ }
+ }
}
- }
+ } else {}
// Normally, this is automatic
// However, since we only do the parsing pass, it may not get imported automatically.
@@ -1537,7 +1560,12 @@ pub fn NewBundler(cache_files: bool) type {
file_path.pretty = allocator.dupe(u8, bundler.fs.relativeTo(file_path.text)) catch unreachable;
}
- bundler.setAllocator(allocator);
+ 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;
switch (loader) {
.css => {
@@ -1593,8 +1621,6 @@ pub fn NewBundler(cache_files: bool) type {
};
},
else => {
- var old_allocator = bundler.allocator;
- bundler.setAllocator(allocator);
var result = bundler.parse(
allocator,
file_path,
@@ -1604,14 +1630,16 @@ 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);
+
+ if (result.empty) {
+ return BuildResolveResultPair{ .written = 0, .input_fd = result.input_fd };
+ }
try bundler.linker.link(file_path, &result, import_path_format, false);
@@ -1838,7 +1866,7 @@ pub fn NewBundler(cache_files: bool) type {
dirname_fd: StoredFileDescriptorType,
file_descriptor: ?StoredFileDescriptorType,
file_hash: ?u32,
- client_entry_point_: ?*ClientEntryPoint,
+ client_entry_point_: anytype,
) ?ParseResult {
if (FeatureFlags.tracing) {
bundler.timer.start();
@@ -1854,20 +1882,26 @@ pub fn NewBundler(cache_files: bool) type {
const source: logger.Source = brk: {
if (client_entry_point_) |client_entry_point| {
- break :brk client_entry_point.source;
- } else {
- const entry = bundler.resolver.caches.fs.readFile(
- bundler.fs,
- path.text,
- dirname_fd,
- true,
- file_descriptor,
- ) catch return null;
- input_fd = entry.fd;
- break :brk logger.Source.initRecycledFile(Fs.File{ .path = path, .contents = entry.contents }, bundler.allocator) catch return null;
+ if (@hasField(std.meta.Child(@TypeOf(client_entry_point)), "source")) {
+ break :brk client_entry_point.source;
+ }
}
+
+ const entry = bundler.resolver.caches.fs.readFile(
+ bundler.fs,
+ path.text,
+ dirname_fd,
+ true,
+ file_descriptor,
+ ) catch return null;
+ input_fd = entry.fd;
+ break :brk logger.Source.initRecycledFile(Fs.File{ .path = path, .contents = entry.contents }, bundler.allocator) catch return null;
};
+ if (source.contents.len == 0 or (source.contents.len < 33 and std.mem.trim(u8, source.contents, "\n\r ").len == 0)) {
+ return ParseResult{ .source = source, .input_fd = input_fd, .loader = loader, .empty = true, .ast = js_ast.Ast.empty };
+ }
+
switch (loader) {
.js,
.jsx,
@@ -2140,7 +2174,7 @@ pub fn NewBundler(cache_files: bool) type {
if (load_from_routes) {
if (bundler.options.framework) |*framework| {
- if (framework.client.len > 0) {
+ if (framework.client.isEnabled()) {
did_start = true;
try switch (bundler.options.import_path_format) {
.relative => bundler.processResolveQueue(.relative, true, @TypeOf(outstream), outstream),
@@ -2171,7 +2205,7 @@ pub fn NewBundler(cache_files: bool) type {
if (load_from_routes) {
if (bundler.options.framework) |*framework| {
- if (framework.client.len > 0) {
+ if (framework.client.isEnabled()) {
did_start = true;
try switch (bundler.options.import_path_format) {
.relative => bundler.processResolveQueue(.relative, true, std.fs.Dir, output_dir),
@@ -2245,7 +2279,7 @@ pub fn NewBundler(cache_files: bool) type {
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, path.name, bundler.options.framework.?.client);
+ try client_entry_point.generate(ThisBundler, bundler, path.name, bundler.options.framework.?.client.path);
try bundler.virtual_modules.append(client_entry_point);
const entry_point_output_file = bundler.buildWithResolveResultEager(
@@ -2577,6 +2611,61 @@ pub const ServeResult = struct {
mime_type: MimeType,
};
+pub const FallbackEntryPoint = struct {
+ code_buffer: [8096]u8 = undefined,
+ path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
+ source: logger.Source = undefined,
+ built_code: string = "",
+
+ pub fn generate(
+ entry: *FallbackEntryPoint,
+ input_path: string,
+ comptime BundlerType: type,
+ bundler: *BundlerType,
+ ) !void {
+ // This is *extremely* naive.
+ // The basic idea here is this:
+ // --
+ // import * as EntryPoint from 'entry-point';
+ // import boot from 'framework';
+ // boot(EntryPoint);
+ // --
+ // We go through the steps of printing the code -- only to then parse/transpile it because
+ // we want it to go through the linker and the rest of the transpilation process
+
+ const dir_to_use: string = bundler.fs.top_level_dir;
+ const disable_css_imports = bundler.options.framework.?.client_css_in_js != .auto_onimportcss;
+
+ var code: string = undefined;
+
+ if (disable_css_imports) {
+ code = try std.fmt.bufPrint(
+ &entry.code_buffer,
+ \\globalThis.Bun_disableCSSImports = true;
+ \\import boot from '{s}';
+ \\boot(globalThis.__BUN_DATA__);
+ ,
+ .{
+ input_path,
+ },
+ );
+ } else {
+ code = try std.fmt.bufPrint(
+ &entry.code_buffer,
+ \\import boot from '{s}';
+ \\boot(globalThis.__BUN_DATA__);
+ ,
+ .{
+ input_path,
+ },
+ );
+ }
+
+ entry.source = logger.Source.initPathString(input_path, code);
+ entry.source.path.namespace = "fallback-entry";
+ }
+};
+
pub const ClientEntryPoint = struct {
code_buffer: [8096]u8 = undefined,
path_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
diff --git a/src/cli/bun_command.zig b/src/cli/bun_command.zig
index 1a63a140d..a3e56f82a 100644
--- a/src/cli/bun_command.zig
+++ b/src/cli/bun_command.zig
@@ -105,7 +105,7 @@ pub const BunCommand = struct {
};
var loaded_framework: ?Api.LoadedFramework = brk: {
if (this_bundler.options.framework) |*conf| {
- break :brk conf.toAPI(allocator, this_bundler.fs.top_level_dir, true);
+ break :brk try conf.toAPI(allocator, this_bundler.fs.top_level_dir);
}
break :brk null;
};
@@ -114,7 +114,7 @@ pub const BunCommand = struct {
var server_bundler_generator_thread: ?std.Thread = null;
var generated_server = false;
if (this_bundler.options.framework) |*framework| {
- if (framework.toAPI(allocator, this_bundler.fs.top_level_dir, false)) |_server_conf| {
+ if (framework.toAPI(allocator, this_bundler.fs.top_level_dir) catch null) |_server_conf| {
if (FeatureFlags.parallel_bun) {
wait_group.add();
server_bundler_generator_thread = try std.Thread.spawn(
diff --git a/src/fallback.html b/src/fallback.html
new file mode 100644
index 000000000..6d40584c3
--- /dev/null
+++ b/src/fallback.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <!-- prettier-ignore -->
+ <script id="__bunfallback" type="binary/peechy">{[blob]s}</script>
+ {[preload]s}
+ </head>
+ <body style="visibility: hidden"></body>
+
+ <!-- prettier-ignore -->
+ <script id='__bun_fallback_script' type="application/javascript">{[fallback]s}</script>
+
+ <!-- prettier-ignore -->
+ <script async type="module">{[entry_point]s}</script>
+</html>
diff --git a/src/fallback.ts b/src/fallback.ts
new file mode 100644
index 000000000..cf4195c4d
--- /dev/null
+++ b/src/fallback.ts
@@ -0,0 +1,24 @@
+import { ByteBuffer } from "peechy";
+import { FallbackStep } from "./api/schema";
+import {
+ decodeFallbackMessageContainer,
+ FallbackMessageContainer,
+} from "./api/schema";
+
+function getFallbackInfo(): FallbackMessageContainer {
+ var binary_string = window.atob(
+ document.querySelector("#__bunfallback").textContent.trim()
+ );
+ document.querySelector("#__bunfallback").remove();
+
+ var len = binary_string.length;
+ var bytes = new Uint8Array(len);
+ for (var i = 0; i < len; i++) {
+ bytes[i] = binary_string.charCodeAt(i);
+ }
+
+ return decodeFallbackMessageContainer(new ByteBuffer(bytes));
+}
+
+globalThis.__BUN_DATA__ = getFallbackInfo();
+document.getElementById("__bun_fallback_script")?.remove();
diff --git a/src/fallback.version b/src/fallback.version
new file mode 100644
index 000000000..3b2d7e4b9
--- /dev/null
+++ b/src/fallback.version
@@ -0,0 +1 @@
+8bf9555fd27e865d \ No newline at end of file
diff --git a/src/http.zig b/src/http.zig
index 27eba24ba..d70daf2e0 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -11,6 +11,7 @@ const bundler = @import("bundler.zig");
const logger = @import("logger.zig");
const Fs = @import("./fs.zig");
const Options = @import("./options.zig");
+const Fallback = @import("./runtime.zig").Fallback;
const Css = @import("css_scanner.zig");
const NodeModuleBundle = @import("./node_module_bundle.zig").NodeModuleBundle;
const resolve_path = @import("./resolver/resolve_path.zig");
@@ -162,6 +163,129 @@ pub const RequestContext = struct {
return null;
}
+ pub fn renderFallback(
+ this: *RequestContext,
+ allocator: *std.mem.Allocator,
+ bundler_: *Bundler,
+ step: Api.FallbackStep,
+ log: *logger.Log,
+ err: anyerror,
+ exceptions: []Api.JsException,
+ comptime fmt: string,
+ args: anytype,
+ ) !void {
+ var route_index: i32 = -1;
+ const routes: []const string = if (bundler_.router != null) brk: {
+ const router = &bundler_.router.?;
+ var list = try router.getEntryPointsWithBuffer(allocator, false);
+ break :brk list.entry_points;
+ } else &([_]string{});
+ var preload: string = "";
+
+ var params: Api.StringMap = std.mem.zeroes(Api.StringMap);
+ if (fallback_entry_point_created == false) {
+ defer fallback_entry_point_created = true;
+ defer bundler_.resetStore();
+
+ // You'd think: hey we're just importing a file
+ // Do we really need to run it through the transpiler and linking and printing?
+ // The answer, however, is yes.
+ // What if you're importing a fallback that's in node_modules?
+ try fallback_entry_point.generate(bundler_.options.framework.?.fallback.path, Bundler, bundler_);
+ if (bundler_.parse(
+ default_allocator,
+ fallback_entry_point.source.path,
+ .js,
+ 0,
+ null,
+ null,
+ @as(?*bundler.FallbackEntryPoint, &fallback_entry_point),
+ )) |*result| {
+ try bundler_.linker.link(fallback_entry_point.source.path, result, .absolute_url, false);
+ var buffer_writer = try js_printer.BufferWriter.init(default_allocator);
+ var writer = js_printer.BufferPrinter.init(buffer_writer);
+ _ = try bundler_.print(
+ result.*,
+ @TypeOf(&writer),
+ &writer,
+ .esm,
+ );
+ var slice = writer.ctx.buffer.toOwnedSliceLeaky();
+
+ fallback_entry_point.built_code = try default_allocator.dupe(u8, slice);
+
+ writer.ctx.buffer.deinit();
+ }
+ }
+
+ if (this.matched_route) |match| {
+ if (match.params.len > 0) {
+ var all = try allocator.alloc(string, match.params.len * 2);
+ var keys = all[0..match.params.len];
+ var values = all[match.params.len..];
+ var slice = match.params.slice();
+
+ var _keys: []Router.TinyPtr = slice.items(.key);
+ var _values: []Router.TinyPtr = slice.items(.value);
+
+ for (_keys) |key, i| {
+ keys[i] = key.str(match.name);
+ values[i] = _values[i].str(match.pathnameWithoutLeadingSlash());
+ }
+
+ params.keys = keys;
+ params.values = values;
+ }
+
+ for (routes) |route, i| {
+ var comparator = route;
+ if (comparator[0] == '/') comparator = comparator[1..];
+
+ if (this.bundler.router.?.config.asset_prefix_path.len > 0) {
+ comparator = comparator[this.bundler.router.?.config.asset_prefix_path.len..];
+ }
+
+ if (strings.endsWith(match.file_path, comparator)) {
+ route_index = @truncate(i32, @intCast(i64, i));
+ break;
+ }
+ }
+ }
+
+ var fallback_container = try allocator.create(Api.FallbackMessageContainer);
+ defer allocator.destroy(fallback_container);
+ fallback_container.* = Api.FallbackMessageContainer{
+ .message = try std.fmt.allocPrint(allocator, fmt, args),
+ .router = if (routes.len > 0) Api.Router{ .route = route_index, .params = params, .routes = routes } else null,
+ .reason = step,
+ .problems = Api.Problems{
+ .code = @truncate(u16, @errorToInt(err)),
+ .name = @errorName(err),
+ .exceptions = exceptions,
+ .build = try log.toAPI(allocator),
+ },
+ };
+
+ defer this.done();
+ try this.writeStatus(500);
+
+ this.appendHeader("Content-Type", MimeType.html.value);
+ var bb = std.ArrayList(u8).init(allocator);
+ defer bb.deinit();
+ var bb_writer = bb.writer();
+
+ try Fallback.render(
+ allocator,
+ fallback_container,
+ preload,
+ fallback_entry_point.built_code,
+ @TypeOf(bb_writer),
+ bb_writer,
+ );
+ try this.prepareToSendBody(bb.items.len, false);
+ try this.writeBodyBuf(bb.items);
+ }
+
fn matchPublicFolder(this: *RequestContext) ?bundler.ServeResult {
if (!this.bundler.options.routes.static_dir_enabled) return null;
const relative_path = this.url.path;
@@ -703,10 +827,134 @@ pub const RequestContext = struct {
args: Api.TransformOptions,
framework: Options.Framework,
existing_bundle: ?*NodeModuleBundle,
- log: ?*logger.Log = null,
+ log: *logger.Log = undefined,
watcher: *Watcher,
env_loader: *DotEnv.Loader,
origin: ZigURL,
+ client_bundler: Bundler,
+
+ pub fn handleJSError(
+ this: *HandlerThread,
+ comptime step: Api.FallbackStep,
+ err: anyerror,
+ ) !void {
+ return try this.handleJSErrorFmt(
+ step,
+ err,
+
+ "<r>JavaScript VM failed to start due to <red>{s}<r>.",
+ .{
+ @errorName(err),
+ },
+ );
+ }
+
+ pub fn handleJSErrorFmt(this: *HandlerThread, comptime step: Api.FallbackStep, err: anyerror, comptime fmt: string, args: anytype) !void {
+ var arena = std.heap.ArenaAllocator.init(default_allocator);
+ var allocator = &arena.allocator;
+ defer arena.deinit();
+
+ defer this.log.msgs.clearRetainingCapacity();
+
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter()) catch continue;
+ }
+ }
+
+ Output.prettyErrorln(fmt, args);
+ Output.flush();
+
+ while (channel.tryReadItem() catch null) |item| {
+ item.ctx.renderFallback(
+ allocator,
+ &this.client_bundler,
+ step,
+ this.log,
+ err,
+ &[_]Api.JsException{},
+ comptime Output.prettyFmt(fmt, false),
+ args,
+ ) catch {};
+ }
+ }
+
+ pub fn handleRuntimeJSError(this: *HandlerThread, js_value: JSValue, comptime step: Api.FallbackStep, comptime fmt: string, args: anytype) !void {
+ var arena = std.heap.ArenaAllocator.init(default_allocator);
+ var allocator = &arena.allocator;
+ defer arena.deinit();
+ defer this.log.msgs.clearRetainingCapacity();
+
+ var exception_list: std.ArrayList(Api.JsException) = std.ArrayList(Api.JsException).init(allocator);
+ defer exception_list.deinit();
+
+ if (!js_value.isUndefinedOrNull()) {
+ javascript_vm.?.defaultErrorHandler(
+ js_value,
+ &exception_list,
+ );
+ } else {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter()) catch continue;
+ }
+ }
+
+ Output.flush();
+ }
+
+ while (channel.tryReadItem() catch null) |item| {
+ item.ctx.renderFallback(
+ allocator,
+ &this.client_bundler,
+ step,
+ this.log,
+ error.JSError,
+ exception_list.items,
+ comptime Output.prettyFmt(fmt, false),
+ args,
+ ) catch {};
+ }
+ }
+
+ pub fn handleFetchEventError(this: *HandlerThread, err: anyerror, js_value: JSValue, ctx: *RequestContext) !void {
+ var arena = std.heap.ArenaAllocator.init(default_allocator);
+ var allocator = &arena.allocator;
+ defer arena.deinit();
+
+ defer this.log.msgs.clearRetainingCapacity();
+
+ var exception_list: std.ArrayList(Api.JsException) = std.ArrayList(Api.JsException).init(allocator);
+ defer exception_list.deinit();
+ var did_log_messages = false;
+ if (!js_value.isUndefinedOrNull()) {
+ var start_count = this.log.msgs.items.len;
+ javascript_vm.?.defaultErrorHandler(
+ js_value,
+ &exception_list,
+ );
+ did_log_messages = start_count != this.log.msgs.items.len and exception_list.items.len == 0;
+ } else {
+ if (this.log.msgs.items.len > 0) {
+ for (this.log.msgs.items) |msg| {
+ msg.writeFormat(Output.errorWriter()) catch continue;
+ }
+ }
+
+ Output.flush();
+ }
+
+ ctx.renderFallback(
+ allocator,
+ &this.client_bundler,
+ Api.FallbackStep.fetch_event_handler,
+ this.log,
+ if (did_log_messages) error.BuildTimeError else err,
+ exception_list.items,
+ "",
+ .{},
+ ) catch {};
+ }
};
pub const Channel = sync.Channel(*JavaScriptHandler, .{ .Static = 100 });
@@ -714,15 +962,14 @@ pub const RequestContext = struct {
var has_loaded_channel = false;
pub var javascript_disabled = false;
- pub fn spawnThread(handler: HandlerThread) !void {
+ pub fn spawnThread(handler: *HandlerThread) !void {
var thread = try std.Thread.spawn(.{}, spawn, .{handler});
thread.setName("WebSocket") catch {};
thread.detach();
}
- pub fn spawn(handler: HandlerThread) void {
- var _handler = handler;
- _spawn(&_handler) catch {};
+ pub fn spawn(handler: *HandlerThread) void {
+ _spawn(handler) catch {};
}
pub fn _spawn(handler: *HandlerThread) !void {
@@ -750,62 +997,49 @@ pub const RequestContext = struct {
handler.log,
handler.env_loader,
) catch |err| {
- Output.prettyErrorln(
- "JavaScript VM failed to start: <r><red>{s}<r>",
- .{@errorName(err)},
- );
- Output.flush();
+ handler.handleJSError(.create_vm, err) catch {};
return;
};
-
+ vm.bundler.log = handler.log;
std.debug.assert(JavaScript.VirtualMachine.vm_loaded);
javascript_vm = vm;
vm.bundler.options.origin = handler.origin;
- const boot = vm.bundler.options.framework.?.server;
+ const boot = vm.bundler.options.framework.?.server.path;
std.debug.assert(boot.len > 0);
errdefer vm.deinit();
vm.watcher = handler.watcher;
{
defer vm.flush();
- vm.bundler.configureRouter(false) catch {};
+ vm.bundler.configureRouter(false) catch |err| {
+ handler.handleJSError(.configure_router, err) catch {};
+ return;
+ };
vm.bundler.configureDefines() catch |err| {
- if (vm.log.msgs.items.len > 0) {
- for (vm.log.msgs.items) |msg| {
- msg.writeFormat(Output.errorWriter()) catch continue;
- }
- }
-
- Output.prettyErrorln(
- "<r>JavaScript VM failed to start due to <red>{s}<r>.",
- .{
- @errorName(err),
- },
- );
-
- Output.flush();
-
- if (channel.tryReadItem() catch null) |item| {
- item.ctx.sendInternalError(error.JSFailedToStart) catch {};
- }
+ handler.handleJSError(.configure_defines, err) catch {};
return;
};
var entry_point = boot;
if (!std.fs.path.isAbsolute(entry_point)) {
- const resolved_entry_point = try vm.bundler.resolver.resolve(
+ const resolved_entry_point = vm.bundler.resolver.resolve(
std.fs.path.dirname(boot) orelse vm.bundler.fs.top_level_dir,
vm.bundler.normalizeEntryPointPath(boot),
.entry_point,
- );
+ ) catch |err| {
+ try handler.handleJSError(
+ .resolve_entry_point,
+ err,
+ );
+ return;
+ };
entry_point = (resolved_entry_point.pathConst() orelse {
- Output.prettyErrorln(
+ handler.handleJSErrorFmt(
+ .resolve_entry_point,
+ error.EntryPointDisabled,
"<r>JavaScript VM failed to start due to disabled entry point: <r><b>\"{s}\"",
.{resolved_entry_point.path_pair.primary.text},
- );
+ ) catch {};
- if (channel.tryReadItem() catch null) |item| {
- item.ctx.sendInternalError(error.JSFailedToStart) catch {};
- }
return;
}).text;
}
@@ -813,42 +1047,38 @@ pub const RequestContext = struct {
var load_result = vm.loadEntryPoint(
entry_point,
) catch |err| {
- Output.prettyErrorln(
+ handler.handleJSErrorFmt(
+ .load_entry_point,
+ err,
"<r>JavaScript VM failed to start.\n<red>{s}:<r> while loading <r><b>\"{s}\"",
.{ @errorName(err), entry_point },
- );
+ ) catch {};
- if (channel.tryReadItem() catch null) |item| {
- item.ctx.sendInternalError(error.JSFailedToStart) catch {};
- item.ctx.arena.deinit();
- }
return;
};
switch (load_result.status(vm.global.vm())) {
JSPromise.Status.Fulfilled => {},
else => {
- Output.prettyErrorln(
- "JavaScript VM failed to start",
- .{},
- );
var result = load_result.result(vm.global.vm());
- vm.defaultErrorHandler(result);
-
- if (channel.tryReadItem() catch null) |item| {
- item.ctx.sendInternalError(error.JSFailedToStart) catch {};
- item.ctx.arena.deinit();
- }
+ handler.handleRuntimeJSError(
+ result,
+ .eval_entry_point,
+ "<r>JavaScript VM failed to start.\nwhile loading <r><b>\"{s}\"",
+ .{entry_point},
+ ) catch {};
return;
},
}
if (vm.event_listeners.count() == 0) {
- Output.prettyErrorln("<r><red>error<r>: Framework didn't run <b><cyan>addEventListener(\"fetch\", callback)<r>, which means it can't accept HTTP requests.\nShutting down JS.", .{});
- if (channel.tryReadItem() catch null) |item| {
- item.ctx.sendInternalError(error.JSFailedToStart) catch {};
- }
+ handler.handleJSErrorFmt(
+ .eval_entry_point,
+ error.MissingFetchHandler,
+ "<r><red>error<r>: Framework didn't run <b><cyan>addEventListener(\"fetch\", callback)<r>, which means it can't accept HTTP requests.\nShutting down JS.",
+ .{},
+ ) catch {};
return;
}
}
@@ -858,10 +1088,10 @@ pub const RequestContext = struct {
JavaScript.Bun.flushCSSImports();
vm.flush();
- try runLoop(vm);
+ try runLoop(vm, handler);
}
- pub fn runLoop(vm: *JavaScript.VirtualMachine) !void {
+ pub fn runLoop(vm: *JavaScript.VirtualMachine, thread: *HandlerThread) !void {
var module_map = ZigGlobalObject.getModuleRegistryMap(vm.global);
JavaScript.VirtualMachine.vm.has_loaded = true;
while (true) {
@@ -875,7 +1105,13 @@ pub const RequestContext = struct {
var handler: *JavaScriptHandler = try channel.readItem();
JavaScript.VirtualMachine.vm.preflush();
- try JavaScript.EventListenerMixin.emitFetchEvent(vm, &handler.ctx);
+ JavaScript.EventListenerMixin.emitFetchEvent(
+ vm,
+ &handler.ctx,
+ HandlerThread,
+ thread,
+ HandlerThread.handleFetchEventError,
+ ) catch |err| {};
}
}
@@ -899,36 +1135,43 @@ pub const RequestContext = struct {
std.mem.copy(u8, &clone.ctx.match_file_path_buf, filepath_buf[0..ctx.matched_route.?.file_path.len]);
if (!has_loaded_channel) {
+ var handler_thread = try server.allocator.create(HandlerThread);
+
has_loaded_channel = true;
channel = Channel.init();
var transform_options = server.transform_options;
if (server.transform_options.node_modules_bundle_path_server) |bundle_path| {
transform_options.node_modules_bundle_path = bundle_path;
transform_options.node_modules_bundle_path_server = null;
- try JavaScriptHandler.spawnThread(
- HandlerThread{
- .args = transform_options,
- .framework = server.bundler.options.framework.?,
- .existing_bundle = null,
- .log = &server.log,
- .watcher = server.watcher,
- .env_loader = server.bundler.env,
- .origin = server.bundler.options.origin,
- },
- );
+ handler_thread.* = HandlerThread{
+ .args = transform_options,
+ .framework = server.bundler.options.framework.?,
+ .existing_bundle = null,
+ .log = undefined,
+ .watcher = server.watcher,
+ .env_loader = server.bundler.env,
+ .origin = server.bundler.options.origin,
+ .client_bundler = server.bundler,
+ };
} else {
- try JavaScriptHandler.spawnThread(
- HandlerThread{
- .args = server.transform_options,
- .framework = server.bundler.options.framework.?,
- .existing_bundle = server.bundler.options.node_modules_bundle,
- .log = &server.log,
- .watcher = server.watcher,
- .env_loader = server.bundler.env,
- .origin = server.bundler.options.origin,
- },
- );
+ handler_thread.* = HandlerThread{
+ .args = server.transform_options,
+ .framework = server.bundler.options.framework.?,
+ .existing_bundle = server.bundler.options.node_modules_bundle,
+ .watcher = server.watcher,
+ .env_loader = server.bundler.env,
+ .log = undefined,
+ .origin = server.bundler.options.origin,
+ .client_bundler = server.bundler,
+ };
}
+
+ handler_thread.log = try server.allocator.create(logger.Log);
+ handler_thread.log.* = logger.Log.init(server.allocator);
+
+ try server.bundler.clone(server.allocator, &handler_thread.client_bundler);
+
+ try JavaScriptHandler.spawnThread(handler_thread);
}
defer ctx.controlled = true;
@@ -1335,6 +1578,8 @@ pub const RequestContext = struct {
}
threadlocal var client_entry_point: bundler.ClientEntryPoint = undefined;
+ threadlocal var fallback_entry_point: bundler.FallbackEntryPoint = undefined;
+ threadlocal var fallback_entry_point_created: bool = false;
pub fn renderServeResult(ctx: *RequestContext, result: bundler.ServeResult) !void {
if (ctx.keep_alive) {
@@ -1465,10 +1710,10 @@ pub const RequestContext = struct {
var client_entry_point_: ?*bundler.ClientEntryPoint = null;
if (resolve_result.import_kind == .entry_point and loader.supportsClientEntryPoint()) {
if (ctx.bundler.options.framework) |*framework| {
- if (framework.client.len > 0) {
+ if (framework.client.isEnabled()) {
client_entry_point = bundler.ClientEntryPoint{};
- try client_entry_point.generate(Bundler, ctx.bundler, path.name, framework.client);
+ try client_entry_point.generate(Bundler, ctx.bundler, path.name, framework.client.path);
client_entry_point_ = &client_entry_point;
}
}
@@ -1633,7 +1878,7 @@ pub const RequestContext = struct {
fn handleBlobURL(ctx: *RequestContext, server: *Server) !void {
var id = ctx.url.path["blob:".len..];
- // This lets us print
+ // This makes it Just Work if you pass a line/column number
if (strings.indexOfChar(id, ':')) |colon| {
id = id[0..colon];
}
@@ -1651,19 +1896,46 @@ pub const RequestContext = struct {
try ctx.writeBodyBuf(blob.ptr[0..blob.len]);
}
+ fn handleBunURL(ctx: *RequestContext, server: *Server) !void {
+ const path = ctx.url.path["bun:".len..];
+
+ if (strings.eqlComptime(path, "_api.hmr")) {
+ try ctx.handleWebsocket(server);
+ return;
+ }
+
+ if (strings.eqlComptime(path, "fallback")) {
+ const resolved = try ctx.bundler.resolver.resolve(ctx.bundler.fs.top_level_dir, ctx.bundler.options.framework.?.fallback.path, .stmt);
+ const resolved_path = resolved.pathConst() orelse return try ctx.sendNotFound();
+ const mime_type_ext = ctx.bundler.options.out_extensions.get(resolved_path.name.ext) orelse resolved_path.name.ext;
+ const loader = ctx.bundler.options.loader(resolved_path.name.ext);
+ try ctx.renderServeResult(bundler.ServeResult{
+ .file = Options.OutputFile.initPending(loader, resolved),
+ .mime_type = MimeType.byLoader(
+ loader,
+ mime_type_ext[1..],
+ ),
+ });
+ return;
+ }
+
+ try ctx.sendNotFound();
+ return;
+ }
+
pub fn handleReservedRoutes(ctx: *RequestContext, server: *Server) !bool {
if (strings.eqlComptime(ctx.url.extname, "bun") and ctx.bundler.options.node_modules_bundle != null) {
try ctx.sendJSB();
return true;
}
- if (strings.eqlComptime(ctx.url.path, "_api.hmr")) {
- try ctx.handleWebsocket(server);
+ if (ctx.url.path.len > "blob:".len and strings.eqlComptime(ctx.url.path[0.."blob:".len], "blob:")) {
+ try ctx.handleBlobURL(server);
return true;
}
- if (ctx.url.path.len > "blob:".len and strings.eqlComptime(ctx.url.path[0.."blob:".len], "blob:")) {
- try ctx.handleBlobURL(server);
+ if (ctx.url.path.len > "bun:".len and strings.eqlComptime(ctx.url.path[0.."bun:".len], "bun:")) {
+ try ctx.handleBunURL(server);
return true;
}
diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig
index 6a8c6328b..c6a6c2b88 100644
--- a/src/javascript/jsc/bindings/exports.zig
+++ b/src/javascript/jsc/bindings/exports.zig
@@ -5,6 +5,7 @@ const CAPI = @import("../JavaScriptCore.zig");
const JS = @import("../javascript.zig");
const JSBase = @import("../base.zig");
const ZigURL = @import("../../../query_string_map.zig").URL;
+const Api = @import("../../../api/schema.zig").Api;
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();
@@ -169,40 +170,6 @@ pub const ZigErrorType = extern struct {
}
};
-pub const JSErrorCode = enum(u8) {
- Error = 0,
- EvalError = 1,
- RangeError = 2,
- ReferenceError = 3,
- SyntaxError = 4,
- TypeError = 5,
- URIError = 6,
- AggregateError = 7,
-
- // StackOverflow & OutOfMemoryError is not an ErrorType in <JavaScriptCore/ErrorType.h> within JSC, so the number here is just totally made up
- OutOfMemoryError = 8,
- BundlerError = 252,
- StackOverflow = 253,
- UserErrorCode = 254,
- _,
-};
-
-pub const JSRuntimeType = enum(u16) {
- Nothing = 0x0,
- Function = 0x1,
- Undefined = 0x2,
- Null = 0x4,
- Boolean = 0x8,
- AnyInt = 0x10,
- Number = 0x20,
- String = 0x40,
- Object = 0x80,
- Symbol = 0x100,
- BigInt = 0x200,
-
- _,
-};
-
pub fn Errorable(comptime Type: type) type {
return extern struct {
result: Result,
@@ -251,6 +218,40 @@ pub const ResolvedSource = extern struct {
bytecodecache_fd: u64,
};
+pub const JSErrorCode = enum(u8) {
+ Error = 0,
+ EvalError = 1,
+ RangeError = 2,
+ ReferenceError = 3,
+ SyntaxError = 4,
+ TypeError = 5,
+ URIError = 6,
+ AggregateError = 7,
+
+ // StackOverflow & OutOfMemoryError is not an ErrorType in <JavaScriptCore/ErrorType.h> within JSC, so the number here is just totally made up
+ OutOfMemoryError = 8,
+ BundlerError = 252,
+ StackOverflow = 253,
+ UserErrorCode = 254,
+ _,
+};
+
+pub const JSRuntimeType = enum(u16) {
+ Nothing = 0x0,
+ Function = 0x1,
+ Undefined = 0x2,
+ Null = 0x4,
+ Boolean = 0x8,
+ AnyInt = 0x10,
+ Number = 0x20,
+ String = 0x40,
+ Object = 0x80,
+ Symbol = 0x100,
+ BigInt = 0x200,
+
+ _,
+};
+
pub const ZigStackFrameCode = enum(u8) {
None = 0,
// 🏃
@@ -301,6 +302,49 @@ pub const ZigStackTrace = extern struct {
frames_ptr: [*c]ZigStackFrame,
frames_len: u8,
+ pub fn toAPI(this: *const ZigStackTrace, allocator: *std.mem.Allocator) !Api.StackTrace {
+ var stack_trace: Api.StackTrace = std.mem.zeroes(Api.StackTrace);
+ {
+ var source_lines_iter = this.sourceLineIterator();
+
+ var source_line_len: usize = 0;
+ var count: usize = 0;
+ while (source_lines_iter.next()) |source| {
+ count += 1;
+ source_line_len += source.text.len;
+ }
+
+ if (count > 0 and source_line_len > 0) {
+ var source_lines = try allocator.alloc(Api.SourceLine, count);
+ var source_line_buf = try allocator.alloc(u8, source_line_len);
+ source_lines_iter = this.sourceLineIterator();
+ var remain_buf = source_line_buf[0..];
+ var i: usize = 0;
+ while (source_lines_iter.next()) |source| {
+ std.mem.copy(u8, remain_buf, source.text);
+ const copied_line = remain_buf[0..source.text.len];
+ remain_buf = remain_buf[source.text.len..];
+ source_lines[i] = .{ .text = copied_line, .line = source.line };
+ i += 1;
+ }
+ stack_trace.source_lines = source_lines;
+ }
+ }
+ {
+ var _frames = this.frames();
+ if (_frames.len > 0) {
+ var stack_frames = try allocator.alloc(Api.StackFrame, _frames.len);
+ stack_trace.frames = stack_frames;
+
+ for (_frames) |frame, i| {
+ stack_frames[i] = try frame.toAPI(allocator);
+ }
+ }
+ }
+
+ return stack_trace;
+ }
+
pub fn frames(this: *const ZigStackTrace) []const ZigStackFrame {
return this.frames_ptr[0..this.frames_len];
}
@@ -344,6 +388,34 @@ pub const ZigStackTrace = extern struct {
};
pub const ZigStackFrame = extern struct {
+ function_name: ZigString,
+ source_url: ZigString,
+ position: ZigStackFramePosition,
+ code_type: ZigStackFrameCode,
+
+ pub fn toAPI(this: *const ZigStackFrame, allocator: *std.mem.Allocator) !Api.StackFrame {
+ var frame: Api.StackFrame = std.mem.zeroes(Api.StackFrame);
+ if (this.function_name.len > 0) {
+ frame.function_name = try allocator.dupe(u8, this.function_name.slice());
+ }
+
+ if (this.source_url.len > 0) {
+ frame.file = try allocator.dupe(u8, this.source_url.slice());
+ }
+
+ frame.position.source_offset = this.position.source_offset;
+ frame.position.line = this.position.line;
+ frame.position.line_start = this.position.line_start;
+ frame.position.line_stop = this.position.line_stop;
+ frame.position.column_start = this.position.column_start;
+ frame.position.column_stop = this.position.column_stop;
+ frame.position.expression_start = this.position.expression_start;
+ frame.position.expression_stop = this.position.expression_stop;
+ frame.scope = @intToEnum(Api.StackFrameScope, @enumToInt(this.code_type));
+
+ return frame;
+ }
+
pub const SourceURLFormatter = struct {
source_url: ZigString,
position: ZigStackFramePosition,
@@ -415,11 +487,6 @@ pub const ZigStackFrame = extern struct {
.position = ZigStackFramePosition.Invalid,
};
- function_name: ZigString,
- source_url: ZigString,
- position: ZigStackFramePosition,
- code_type: ZigStackFrameCode,
-
pub fn nameFormatter(this: *const ZigStackFrame, comptime enable_color: bool) NameFormatter {
return NameFormatter{ .function_name = this.function_name, .code_type = this.code_type, .enable_color = enable_color };
}
@@ -455,10 +522,6 @@ pub const ZigStackFramePosition = extern struct {
};
pub const ZigException = extern struct {
- pub const shim = Shimmer("Zig", "Exception", @This());
- pub const name = "ZigException";
- pub const namespace = shim.namespace;
-
code: JSErrorCode,
runtime_type: JSRuntimeType,
name: ZigString,
@@ -467,6 +530,10 @@ pub const ZigException = extern struct {
exception: ?*c_void,
+ pub const shim = Shimmer("Zig", "Exception", @This());
+ pub const name = "ZigException";
+ pub const namespace = shim.namespace;
+
pub const Holder = extern struct {
const frame_count = 24;
const source_lines_count = 6;
@@ -529,6 +596,36 @@ pub const ZigException = extern struct {
return shim.cppFn("fromException", .{exception});
}
+ pub fn addToErrorList(this: *ZigException, error_list: *std.ArrayList(Api.JsException)) !void {
+ const _name: string = @field(this, "name").slice();
+ const message: string = @field(this, "message").slice();
+
+ var is_empty = true;
+ var api_exception = Api.JsException{
+ .runtime_type = @enumToInt(this.runtime_type),
+ .code = @enumToInt(this.code),
+ };
+
+ if (_name.len > 0) {
+ api_exception.name = try error_list.allocator.dupe(u8, _name);
+ is_empty = false;
+ }
+
+ if (message.len > 0) {
+ api_exception.message = try error_list.allocator.dupe(u8, message);
+ is_empty = false;
+ }
+
+ if (this.stack.frames_len > 0) {
+ api_exception.stack = try this.stack.toAPI(error_list.allocator);
+ is_empty = false;
+ }
+
+ if (!is_empty) {
+ try error_list.append(api_exception);
+ }
+ }
+
pub const Extern = [_][]const u8{"fromException"};
};
@@ -656,7 +753,7 @@ pub const ZigConsoleClient = struct {
switch (@intToEnum(CellType, value.asCell().getType())) {
CellType.ErrorInstanceType => {
- JS.VirtualMachine.printErrorlikeObject(JS.VirtualMachine.vm, value, null, enable_ansi_colors);
+ JS.VirtualMachine.printErrorlikeObject(JS.VirtualMachine.vm, value, null, null, enable_ansi_colors);
return;
},
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index fa942e4a2..8bace87e9 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -761,8 +761,10 @@ pub const VirtualMachine = struct {
return slice;
}
+
+ // This double prints
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
- VirtualMachine.vm.defaultErrorHandler(promise.result(global.vm()));
+ // VirtualMachine.vm.defaultErrorHandler(promise.result(global.vm()), null);
return JSValue.jsUndefined();
}
@@ -854,30 +856,52 @@ pub const VirtualMachine = struct {
// TODO:
pub fn deinit(this: *VirtualMachine) void {}
- pub fn printException(this: *VirtualMachine, exception: *Exception) void {
+ pub const ExceptionList = std.ArrayList(Api.JsException);
+
+ pub fn printException(this: *VirtualMachine, exception: *Exception, exception_list: ?*ExceptionList) void {
if (Output.enable_ansi_colors) {
- this.printErrorlikeObject(exception.value(), exception, true);
+ this.printErrorlikeObject(exception.value(), exception, exception_list, true);
} else {
- this.printErrorlikeObject(exception.value(), exception, false);
+ this.printErrorlikeObject(exception.value(), exception, exception_list, false);
}
}
- pub fn defaultErrorHandler(this: *VirtualMachine, result: JSValue) void {
+ pub fn defaultErrorHandler(this: *VirtualMachine, result: JSValue, exception_list: ?*ExceptionList) void {
if (result.isException(this.global.vm())) {
var exception = @ptrCast(*Exception, result.asVoid());
- this.printException(exception);
+ this.printException(exception, exception_list);
} else if (Output.enable_ansi_colors) {
- this.printErrorlikeObject(result, null, true);
+ this.printErrorlikeObject(result, null, exception_list, true);
} else {
- this.printErrorlikeObject(result, null, false);
+ this.printErrorlikeObject(result, null, exception_list, false);
}
}
pub fn loadEntryPoint(this: *VirtualMachine, entry_path: string) !*JSInternalPromise {
try this.entry_point.generate(@TypeOf(this.bundler), &this.bundler, Fs.PathName.init(entry_path), main_file_name);
this.main = entry_path;
- var promise = JSModuleLoader.loadAndEvaluateModule(this.global, ZigString.init(std.mem.span(main_file_name)));
+
+ var promise: *JSInternalPromise = undefined;
+ // We first import the node_modules bundle. This prevents any potential TDZ issues.
+ // The contents of the node_modules bundle are lazy, so hopefully this should be pretty quick.
+ if (this.node_modules != null) {
+ promise = JSModuleLoader.loadAndEvaluateModule(this.global, ZigString.init(std.mem.span(vm.bundler.linker.nodeModuleBundleImportPath())));
+
+ this.global.vm().drainMicrotasks();
+
+ while (promise.status(this.global.vm()) == JSPromise.Status.Pending) {
+ this.global.vm().drainMicrotasks();
+ }
+
+ if (promise.status(this.global.vm()) == JSPromise.Status.Rejected) {
+ return promise;
+ }
+
+ _ = promise.result(this.global.vm());
+ }
+
+ promise = JSModuleLoader.loadAndEvaluateModule(this.global, ZigString.init(std.mem.span(main_file_name)));
this.global.vm().drainMicrotasks();
@@ -896,14 +920,14 @@ pub const VirtualMachine = struct {
// In that case, this function becomes recursive.
// In all other cases, we will convert it to a ZigException.
const errors_property = ZigString.init("errors");
- pub fn printErrorlikeObject(this: *VirtualMachine, value: JSValue, exception: ?*Exception, comptime allow_ansi_color: bool) void {
+ pub fn printErrorlikeObject(this: *VirtualMachine, value: JSValue, exception: ?*Exception, exception_list: ?*ExceptionList, comptime allow_ansi_color: bool) void {
var was_internal = false;
defer {
if (was_internal) {
if (exception) |exception_| {
var holder = ZigException.Holder.init();
- var zig_exception = holder.zigException();
+ var zig_exception: *ZigException = holder.zigException();
exception_.getStackTrace(&zig_exception.stack);
if (zig_exception.stack.frames_len > 0) {
var buffered_writer = std.io.bufferedWriter(Output.errorWriter());
@@ -917,12 +941,17 @@ pub const VirtualMachine = struct {
buffered_writer.flush() catch {};
}
+
+ if (exception_list) |list| {
+ zig_exception.addToErrorList(list) catch {};
+ }
}
}
}
if (value.isAggregateError(this.global)) {
const AggregateErrorIterator = struct {
+ pub var current_exception_list: ?*ExceptionList = null;
pub fn iteratorWithColor(_vm: [*c]VM, globalObject: [*c]JSGlobalObject, nextValue: JSValue) callconv(.C) void {
iterator(_vm, globalObject, nextValue, true);
}
@@ -930,9 +959,11 @@ pub const VirtualMachine = struct {
iterator(_vm, globalObject, nextValue, false);
}
inline fn iterator(_vm: [*c]VM, globalObject: [*c]JSGlobalObject, nextValue: JSValue, comptime color: bool) void {
- VirtualMachine.vm.printErrorlikeObject(nextValue, null, color);
+ VirtualMachine.vm.printErrorlikeObject(nextValue, null, current_exception_list, color);
}
};
+ AggregateErrorIterator.current_exception_list = exception_list;
+ defer AggregateErrorIterator.current_exception_list = null;
if (comptime allow_ansi_color) {
value.getErrorsProperty(this.global).forEach(this.global, AggregateErrorIterator.iteratorWithColor);
} else {
@@ -943,34 +974,51 @@ pub const VirtualMachine = struct {
if (js.JSValueIsObject(vm.global.ref(), value.asRef())) {
if (js.JSObjectGetPrivate(value.asRef())) |priv| {
- was_internal = this.printErrorFromMaybePrivateData(priv, allow_ansi_color);
+ was_internal = this.printErrorFromMaybePrivateData(priv, exception_list, allow_ansi_color);
return;
}
}
- was_internal = this.printErrorFromMaybePrivateData(value.asRef(), allow_ansi_color);
+ was_internal = this.printErrorFromMaybePrivateData(value.asRef(), exception_list, allow_ansi_color);
}
- pub fn printErrorFromMaybePrivateData(this: *VirtualMachine, value: ?*c_void, comptime allow_ansi_color: bool) bool {
+ pub fn printErrorFromMaybePrivateData(this: *VirtualMachine, value: ?*c_void, exception_list: ?*ExceptionList, comptime allow_ansi_color: bool) bool {
const private_data_ptr = JSPrivateDataPtr.from(value);
switch (private_data_ptr.tag()) {
.BuildError => {
defer Output.flush();
- const build_error = private_data_ptr.as(BuildError);
- var writer = Output.errorWriter();
- build_error.msg.formatWriter(@TypeOf(writer), writer, allow_ansi_color) catch {};
+ var build_error = private_data_ptr.as(BuildError);
+ if (!build_error.logged) {
+ var writer = Output.errorWriter();
+ build_error.msg.formatWriter(@TypeOf(writer), writer, allow_ansi_color) catch {};
+ build_error.logged = true;
+ }
+ if (exception_list != null) {
+ this.log.addMsg(
+ build_error.msg,
+ ) catch {};
+ }
return true;
},
.ResolveError => {
defer Output.flush();
- const resolve_error = private_data_ptr.as(ResolveError);
- var writer = Output.errorWriter();
- resolve_error.msg.formatWriter(@TypeOf(writer), writer, allow_ansi_color) catch {};
+ var resolve_error = private_data_ptr.as(ResolveError);
+ if (!resolve_error.logged) {
+ var writer = Output.errorWriter();
+ resolve_error.msg.formatWriter(@TypeOf(writer), writer, allow_ansi_color) catch {};
+ resolve_error.logged = true;
+ }
+
+ if (exception_list != null) {
+ this.log.addMsg(
+ resolve_error.msg,
+ ) catch {};
+ }
return true;
},
else => {
- this.printErrorInstance(@intToEnum(JSValue, @intCast(i64, (@ptrToInt(value)))), allow_ansi_color) catch |err| {
+ this.printErrorInstance(@intToEnum(JSValue, @intCast(i64, (@ptrToInt(value)))), exception_list, allow_ansi_color) catch |err| {
if (comptime isDebug) {
// yo dawg
Output.printErrorln("Error while printing Error-like object: {s}", .{@errorName(err)});
@@ -1053,10 +1101,13 @@ pub const VirtualMachine = struct {
}
}
- pub fn printErrorInstance(this: *VirtualMachine, error_instance: JSValue, comptime allow_ansi_color: bool) !void {
+ pub fn printErrorInstance(this: *VirtualMachine, error_instance: JSValue, exception_list: ?*ExceptionList, comptime allow_ansi_color: bool) !void {
var exception_holder = ZigException.Holder.init();
var exception = exception_holder.zigException();
error_instance.toZigException(vm.global, exception);
+ if (exception_list) |list| {
+ try exception.addToErrorList(list);
+ }
var stderr: std.fs.File = Output.errorStream();
var buffered = std.io.bufferedWriter(stderr.writer());
@@ -1223,40 +1274,36 @@ pub const EventListenerMixin = struct {
}
};
- pub fn emitFetchEventError(
- request: *http.RequestContext,
- comptime fmt: string,
- args: anytype,
- ) void {
- Output.prettyErrorln(fmt, args);
- request.sendInternalError(error.FetchEventError) catch {};
- }
-
pub fn emitFetchEvent(
vm: *VirtualMachine,
request_context: *http.RequestContext,
+ comptime CtxType: type,
+ ctx: *CtxType,
+ comptime onError: fn (ctx: *CtxType, err: anyerror, value: JSValue, request_ctx: *http.RequestContext) anyerror!void,
) !void {
- var listeners = vm.event_listeners.get(EventType.fetch) orelse return emitFetchEventError(
- request_context,
- "Missing \"fetch\" handler. Did you run \"addEventListener(\"fetch\", (event) => {{}})\"?",
- .{},
- );
- if (listeners.items.len == 0) return emitFetchEventError(
- request_context,
- "Missing \"fetch\" handler. Did you run \"addEventListener(\"fetch\", (event) => {{}})\"?",
- .{},
- );
+ var listeners = vm.event_listeners.get(EventType.fetch) orelse (return onError(ctx, error.NoListeners, JSValue.jsUndefined(), request_context) catch {});
+ if (listeners.items.len == 0) return onError(ctx, error.NoListeners, JSValue.jsUndefined(), request_context) catch {};
+ const FetchEventRejectionHandler = struct {
+ pub fn onRejection(_ctx: *c_void, err: anyerror, fetch_event: *FetchEvent, value: JSValue) void {
+ onError(
+ @intToPtr(*CtxType, @ptrToInt(_ctx)),
+ err,
+ value,
+ fetch_event.request_context,
+ ) catch {};
+ }
+ };
// Rely on JS finalizer
var fetch_event = try vm.allocator.create(FetchEvent);
fetch_event.* = FetchEvent{
.request_context = request_context,
.request = Request{ .request_context = request_context },
+ .onPromiseRejectionCtx = @as(*c_void, ctx),
+ .onPromiseRejectionHandler = FetchEventRejectionHandler.onRejection,
};
var fetch_args: [1]js.JSObjectRef = undefined;
- var exception: ?*Exception = null;
- const failed_str = "Failed";
for (listeners.items) |listener_ref| {
var listener = @intToEnum(JSValue, @intCast(i64, @ptrToInt(listener_ref)));
@@ -1266,19 +1313,11 @@ pub const EventListenerMixin = struct {
var promise = JSPromise.resolvedPromise(vm.global, result);
vm.global.vm().drainMicrotasks();
+ if (fetch_event.rejected) return;
+
if (promise.status(vm.global.vm()) == .Rejected) {
- if (exception == null) {
- var res = promise.result(vm.global.vm());
- if (res.isException(vm.global.vm())) {
- exception = @ptrCast(*Exception, res.asVoid());
- } else {
- vm.defaultErrorHandler(res);
- if (!request_context.has_called_done) {
- request_context.sendInternalError(error.JavaScriptErrorNeedARealErrorPageSorryAboutThisSeeTheTerminal) catch {};
- }
- return;
- }
- }
+ onError(ctx, error.JSError, promise.result(vm.global.vm()), request_context) catch {};
+ return;
} else {
_ = promise.result(vm.global.vm());
}
@@ -1290,21 +1329,9 @@ pub const EventListenerMixin = struct {
}
}
- if (exception) |except| {
- vm.printException(except);
-
- if (!request_context.has_called_done) {
- request_context.sendInternalError(error.JavaScriptErrorNeedARealErrorPageSorryAboutThisSeeTheTerminal) catch {};
- }
- return;
- }
-
if (!request_context.has_called_done) {
- return emitFetchEventError(
- request_context,
- "\"fetch\" handler never called event.respondWith()",
- .{},
- );
+ onError(ctx, error.FetchHandlerRespondWithNeverCalled, JSValue.jsUndefined(), request_context) catch {};
+ return;
}
}
@@ -1368,6 +1395,7 @@ pub const ResolveError = struct {
msg: logger.Msg,
allocator: *std.mem.Allocator,
referrer: ?Fs.Path = null,
+ logged: bool = false,
pub fn fmt(allocator: *std.mem.Allocator, specifier: string, referrer: string, err: anyerror) !string {
switch (err) {
@@ -1515,6 +1543,7 @@ pub const BuildError = struct {
msg: logger.Msg,
// resolve_result: Resolver.Result,
allocator: *std.mem.Allocator,
+ logged: bool = false,
pub const Class = NewClass(
BuildError,
diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig
index 09014c17f..55e4a753e 100644
--- a/src/javascript/jsc/webcore/response.zig
+++ b/src/javascript/jsc/webcore/response.zig
@@ -1009,6 +1009,10 @@ pub const FetchEvent = struct {
request_context: *http.RequestContext,
request: Request,
+ onPromiseRejectionCtx: *c_void = undefined,
+ onPromiseRejectionHandler: ?fn (ctx: *c_void, err: anyerror, fetch_event: *FetchEvent, value: JSValue) void = null,
+ rejected: bool = false,
+
pub const Class = NewClass(
FetchEvent,
.{
@@ -1101,8 +1105,13 @@ pub const FetchEvent = struct {
switch (status) {
.Fulfilled => {},
else => {
- VirtualMachine.vm.defaultErrorHandler(resolved.result(VirtualMachine.vm.global.vm()));
- this.request_context.sendInternalError(error.rejectedPromiseSeeConsole) catch {};
+ this.rejected = true;
+ this.onPromiseRejectionHandler.?(
+ this.onPromiseRejectionCtx,
+ error.PromiseRejection,
+ this,
+ resolved.result(VirtualMachine.vm.global.vm()),
+ );
return js.JSValueMakeUndefined(ctx);
},
}
@@ -1110,14 +1119,16 @@ pub const FetchEvent = struct {
var arg = resolved.result(VirtualMachine.vm.global.vm()).asObjectRef();
if (!js.JSValueIsObjectOfClass(ctx, arg, Response.Class.ref)) {
+ this.rejected = true;
JSError(getAllocator(ctx), "event.respondWith() must be a Response or a Promise<Response>.", .{}, ctx, exception);
- this.request_context.sendInternalError(error.respondWithWasEmpty) catch {};
+ this.onPromiseRejectionHandler.?(this.onPromiseRejectionCtx, error.RespondWithInvalidType, this, JSValue.fromRef(exception.*));
return js.JSValueMakeUndefined(ctx);
}
var response: *Response = GetJSPrivateData(Response, arg) orelse {
+ this.rejected = true;
JSError(getAllocator(ctx), "event.respondWith()'s Response object was invalid. This may be an internal error.", .{}, ctx, exception);
- this.request_context.sendInternalError(error.respondWithWasInvalid) catch {};
+ this.onPromiseRejectionHandler.?(this.onPromiseRejectionCtx, error.RespondWithInvalidTypeInternal, this, JSValue.fromRef(exception.*));
return js.JSValueMakeUndefined(ctx);
};
diff --git a/src/js_ast.zig b/src/js_ast.zig
index be84afb08..746fb5796 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -3656,6 +3656,8 @@ pub const Ast = struct {
};
}
+ pub const empty = Ast{ .parts = &[_]Part{}, .runtime_imports = undefined };
+
pub fn toJSON(self: *const Ast, allocator: *std.mem.Allocator, stream: anytype) !void {
const opts = std.json.StringifyOptions{ .whitespace = std.json.StringifyOptions.Whitespace{
.separator = true,
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 83a1b0127..62bf836e7 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -10623,18 +10623,19 @@ pub fn NewParser(
switch (runtime) {
.classic => {
// Arguments to createElement()
- const args = p.allocator.alloc(Expr, 1 + children_count) catch unreachable;
+ const args = p.allocator.alloc(Expr, 2 + children_count) catch unreachable;
var i: usize = 1;
+ args[0] = tag;
if (e_.properties.len > 0) {
if (e_.key) |key| {
var props = List(G.Property).fromOwnedSlice(p.allocator, e_.properties);
props.append(G.Property{ .key = Expr{ .loc = key.loc, .data = keyExprData }, .value = key }) catch unreachable;
- args[0] = p.e(E.Object{ .properties = props.toOwnedSlice() }, expr.loc);
+ args[1] = p.e(E.Object{ .properties = props.toOwnedSlice() }, expr.loc);
} else {
- args[0] = p.e(E.Object{ .properties = e_.properties }, expr.loc);
+ args[1] = p.e(E.Object{ .properties = e_.properties }, expr.loc);
}
} else {
- args[0] = p.e(E.Null{}, expr.loc);
+ args[1] = p.e(E.Null{}, expr.loc);
}
for (e_.children[0..children_count]) |child| {
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 42af0cd63..0f0a493de 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -2333,7 +2333,7 @@ pub fn NewPrinter(
switch (s.value) {
.expr => |expr| {
if (rewrite_esm_to_cjs) {
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(".default = ");
}
@@ -2354,7 +2354,7 @@ pub fn NewPrinter(
// p.printSymbol(name.ref.?);
// p.print(" = ");
} else {
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(".default = ");
}
}
@@ -2400,7 +2400,7 @@ pub fn NewPrinter(
// p.printSymbol(name.ref.?);
// p.print(" = ");
} else {
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(".default = ");
}
}
@@ -2448,7 +2448,7 @@ pub fn NewPrinter(
} else {
p.printSymbol(p.options.runtime_imports.__reExport.?);
p.print("(");
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(",");
p.printLoadFromBundle(s.import_record_index);
@@ -2506,7 +2506,7 @@ pub fn NewPrinter(
else => {
p.print("Object.assign");
p.print("(");
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(", {");
const last = s.items.len - 1;
for (s.items) |item, i| {
@@ -2583,7 +2583,7 @@ pub fn NewPrinter(
const item = s.items[0];
p.printSymbol(p.options.runtime_imports.lazy_export.?);
p.print("(");
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(",");
// Avoid initializing an entire component library because you imported one icon
p.printLoadFromBundleWithoutCall(s.import_record_index);
@@ -2599,7 +2599,7 @@ pub fn NewPrinter(
} else {
p.printSymbol(p.options.runtime_imports.lazy_export.?);
p.print("(");
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(",");
// Avoid initializing an entire component library because you imported one icon
@@ -3243,6 +3243,10 @@ pub fn NewPrinter(
}
}
+ pub fn printModuleExportSymbol(p: *Printer) void {
+ p.print("module.exports");
+ }
+
pub fn printBundledImport(p: *Printer, record: importRecord.ImportRecord, s: *S.Import, stmt: Stmt) void {
if (record.is_internal) {
return;
@@ -3617,7 +3621,7 @@ pub fn NewPrinter(
p.printIndent();
p.printSpaceBeforeIdentifier();
p.print("Object.defineProperties(");
- p.printSymbol(p.options.runtime_imports.__export.?);
+ p.printModuleExportSymbol();
p.print(",{");
for (decls) |decl, i| {
p.print("'");
diff --git a/src/lock.zig b/src/lock.zig
index 73dfdebd2..4ae9444e0 100644
--- a/src/lock.zig
+++ b/src/lock.zig
@@ -6,118 +6,101 @@ const Futex = std.Thread.Futex;
pub const Mutex = struct {
state: Atomic(u32) = Atomic(u32).init(UNLOCKED),
- const UNLOCKED: u32 = 0;
- const LOCKED: u32 = 1;
- const CONTENDED: u32 = 2;
+ const UNLOCKED = 0;
+ const LOCKED = 0b01;
+ const CONTENDED = 0b11;
+ const is_x86 = std.Target.current.cpu.arch.isX86();
pub fn tryAcquire(self: *Mutex) bool {
- return self.state.compareAndSwap(
- UNLOCKED,
- LOCKED,
- .Acquire,
- .Monotonic,
- ) == null;
+ return self.acquireFast(true);
}
pub fn acquire(self: *Mutex) void {
- if (self.state.tryCompareAndSwap(
- UNLOCKED,
- LOCKED,
- .Acquire,
- .Monotonic,
- )) |updated| {
+ if (!self.acquireFast(false)) {
self.acquireSlow();
}
}
- fn acquireSlow(self: *Mutex) void {
- @setCold(true);
+ inline fn acquireFast(self: *Mutex, comptime strong: bool) bool {
+ // On x86, "lock bts" uses less i-cache & can be faster than "lock cmpxchg" below.
+ if (comptime is_x86) {
+ return self.state.bitSet(@ctz(u32, LOCKED), .Acquire) == UNLOCKED;
+ }
- // true if the cpu's atomic swap instruction should be preferred
- const has_fast_swap = comptime blk: {
- const arch = std.Target.current.cpu.arch;
- break :blk arch.isX86() or arch.isRISCV();
+ const cas_fn = comptime switch (strong) {
+ true => "compareAndSwap",
+ else => "tryCompareAndSwap",
};
- var acquire_state = LOCKED;
- var state = self.state.load(.Monotonic);
- var spin: u8 = if (comptime has_fast_swap) 100 else 10;
-
- while (true) {
- // Try to lock the Mutex if its unlocked.
- // acquire_state is changed to CONTENDED if this thread goes to sleep.
- //
- // We acquire with CONTENDED instead of LOCKED in that scenario
- // to make sure that we wake another thread sleeping in release()
- // which didn't see the transition to UNLOCKED since it was asleep.
- //
- // A CONTENDED acquire unfortunately results in one extra wake()
- // if there were no other sleeping threads at the time of the acquire.
- if (state == UNLOCKED) {
- state = self.state.tryCompareAndSwap(
- state,
- acquire_state,
+ return @field(self.state, cas_fn)(
+ UNLOCKED,
+ LOCKED,
+ .Acquire,
+ .Monotonic,
+ ) == null;
+ }
+
+ noinline fn acquireSlow(self: *Mutex) void {
+ // Spin a little bit on the Mutex state in the hopes that
+ // we can acquire it without having to call Futex.wait().
+ // Give up spinning if the Mutex is contended.
+ // This helps acquire() latency under micro-contention.
+ //
+ // Only spin on x86 as other platforms are assumed to
+ // prioritize power efficiency over strict performance.
+ var spin: u8 = comptime if (is_x86) 100 else 0;
+ while (spin > 0) : (spin -= 1) {
+ std.atomic.spinLoopHint();
+
+ switch (self.state.load(.Monotonic)) {
+ UNLOCKED => _ = self.state.tryCompareAndSwap(
+ UNLOCKED,
+ LOCKED,
.Acquire,
.Monotonic,
- ) orelse return;
- continue;
+ ) orelse return,
+ LOCKED => continue,
+ CONTENDED => break,
+ else => unreachable, // invalid Mutex state
}
+ }
- if (state != CONTENDED) uncontended: {
- // If there's no pending threads, try to spin on the Mutex a few times.
- // This makes the throughput close to a spinlock when under micro-contention.
- if (spin > 0) {
- spin -= 1;
- std.atomic.spinLoopHint();
- state = self.state.load(.Monotonic);
- continue;
- }
-
- // Indicate that there will be a waiting thread by updating to CONTENDED.
- // Acquire barrier as this swap could also possibly lock the Mutex.
- if (comptime has_fast_swap) {
- state = self.state.swap(CONTENDED, .Acquire);
- if (state == UNLOCKED) return;
- break :uncontended;
- }
-
- // For other platforms, mark the Mutex as CONTENDED if it's not already.
- // This just indicates that there's waiting threads so no Acquire barrier needed.
- if (self.state.tryCompareAndSwap(
- state,
- CONTENDED,
- .Monotonic,
- .Monotonic,
- )) |updated| {
- state = updated;
- continue;
+ // Make sure the state is CONTENDED before sleeping with Futex so release() can wake us up.
+ // Transitioning to CONTENDED may also acquire the mutex in the process.
+ //
+ // If we sleep, we must acquire the Mutex with CONTENDED to ensure that other threads
+ // sleeping on the Futex having seen CONTENDED before are eventually woken up by release().
+ // This unfortunately ends up in an extra Futex.wake() for the last thread but that's ok.
+ while (true) : (Futex.wait(&self.state, CONTENDED, null) catch unreachable) {
+ // On x86, "xchg" can be faster than "lock cmpxchg" below.
+ if (comptime is_x86) {
+ switch (self.state.swap(CONTENDED, .Acquire)) {
+ UNLOCKED => return,
+ LOCKED, CONTENDED => continue,
+ else => unreachable, // invalid Mutex state
}
}
- Futex.wait(&self.state, CONTENDED, null) catch unreachable;
- state = self.state.load(.Monotonic);
- acquire_state = CONTENDED;
+ var state = self.state.load(.Monotonic);
+ while (state != CONTENDED) {
+ state = switch (state) {
+ UNLOCKED => self.state.tryCompareAndSwap(state, CONTENDED, .Acquire, .Monotonic) orelse return,
+ LOCKED => self.state.tryCompareAndSwap(state, CONTENDED, .Monotonic, .Monotonic) orelse break,
+ CONTENDED => unreachable, // checked above
+ else => unreachable, // invalid Mutex state
+ };
+ }
}
}
pub fn release(self: *Mutex) void {
- const state = self.state.swap(UNLOCKED, .Release);
-
- // Wake up a sleeping thread if it was previously CONTENDED.
- // The woken up thread would acquire by updating the state to CONTENDED again.
- // This is to make sure a future release() wouldn't miss waking up threads that
- // don't see the reset to UNLOCKED above due to them being asleep.
- if (state == CONTENDED) {
- self.releaseSlow();
+ switch (self.state.swap(UNLOCKED, .Release)) {
+ UNLOCKED => unreachable, // released without being acquired
+ LOCKED => {},
+ CONTENDED => Futex.wake(&self.state, 1),
+ else => unreachable, // invalid Mutex state
}
}
-
- fn releaseSlow(self: *Mutex) void {
- @setCold(true);
-
- const num_waiters = 1;
- Futex.wake(&self.state, num_waiters);
- }
};
pub const Lock = struct {
@@ -136,7 +119,4 @@ pub const Lock = struct {
}
};
-
-pub fn spinCycle() void {
-
-} \ No newline at end of file
+pub fn spinCycle() void {}
diff --git a/src/logger.zig b/src/logger.zig
index cf9fb6960..8ccffd06f 100644
--- a/src/logger.zig
+++ b/src/logger.zig
@@ -43,13 +43,12 @@ pub const Kind = enum(i8) {
};
}
- pub inline fn toAPI(kind: Kind) Api.MessageKind {
+ pub inline fn toAPI(kind: Kind) Api.MessageLevel {
return switch (kind) {
- .err => err,
- .warn => warn,
- .note => note,
- .debug => debug,
- .verbose => verbose,
+ .err => .err,
+ .warn => .warn,
+ .note => .note,
+ else => .debug,
};
}
};
@@ -92,6 +91,18 @@ pub const Location = struct {
suggestion: ?string = null,
offset: usize = 0,
+ pub fn toAPI(this: *const Location) Api.Location {
+ return Api.Location{
+ .file = this.file,
+ .namespace = this.namespace,
+ .line = this.line,
+ .column = this.column,
+ .line_text = this.line_text orelse "",
+ .suggestion = this.suggestion orelse "",
+ .offset = @truncate(u32, this.offset),
+ };
+ }
+
// don't really know what's safe to deinit here!
pub fn deinit(l: *Location, allocator: *std.mem.Allocator) void {}
@@ -151,6 +162,13 @@ pub const Data = struct {
allocator.free(text);
}
+ pub fn toAPI(this: *const Data) Api.MessageData {
+ return Api.MessageData{
+ .text = this.text,
+ .location = if (this.location != null) this.location.?.toAPI() else null,
+ };
+ }
+
pub fn writeFormat(
this: *const Data,
to: anytype,
@@ -213,17 +231,26 @@ pub const Msg = struct {
};
};
- pub fn toAPI(this: *const Msg, allocator: *std.mem.Allocator) Api.Message {
+ pub fn toAPI(this: *const Msg, allocator: *std.mem.Allocator) !Api.Message {
+ const notes_len = if (this.notes != null) this.notes.?.len else 0;
+ var _notes = try allocator.alloc(
+ Api.MessageData,
+ notes_len,
+ );
var msg = Api.Message{
- .kind = this.kind.toAPI(),
+ .level = this.kind.toAPI(),
.data = this.data.toAPI(),
+ .notes = _notes,
+ .on = Api.MessageMeta{
+ .resolve = if (this.metadata == .resolve) this.metadata.resolve.specifier.slice(this.data.text) else "",
+ .build = this.metadata == .build,
+ },
};
if (this.notes) |notes| {
if (notes.len > 0) {
- msg.notes = try allocator.alloc(Api.MessageData, notes.len);
for (notes) |note, i| {
- msg.notes[i] = note.toAPI();
+ _notes[i] = note.toAPI();
}
}
}
@@ -232,7 +259,7 @@ pub const Msg = struct {
}
pub fn toAPIFromList(comptime ListType: type, list: ListType, allocator: *std.mem.Allocator) ![]Api.Message {
- var out_list = try allocator.alloc(Api.Msg, list.items.len);
+ var out_list = try allocator.alloc(Api.Message, list.items.len);
for (list.items) |item, i| {
out_list[i] = try item.toAPI(allocator);
}
@@ -341,9 +368,16 @@ pub const Log = struct {
level: Level = if (isDebug) Level.info else Level.warn,
pub fn toAPI(this: *const Log, allocator: *std.mem.Allocator) !Api.Log {
+ var warnings: u32 = 0;
+ var errors: u32 = 0;
+ for (this.msgs.items) |msg, i| {
+ errors += @intCast(u32, @boolToInt(msg.kind == .err));
+ warnings += @intCast(u32, @boolToInt(msg.kind == .warn));
+ }
+
return Api.Log{
- .warnings = this.warnings,
- .errors = this.errors,
+ .warnings = warnings,
+ .errors = errors,
.msgs = try Msg.toAPIFromList(@TypeOf(this.msgs), this.msgs, allocator),
};
}
@@ -392,7 +426,12 @@ pub const Log = struct {
const msg = self.msgs.items[i];
if (msg.data.location) |location| {
if (location.line_text) |line_text| {
- other.msgs.items[j].data.location.?.line_text = try other.msgs.allocator.dupe(u8, line_text);
+ other.msgs.items[j].data.location.?.line_text = try other.msgs.allocator.dupe(
+ u8,
+ // Naively truncate to 690 characters per line.
+ // This doesn't catch where an error occurred for extremely long, minified lines.
+ line_text[0..std.math.min(line_text.len, 690)],
+ );
}
}
}
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig
index 979c1bba5..4fd781829 100644
--- a/src/node_module_bundle.zig
+++ b/src/node_module_bundle.zig
@@ -297,6 +297,7 @@ pub const NodeModuleBundle = struct {
var read_bytes = file_bytes[0..read_count];
var reader = schema.Reader.init(read_bytes, allocator);
var container = try Api.JavascriptBundleContainer.decode(&reader);
+ if (container.bundle == null) return error.InvalidBundle;
var bundle = NodeModuleBundle{
.allocator = allocator,
.container = container,
diff --git a/src/options.zig b/src/options.zig
index 05a32cc28..f5b636d5f 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -851,7 +851,7 @@ pub const BundleOptions = struct {
pub fn isFrontendFrameworkEnabled(this: *const BundleOptions) bool {
const framework: *const Framework = &(this.framework orelse return false);
- return framework.resolved and framework.client.len > 0;
+ return framework.resolved and (framework.client.isEnabled() or framework.fallback.isEnabled());
}
pub const ImportPathFormat = enum {
@@ -999,15 +999,17 @@ pub const BundleOptions = struct {
if (transform.framework == null) {
if (bundle.container.framework) |loaded_framework| {
- opts.framework = Framework.fromLoadedFramework(loaded_framework, allocator);
- opts.framework.?.client_env.allocator = allocator;
- opts.framework.?.server_env.allocator = allocator;
+ opts.framework = try Framework.fromLoadedFramework(loaded_framework, allocator);
if (transform.define == null) {
if (opts.platform.isClient()) {
- opts.env = opts.framework.?.client_env;
+ if (opts.framework.?.client.kind != .disabled) {
+ opts.env = opts.framework.?.client.env;
+ } else if (opts.framework.?.fallback.kind != .disabled) {
+ opts.env = opts.framework.?.fallback.env;
+ }
} else {
- opts.env = opts.framework.?.server_env;
+ opts.env = opts.framework.?.server.env;
}
}
}
@@ -1034,17 +1036,7 @@ pub const BundleOptions = struct {
// }
if (transform.framework) |_framework| {
- opts.framework = try Framework.fromApi(_framework);
-
- if (_framework.client_env) |env| {
- opts.framework.?.client_env.allocator = allocator;
- try opts.framework.?.client_env.setFromAPI(env);
- }
-
- if (_framework.server_env) |env| {
- opts.framework.?.server_env.allocator = allocator;
- try opts.framework.?.server_env.setFromAPI(env);
- }
+ opts.framework = try Framework.fromApi(_framework, allocator);
}
if (transform.router) |routes| {
@@ -1520,22 +1512,41 @@ pub const Env = struct {
}
};
-pub const Framework = struct {
- client: string,
- server: string,
- package: string = "",
- development: bool = true,
- resolved: bool = false,
- from_bundle: bool = false,
+pub const EntryPoint = struct {
+ path: string = "",
+ env: Env = Env{},
+ kind: Kind = Kind.disabled,
- client_env: Env = Env{},
- server_env: Env = Env{},
+ pub fn isEnabled(this: *const EntryPoint) bool {
+ return this.kind != .disabled and this.path.len > 0;
+ }
- client_css_in_js: Api.CssInJsBehavior = .auto_onimportcss,
+ pub const Kind = enum {
+ client,
+ server,
+ fallback,
+ disabled,
+
+ pub fn toAPI(this: Kind) Api.FrameworkEntryPointType {
+ return switch (this) {
+ .client => .client,
+ .server => .server,
+ .fallback => .fallback,
+ else => unreachable,
+ };
+ }
+ };
+
+ pub fn toAPI(this: *const EntryPoint, allocator: *std.mem.Allocator, toplevel_path: string, kind: Kind) !?Api.FrameworkEntryPoint {
+ if (this.kind == .disabled)
+ return null;
+
+ return Api.FrameworkEntryPoint{ .kind = kind.toAPI(), .env = this.env.toAPI(), .path = try this.normalizedPath(allocator, toplevel_path) };
+ }
- fn normalizedPath(allocator: *std.mem.Allocator, toplevel_path: string, path: string) !string {
- std.debug.assert(std.fs.path.isAbsolute(path));
- var str = path;
+ fn normalizedPath(this: *const EntryPoint, allocator: *std.mem.Allocator, toplevel_path: string) !string {
+ std.debug.assert(std.fs.path.isAbsolute(this.path));
+ var str = this.path;
if (strings.indexOf(str, toplevel_path)) |top| {
str = str[top + toplevel_path.len ..];
}
@@ -1554,53 +1565,103 @@ pub const Framework = struct {
}
}
- pub fn fromLoadedFramework(loaded: Api.LoadedFramework, allocator: *std.mem.Allocator) Framework {
- const client = if (loaded.client) loaded.entry_point else "";
- const server = if (!loaded.client) loaded.entry_point else "";
+ pub fn fromLoaded(
+ this: *EntryPoint,
+ framework_entry_point: Api.FrameworkEntryPoint,
+ allocator: *std.mem.Allocator,
+ kind: Kind,
+ ) !void {
+ this.path = framework_entry_point.path;
+ this.kind = kind;
+ this.env.setFromLoaded(framework_entry_point.env, allocator) catch {};
+ }
+
+ pub fn fromAPI(
+ this: *EntryPoint,
+ framework_entry_point: Api.FrameworkEntryPointMessage,
+ allocator: *std.mem.Allocator,
+ kind: Kind,
+ ) !void {
+ this.path = framework_entry_point.path orelse "";
+ this.kind = kind;
+
+ if (this.path.len == 0) {
+ this.kind = .disabled;
+ return;
+ }
+
+ if (framework_entry_point.env) |env| {
+ this.env.allocator = allocator;
+ try this.env.setFromAPI(env);
+ }
+ }
+};
+
+pub const Framework = struct {
+ client: EntryPoint = EntryPoint{},
+ server: EntryPoint = EntryPoint{},
+ fallback: EntryPoint = EntryPoint{},
+
+ package: string = "",
+ development: bool = true,
+ resolved: bool = false,
+ from_bundle: bool = false,
+
+ client_css_in_js: Api.CssInJsBehavior = .auto_onimportcss,
+
+ pub const fallback_html: string = @embedFile("./fallback.html");
+
+ pub fn platformEntryPoint(this: *const Framework, platform: Platform) ?*const EntryPoint {
+ const entry: *const EntryPoint = switch (platform) {
+ .neutral, .browser => &this.client,
+ .bun => &this.server,
+ .node => return null,
+ };
+
+ if (entry.kind == .disabled) return null;
+ return entry;
+ }
+
+ pub fn fromLoadedFramework(loaded: Api.LoadedFramework, allocator: *std.mem.Allocator) !Framework {
var framework = Framework{
- .client = client,
- .server = server,
.package = loaded.package,
.development = loaded.development,
.from_bundle = true,
.client_css_in_js = loaded.client_css_in_js,
};
- if (loaded.client) {
- framework.client_env.setFromLoaded(loaded.env, allocator) catch {};
- } else {
- framework.server_env.setFromLoaded(loaded.env, allocator) catch {};
+ if (loaded.entry_points.fallback) |fallback| {
+ try framework.fallback.fromLoaded(fallback, allocator, .fallback);
}
- return framework;
- }
+ if (loaded.entry_points.client) |client| {
+ try framework.client.fromLoaded(client, allocator, .client);
+ }
- pub fn toAPI(this: *const Framework, allocator: *std.mem.Allocator, toplevel_path: string, comptime client: bool) ?Api.LoadedFramework {
- if (comptime client) {
- if (this.client.len > 0) {
- return Api.LoadedFramework{
- .entry_point = normalizedPath(allocator, toplevel_path, this.client) catch unreachable,
- .package = this.package,
- .development = this.development,
- .client = true,
- .env = this.client_env.toAPI(),
- .client_css_in_js = this.client_css_in_js,
- };
- }
- } else {
- if (this.server.len > 0) {
- return Api.LoadedFramework{
- .entry_point = normalizedPath(allocator, toplevel_path, this.server) catch unreachable,
- .package = this.package,
- .development = this.development,
- .client = false,
- .env = this.server_env.toAPI(),
- .client_css_in_js = this.client_css_in_js,
- };
- }
+ if (loaded.entry_points.server) |server| {
+ try framework.server.fromLoaded(server, allocator, .server);
}
- return null;
+ return framework;
+ }
+
+ pub fn toAPI(
+ this: *const Framework,
+ allocator: *std.mem.Allocator,
+ toplevel_path: string,
+ ) !?Api.LoadedFramework {
+ if (this.client.kind == .disabled and this.server.kind == .disabled and this.fallback.kind == .disabled) return null;
+
+ return Api.LoadedFramework{
+ .package = this.package,
+ .development = this.development,
+ .entry_points = .{
+ .client = try this.client.toAPI(allocator, toplevel_path, .client),
+ .fallback = try this.fallback.toAPI(allocator, toplevel_path, .fallback),
+ .server = try this.server.toAPI(allocator, toplevel_path, .server),
+ },
+ .client_css_in_js = this.client_css_in_js,
+ };
}
pub fn needsResolveFromPackage(this: *const Framework) bool {
@@ -1609,10 +1670,28 @@ pub const Framework = struct {
pub fn fromApi(
transform: Api.FrameworkConfig,
+ allocator: *std.mem.Allocator,
) !Framework {
+ var client = EntryPoint{};
+ var server = EntryPoint{};
+ var fallback = EntryPoint{};
+
+ if (transform.client) |_client| {
+ try client.fromAPI(_client, allocator, .client);
+ }
+
+ if (transform.server) |_server| {
+ try server.fromAPI(_server, allocator, .server);
+ }
+
+ if (transform.fallback) |_fallback| {
+ try fallback.fromAPI(_fallback, allocator, .fallback);
+ }
+
return Framework{
- .client = transform.client orelse "",
- .server = transform.server orelse "",
+ .client = client,
+ .server = server,
+ .fallback = fallback,
.package = transform.package orelse "",
.development = transform.development orelse true,
.resolved = false,
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig
index b3b484a84..13ac223e5 100644
--- a/src/resolver/package_json.zig
+++ b/src/resolver/package_json.zig
@@ -153,7 +153,17 @@ pub const PackageJSON = struct {
if (json.asProperty("client")) |client| {
if (client.expr.asString(allocator)) |str| {
if (str.len > 0) {
- framework.client = str;
+ framework.client.path = str;
+ framework.client.kind = .client;
+ }
+ }
+ }
+
+ if (json.asProperty("fallback")) |client| {
+ if (client.expr.asString(allocator)) |str| {
+ if (str.len > 0) {
+ framework.fallback.path = str;
+ framework.fallback.kind = .fallback;
}
}
}
@@ -170,25 +180,41 @@ pub const PackageJSON = struct {
if (comptime read_define) {
if (json.asProperty("define")) |defines| {
+ var skip_fallback = false;
if (defines.expr.asProperty("client")) |client| {
if (client.expr.data == .e_object) {
const object = client.expr.data.e_object;
- framework.client_env = options.Env.init(
+ framework.client.env = options.Env.init(
allocator,
);
- loadDefineExpression(&framework.client_env, object, allocator) catch {};
+ loadDefineExpression(&framework.client.env, object, allocator) catch {};
+ framework.fallback.env = framework.client.env;
+ skip_fallback = true;
+ }
+ }
+
+ if (!skip_fallback) {
+ if (defines.expr.asProperty("fallback")) |client| {
+ if (client.expr.data == .e_object) {
+ const object = client.expr.data.e_object;
+ framework.fallback.env = options.Env.init(
+ allocator,
+ );
+
+ loadDefineExpression(&framework.fallback.env, object, allocator) catch {};
+ }
}
}
if (defines.expr.asProperty("server")) |server| {
if (server.expr.data == .e_object) {
const object = server.expr.data.e_object;
- framework.server_env = options.Env.init(
+ framework.server.env = options.Env.init(
allocator,
);
- loadDefineExpression(&framework.server_env, object, allocator) catch {};
+ loadDefineExpression(&framework.server.env, object, allocator) catch {};
}
}
}
@@ -197,12 +223,13 @@ pub const PackageJSON = struct {
if (json.asProperty("server")) |server| {
if (server.expr.asString(allocator)) |str| {
if (str.len > 0) {
- framework.server = str;
+ framework.server.path = str;
+ framework.server.kind = .server;
}
}
}
- return framework.client.len > 0;
+ return framework.client.isEnabled() or framework.server.isEnabled() or framework.fallback.isEnabled();
}
pub fn loadFrameworkWithPreference(
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index c44608d3b..8dffbb497 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -502,17 +502,25 @@ pub fn NewResolver(cache_files: bool) type {
pkg.loadFrameworkWithPreference(pair, json, r.allocator, load_defines, preference);
const dir = pkg.source.path.name.dirWithTrailingSlash();
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
- if (pair.framework.client.len > 0) {
- var parts = [_]string{ dir, pair.framework.client };
+
+ if (pair.framework.client.isEnabled()) {
+ var parts = [_]string{ dir, pair.framework.client.path };
+ const abs = r.fs.abs(&parts);
+ pair.framework.client.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.resolved = true;
+ }
+
+ if (pair.framework.server.isEnabled()) {
+ var parts = [_]string{ dir, pair.framework.server.path };
const abs = r.fs.abs(&parts);
- pair.framework.client = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.server.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
pair.framework.resolved = true;
}
- if (pair.framework.server.len > 0) {
- var parts = [_]string{ dir, pair.framework.server };
+ if (pair.framework.fallback.isEnabled()) {
+ var parts = [_]string{ dir, pair.framework.fallback.path };
const abs = r.fs.abs(&parts);
- pair.framework.server = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.fallback.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
pair.framework.resolved = true;
}
diff --git a/src/router.zig b/src/router.zig
index 4959fd5cc..53c7f126f 100644
--- a/src/router.zig
+++ b/src/router.zig
@@ -208,7 +208,7 @@ pub fn loadRoutes(
}
}
-const TinyPtr = packed struct {
+pub const TinyPtr = packed struct {
offset: u16 = 0,
len: u16 = 0,
diff --git a/src/runtime.version b/src/runtime.version
index 1d355c2cd..866b687de 100644
--- a/src/runtime.version
+++ b/src/runtime.version
@@ -1 +1 @@
-ffa36d1436d2546f \ No newline at end of file
+f763299933041bd3 \ No newline at end of file
diff --git a/src/runtime.zig b/src/runtime.zig
index 72b97154c..b694aa41a 100644
--- a/src/runtime.zig
+++ b/src/runtime.zig
@@ -2,11 +2,110 @@ const options = @import("./options.zig");
usingnamespace @import("ast/base.zig");
usingnamespace @import("global.zig");
const std = @import("std");
-pub const ProdSourceContent = @embedFile("./runtime.out.js");
const resolve_path = @import("./resolver/resolve_path.zig");
const Fs = @import("./fs.zig");
+const Schema = @import("./api/schema.zig");
+
+const Api = Schema.Api;
+
+pub const Fallback = struct {
+ pub const ProdSourceContent = @embedFile("./fallback.out.js");
+ pub const HTMLTemplate = @embedFile("./fallback.html");
+
+ const Base64FallbackMessage = struct {
+ msg: *const Api.FallbackMessageContainer,
+ allocator: *std.mem.Allocator,
+ pub fn format(this: Base64FallbackMessage, comptime fmt: []const u8, opts_: std.fmt.FormatOptions, writer: anytype) !void {
+ var bb = std.ArrayList(u8).init(this.allocator);
+ defer bb.deinit();
+ var bb_writer = bb.writer();
+ const Encoder = Schema.Writer(@TypeOf(bb_writer));
+ var encoder = Encoder.init(bb_writer);
+ this.msg.encode(&encoder) catch {};
+
+ Base64Encoder.encode(bb.items, @TypeOf(writer), writer) catch {};
+ }
+
+ pub const Base64Encoder = struct {
+ const alphabet_chars = std.base64.standard_alphabet_chars;
+
+ pub fn encode(source: []const u8, comptime Writer: type, writer: Writer) !void {
+ var acc: u12 = 0;
+ var acc_len: u4 = 0;
+ for (source) |v| {
+ acc = (acc << 8) + v;
+ acc_len += 8;
+ while (acc_len >= 6) {
+ acc_len -= 6;
+ try writer.writeByte(alphabet_chars[@truncate(u6, (acc >> acc_len))]);
+ }
+ }
+ if (acc_len > 0) {
+ try writer.writeByte(alphabet_chars[@truncate(u6, (acc << 6 - acc_len))]);
+ }
+ }
+ };
+ };
+
+ pub inline fn scriptContent() string {
+ if (comptime isDebug) {
+ var dirpath = std.fs.path.dirname(@src().file).?;
+ var env = std.process.getEnvMap(default_allocator) catch unreachable;
+
+ const dir = std.mem.replaceOwned(
+ u8,
+ default_allocator,
+ dirpath,
+ "jarred",
+ env.get("USER").?,
+ ) catch unreachable;
+ var runtime_path = std.fs.path.join(default_allocator, &[_]string{ dir, "fallback.out.js" }) catch unreachable;
+ const file = std.fs.openFileAbsolute(runtime_path, .{}) catch unreachable;
+ defer file.close();
+ return file.readToEndAlloc(default_allocator, (file.stat() catch unreachable).size) catch unreachable;
+ } else {
+ return ProdSourceContent;
+ }
+ }
+ pub const version_hash = @embedFile("./fallback.version");
+ var version_hash_int: u32 = 0;
+ pub fn versionHash() u32 {
+ if (version_hash_int == 0) {
+ version_hash_int = @truncate(u32, std.fmt.parseInt(u64, version(), 16) catch unreachable);
+ }
+ return version_hash_int;
+ }
+
+ pub fn version() string {
+ return version_hash;
+ }
+
+ pub fn render(
+ allocator: *std.mem.Allocator,
+ msg: *const Api.FallbackMessageContainer,
+ preload: string,
+ entry_point: string,
+ comptime WriterType: type,
+ writer: WriterType,
+ ) !void {
+ const PrintArgs = struct {
+ blob: Base64FallbackMessage,
+ preload: string,
+ fallback: string,
+ entry_point: string,
+ };
+ try writer.print(HTMLTemplate, PrintArgs{
+ .blob = Base64FallbackMessage{ .msg = msg, .allocator = allocator },
+ .preload = preload,
+ .fallback = scriptContent(),
+ .entry_point = entry_point,
+ });
+ }
+};
pub const Runtime = struct {
+ pub const ProdSourceContent = @embedFile("./runtime.out.js");
+
pub fn sourceContent() string {
if (comptime isDebug) {
var dirpath = std.fs.path.dirname(@src().file).?;
@@ -36,6 +135,10 @@ pub const Runtime = struct {
return version_hash_int;
}
+ pub fn version() string {
+ return version_hash;
+ }
+
const bytecodeCacheFilename = std.fmt.comptimePrint("__runtime.{s}", .{version_hash});
var bytecodeCacheFetcher = Fs.BytecodeCacheFetcher{};
@@ -43,10 +146,6 @@ pub const Runtime = struct {
return bytecodeCacheFetcher.fetch(bytecodeCacheFilename, fs);
}
- pub fn version() string {
- return version_hash;
- }
-
pub const Features = struct {
react_fast_refresh: bool = false,
hot_module_reloading: bool = false,
diff --git a/src/runtime/hmr.ts b/src/runtime/hmr.ts
index ecd3aadb2..46b841b7a 100644
--- a/src/runtime/hmr.ts
+++ b/src/runtime/hmr.ts
@@ -435,7 +435,7 @@ if (typeof window !== "undefined") {
clientStartTime = performance.now();
- const baseURL = new URL(location.origin + "/_api.hmr");
+ const baseURL = new URL(location.origin + "/bun:_api.hmr");
baseURL.protocol = location.protocol === "https:" ? "wss" : "ws";
this.socket = new WebSocket(baseURL.toString(), ["bun-hmr"]);
this.socket.binaryType = "arraybuffer";
diff --git a/src/test/fixtures/fragment.jsx b/src/test/fixtures/fragment.jsx
new file mode 100644
index 000000000..3f5615368
--- /dev/null
+++ b/src/test/fixtures/fragment.jsx
@@ -0,0 +1 @@
+const Foo = <>hi</>;