fix: wasi build of site

This commit is contained in:
Nurul Huda (Apon) 2026-03-22 21:34:28 +06:00
parent 46be5acac2
commit 754c9246cd
No known key found for this signature in database
GPG Key ID: 5D3F1DE2855A2F79
13 changed files with 205 additions and 20 deletions

View File

@ -73,4 +73,38 @@ jobs:
uses: actions/checkout@v4
- name: Deploy ssr.ziex.dev
run: bash tools/docdeploy
run: bash tools/docdeploy
deploy:
environment:
name: edge
url: https://site.ziex.workers.dev
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v4
- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: 0.15.2
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: 1.3.5
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Install Node Dependencies
run: cd site && bun install
- name: Deploy to Edge
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: ./site

View File

@ -117,7 +117,7 @@ fn serverStateUpdateHandler(e: *zx.server.Event.Stateful) void {
}
// This should be a server action
fn handleSubmit(ctx: zx.ActionContext) void {
fn handleSubmit(ctx: zx.server.Action) void {
// const formdata = ctx.request.formData();
// const username = formdata.get("username") orelse "";
@ -145,7 +145,7 @@ const FormData = struct {
};
// This should be a server action
fn typedform(ctx: zx.ActionContext) void {
fn typedform(ctx: zx.server.Action) void {
const data = ctx.data(FormData);
std.log.info("server form handler name: {s}, id: {d}", .{data.name, data.id});

View File

@ -88,7 +88,6 @@ pub const ComponentCtx = ctxs.ComponentCtx;
pub const ComponentContext = ComponentCtx(void);
pub const StateContext = @import("runtime/core/Event.zig").StateContext;
pub const StateHandle = @import("runtime/core/Event.zig").StateHandle;
pub const ActionContext = ctxs.ActionContext;
pub const BuiltinAttribute = @import("attributes.zig").builtin;
pub const Platform = plfm.Platform;

View File

@ -36,7 +36,7 @@ callback: *const fn (ctx: *anyopaque, event: zx.client.Event) void,
context: *anyopaque,
/// Non-null when created from a form `action={}` handler.
/// Takes a pointer so the server wrapper can write `_state_ctx` back after the call.
action_fn: ?*const fn (*zx.ActionContext) void = null,
action_fn: ?*const fn (*zx.server.Action) void = null,
/// Server-side handler; takes *ServerEventContext so the wrapper can set _state_ctx.
server_event_fn: ?*const fn (*zx.server.Event) void = null,
/// Unique ID for this handler instance on the current page.
@ -52,13 +52,13 @@ pub fn wrap(comptime func: anytype) Self {
const fn_info = @typeInfo(FnType);
const params = fn_info.@"fn".params;
// Server action: fn (zx.ActionContext) void
// Server action: fn (zx.server.Action) void
if (comptime params.len == 1) {
const arg_type = params[0].type.?;
switch (arg_type) {
zx.ActionContext => {
zx.server.Action => {
const Wrap = struct {
fn w(ctx: *zx.ActionContext) void {
fn w(ctx: *zx.server.Action) void {
func(ctx.*);
}
};
@ -122,12 +122,12 @@ pub fn action(comptime func: anytype) Self {
if (comptime params.len == 1) {
const arg_type = params[0].type.?;
if (comptime @typeInfo(arg_type) == .@"struct" and
arg_type != zx.ActionContext and
arg_type != zx.server.Action and
arg_type != zx.client.Event and
arg_type != zx.server.Event)
{
const DirectTyped = struct {
fn w(ctx: *zx.ActionContext) void {
fn w(ctx: *zx.server.Action) void {
func(ctx.data(arg_type));
}
};
@ -321,7 +321,11 @@ pub fn actionHandler(ctx: *anyopaque, event: zx.client.Event) void {
client_fetch.fetchAsync(
getGlobalAllocator(),
"",
.{ .method = .GET, .headers = &headers, .body = "{}", },
.{
.method = .GET,
.headers = &headers,
.body = "{}",
},
onActionResponse,
);
}

View File

@ -1,6 +1,7 @@
const server = @import("server/Server.zig");
pub const Event = @import("server/Event.zig");
pub const Action = @import("../contexts.zig").ActionContext;
// Legacy --- will be renamed
pub const SerilizableAppMeta = server.SerilizableAppMeta;

View File

@ -71,7 +71,7 @@ pub fn dispatchAction(
const is_js = request.headers.has("x-zx-action");
if (registry.get(route_path)) |action_fn| {
var action_ctx = zx.ActionContext{
var action_ctx = zx.server.Action{
.request = request,
.response = response,
.allocator = allocator,
@ -90,7 +90,7 @@ pub fn dispatchAction(
}
if (registry.get(route_path)) |action_fn| {
var action_ctx = zx.ActionContext{
var action_ctx = zx.server.Action{
.request = request,
.response = response,
.allocator = allocator,

View File

@ -1,7 +1,7 @@
const std = @import("std");
const zx = @import("../../root.zig");
pub const ActionFn = *const fn (*zx.ActionContext) void;
pub const ActionFn = *const fn (*zx.server.Action) void;
pub const ServerEventFn = *const fn (*zx.server.Event) void;
var mu: std.Thread.Mutex = .{};

View File

@ -151,6 +151,7 @@ pub fn run() !void {
// --- Server Action Dispatch --- //
switch (try server_dispatch.dispatchAction(request, response, allocator, allocator, route.path, pagectx, route.page)) {
.not_triggered => {},
.ok_native => {},
.ok => |r| {
if (r.body) |body| {
wasi_res.setContentTypeStr("application/json");
@ -179,6 +180,7 @@ pub fn run() !void {
// --- Server Event Dispatch --- //
switch (try server_dispatch.dispatchServerEvent(request, allocator, allocator, route.path, pagectx, route.page)) {
.not_triggered => {},
.ok_native => {},
.ok => |r| {
wasi_res.setContentTypeStr("application/json");
wasi_res.body.deinit();

View File

@ -1,14 +1,73 @@
pub fn Page(ctx: zx.PageContext) zx.Component {
return (
<main @allocator={ctx.arena}>
<p>{get_about_zx()}</p>
<a href="/">Back to Home</a>
// <LoginForm @rendering={.client} />
<EventForm @rendering={.client} />
</main>
);
}
pub fn get_about_zx() []const u8 {
return "Ziex is a framework for building web applications with Zig.";
pub fn LoginForm(ctx: *zx.ComponentContext) zx.Component {
const msg = ctx.state([]const u8, "Please log in");
return (
<form @allocator={ctx.allocator} action={handleLogin}>
<p>{msg}</p>
<input placeholder="Enter name" name="name" defaultValue="John Doe" required />
<input placeholder="Enter ID" name="id" defaultValue="123" required />
<input placeholder="Photo" type="file" name="file" />
<button>Submit</button>
</form>
);
}
const LoginInput = struct {
name: []const u8,
id: i32,
file: []const u8,
};
fn handleLogin(data: LoginInput) void {
zx.log.info(
"\n\nName: {s}\nID: {d}\nFile: {s}\n",
.{ data.name, data.id, data.file },
);
}
fn handleSubmit(data: LoginInput, sc: *zx.StateContext) void {
sc.state([]const u8).set(sc.fmt(
"Hello, {s}!",
.{data.name},
) catch "Err");
zx.log.info(
"\n\nName: {s}\nID: {d}\nFile: {s}\n",
.{ data.name, data.id, data.file },
);
}
pub fn EventForm(
ctx: *zx.ComponentContext,
) zx.Component {
const count = ctx.state(i32, 1);
return (
<button onclick={ctx.bind(onclick)}>
Click Me {count}
</button>
);
}
fn onclick(
e: *zx.server.Event.Stateful,
) void {
const c = e.state(i32);
c.set(c.get() + 1);
zx.log.info("d{d} \n", .{c.get()});
}
pub const options: zx.PageOptions = .{
.methods = &.{ .GET, .POST },
};
const zx = @import("zx");

View File

@ -0,0 +1,28 @@
pub fn Page(ctx: zx.PageContext) zx.Component {
return (
<main @allocator={ctx.arena}>
<EventForm @rendering={.client} />
</main>
);
}
pub fn EventForm(ctx: *zx.ComponentContext) zx.Component {
const count = ctx.state(i32, 1);
return (
<button onclick={ctx.bind(onclick)}>
Click Me {count}
</button>
);
}
fn onclick(e: *zx.client.Event.Stateful) void {
const c = e.state(i32);
c.set(c.get() + 1);
zx.log.info("Count> {d}. \n", .{c.get()});
}
pub const options: zx.PageOptions = .{
.methods = &.{ .GET, .POST },
};
const zx = @import("zx");

View File

@ -0,0 +1,30 @@
pub fn Page(ctx: zx.PageContext) zx.Component {
return (
<main @allocator={ctx.arena}>
<LoginForm @rendering={.client} name="Ziex Client" />
<LoginForm name="Ziex Server" />
</main>
);
}
const LoginInput = struct { name: []const u8, id: i32 = 123 };
pub fn LoginForm(ctx: *zx.ComponentCtx(LoginInput)) zx.Component {
return (
<form @allocator={ctx.allocator} action={handleLogin}>
<input name="name" value={ctx.props.name} />
<input name="id" value={ctx.props.id} />
<button>Submit</button>
</form>
);
}
fn handleLogin(data: LoginInput) void {
zx.log.info("\n\nName: {s}\nID: {d}\n", .{ data.name, data.id });
}
pub const options: zx.PageOptions = .{
.methods = &.{.POST},
};
const zx = @import("zx");

View File

@ -0,0 +1,28 @@
pub fn Page(ctx: zx.PageContext) zx.Component {
return (
<main @allocator={ctx.arena}>
<EventForm @rendering={.client} />
</main>
);
}
pub fn EventForm(ctx: *zx.ComponentContext) zx.Component {
const count = ctx.state(i32, 1);
return (
<button onclick={ctx.bind(onclick)}>
Click Me {count}
</button>
);
}
fn onclick(e: *zx.server.Event.Stateful) void {
const c = e.state(i32);
c.set(c.get() + 1);
zx.log.info("Count> {d}. \n", .{c.get()});
}
pub const options: zx.PageOptions = .{
.methods = &.{ .GET, .POST },
};
const zx = @import("zx");

View File

@ -5,8 +5,8 @@
.minimum_zig_version = "0.15.2",
.dependencies = .{
.zx = .{
.url = "git+https://github.com/ziex-dev/ziex#3f6ff52c055d83d0ac50811e08e9d8c202439b53",
.hash = "zx-0.1.0-dev.805-8okzKum06wBFG7SgsZ6Y-wSUZDOXlo1PRNxqBOtFXVZM",
.url = "git+https://github.com/ziex-dev/ziex#46be5acac2c0cc75b66435fcdfb99543bf76cf7d",
.hash = "zx-0.1.0-dev.805-8okzKvtB7ACTCWIhE8utCDb7qZkTBSt3GG569zDV4lYS",
},
},
.paths = .{