Skip to content

Commit b9d12a6

Browse files
committed
Fix depleted account handling and UI
1 parent 0404c89 commit b9d12a6

5 files changed

Lines changed: 45 additions & 12 deletions

File tree

build.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,9 @@ pub fn build(b: *std.Build) void {
313313

314314
const backend_tests = b.addTest(.{
315315
.root_module = b.createModule(.{
316-
.root_source_file = b.path("src/rpc.zig"),
316+
// Keep package root at repo root so @embedFile("../frontend/...") used by
317+
// imported modules remains inside package boundaries during tests.
318+
.root_source_file = b.path("rpc_tests.zig"),
317319
.target = target,
318320
.optimize = optimize,
319321
.strip = strip_symbols,

frontend/src/lib/codexAuth.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,34 @@ const decodeBridgeValue = <T>(op: string, value: unknown): T => {
345345
return value as T;
346346
};
347347

348-
const callBridge = async <T>(op: string, payload: Record<string, unknown> = {}): Promise<T> => {
349-
const request = JSON.stringify({ op, ...payload });
348+
const getWebuiBridge = (): WebuiRpcBridge | null => {
350349
const bridge = (globalThis as { webuiRpc?: WebuiRpcBridge }).webuiRpc;
351350
if (!bridge || typeof bridge.cm_rpc !== "function") {
352-
throw new Error("WebUI bridge is unavailable (webuiRpc.cm_rpc missing).");
351+
return null;
353352
}
353+
return bridge;
354+
};
354355

356+
const waitForWebuiBridge = async (): Promise<WebuiRpcBridge> => {
357+
const immediate = getWebuiBridge();
358+
if (immediate) {
359+
return immediate;
360+
}
361+
362+
for (let attempt = 0; attempt < 40; attempt += 1) {
363+
await new Promise((resolve) => window.setTimeout(resolve, 25));
364+
const bridge = getWebuiBridge();
365+
if (bridge) {
366+
return bridge;
367+
}
368+
}
369+
370+
throw new Error("WebUI bridge is unavailable (webuiRpc.cm_rpc missing).");
371+
};
372+
373+
const callBridge = async <T>(op: string, payload: Record<string, unknown> = {}): Promise<T> => {
374+
const request = JSON.stringify({ op, ...payload });
375+
const bridge = await waitForWebuiBridge();
355376
const rawResponse = await bridge.cm_rpc(request);
356377
return decodeBridgeValue<T>(op, rawResponse);
357378
};

rpc_tests.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const _ = @import("src/rpc.zig");
2+
3+
test {
4+
// Tests are defined in src/rpc.zig and are included via import.
5+
}

src/main.zig

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const builtin = @import("builtin");
23
const webui = @import("webui");
34

45
const embedded_index = @import("embedded_index.zig");
@@ -31,8 +32,16 @@ var oauth_listener_cancel = std.atomic.Value(bool).init(false);
3132

3233
pub fn main() !void {
3334
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
34-
defer _ = gpa.deinit();
35-
const allocator = gpa.allocator();
35+
defer {
36+
if (builtin.mode == .Debug) {
37+
_ = gpa.deinit();
38+
}
39+
}
40+
41+
const allocator = if (builtin.mode == .Debug)
42+
gpa.allocator()
43+
else
44+
std.heap.smp_allocator;
3645

3746
const args = try std.process.argsAlloc(allocator);
3847
defer std.process.argsFree(allocator, args);

src/rpc_webui.zig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ pub const RpcBridgeMethods = struct {
2222
};
2323
defer std.heap.page_allocator.free(rpc_response);
2424

25-
bridge_response_lock.lock();
26-
defer bridge_response_lock.unlock();
27-
2825
if (rpc_response.len > bridge_response_storage.len) {
2926
return .{ .data = "{\"ok\":false,\"error\":\"RPC response exceeds bridge buffer\"}" };
3027
}
@@ -36,9 +33,8 @@ pub const RpcBridgeMethods = struct {
3633
};
3734

3835
var bridge_cancel_ptr: ?*std.atomic.Value(bool) = null;
39-
var bridge_response_lock: std.Thread.Mutex = .{};
40-
var bridge_response_storage: [8 * 1024 * 1024]u8 = undefined;
41-
var bridge_response_len: usize = 0;
36+
threadlocal var bridge_response_storage: [8 * 1024 * 1024]u8 = undefined;
37+
threadlocal var bridge_response_len: usize = 0;
4238

4339
pub fn setCancelPointer(cancel_ptr: *std.atomic.Value(bool)) void {
4440
bridge_cancel_ptr = cancel_ptr;

0 commit comments

Comments
 (0)