add some missing APIs to Console

This commit is contained in:
Karl Seguin
2026-01-10 17:45:25 +08:00
parent 516a86e33f
commit 10035ab2f4
2 changed files with 105 additions and 17 deletions

View File

@@ -53,6 +53,10 @@ pub fn toString(self: Value, allocator: Allocator) ![]const u8 {
return self.context.valueToString(self.js_val, .{ .allocator = allocator }); return self.context.valueToString(self.js_val, .{ .allocator = allocator });
} }
pub fn toBool(self: Value) bool {
return self.js_val.toBool(self.context.isolate);
}
pub fn fromJson(ctx: *js.Context, json: []const u8) !Value { pub fn fromJson(ctx: *js.Context, json: []const u8) !Value {
const json_string = v8.String.initUtf8(ctx.isolate, json); const json_string = v8.String.initUtf8(ctx.isolate, json);
const value = try v8.Json.parse(ctx.v8_context, json_string); const value = try v8.Json.parse(ctx.v8_context, json_string);
@@ -86,19 +90,3 @@ pub fn toArray(self: Value) js.Array {
.js_arr = self.js_val.castTo(v8.Array), .js_arr = self.js_val.castTo(v8.Array),
}; };
} }
// pub const Value = struct {
// value: v8.Value,
// context: *const Context,
// // the caller needs to deinit the string returned
// pub fn toString(self: Value, allocator: Allocator) ![]const u8 {
// return self.context.valueToString(self.value, .{ .allocator = allocator });
// }
// pub fn fromJson(ctx: *Context, json: []const u8) !Value {
// const json_string = v8.String.initUtf8(ctx.isolate, json);
// const value = try v8.Json.parse(ctx.v8_context, json_string);
// return Value{ .context = ctx, .value = value };
// }
// };

View File

@@ -23,10 +23,27 @@ const Page = @import("../Page.zig");
const logger = @import("../../log.zig"); const logger = @import("../../log.zig");
const Console = @This(); const Console = @This();
_pad: bool = false,
_timers: std.StringHashMapUnmanaged(u64) = .{},
_counts: std.StringHashMapUnmanaged(u64) = .{},
pub const init: Console = .{}; pub const init: Console = .{};
pub fn trace(_: *const Console, values: []js.Object, page: *Page) !void {
logger.debug(.js, "console.trace", .{
.stack = page.js.stackTrace() catch "???",
.args = ValueWriter{ .page = page, .values = values },
});
}
pub fn debug(_: *const Console, values: []js.Object, page: *Page) void {
logger.debug(.js, "console.debug", .{ValueWriter{ .page = page, .values = values }});
}
pub fn info(_: *const Console, values: []js.Object, page: *Page) void {
logger.info(.js, "console.info", .{ValueWriter{ .page = page, .values = values }});
}
pub fn log(_: *const Console, values: []js.Object, page: *Page) void { pub fn log(_: *const Console, values: []js.Object, page: *Page) void {
logger.info(.js, "console.log", .{ValueWriter{ .page = page, .values = values }}); logger.info(.js, "console.log", .{ValueWriter{ .page = page, .values = values }});
} }
@@ -35,10 +52,82 @@ pub fn warn(_: *const Console, values: []js.Object, page: *Page) void {
logger.warn(.js, "console.warn", .{ValueWriter{ .page = page, .values = values }}); logger.warn(.js, "console.warn", .{ValueWriter{ .page = page, .values = values }});
} }
pub fn clear(_: *const Console) void {}
pub fn assert(_: *const Console, assertion: js.Value, values: []js.Object, page: *Page) void {
if (assertion.toBool()) {
return;
}
logger.warn(.js, "console.assert", .{ValueWriter{ .page = page, .values = values }});
}
pub fn @"error"(_: *const Console, values: []js.Object, page: *Page) void { pub fn @"error"(_: *const Console, values: []js.Object, page: *Page) void {
logger.warn(.js, "console.error", .{ValueWriter{ .page = page, .values = values, .include_stack = true }}); logger.warn(.js, "console.error", .{ValueWriter{ .page = page, .values = values, .include_stack = true }});
} }
pub fn count(self: *Console, label_: ?[]const u8, page: *Page) !void {
const label = label_ orelse "default";
const gop = try self._counts.getOrPut(page.arena, label);
var current: u64 = 0;
if (gop.found_existing) {
current = gop.value_ptr.*;
} else {
gop.key_ptr.* = try page.dupeString(label);
}
const c = current + 1;
gop.value_ptr.* = c;
logger.info(.js, "console.count", .{ .label = label, .count = c });
}
pub fn countReset(self: *Console, label_: ?[]const u8) !void {
const label = label_ orelse "default";
const kv = self._counts.fetchRemove(label) orelse {
logger.info(.js, "console.countReset", .{ .label = label, .err = "invalid label" });
return;
};
logger.info(.js, "console.countReset", .{ .label = label, .count = kv.value });
}
pub fn time(self: *Console, label_: ?[]const u8, page: *Page) !void {
const label = label_ orelse "default";
const gop = try self._timers.getOrPut(page.arena, label);
if (gop.found_existing) {
logger.info(.js, "console.time", .{ .label = label, .err = "duplicate timer" });
return;
}
gop.key_ptr.* = try page.dupeString(label);
gop.value_ptr.* = timestamp();
}
pub fn timeLog(self: *Console, label_: ?[]const u8) void {
const elapsed = timestamp();
const label = label_ orelse "default";
const start = self._timers.get(label) orelse {
logger.info(.js, "console.timeLog", .{ .label = label, .err = "invalid timer" });
return;
};
logger.info(.js, "console.timeLog", .{ .label = label, .elapsed = elapsed - start });
}
pub fn timeEnd(self: *Console, label_: ?[]const u8) void {
const elapsed = timestamp();
const label = label_ orelse "default";
const kv = self._timers.fetchRemove(label) orelse {
logger.info(.js, "console.timeEnd", .{ .label = label, .err = "invalid timer" });
return;
};
logger.info(.js, "console.timeEnd", .{ .label = label, .elapsed = elapsed - kv.value });
}
fn timestamp() u64 {
return @import("../../datetime.zig").timestamp(.monotonic);
}
const ValueWriter = struct { const ValueWriter = struct {
page: *Page, page: *Page,
values: []js.Object, values: []js.Object,
@@ -81,7 +170,18 @@ pub const JsApi = struct {
pub const empty_with_no_proto = true; pub const empty_with_no_proto = true;
}; };
pub const trace = bridge.function(Console.trace, .{});
pub const debug = bridge.function(Console.debug, .{});
pub const info = bridge.function(Console.info, .{});
pub const log = bridge.function(Console.log, .{}); pub const log = bridge.function(Console.log, .{});
pub const warn = bridge.function(Console.warn, .{}); pub const warn = bridge.function(Console.warn, .{});
pub const clear = bridge.function(Console.clear, .{});
pub const assert = bridge.function(Console.assert, .{});
pub const @"error" = bridge.function(Console.@"error", .{}); pub const @"error" = bridge.function(Console.@"error", .{});
pub const exception = bridge.function(Console.@"error", .{});
pub const count = bridge.function(Console.count, .{});
pub const countReset = bridge.function(Console.countReset, .{});
pub const time = bridge.function(Console.time, .{});
pub const timeLog = bridge.function(Console.timeLog, .{});
pub const timeEnd = bridge.function(Console.timeEnd, .{});
}; };