create-ziex 0.1.0-dev.1 → 0.1.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +77 -0
- package/package.json +12 -1
- package/tmp/cf/.gitattributes +3 -0
- package/tmp/cf/LICENSE +19 -0
- package/tmp/cf/README.md +82 -0
- package/tmp/cf/app/assets/style.css +55 -0
- package/tmp/cf/app/main.ts +4 -0
- package/tmp/cf/app/main.zig +19 -0
- package/tmp/cf/app/pages/about/page.zx +14 -0
- package/tmp/cf/app/pages/client.zx +35 -0
- package/tmp/cf/app/pages/layout.zx +18 -0
- package/tmp/cf/app/pages/page.zx +28 -0
- package/tmp/cf/app/public/favicon.ico +0 -0
- package/tmp/cf/build.zig +32 -0
- package/tmp/cf/build.zig.zon +17 -0
- package/tmp/cf/package.json +15 -0
- package/tmp/cf/type.d.ts +6 -0
- package/tmp/cf/wrangler.jsonc +20 -0
- package/tmp/test-real/.gitattributes +3 -0
- package/tmp/test-real/.vercelignore +16 -0
- package/tmp/test-real/LICENSE +19 -0
- package/tmp/test-real/README.md +85 -0
- package/tmp/test-real/api/index.ts +7 -0
- package/tmp/test-real/api/nodejs.ts +9 -0
- package/tmp/test-real/app/assets/style.css +55 -0
- package/tmp/test-real/app/main.zig +19 -0
- package/tmp/test-real/app/pages/about/page.zx +14 -0
- package/tmp/test-real/app/pages/client.zx +35 -0
- package/tmp/test-real/app/pages/layout.zx +18 -0
- package/tmp/test-real/app/pages/page.zx +28 -0
- package/tmp/test-real/app/public/favicon.ico +0 -0
- package/tmp/test-real/build.zig +39 -0
- package/tmp/test-real/build.zig.zon +17 -0
- package/tmp/test-real/package.json +14 -0
- package/tmp/test-real/type.d.ts +6 -0
- package/tmp/test-real/vercel.json +12 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { intro, outro, text, select, spinner, isCancel, cancel } from '@clack/prompts';
|
|
4
|
+
import color from 'picocolors';
|
|
5
|
+
import { downloadTemplate } from 'giget';
|
|
6
|
+
import { replaceInFile } from 'replace-in-file';
|
|
7
|
+
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
console.log();
|
|
12
|
+
intro(color.bgCyan(color.black(' create-ziex ')));
|
|
13
|
+
|
|
14
|
+
// 1. Gather User Input
|
|
15
|
+
const project = await text({
|
|
16
|
+
message: 'Where should we create your project?',
|
|
17
|
+
placeholder: './my-ziex-app',
|
|
18
|
+
validate: (value) => {
|
|
19
|
+
if (!value) return 'Please enter a path.';
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (isCancel(project)) {
|
|
24
|
+
cancel('Operation cancelled.');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const template = await select({
|
|
29
|
+
message: 'Pick a template',
|
|
30
|
+
options: [
|
|
31
|
+
{ value: 'vercel', label: 'Vercel', hint: 'Ziex on Vercel' },
|
|
32
|
+
{ value: 'cloudflare', label: 'Cloudflare', hint: 'Ziex on Cloudflare' },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const s = spinner();
|
|
37
|
+
const targetDir = path.resolve(process.cwd(), project);
|
|
38
|
+
|
|
39
|
+
// 2. Download from GitHub
|
|
40
|
+
s.start('Downloading template...');
|
|
41
|
+
try {
|
|
42
|
+
// Uses giget to fetch from: github:ziex-dev/templates/templates/<name>
|
|
43
|
+
await downloadTemplate(`github:ziex-dev/template-${template}`, {
|
|
44
|
+
dir: targetDir,
|
|
45
|
+
force: true,
|
|
46
|
+
});
|
|
47
|
+
s.stop('Template downloaded successfully!');
|
|
48
|
+
} catch (err) {
|
|
49
|
+
s.stop('Failed to download template', 1);
|
|
50
|
+
console.error(err);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. Perform String Replacements
|
|
55
|
+
s.start('Customizing project files...');
|
|
56
|
+
try {
|
|
57
|
+
const projectName = sanitizeProjectName(path.basename(targetDir));
|
|
58
|
+
await replaceInFile({
|
|
59
|
+
files: `${targetDir}/**/*`,
|
|
60
|
+
from: /zx_app/g,
|
|
61
|
+
to: projectName,
|
|
62
|
+
});
|
|
63
|
+
s.stop('Project customized!');
|
|
64
|
+
} catch (err) {
|
|
65
|
+
s.stop('Replacement failed', 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
outro(`Successfully created ${color.cyan(project)}!`);
|
|
69
|
+
console.log(`\n cd ${project}\n zig build dev\n`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Make sure project name is suported Zig identifier
|
|
73
|
+
function sanitizeProjectName(name) {
|
|
74
|
+
return name.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ziex",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.2",
|
|
4
|
+
"bin": "bin/index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@clack/prompts": "^1.1.0",
|
|
11
|
+
"giget": "^3.1.2",
|
|
12
|
+
"picocolors": "^1.1.1",
|
|
13
|
+
"replace-in-file": "^8.4.0"
|
|
14
|
+
}
|
|
4
15
|
}
|
package/tmp/cf/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2025 Nurul Huda (Apon).
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
package/tmp/cf/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Ziex App on Cloudflare
|
|
2
|
+
|
|
3
|
+
> A starter template for building web applications with [Ziex](https://ziex.dev) deployed on [Cloudflare Workers](https://workers.cloudflare.com/).
|
|
4
|
+
|
|
5
|
+
**[Documentation →](https://ziex.dev)**
|
|
6
|
+
|
|
7
|
+
[](https://deploy.workers.cloudflare.com/?url=https://github.com/ziex-dev/template-cloudflare)
|
|
8
|
+
|
|
9
|
+
## Getting Started
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
**1. Install ZX CLI**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Linux/macOS
|
|
17
|
+
curl -fsSL https://ziex.dev/install | bash
|
|
18
|
+
|
|
19
|
+
# Windows
|
|
20
|
+
powershell -c "irm ziex.dev/install.ps1 | iex"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**2. Install Zig**
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
brew install zig # macOS
|
|
27
|
+
winget install -e --id zig.zig # Windows
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
[_Other platforms →_](https://ziglang.org/learn/getting-started/)
|
|
31
|
+
|
|
32
|
+
**3. Install Node.js** (for Wrangler)
|
|
33
|
+
|
|
34
|
+
[_Download →_](https://nodejs.org/)
|
|
35
|
+
|
|
36
|
+
## Project Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
├── app/
|
|
40
|
+
│ ├── assets/ # Static assets (CSS, images, etc)
|
|
41
|
+
│ ├── main.ts # Cloudflare Worker entrypoint
|
|
42
|
+
│ ├── main.zig # Zig entrypoint
|
|
43
|
+
│ ├── pages/ # Pages (Zig/ZX)
|
|
44
|
+
│ │ ├── layout.zx # Root layout
|
|
45
|
+
│ │ ├── page.zx # Home page
|
|
46
|
+
│ │ ├── client.zx # Client-side component
|
|
47
|
+
│ │ └── ...
|
|
48
|
+
│ └── public/ # Public static files (favicon, etc)
|
|
49
|
+
├── build.zig # Zig build script
|
|
50
|
+
├── build.zig.zon # Zig package manager config
|
|
51
|
+
├── wrangler.jsonc # Cloudflare Workers config
|
|
52
|
+
└── package.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
### Development
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
zig build dev
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
App will be available at [`http://localhost:3000`](http://localhost:3000) with hot reload enabled.
|
|
64
|
+
|
|
65
|
+
### Deploy to Cloudflare
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx wrangler deploy
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or click the **Deploy to Cloudflare Workers** button above for one-click deployment.
|
|
72
|
+
|
|
73
|
+
## Contributing
|
|
74
|
+
|
|
75
|
+
Contributions are welcome! For feature requests, bug reports, or questions, see the [Ziex Repo](https://github.com/ziex-dev/ziex).
|
|
76
|
+
|
|
77
|
+
## Links
|
|
78
|
+
|
|
79
|
+
- [Documentation](https://ziex.dev)
|
|
80
|
+
- [Discord](https://ziex.dev/r/discord)
|
|
81
|
+
- [Cloudflare Workers Docs](https://developers.cloudflare.com/workers/)
|
|
82
|
+
- [Zig Language](https://ziglang.org/)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
font-family: sans-serif;
|
|
4
|
+
font-size: 1.4rem;
|
|
5
|
+
line-height: 1.6;
|
|
6
|
+
color: white;
|
|
7
|
+
background-color: black;
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
text-align: center;
|
|
13
|
+
height: 100vh;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
color: #ffffff;
|
|
18
|
+
font-size: 1rem;
|
|
19
|
+
text-decoration: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
button {
|
|
23
|
+
padding: 2px;
|
|
24
|
+
min-width: 100px;
|
|
25
|
+
font-size: 0.8rem;
|
|
26
|
+
border-radius: 5px;
|
|
27
|
+
margin: 3px;
|
|
28
|
+
border: 1px solid #ffffff;
|
|
29
|
+
background-color: transparent;
|
|
30
|
+
color: #ffffff;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
transition: all 0.3s ease;
|
|
33
|
+
&:hover {
|
|
34
|
+
background-color: #ffffff;
|
|
35
|
+
color: #000000;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.counter-row {
|
|
40
|
+
height: 150px;
|
|
41
|
+
margin: 10px;
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: 20px;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.counter-row > * {
|
|
49
|
+
min-width: 150px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.counter-plus {
|
|
53
|
+
width: 70px;
|
|
54
|
+
display: inline-block;
|
|
55
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const zx = @import("zx");
|
|
3
|
+
|
|
4
|
+
pub fn main() !void {
|
|
5
|
+
if (zx.platform == .browser) return zx.Client.run();
|
|
6
|
+
if (zx.platform == .edge) return zx.Edge.run();
|
|
7
|
+
|
|
8
|
+
var gpa = std.heap.DebugAllocator(.{}){};
|
|
9
|
+
const allocator = gpa.allocator();
|
|
10
|
+
defer _ = gpa.deinit();
|
|
11
|
+
|
|
12
|
+
const app = try zx.Server(void).init(allocator, .{}, {});
|
|
13
|
+
defer app.deinit();
|
|
14
|
+
|
|
15
|
+
app.info();
|
|
16
|
+
try app.start();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub const std_options = zx.std_options;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
pub fn Page(ctx: zx.PageContext) zx.Component {
|
|
2
|
+
return (
|
|
3
|
+
<main @allocator={ctx.arena}>
|
|
4
|
+
<p>{get_about_zx()}</p>
|
|
5
|
+
<a href="/">Back to Home</a>
|
|
6
|
+
</main>
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
pub fn get_about_zx() []const u8 {
|
|
11
|
+
return "Ziex is a framework for building web applications with Zig.";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var count: *zx.State(i128) = undefined;
|
|
2
|
+
|
|
3
|
+
pub fn CounterComponent(ctx: *zx.ComponentCtx(struct { count: i128 })) zx.Component {
|
|
4
|
+
count = ctx.state(i128, ctx.props.count);
|
|
5
|
+
|
|
6
|
+
return (
|
|
7
|
+
<div @allocator={ctx.allocator}>
|
|
8
|
+
<button onclick={reset}>Reset</button>
|
|
9
|
+
<h5>{&count}</h5>
|
|
10
|
+
<button onclick={decrement}>Decrement</button>
|
|
11
|
+
<button onclick={increment}>Increment</button>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fn increment() void {
|
|
17
|
+
count.set(count.get() + 1);
|
|
18
|
+
fetch("?increment=true");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fn decrement() void {
|
|
22
|
+
count.set(count.get() - 1);
|
|
23
|
+
fetch("?decrement=true");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn reset(_: zx.client.Event) void {
|
|
27
|
+
count.set(0);
|
|
28
|
+
fetch("?reset=true");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn fetch(url: []const u8) void {
|
|
32
|
+
_ = zx.fetch(.noop, zx.client_allocator, url, .{}) catch {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
pub fn Layout(ctx: zx.LayoutContext, children: zx.Component) zx.Component {
|
|
2
|
+
return (
|
|
3
|
+
<html @allocator={ctx.arena} lang="en-US">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<title>Ziex</title>
|
|
7
|
+
<link rel="stylesheet" href="/assets/style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<h1>Ziex</h1>
|
|
12
|
+
{children}
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
pub fn Page(ctx: zx.PageContext) !zx.Component {
|
|
2
|
+
const query = ctx.request.searchParams;
|
|
3
|
+
|
|
4
|
+
if (query.get("reset")) |_|
|
|
5
|
+
count = 0
|
|
6
|
+
else if (query.get("increment")) |_|
|
|
7
|
+
count += 1
|
|
8
|
+
else if (query.get("decrement")) |_|
|
|
9
|
+
count -= 1
|
|
10
|
+
else
|
|
11
|
+
count += 1;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<main @allocator={ctx.arena}>
|
|
15
|
+
<p>Ziex is a framework for building web applications with Zig.</p>
|
|
16
|
+
<a href={zx.info.homepage} target="_blank">See Ziex Docs →</a>
|
|
17
|
+
<br />
|
|
18
|
+
<CounterComponent @rendering={.client} count={count} />
|
|
19
|
+
<br />
|
|
20
|
+
<hr />
|
|
21
|
+
<a href="/about">Navigate to About Page</a>
|
|
22
|
+
</main>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
var count: i128 = 0;
|
|
26
|
+
|
|
27
|
+
const zx = @import("zx");
|
|
28
|
+
pub const CounterComponent = @import("./client.zig").CounterComponent;
|
|
Binary file
|
package/tmp/cf/build.zig
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const zx = @import("zx");
|
|
3
|
+
|
|
4
|
+
pub fn build(b: *std.Build) !void {
|
|
5
|
+
// --- Target and Optimize from `zig build` arguments ---
|
|
6
|
+
const target = b.standardTargetOptions(.{});
|
|
7
|
+
const optimize = b.standardOptimizeOption(.{});
|
|
8
|
+
|
|
9
|
+
// --- ZX App Executable ---
|
|
10
|
+
const app_exe = b.addExecutable(.{
|
|
11
|
+
.name = "cf",
|
|
12
|
+
.root_module = b.createModule(.{
|
|
13
|
+
.root_source_file = b.path("app/main.zig"),
|
|
14
|
+
.target = target,
|
|
15
|
+
.optimize = optimize,
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// --- ZX setup: wires dependencies and adds `zx`/`dev` build steps ---
|
|
20
|
+
var zx_build = try zx.init(b, app_exe, .{});
|
|
21
|
+
|
|
22
|
+
// HACK: on wasi we do not inject jsglue automatically yet
|
|
23
|
+
if (target.result.os.tag == .wasi)
|
|
24
|
+
zx_build.addElement(.{
|
|
25
|
+
.parent = .body,
|
|
26
|
+
.position = .ending,
|
|
27
|
+
.element = .{
|
|
28
|
+
.tag = "script",
|
|
29
|
+
.attributes = "src=\"https://cdn.jsdelivr.net/npm/ziex@0.1.0-dev.804/wasm/init.min.js\"",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.{
|
|
2
|
+
.name = .cf,
|
|
3
|
+
.version = "0.0.0",
|
|
4
|
+
.fingerprint = 0x77989223bd4e92d3,
|
|
5
|
+
.minimum_zig_version = "0.15.2",
|
|
6
|
+
.dependencies = .{
|
|
7
|
+
.zx = .{
|
|
8
|
+
.url = "git+https://github.com/ziex-dev/ziex#e385bf19316eb365a7edb41fa8465e7bf977a04c",
|
|
9
|
+
.hash = "zx-0.1.0-dev.805-8okzKpLD6wAa_H-raN-DxUH_YAfYibSGt-778EdgZXta",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
.paths = .{
|
|
13
|
+
"build.zig",
|
|
14
|
+
"build.zig.zon",
|
|
15
|
+
"app",
|
|
16
|
+
},
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ziex_cloudflare",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"build": "wrangler build",
|
|
6
|
+
"deploy": "wrangler deploy",
|
|
7
|
+
"dev": "wrangler dev"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"ziex": "^0.1.0-dev.804"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"wrangler": "^4.73.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
package/tmp/cf/type.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "node_modules/wrangler/config-schema.json",
|
|
3
|
+
"name": "ziex_cloudflare",
|
|
4
|
+
"main": "app/main.ts",
|
|
5
|
+
"compatibility_date": "2026-03-10",
|
|
6
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
7
|
+
"kv_namespaces": [
|
|
8
|
+
{
|
|
9
|
+
"binding": "KV",
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
"build": {
|
|
13
|
+
"watch_dir": "./app",
|
|
14
|
+
"command": "zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall",
|
|
15
|
+
},
|
|
16
|
+
"assets": {
|
|
17
|
+
"directory": "./zig-out/static",
|
|
18
|
+
"binding": "ASSETS",
|
|
19
|
+
},
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2025 Nurul Huda (Apon).
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Ziex App on Vercel
|
|
2
|
+
|
|
3
|
+
> A starter template for building web applications with [Ziex](https://ziex.dev) deployed on [Vercel](https://vercel.com/).
|
|
4
|
+
|
|
5
|
+
**[Documentation →](https://ziex.dev)**
|
|
6
|
+
|
|
7
|
+
[](https://vercel.com/new/clone?repository-url=https://github.com/ziex-dev/template-vercel)
|
|
8
|
+
|
|
9
|
+
## Getting Started
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
**1. Install ZX CLI**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Linux/macOS
|
|
17
|
+
curl -fsSL https://ziex.dev/install | bash
|
|
18
|
+
|
|
19
|
+
# Windows
|
|
20
|
+
powershell -c "irm ziex.dev/install.ps1 | iex"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**2. Install Zig**
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
brew install zig # macOS
|
|
27
|
+
winget install -e --id zig.zig # Windows
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
[_Other platforms →_](https://ziglang.org/learn/getting-started/)
|
|
31
|
+
|
|
32
|
+
**3. Install Node.js** (for Vercel CLI)
|
|
33
|
+
|
|
34
|
+
[_Download →_](https://nodejs.org/)
|
|
35
|
+
|
|
36
|
+
## Project Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
├── api/
|
|
40
|
+
│ └── index.ts # Vercel Edge Function entrypoint
|
|
41
|
+
│ └── nodejs.ts # Vercel Node.js Function entrypoint
|
|
42
|
+
├── app/
|
|
43
|
+
│ ├── assets/ # Static assets (CSS, images, etc)
|
|
44
|
+
│ ├── main.zig # Zig entrypoint
|
|
45
|
+
│ ├── pages/ # Pages (Zig/ZX)
|
|
46
|
+
│ │ ├── layout.zx # Root layout
|
|
47
|
+
│ │ ├── page.zx # Home page
|
|
48
|
+
│ │ ├── client.zx # Client-side component
|
|
49
|
+
│ │ └── ...
|
|
50
|
+
│ └── public/ # Public static files (favicon, etc)
|
|
51
|
+
├── build.zig # Zig build script
|
|
52
|
+
├── build.zig.zon # Zig package manager config
|
|
53
|
+
└── package.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
By default the app is configured to use Vercel Edge Functions. If you want to use Node.js runtime instead, update .vercelignore to remove `api/nodejs.ts` and update `vercel.json` to point to `api/nodejs.ts` as the entrypoint.
|
|
59
|
+
|
|
60
|
+
### Development
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
vercel dev
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
App will be available at [`http://localhost:3000`](http://localhost:3000) with hot reload enabled.
|
|
67
|
+
|
|
68
|
+
### Deploy to Vercel
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
vercel deploy
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or click the **Deploy with Vercel** button above for one-click deployment.
|
|
75
|
+
|
|
76
|
+
## Contributing
|
|
77
|
+
|
|
78
|
+
Contributions are welcome! For feature requests, bug reports, or questions, see the [Ziex Repo](https://github.com/ziex-dev/ziex).
|
|
79
|
+
|
|
80
|
+
## Links
|
|
81
|
+
|
|
82
|
+
- [Documentation](https://ziex.dev)
|
|
83
|
+
- [Discord](https://ziex.dev/r/discord)
|
|
84
|
+
- [Vercel Docs](https://vercel.com/docs)
|
|
85
|
+
- [Zig Language](https://ziglang.org/)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import module from "../zig-out/bin/zx_app.wasm?module";
|
|
2
|
+
import { Ziex } from "../zig-out/pkg/ziex/index.js";
|
|
3
|
+
import { handle } from "../zig-out/pkg/ziex/vercel/index.js";
|
|
4
|
+
|
|
5
|
+
export const config = { runtime: "edge" };
|
|
6
|
+
|
|
7
|
+
export default handle(new Ziex({ module }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { WASI } from "node:wasi";
|
|
4
|
+
import { Ziex } from "../zig-out/pkg/ziex/index.js";
|
|
5
|
+
|
|
6
|
+
export default new Ziex({
|
|
7
|
+
module: readFileSync(fileURLToPath(new URL("../zig-out/bin/ziex_dev.wasm", import.meta.url).href)),
|
|
8
|
+
wasi: new WASI({ version: "preview1" }),
|
|
9
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
font-family: sans-serif;
|
|
4
|
+
font-size: 1.4rem;
|
|
5
|
+
line-height: 1.6;
|
|
6
|
+
color: white;
|
|
7
|
+
background-color: black;
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
text-align: center;
|
|
13
|
+
height: 100vh;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
color: #ffffff;
|
|
18
|
+
font-size: 1rem;
|
|
19
|
+
text-decoration: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
button {
|
|
23
|
+
padding: 2px;
|
|
24
|
+
min-width: 100px;
|
|
25
|
+
font-size: 0.8rem;
|
|
26
|
+
border-radius: 5px;
|
|
27
|
+
margin: 3px;
|
|
28
|
+
border: 1px solid #ffffff;
|
|
29
|
+
background-color: transparent;
|
|
30
|
+
color: #ffffff;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
transition: all 0.3s ease;
|
|
33
|
+
&:hover {
|
|
34
|
+
background-color: #ffffff;
|
|
35
|
+
color: #000000;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.counter-row {
|
|
40
|
+
height: 150px;
|
|
41
|
+
margin: 10px;
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: 20px;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.counter-row > * {
|
|
49
|
+
min-width: 150px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.counter-plus {
|
|
53
|
+
width: 70px;
|
|
54
|
+
display: inline-block;
|
|
55
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const zx = @import("zx");
|
|
3
|
+
|
|
4
|
+
pub fn main() !void {
|
|
5
|
+
if (zx.platform == .browser) return zx.Client.run();
|
|
6
|
+
if (zx.platform == .edge) return zx.Edge.run();
|
|
7
|
+
|
|
8
|
+
var gpa = std.heap.DebugAllocator(.{}){};
|
|
9
|
+
const allocator = gpa.allocator();
|
|
10
|
+
defer _ = gpa.deinit();
|
|
11
|
+
|
|
12
|
+
const app = try zx.Server(void).init(allocator, .{}, {});
|
|
13
|
+
defer app.deinit();
|
|
14
|
+
|
|
15
|
+
app.info();
|
|
16
|
+
try app.start();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub const std_options = zx.std_options;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
pub fn Page(ctx: zx.PageContext) zx.Component {
|
|
2
|
+
return (
|
|
3
|
+
<main @allocator={ctx.arena}>
|
|
4
|
+
<p>{get_about_zx()}</p>
|
|
5
|
+
<a href="/">Back to Home</a>
|
|
6
|
+
</main>
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
pub fn get_about_zx() []const u8 {
|
|
11
|
+
return "Ziex is a framework for building web applications with Zig.";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var count: *zx.State(i128) = undefined;
|
|
2
|
+
|
|
3
|
+
pub fn CounterComponent(ctx: *zx.ComponentCtx(struct { count: i128 })) zx.Component {
|
|
4
|
+
count = ctx.state(i128, ctx.props.count);
|
|
5
|
+
|
|
6
|
+
return (
|
|
7
|
+
<div @allocator={ctx.allocator}>
|
|
8
|
+
<button onclick={reset}>Reset</button>
|
|
9
|
+
<h5>{&count}</h5>
|
|
10
|
+
<button onclick={decrement}>Decrement</button>
|
|
11
|
+
<button onclick={increment}>Increment</button>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fn increment() void {
|
|
17
|
+
count.set(count.get() + 1);
|
|
18
|
+
fetch("?increment=true");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fn decrement() void {
|
|
22
|
+
count.set(count.get() - 1);
|
|
23
|
+
fetch("?decrement=true");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn reset(_: zx.client.Event) void {
|
|
27
|
+
count.set(0);
|
|
28
|
+
fetch("?reset=true");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn fetch(url: []const u8) void {
|
|
32
|
+
_ = zx.fetch(.noop, zx.client_allocator, url, .{}) catch {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
pub fn Layout(ctx: zx.LayoutContext, children: zx.Component) zx.Component {
|
|
2
|
+
return (
|
|
3
|
+
<html @allocator={ctx.arena} lang="en-US">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<title>Ziex</title>
|
|
7
|
+
<link rel="stylesheet" href="/assets/style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<h1>Ziex</h1>
|
|
12
|
+
{children}
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const zx = @import("zx");
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
pub fn Page(ctx: zx.PageContext) !zx.Component {
|
|
2
|
+
const query = ctx.request.searchParams;
|
|
3
|
+
|
|
4
|
+
if (query.get("reset")) |_|
|
|
5
|
+
count = 0
|
|
6
|
+
else if (query.get("increment")) |_|
|
|
7
|
+
count += 1
|
|
8
|
+
else if (query.get("decrement")) |_|
|
|
9
|
+
count -= 1
|
|
10
|
+
else
|
|
11
|
+
count += 1;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<main @allocator={ctx.arena}>
|
|
15
|
+
<p>Ziex is a framework for building web applications with Zig.</p>
|
|
16
|
+
<a href={zx.info.homepage} target="_blank">See Ziex Docs →</a>
|
|
17
|
+
<br />
|
|
18
|
+
<CounterComponent @rendering={.client} count={count} />
|
|
19
|
+
<br />
|
|
20
|
+
<hr />
|
|
21
|
+
<a href="/about">Navigate to About Page</a>
|
|
22
|
+
</main>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
var count: i128 = 0;
|
|
26
|
+
|
|
27
|
+
const zx = @import("zx");
|
|
28
|
+
pub const CounterComponent = @import("./client.zig").CounterComponent;
|
|
Binary file
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const zx = @import("zx");
|
|
3
|
+
|
|
4
|
+
pub fn build(b: *std.Build) !void {
|
|
5
|
+
// --- Target and Optimize from `zig build` arguments ---
|
|
6
|
+
const target = b.standardTargetOptions(.{});
|
|
7
|
+
const optimize = b.standardOptimizeOption(.{});
|
|
8
|
+
|
|
9
|
+
// --- ZX App Executable ---
|
|
10
|
+
const app_exe = b.addExecutable(.{
|
|
11
|
+
.name = "zx_app",
|
|
12
|
+
.root_module = b.createModule(.{
|
|
13
|
+
.root_source_file = b.path("app/main.zig"),
|
|
14
|
+
.target = target,
|
|
15
|
+
.optimize = optimize,
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// --- ZX setup: wires dependencies and adds `zx`/`dev` build steps ---
|
|
20
|
+
var zx_build = try zx.init(b, app_exe, .{});
|
|
21
|
+
|
|
22
|
+
// HACK: on wasi we do not inject jsglue automatically yet
|
|
23
|
+
if (target.result.os.tag == .wasi)
|
|
24
|
+
zx_build.addElement(.{
|
|
25
|
+
.parent = .body,
|
|
26
|
+
.position = .ending,
|
|
27
|
+
.element = .{
|
|
28
|
+
.tag = "script",
|
|
29
|
+
.attributes = "src=\"https://cdn.jsdelivr.net/npm/ziex@0.1.0-dev.804/wasm/init.min.js\"",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// --- Assets -- //
|
|
34
|
+
b.installDirectory(.{
|
|
35
|
+
.source_dir = zx_build.ziex_js.dep.path("."),
|
|
36
|
+
.install_dir = .prefix,
|
|
37
|
+
.install_subdir = "pkg/ziex",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.{
|
|
2
|
+
.name = .zx_app,
|
|
3
|
+
.version = "0.0.0",
|
|
4
|
+
.fingerprint = 0x77989223bd4e92d3,
|
|
5
|
+
.minimum_zig_version = "0.15.2",
|
|
6
|
+
.dependencies = .{
|
|
7
|
+
.zx = .{
|
|
8
|
+
.url = "git+https://github.com/ziex-dev/ziex#e385bf19316eb365a7edb41fa8465e7bf977a04c",
|
|
9
|
+
.hash = "zx-0.1.0-dev.805-8okzKpLD6wAa_H-raN-DxUH_YAfYibSGt-778EdgZXta",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
.paths = .{
|
|
13
|
+
"build.zig",
|
|
14
|
+
"build.zig.zon",
|
|
15
|
+
"app",
|
|
16
|
+
},
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://openapi.vercel.sh/vercel.json",
|
|
3
|
+
"framework": null,
|
|
4
|
+
"buildCommand": "zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall",
|
|
5
|
+
"outputDirectory": "zig-out/static",
|
|
6
|
+
"rewrites": [
|
|
7
|
+
{
|
|
8
|
+
"source": "/(.*)",
|
|
9
|
+
"destination": "/api/index"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|