aboutsummaryrefslogtreecommitdiff
path: root/src/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript')
-rw-r--r--src/javascript/jsc/api/router.zig80
-rw-r--r--src/javascript/jsc/base.zig83
-rw-r--r--src/javascript/jsc/bindings/exports.zig22
-rw-r--r--src/javascript/jsc/javascript.zig31
4 files changed, 124 insertions, 92 deletions
diff --git a/src/javascript/jsc/api/router.zig b/src/javascript/jsc/api/router.zig
index 84dad71ef..6e6fea896 100644
--- a/src/javascript/jsc/api/router.zig
+++ b/src/javascript/jsc/api/router.zig
@@ -4,10 +4,12 @@ const Api = @import("../../../api/schema.zig").Api;
const FilesystemRouter = @import("../../../router.zig");
const http = @import("../../../http.zig");
const JavaScript = @import("../javascript.zig");
-
+usingnamespace @import("../bindings/bindings.zig");
usingnamespace @import("../webcore/response.zig");
const Router = @This();
+const VirtualMachine = JavaScript.VirtualMachine;
+
route: *const FilesystemRouter.Match,
file_path_str: js.JSStringRef = null,
pathname_str: js.JSStringRef = null,
@@ -20,16 +22,13 @@ pub fn importRoute(
arguments: []const js.JSValueRef,
exception: js.ExceptionRef,
) js.JSObjectRef {
- return JavaScript.VirtualMachine.instance.require(
- ctx,
- std.fs.path.dirname(this.route.file_path).?,
- this.route.file_path,
- exception,
- );
+ const prom = JSModuleLoader.loadAndEvaluateModule(VirtualMachine.vm.global, ZigString.init(this.route.file_path));
+ VirtualMachine.vm.global.vm().drainMicrotasks();
+ return prom.result(VirtualMachine.vm.global.vm()).asRef();
}
pub fn match(
- obj: *c_void,
+ obj: void,
ctx: js.JSContextRef,
function: js.JSObjectRef,
thisObject: js.JSObjectRef,
@@ -96,10 +95,10 @@ fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext, exce
.route = route,
};
- return Class.new(ctx, router);
+ return Instance.make(ctx, router);
}
-const match_type_definition = &[_]d.ts{
+pub const match_type_definition = &[_]d.ts{
.{
.tsdoc = "Match a {@link https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent FetchEvent} to a `Route` from the local filesystem. Returns `null` if there is no match.",
.args = &[_]d.ts.arg{
@@ -132,29 +131,6 @@ const match_type_definition = &[_]d.ts{
},
};
-pub const Class = NewClass(
- c_void,
- .{
- .name = "Router",
- .read_only = true,
- .ts = .{
- .module = .{
- .path = "speedy.js/router",
- .tsdoc = "Filesystem Router supporting dynamic routes, exact routes, catch-all routes, and optional catch-all routes. Implemented in native code and only available with Speedy.js.",
- },
- },
- },
- .{
- .match = .{
- .rfn = match,
- .ts = match_type_definition,
- },
- },
- .{
- .Route = Instance.GetClass(c_void){},
- },
-);
-
pub const Instance = NewClass(
Router,
.{
@@ -249,16 +225,11 @@ pub fn getFilePath(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- if (this.file_path_str == null) {
- this.file_path_str = js.JSStringCreateWithUTF8CString(this.route.file_path.ptr);
- }
-
- return js.JSValueMakeString(ctx, this.file_path_str);
+ return ZigString.init(this.route.file_path).toValue(VirtualMachine.vm.global).asRef();
}
pub fn finalize(
this: *Router,
- ctx: js.JSObjectRef,
) void {
// this.deinit();
}
@@ -270,11 +241,7 @@ pub fn getPathname(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- if (this.pathname_str == null) {
- this.pathname_str = js.JSStringCreateWithUTF8CString(this.route.pathname.ptr);
- }
-
- return js.JSValueMakeString(ctx, this.pathname_str);
+ return ZigString.init(this.route.pathname).toValue(VirtualMachine.vm.global).asRef();
}
pub fn getRoute(
@@ -284,9 +251,28 @@ pub fn getRoute(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- return js.JSValueMakeString(ctx, Properties.Refs.default);
+ return ZigString.init(this.route.name).toValue(VirtualMachine.vm.global).asRef();
}
+const KindEnum = struct {
+ pub const exact = "exact";
+ pub const catch_all = "catch-all";
+ pub const optional_catch_all = "optional-catch-all";
+ pub const dynamic = "dynamic";
+
+ pub fn init(name: string) ZigString {
+ if (strings.contains(name, "[[...")) {
+ return ZigString.init(optional_catch_all);
+ } else if (strings.contains(name, "[...")) {
+ return ZigString.init(catch_all);
+ } else if (strings.contains(name, "[")) {
+ return ZigString.init(dynamic);
+ } else {
+ return ZigString.init(exact);
+ }
+ }
+};
+
pub fn getKind(
this: *Router,
ctx: js.JSContextRef,
@@ -294,7 +280,7 @@ pub fn getKind(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- return js.JSValueMakeString(ctx, Properties.Refs.default);
+ return KindEnum.init(this.route.name).toValue(VirtualMachine.vm.global).asRef();
}
pub fn getQuery(
@@ -304,5 +290,5 @@ pub fn getQuery(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- return js.JSValueMakeString(ctx, Properties.Refs.default);
+ return ZigString.init(this.route.query_string).toValue(VirtualMachine.vm.global).asRef();
}
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig
index 55ce93164..5c2b630e3 100644
--- a/src/javascript/jsc/base.zig
+++ b/src/javascript/jsc/base.zig
@@ -3,6 +3,7 @@ const std = @import("std");
pub usingnamespace @import("../../global.zig");
usingnamespace @import("./javascript.zig");
usingnamespace @import("./webcore/response.zig");
+const Router = @import("./api/router.zig");
const TaggedPointerTypes = @import("../../tagged_pointer.zig");
const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion;
@@ -10,6 +11,11 @@ const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion;
pub const ExceptionValueRef = [*c]js.JSValueRef;
pub const JSValueRef = js.JSValueRef;
+fn ObjectPtrType(comptime Type: type) type {
+ if (Type == void) return Type;
+ return *Type;
+}
+
pub const To = struct {
pub const JS = struct {
pub inline fn str(ref: anytype, val: anytype) js.JSStringRef {
@@ -18,11 +24,11 @@ pub const To = struct {
pub fn functionWithCallback(
comptime ZigContextType: type,
- zig: *ZigContextType,
+ zig: ObjectPtrType(ZigContextType),
name: js.JSStringRef,
ctx: js.JSContextRef,
comptime callback: fn (
- obj: *ZigContextType,
+ obj: ObjectPtrType(ZigContextType),
ctx: js.JSContextRef,
function: js.JSObjectRef,
thisObject: js.JSObjectRef,
@@ -41,7 +47,7 @@ pub const To = struct {
pub fn Finalize(
comptime ZigContextType: type,
comptime ctxfn: fn (
- this: *ZigContextType,
+ this: ObjectPtrType(ZigContextType),
) void,
) type {
return struct {
@@ -109,7 +115,7 @@ pub const To = struct {
pub fn Callback(
comptime ZigContextType: type,
comptime ctxfn: fn (
- obj: *ZigContextType,
+ obj: ObjectPtrType(ZigContextType),
ctx: js.JSContextRef,
function: js.JSObjectRef,
thisObject: js.JSObjectRef,
@@ -137,6 +143,15 @@ pub const To = struct {
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
exception,
);
+ } else if (comptime ZigContextType == void) {
+ return ctxfn(
+ void{},
+ ctx,
+ function,
+ thisObject,
+ if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
+ exception,
+ );
} else {
return ctxfn(
GetJSPrivateData(ZigContextType, function) orelse GetJSPrivateData(ZigContextType, thisObject) orelse return js.JSValueMakeUndefined(ctx),
@@ -168,32 +183,6 @@ pub const To = struct {
};
};
-pub const RuntimeImports = struct {
- pub fn resolve(ctx: js.JSContextRef, str: string) ?js.JSObjectRef {
- switch (ModuleList.Map.get(str) orelse ModuleList.none) {
- .Router => {
- const Router = @import("./api/router.zig");
- return js.JSObjectMake(ctx, Router.Class.get().*, null);
- },
- else => {
- return null;
- },
- }
- }
-
- pub const ModuleList = enum(u8) {
- Router = 0,
- none = std.math.maxInt(u8),
-
- pub const Map = std.ComptimeStringMap(
- ModuleList,
- .{
- .{ "speedy.js/router", ModuleList.Router },
- },
- );
- };
-};
-
pub const Properties = struct {
pub const UTF8 = struct {
pub const module: string = "module";
@@ -751,6 +740,23 @@ pub fn NewClass(
}
};
+ pub fn throwInvalidConstructorError(ctx: js.JSContextRef, obj: js.JSObjectRef, c: usize, a: [*c]const js.JSValueRef, exception: js.ExceptionRef) callconv(.C) js.JSObjectRef {
+ JSError(getAllocator(ctx), "" ++ name ++ " is not a constructor", .{}, ctx, exception);
+ return null;
+ }
+
+ pub fn throwInvalidFunctionError(
+ ctx: js.JSContextRef,
+ function: js.JSObjectRef,
+ thisObject: js.JSObjectRef,
+ argumentCount: usize,
+ arguments: [*c]const js.JSValueRef,
+ exception: js.ExceptionRef,
+ ) callconv(.C) js.JSValueRef {
+ JSError(getAllocator(ctx), "" ++ name ++ " is not a function", .{}, ctx, exception);
+ return null;
+ }
+
pub const Constructor = ConstructorWrapper.rfn;
pub const static_value_count = static_properties.len;
@@ -872,7 +878,7 @@ pub fn NewClass(
prop: js.JSStringRef,
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
- var this = GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
+ var this: ObjectPtrType(ZigType) = if (comptime ZigType == void) void{} else GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
var exc: js.JSValueRef = null;
const Field = @TypeOf(@field(
@@ -902,7 +908,7 @@ pub fn NewClass(
const Func = @typeInfo(@TypeOf(func));
const WithPropFn = fn (
- *ZigType,
+ ObjectPtrType(ZigType),
js.JSContextRef,
js.JSObjectRef,
js.JSStringRef,
@@ -910,7 +916,7 @@ pub fn NewClass(
) js.JSValueRef;
const WithoutPropFn = fn (
- *ZigType,
+ ObjectPtrType(ZigType),
js.JSContextRef,
js.JSObjectRef,
js.ExceptionRef,
@@ -1292,7 +1298,7 @@ pub fn NewClass(
const ctxfn = CtxField.rfn;
const Func: std.builtin.TypeInfo.Fn = @typeInfo(@TypeOf(ctxfn)).Fn;
- const PointerType = std.meta.Child(Func.args[0].arg_type.?);
+ const PointerType = if (Func.args[0].arg_type.? == void) void else std.meta.Child(Func.args[0].arg_type.?);
var callback = if (Func.calling_convention == .C) ctxfn else To.JS.Callback(
PointerType,
@@ -1361,6 +1367,14 @@ pub fn NewClass(
def.className = class_name_str;
// def.getProperty = getPropertyCallback;
+ if (def.callAsConstructor == null) {
+ def.callAsConstructor = throwInvalidConstructorError;
+ }
+
+ if (def.callAsFunction == null) {
+ def.callAsFunction = throwInvalidFunctionError;
+ }
+
if (!singleton)
def.hasInstance = customHasInstance;
return def;
@@ -1422,6 +1436,7 @@ pub const JSPrivateDataPtr = TaggedPointerUnion(.{
FetchEvent,
Headers,
Body,
+ Router,
});
pub inline fn GetJSPrivateData(comptime Type: type, ref: js.JSObjectRef) ?*Type {
diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig
index 89297aaf6..f1996ae0f 100644
--- a/src/javascript/jsc/bindings/exports.zig
+++ b/src/javascript/jsc/bindings/exports.zig
@@ -91,16 +91,18 @@ pub const ZigGlobalObject = extern struct {
return @call(.{ .modifier = .always_inline }, Interface.onCrash, .{});
}
- pub const Export = shim.exportFunctions(.{
- .@"import" = import,
- .@"resolve" = resolve,
- .@"fetch" = fetch,
- // .@"eval" = eval,
- .@"promiseRejectionTracker" = promiseRejectionTracker,
- .@"reportUncaughtException" = reportUncaughtException,
- .@"createImportMetaProperties" = createImportMetaProperties,
- .@"onCrash" = onCrash,
- });
+ pub const Export = shim.exportFunctions(
+ .{
+ .@"import" = import,
+ .@"resolve" = resolve,
+ .@"fetch" = fetch,
+ // .@"eval" = eval,
+ .@"promiseRejectionTracker" = promiseRejectionTracker,
+ .@"reportUncaughtException" = reportUncaughtException,
+ .@"createImportMetaProperties" = createImportMetaProperties,
+ .@"onCrash" = onCrash,
+ },
+ );
pub const Extern = [_][]const u8{ "create", "getModuleRegistryMap", "resetModuleRegistryMap" };
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index b681a4cee..1de47d46e 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -18,8 +18,8 @@ usingnamespace @import("./webcore/response.zig");
usingnamespace @import("./config.zig");
usingnamespace @import("./bindings/exports.zig");
usingnamespace @import("./bindings/bindings.zig");
-
const Runtime = @import("../../runtime.zig");
+const Router = @import("./api/router.zig");
pub const GlobalClasses = [_]type{
Request.Class,
@@ -28,6 +28,34 @@ pub const GlobalClasses = [_]type{
EventListenerMixin.addEventListener(VirtualMachine),
BuildError.Class,
ResolveError.Class,
+ Wundle.Class,
+};
+
+pub const Wundle = struct {
+ top_level_dir: string,
+
+ pub const Class = NewClass(
+ void,
+ .{
+ .name = "Wundle",
+ .read_only = true,
+ .ts = .{
+ .module = .{
+ .path = "speedy.js/router",
+ .tsdoc = "Filesystem Router supporting dynamic routes, exact routes, catch-all routes, and optional catch-all routes. Implemented in native code and only available with Speedy.js.",
+ },
+ },
+ },
+ .{
+ .match = .{
+ .rfn = Router.match,
+ .ts = Router.match_type_definition,
+ },
+ },
+ .{
+ .Route = Router.Instance.GetClass(void){},
+ },
+ );
};
pub const LazyClasses = [_]type{};
@@ -317,6 +345,7 @@ pub const VirtualMachine = struct {
pub fn resolve(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString) void {
var result = ResolveFunctionResult{ .path = "", .result = null };
+
_resolve(&result, global, specifier.slice(), source.slice()) catch |err| {
// This should almost always just apply to dynamic imports