ziex 0.1.0-dev.1309 → 0.1.0-dev.1360
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/README.md +19 -25
- package/cloudflare/index.js +93 -8
- package/index.js +78 -4
- package/package.json +2 -2
- package/pkg/ziex/src/fetch.d.ts +5 -0
- package/{wasm → pkg/ziex/src/wasm}/core.d.ts +2 -2
- package/vendor/jsz/js/src/index.d.ts +1 -0
- package/vendor/jsz/js/src/zigjs.d.ts +107 -0
- package/wasm/index.js +84 -4
- package/wasm/init.dev.js +84 -4
- package/wasm/init.js +3 -2
- /package/{app.d.ts → pkg/ziex/src/app.d.ts} +0 -0
- /package/{aws-lambda → pkg/ziex/src/aws-lambda}/index.d.ts +0 -0
- /package/{browser → pkg/ziex/src/browser}/kv.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/app.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/db.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/do.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/index.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/kv.d.ts +0 -0
- /package/{cloudflare → pkg/ziex/src/cloudflare}/worker.d.ts +0 -0
- /package/{db.d.ts → pkg/ziex/src/db.d.ts} +0 -0
- /package/{index.d.ts → pkg/ziex/src/index.d.ts} +0 -0
- /package/{kv.d.ts → pkg/ziex/src/kv.d.ts} +0 -0
- /package/{react → pkg/ziex/src/react}/dom.d.ts +0 -0
- /package/{react → pkg/ziex/src/react}/index.d.ts +0 -0
- /package/{react → pkg/ziex/src/react}/types.d.ts +0 -0
- /package/{runtime.d.ts → pkg/ziex/src/runtime.d.ts} +0 -0
- /package/{vercel → pkg/ziex/src/vercel}/index.d.ts +0 -0
- /package/{wasi.d.ts → pkg/ziex/src/wasi.d.ts} +0 -0
- /package/{wasm → pkg/ziex/src/wasm}/dom.d.ts +0 -0
- /package/{wasm → pkg/ziex/src/wasm}/index.d.ts +0 -0
- /package/{wasm → pkg/ziex/src/wasm}/init.d.ts +0 -0
- /package/{wasm → pkg/ziex/src/wasm}/types.d.ts +0 -0
- /package/{wasm → pkg/ziex/src/wasm}/wasi.d.ts +0 -0
- /package/{zx.d.ts → pkg/ziex/src/zx.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -8,37 +8,29 @@ Ziex combines the power and performance of Zig with the expressiveness and simpl
|
|
|
8
8
|
|
|
9
9
|
**[Documentation →](https://ziex.dev/learn)**
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
> **Note:** Most of the API and syntax are finalized and stable, and server-side rendering (SSR) features are production-ready, Ziex continues to evolve with ongoing improvements to client-side rendering and state management, see the [roadmap](#roadmap). You can start using the documented features today, as they are stable and unlikely to change. Areas still under development are not yet documented and will be added as they mature. See [versions](#versions) for Zig and Ziex versions compatibility.
|
|
13
12
|
|
|
14
|
-
|
|
15
13
|
## Getting Started
|
|
16
14
|
|
|
17
15
|
### 1. Installing CLI (optional)
|
|
18
16
|
|
|
19
|
-
macOS/Linux
|
|
20
17
|
```bash
|
|
18
|
+
# macOS/Linux
|
|
21
19
|
curl -fsSL https://ziex.dev/install | bash
|
|
22
|
-
|
|
23
|
-
Windows
|
|
24
|
-
```
|
|
20
|
+
|
|
21
|
+
# Windows
|
|
25
22
|
powershell -c "irm ziex.dev/install.ps1 | iex"
|
|
26
23
|
```
|
|
27
24
|
|
|
25
|
+
|
|
28
26
|
### 2. Initializing Project
|
|
27
|
+
|
|
29
28
|
```powershell
|
|
30
29
|
zx init
|
|
31
30
|
# or
|
|
32
31
|
npm init ziex
|
|
33
32
|
```
|
|
34
33
|
|
|
35
|
-
### 3. Running Project
|
|
36
|
-
```powershell
|
|
37
|
-
zx dev
|
|
38
|
-
# or
|
|
39
|
-
npm run dev
|
|
40
|
-
```
|
|
41
|
-
|
|
42
34
|
You will need [compatible](#versions) Zig version when using zx CLI or you can use the `Node` template from `npm init ziex`
|
|
43
35
|
|
|
44
36
|
Read [Getting Started →](https://ziex.dev/learn) for more details.
|
|
@@ -159,6 +151,7 @@ const zx = @import("zx");
|
|
|
159
151
|
</details>
|
|
160
152
|
|
|
161
153
|
## Features
|
|
154
|
+
|
|
162
155
|
- **Declarative UI**: Declarative UI components using with full access to Zig's control flow.
|
|
163
156
|
- **Full-Stack Capabilities**: Build both frontend and backend of web application.
|
|
164
157
|
- **Fast**: Significantly faster at SSR than many other frameworks.
|
|
@@ -170,26 +163,27 @@ const zx = @import("zx");
|
|
|
170
163
|
- **Developer Tooling**: CLI, hot reload, and editor extensions for the best DX.
|
|
171
164
|
|
|
172
165
|
## Versions
|
|
173
|
-
| Zig | Ziex | Branch | Status |
|
|
174
|
-
|-------------|---------------------|-------------------|----------------|
|
|
175
|
-
| `0.17.x` | | `main` | Development |
|
|
176
|
-
| `0.16.x` | `0.1.0-dev.1259` | `zig-0.16` | **Latest** |
|
|
177
|
-
| `0.15.x` | `0.1.0-dev-1050` | `zig-0.15` | Latest (`Zig 0.15.x`) |
|
|
178
166
|
|
|
167
|
+
| Zig | Ziex | Branch | Status |
|
|
168
|
+
| -------- | --------------------------------------------------------------------------------- | ---------- | ----------- |
|
|
169
|
+
| `0.17.x` | | `main` | Development |
|
|
170
|
+
| `0.16.x` | [`0.1.0-dev.1259`](https://github.com/ziex-dev/ziex/releases/tag/v0.1.0-dev.1259) | `zig-0.16` | **Latest** |
|
|
171
|
+
| `0.15.x` | [`0.1.0-dev-1050`](https://github.com/ziex-dev/ziex/releases/tag/v0.1.0-dev.1050) | `zig-0.15` | Outdated |
|
|
179
172
|
|
|
180
173
|
## Roadmap
|
|
181
|
-
[Ziex 0.1.0](https://github.com/ziex-dev/ziex/milestone/2) is planned for release after `Zig 0.17.0` is available. You can view the [roadmap](https://github.com/ziex-dev/ziex/milestone) to learn more.
|
|
182
174
|
|
|
183
|
-
|
|
175
|
+
[Ziex 0.1.0](https://github.com/ziex-dev/ziex/milestone/2) is planned for release after `Zig 0.17.0` is available. You can view the [roadmap](https://github.com/ziex-dev/ziex/milestones) to learn more.
|
|
176
|
+
|
|
177
|
+
The [`0.1.0`](https://github.com/ziex-dev/ziex/milestone/2) release will indicate that Ziex is production-ready, with all major features fully implemented, and will receive patch releases for bug fixes.
|
|
184
178
|
|
|
185
|
-
The `1.0.0` release will signify long-term support for that major version, receiving bug fixes and minor updates.
|
|
179
|
+
The [`1.0.0`](https://github.com/ziex-dev/ziex/milestone/6) release will signify long-term support for that major version, receiving bug fixes and minor updates.
|
|
186
180
|
|
|
187
181
|
## Editor Support
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
183
|
+
- [VSCode](https://marketplace.visualstudio.com/items?itemName=ziex.ziex)/[VSCode Forks](https://open-vsx.org/extension/ziex/ziex)
|
|
184
|
+
- [Neovim](/ide/neovim/)
|
|
185
|
+
- [Helix](/ide/helix/)
|
|
186
|
+
- [Zed](/ide/zed/)
|
|
193
187
|
|
|
194
188
|
## Community
|
|
195
189
|
|
package/cloudflare/index.js
CHANGED
|
@@ -193,6 +193,76 @@ class ZigJS {
|
|
|
193
193
|
return decoder.decode(data);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
// src/fetch.ts
|
|
197
|
+
function createFetchImports(getMemory) {
|
|
198
|
+
const encoder2 = new TextEncoder;
|
|
199
|
+
const decoder2 = new TextDecoder;
|
|
200
|
+
function readStr(ptr, len) {
|
|
201
|
+
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
202
|
+
}
|
|
203
|
+
function writeBytes(buf_ptr, buf_max, data) {
|
|
204
|
+
if (data.length > buf_max)
|
|
205
|
+
return -2;
|
|
206
|
+
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
207
|
+
return data.length;
|
|
208
|
+
}
|
|
209
|
+
function readBytes(ptr, len) {
|
|
210
|
+
return new Uint8Array(getMemory().buffer, ptr, len);
|
|
211
|
+
}
|
|
212
|
+
function parseHeaders(headersJson) {
|
|
213
|
+
let headers = {};
|
|
214
|
+
try {
|
|
215
|
+
headers = JSON.parse(headersJson);
|
|
216
|
+
} catch {
|
|
217
|
+
for (const line of headersJson.split(`
|
|
218
|
+
`)) {
|
|
219
|
+
const colonIdx = line.indexOf(":");
|
|
220
|
+
if (colonIdx > 0) {
|
|
221
|
+
headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return headers;
|
|
226
|
+
}
|
|
227
|
+
async function doFetch(url_ptr, url_len, method_ptr, method_len, headers_ptr, headers_len, body_ptr, body_len, timeout_ms, status_out, buf_ptr, buf_max) {
|
|
228
|
+
const url = readStr(url_ptr, url_len);
|
|
229
|
+
const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
|
|
230
|
+
const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
|
|
231
|
+
const body = body_len > 0 ? readBytes(body_ptr, body_len) : undefined;
|
|
232
|
+
const headers = parseHeaders(headersJson);
|
|
233
|
+
const controller = new AbortController;
|
|
234
|
+
const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
|
|
235
|
+
try {
|
|
236
|
+
const response = await fetch(url, {
|
|
237
|
+
method,
|
|
238
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
239
|
+
body: method !== "GET" && method !== "HEAD" ? body : undefined,
|
|
240
|
+
signal: controller.signal
|
|
241
|
+
});
|
|
242
|
+
if (timeout)
|
|
243
|
+
clearTimeout(timeout);
|
|
244
|
+
new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
|
|
245
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
246
|
+
return writeBytes(buf_ptr, buf_max, bytes);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
if (timeout)
|
|
249
|
+
clearTimeout(timeout);
|
|
250
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
251
|
+
console.error(`wasm fetch failed: ${url} (${msg})`);
|
|
252
|
+
return -1;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const Suspending = WebAssembly.Suspending;
|
|
256
|
+
if (typeof Suspending !== "function") {
|
|
257
|
+
return {
|
|
258
|
+
fetch: (_url_ptr, _url_len, _method_ptr, _method_len, _headers_ptr, _headers_len, _body_ptr, _body_len, _timeout_ms, _status_out, _buf_ptr, _buf_max) => -1
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
fetch: new Suspending(doFetch)
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
196
266
|
// src/wasm/core.ts
|
|
197
267
|
var CallbackType = {
|
|
198
268
|
Event: 0,
|
|
@@ -291,7 +361,7 @@ class ZxBridgeCore {
|
|
|
291
361
|
const url = readString(urlPtr, urlLen);
|
|
292
362
|
const method = methodLen > 0 ? readString(methodPtr, methodLen) : "GET";
|
|
293
363
|
const headersJson = headersLen > 0 ? readString(headersPtr, headersLen) : "{}";
|
|
294
|
-
const body = bodyLen > 0 ?
|
|
364
|
+
const body = bodyLen > 0 ? getMemoryView().subarray(bodyPtr, bodyPtr + bodyLen) : undefined;
|
|
295
365
|
let headers = {};
|
|
296
366
|
try {
|
|
297
367
|
headers = JSON.parse(headersJson);
|
|
@@ -315,8 +385,8 @@ class ZxBridgeCore {
|
|
|
315
385
|
fetch(url, fetchOptions).then(async (response) => {
|
|
316
386
|
if (timeout)
|
|
317
387
|
clearTimeout(timeout);
|
|
318
|
-
const
|
|
319
|
-
this._notifyFetchComplete(fetchId, response.status,
|
|
388
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
389
|
+
this._notifyFetchComplete(fetchId, response.status, bytes, false);
|
|
320
390
|
}).catch((error) => {
|
|
321
391
|
if (timeout)
|
|
322
392
|
clearTimeout(timeout);
|
|
@@ -327,7 +397,7 @@ class ZxBridgeCore {
|
|
|
327
397
|
}
|
|
328
398
|
_notifyFetchComplete(fetchId, statusCode, body, isError) {
|
|
329
399
|
const handler = this.#fetchCompleteHandler;
|
|
330
|
-
const encoded = textEncoder.encode(body);
|
|
400
|
+
const encoded = typeof body === "string" ? textEncoder.encode(body) : body;
|
|
331
401
|
const ptr = this._alloc(encoded.length);
|
|
332
402
|
writeBytes(ptr, encoded);
|
|
333
403
|
invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
|
|
@@ -384,6 +454,11 @@ class ZxBridgeCore {
|
|
|
384
454
|
static createImportObject(bridgeRef) {
|
|
385
455
|
return {
|
|
386
456
|
...jsz.importObject(),
|
|
457
|
+
__zx_net: createFetchImports(() => {
|
|
458
|
+
if (!jsz.memory)
|
|
459
|
+
throw new Error("WASM memory is not ready");
|
|
460
|
+
return jsz.memory;
|
|
461
|
+
}),
|
|
387
462
|
__zx: {
|
|
388
463
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
389
464
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
@@ -793,6 +868,11 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
793
868
|
static createImportObject(bridgeRef) {
|
|
794
869
|
return {
|
|
795
870
|
...jsz.importObject(),
|
|
871
|
+
__zx_net: createFetchImports(() => {
|
|
872
|
+
if (!jsz.memory)
|
|
873
|
+
throw new Error("WASM memory is not ready");
|
|
874
|
+
return jsz.memory;
|
|
875
|
+
}),
|
|
796
876
|
__zx: {
|
|
797
877
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
798
878
|
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
|
@@ -1325,7 +1405,7 @@ class ZxWasiBridge {
|
|
|
1325
1405
|
const url = this.#readString(urlPtr, urlLen);
|
|
1326
1406
|
const method = methodLen > 0 ? this.#readString(methodPtr, methodLen) : "GET";
|
|
1327
1407
|
const headersJson = headersLen > 0 ? this.#readString(headersPtr, headersLen) : "{}";
|
|
1328
|
-
const body = bodyLen > 0 ? this.#
|
|
1408
|
+
const body = bodyLen > 0 ? this.#view().subarray(bodyPtr, bodyPtr + bodyLen) : undefined;
|
|
1329
1409
|
let headers = {};
|
|
1330
1410
|
try {
|
|
1331
1411
|
headers = JSON.parse(headersJson);
|
|
@@ -1347,7 +1427,8 @@ class ZxWasiBridge {
|
|
|
1347
1427
|
}).then(async (res) => {
|
|
1348
1428
|
if (timeout)
|
|
1349
1429
|
clearTimeout(timeout);
|
|
1350
|
-
|
|
1430
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
1431
|
+
this.#notifyFetchComplete(fetchId, res.status, bytes, false);
|
|
1351
1432
|
}).catch((err) => {
|
|
1352
1433
|
if (timeout)
|
|
1353
1434
|
clearTimeout(timeout);
|
|
@@ -1356,7 +1437,7 @@ class ZxWasiBridge {
|
|
|
1356
1437
|
});
|
|
1357
1438
|
}
|
|
1358
1439
|
#notifyFetchComplete(fetchId, status, body, isError) {
|
|
1359
|
-
const encoded = encoder2.encode(body);
|
|
1440
|
+
const encoded = typeof body === "string" ? encoder2.encode(body) : body;
|
|
1360
1441
|
const ptr = this.#alloc(encoded.length);
|
|
1361
1442
|
this.#writeBytes(ptr, encoded);
|
|
1362
1443
|
this.#fetchCompleteHandler(fetchId, status, ptr, encoded.length, isError ? 1 : 0);
|
|
@@ -1563,7 +1644,9 @@ function createWasiImports({
|
|
|
1563
1644
|
"--method",
|
|
1564
1645
|
request.method,
|
|
1565
1646
|
"--search",
|
|
1566
|
-
url.search
|
|
1647
|
+
url.search,
|
|
1648
|
+
"--url",
|
|
1649
|
+
url.href
|
|
1567
1650
|
];
|
|
1568
1651
|
request.headers.forEach((value, name) => {
|
|
1569
1652
|
if (value)
|
|
@@ -2016,6 +2099,7 @@ async function run({
|
|
|
2016
2099
|
__zx_ws: buildWsImports(jspi ? Suspending : null, mem, new TextDecoder, wsState),
|
|
2017
2100
|
__zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
|
|
2018
2101
|
__zx_db: createD1Imports(dbBindings ?? {}, mem),
|
|
2102
|
+
__zx_net: createFetchImports(mem),
|
|
2019
2103
|
...imports ? imports(mem) : {},
|
|
2020
2104
|
...ZxWasiBridge.createImportObject(bridgeRef)
|
|
2021
2105
|
});
|
|
@@ -2190,6 +2274,7 @@ function createWebSocketDO(module, options) {
|
|
|
2190
2274
|
__zx_ws: wsImports,
|
|
2191
2275
|
__zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
|
|
2192
2276
|
__zx_db: createD1Imports(dbBindings ?? {}, mem),
|
|
2277
|
+
__zx_net: createFetchImports(mem),
|
|
2193
2278
|
...options?.imports ? options.imports(mem) : {},
|
|
2194
2279
|
...bridgeImports
|
|
2195
2280
|
});
|
package/index.js
CHANGED
|
@@ -74,7 +74,7 @@ class ZxWasiBridge {
|
|
|
74
74
|
const url = this.#readString(urlPtr, urlLen);
|
|
75
75
|
const method = methodLen > 0 ? this.#readString(methodPtr, methodLen) : "GET";
|
|
76
76
|
const headersJson = headersLen > 0 ? this.#readString(headersPtr, headersLen) : "{}";
|
|
77
|
-
const body = bodyLen > 0 ? this.#
|
|
77
|
+
const body = bodyLen > 0 ? this.#view().subarray(bodyPtr, bodyPtr + bodyLen) : undefined;
|
|
78
78
|
let headers = {};
|
|
79
79
|
try {
|
|
80
80
|
headers = JSON.parse(headersJson);
|
|
@@ -96,7 +96,8 @@ class ZxWasiBridge {
|
|
|
96
96
|
}).then(async (res) => {
|
|
97
97
|
if (timeout)
|
|
98
98
|
clearTimeout(timeout);
|
|
99
|
-
|
|
99
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
100
|
+
this.#notifyFetchComplete(fetchId, res.status, bytes, false);
|
|
100
101
|
}).catch((err) => {
|
|
101
102
|
if (timeout)
|
|
102
103
|
clearTimeout(timeout);
|
|
@@ -105,7 +106,7 @@ class ZxWasiBridge {
|
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
108
|
#notifyFetchComplete(fetchId, status, body, isError) {
|
|
108
|
-
const encoded = encoder.encode(body);
|
|
109
|
+
const encoded = typeof body === "string" ? encoder.encode(body) : body;
|
|
109
110
|
const ptr = this.#alloc(encoded.length);
|
|
110
111
|
this.#writeBytes(ptr, encoded);
|
|
111
112
|
this.#fetchCompleteHandler(fetchId, status, ptr, encoded.length, isError ? 1 : 0);
|
|
@@ -265,6 +266,76 @@ function createKVImports(bindings, getMemory) {
|
|
|
265
266
|
};
|
|
266
267
|
}
|
|
267
268
|
|
|
269
|
+
// src/fetch.ts
|
|
270
|
+
function createFetchImports(getMemory) {
|
|
271
|
+
const encoder2 = new TextEncoder;
|
|
272
|
+
const decoder2 = new TextDecoder;
|
|
273
|
+
function readStr(ptr, len) {
|
|
274
|
+
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
275
|
+
}
|
|
276
|
+
function writeBytes(buf_ptr, buf_max, data) {
|
|
277
|
+
if (data.length > buf_max)
|
|
278
|
+
return -2;
|
|
279
|
+
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
280
|
+
return data.length;
|
|
281
|
+
}
|
|
282
|
+
function readBytes(ptr, len) {
|
|
283
|
+
return new Uint8Array(getMemory().buffer, ptr, len);
|
|
284
|
+
}
|
|
285
|
+
function parseHeaders(headersJson) {
|
|
286
|
+
let headers = {};
|
|
287
|
+
try {
|
|
288
|
+
headers = JSON.parse(headersJson);
|
|
289
|
+
} catch {
|
|
290
|
+
for (const line of headersJson.split(`
|
|
291
|
+
`)) {
|
|
292
|
+
const colonIdx = line.indexOf(":");
|
|
293
|
+
if (colonIdx > 0) {
|
|
294
|
+
headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return headers;
|
|
299
|
+
}
|
|
300
|
+
async function doFetch(url_ptr, url_len, method_ptr, method_len, headers_ptr, headers_len, body_ptr, body_len, timeout_ms, status_out, buf_ptr, buf_max) {
|
|
301
|
+
const url = readStr(url_ptr, url_len);
|
|
302
|
+
const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
|
|
303
|
+
const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
|
|
304
|
+
const body = body_len > 0 ? readBytes(body_ptr, body_len) : undefined;
|
|
305
|
+
const headers = parseHeaders(headersJson);
|
|
306
|
+
const controller = new AbortController;
|
|
307
|
+
const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
|
|
308
|
+
try {
|
|
309
|
+
const response = await fetch(url, {
|
|
310
|
+
method,
|
|
311
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
312
|
+
body: method !== "GET" && method !== "HEAD" ? body : undefined,
|
|
313
|
+
signal: controller.signal
|
|
314
|
+
});
|
|
315
|
+
if (timeout)
|
|
316
|
+
clearTimeout(timeout);
|
|
317
|
+
new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
|
|
318
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
319
|
+
return writeBytes(buf_ptr, buf_max, bytes);
|
|
320
|
+
} catch (err) {
|
|
321
|
+
if (timeout)
|
|
322
|
+
clearTimeout(timeout);
|
|
323
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
324
|
+
console.error(`wasm fetch failed: ${url} (${msg})`);
|
|
325
|
+
return -1;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const Suspending = WebAssembly.Suspending;
|
|
329
|
+
if (typeof Suspending !== "function") {
|
|
330
|
+
return {
|
|
331
|
+
fetch: (_url_ptr, _url_len, _method_ptr, _method_len, _headers_ptr, _headers_len, _body_ptr, _body_len, _timeout_ms, _status_out, _buf_ptr, _buf_max) => -1
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
fetch: new Suspending(doFetch)
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
268
339
|
// src/db.ts
|
|
269
340
|
function decodeBlob(base64) {
|
|
270
341
|
const binary = atob(base64);
|
|
@@ -430,7 +501,9 @@ function createWasiImports({
|
|
|
430
501
|
"--method",
|
|
431
502
|
request.method,
|
|
432
503
|
"--search",
|
|
433
|
-
url.search
|
|
504
|
+
url.search,
|
|
505
|
+
"--url",
|
|
506
|
+
url.href
|
|
434
507
|
];
|
|
435
508
|
request.headers.forEach((value, name) => {
|
|
436
509
|
if (value)
|
|
@@ -883,6 +956,7 @@ async function run({
|
|
|
883
956
|
__zx_ws: buildWsImports(jspi ? Suspending : null, mem, new TextDecoder, wsState),
|
|
884
957
|
__zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
|
|
885
958
|
__zx_db: createD1Imports(dbBindings ?? {}, mem),
|
|
959
|
+
__zx_net: createFetchImports(mem),
|
|
886
960
|
...imports ? imports(mem) : {},
|
|
887
961
|
...ZxWasiBridge.createImportObject(bridgeRef)
|
|
888
962
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ziex",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.1360",
|
|
4
4
|
"description": "Ziex is a framework for building web applications with Zig.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"scripts": {},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ziex/cli": "0.1.0-dev.
|
|
40
|
+
"@ziex/cli": "0.1.0-dev.1360"
|
|
41
41
|
},
|
|
42
42
|
"peerDependenciesMeta": {
|
|
43
43
|
"react": {
|
|
@@ -49,8 +49,8 @@ export declare class ZxBridgeCore {
|
|
|
49
49
|
* Calls __zx_fetch_complete when done.
|
|
50
50
|
*/
|
|
51
51
|
fetchAsync(urlPtr: number, urlLen: number, methodPtr: number, methodLen: number, headersPtr: number, headersLen: number, bodyPtr: number, bodyLen: number, timeoutMs: number, fetchId: bigint): void;
|
|
52
|
-
/** Notify WASM that a fetch completed */
|
|
53
|
-
protected _notifyFetchComplete(fetchId: bigint, statusCode: number, body: string, isError: boolean): void;
|
|
52
|
+
/** Notify WASM that a fetch completed. `body` is raw bytes on success, text on error. */
|
|
53
|
+
protected _notifyFetchComplete(fetchId: bigint, statusCode: number, body: string | Uint8Array, isError: boolean): void;
|
|
54
54
|
/** Set a timeout and callback when it fires */
|
|
55
55
|
setTimeout(callbackId: bigint, delayMs: number): void;
|
|
56
56
|
/** Set an interval and callback each time it fires */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './zigjs';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predefined references.
|
|
3
|
+
* */
|
|
4
|
+
export declare const predefined: {
|
|
5
|
+
nan: number;
|
|
6
|
+
null: number;
|
|
7
|
+
true: number;
|
|
8
|
+
false: number;
|
|
9
|
+
undefined: number;
|
|
10
|
+
globalThis: number;
|
|
11
|
+
runtime: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The main state.
|
|
15
|
+
* */
|
|
16
|
+
export declare class ZigJS {
|
|
17
|
+
/**
|
|
18
|
+
* Set this to the memory of your WebAssembly instance prior to making
|
|
19
|
+
* any Wasm calls that might interface with JS.
|
|
20
|
+
*
|
|
21
|
+
* We have to use a Memory object directly (rather than an ArrayBuffer)
|
|
22
|
+
* so that we can always access memory even if it is resized. Otherwise,
|
|
23
|
+
* a resize could detach the array buffer.
|
|
24
|
+
* */
|
|
25
|
+
memory?: WebAssembly.Memory;
|
|
26
|
+
/**
|
|
27
|
+
* The values, indexed by ID (number). Duplicate values can be in this
|
|
28
|
+
* if they are loaded multiple times. That just acts as duplicate references.
|
|
29
|
+
* */
|
|
30
|
+
private values;
|
|
31
|
+
/**
|
|
32
|
+
* When a value is removed from the values array, its ID is put
|
|
33
|
+
* in the pool so that we can use it next. This avoids fragmentation in
|
|
34
|
+
* our array keys.
|
|
35
|
+
* */
|
|
36
|
+
private idPool;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the import object that should be merged with your import
|
|
39
|
+
* object when instantiating your wasm instance. This injects the required
|
|
40
|
+
* functions into the wasm environment.
|
|
41
|
+
* */
|
|
42
|
+
importObject(): ImportObject;
|
|
43
|
+
/**
|
|
44
|
+
* Get a value from the JS environment.
|
|
45
|
+
* */
|
|
46
|
+
protected valueGet(out: number, id: number, ptr: number, len: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Set a value on an object.
|
|
49
|
+
* */
|
|
50
|
+
protected valueSet(id: number, ptr: number, len: number, refAddr: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* Dereference a value, allowing the JS environment to potentially GC it.
|
|
53
|
+
* */
|
|
54
|
+
protected valueDeinit(id: number): void;
|
|
55
|
+
/**
|
|
56
|
+
* Create an empty object.
|
|
57
|
+
* */
|
|
58
|
+
protected valueObjectCreate(out: number): void;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a string on the JS side from a UTF-8 encoded string in wasm memory.
|
|
61
|
+
* */
|
|
62
|
+
protected valueStringCreate(out: number, ptr: number, len: number): void;
|
|
63
|
+
/**
|
|
64
|
+
* Returns the length of the string given by id.
|
|
65
|
+
* */
|
|
66
|
+
protected valueStringLen(id: number): number;
|
|
67
|
+
/**
|
|
68
|
+
* Copy the string at id "id" into the shared memory at ptr.
|
|
69
|
+
* */
|
|
70
|
+
protected valueStringCopy(id: number, ptr: number, max: number): void;
|
|
71
|
+
/**
|
|
72
|
+
* Call a constructor given by id.
|
|
73
|
+
* */
|
|
74
|
+
protected valueNew(out: number, id: number, argsAddr: number, argsLen: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* Call a function given by id.
|
|
77
|
+
* */
|
|
78
|
+
protected funcApply(out: number, id: number, thisRefAddr: number, argsAddr: number, argsLen: number): void;
|
|
79
|
+
/**
|
|
80
|
+
* This can be used to load a value given by an ID. A WASM function
|
|
81
|
+
* might return a value as an ID. This can be used to retrieve it.
|
|
82
|
+
* */
|
|
83
|
+
loadValue(id: number): any;
|
|
84
|
+
/**
|
|
85
|
+
* This removes the value from the values list and returns it. This
|
|
86
|
+
* will not remove predefined values but can still be used to retrieve
|
|
87
|
+
* them.
|
|
88
|
+
* */
|
|
89
|
+
deleteValue(id: number): any;
|
|
90
|
+
loadRef(refAddr: number): any;
|
|
91
|
+
loadRefId(refAddr: number): number;
|
|
92
|
+
storeValue(out: number, val: any): void;
|
|
93
|
+
loadString(ptr: number, len: number): string;
|
|
94
|
+
}
|
|
95
|
+
export interface ImportObject {
|
|
96
|
+
"zig-js": {
|
|
97
|
+
valueGet: (out: number, id: number, ptr: number, len: number) => void;
|
|
98
|
+
valueSet: (id: number, ptr: number, len: number, valueRef: number) => void;
|
|
99
|
+
valueObjectCreate: (out: number) => void;
|
|
100
|
+
valueStringCreate: (out: number, ptr: number, len: number) => void;
|
|
101
|
+
valueStringLen: (id: number) => number;
|
|
102
|
+
valueStringCopy: (id: number, ptr: number, max: number) => void;
|
|
103
|
+
valueDeinit: (id: number) => void;
|
|
104
|
+
valueNew: (out: number, funcId: number, argsPtr: number, argsLen: number) => void;
|
|
105
|
+
funcApply: (out: number, funcId: number, thisRef: number, argsPtr: number, argsLen: number) => void;
|
|
106
|
+
};
|
|
107
|
+
}
|
package/wasm/index.js
CHANGED
|
@@ -193,6 +193,76 @@ class ZigJS {
|
|
|
193
193
|
return decoder.decode(data);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
+
// src/fetch.ts
|
|
197
|
+
function createFetchImports(getMemory) {
|
|
198
|
+
const encoder2 = new TextEncoder;
|
|
199
|
+
const decoder2 = new TextDecoder;
|
|
200
|
+
function readStr(ptr, len) {
|
|
201
|
+
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
202
|
+
}
|
|
203
|
+
function writeBytes(buf_ptr, buf_max, data) {
|
|
204
|
+
if (data.length > buf_max)
|
|
205
|
+
return -2;
|
|
206
|
+
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
207
|
+
return data.length;
|
|
208
|
+
}
|
|
209
|
+
function readBytes(ptr, len) {
|
|
210
|
+
return new Uint8Array(getMemory().buffer, ptr, len);
|
|
211
|
+
}
|
|
212
|
+
function parseHeaders(headersJson) {
|
|
213
|
+
let headers = {};
|
|
214
|
+
try {
|
|
215
|
+
headers = JSON.parse(headersJson);
|
|
216
|
+
} catch {
|
|
217
|
+
for (const line of headersJson.split(`
|
|
218
|
+
`)) {
|
|
219
|
+
const colonIdx = line.indexOf(":");
|
|
220
|
+
if (colonIdx > 0) {
|
|
221
|
+
headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return headers;
|
|
226
|
+
}
|
|
227
|
+
async function doFetch(url_ptr, url_len, method_ptr, method_len, headers_ptr, headers_len, body_ptr, body_len, timeout_ms, status_out, buf_ptr, buf_max) {
|
|
228
|
+
const url = readStr(url_ptr, url_len);
|
|
229
|
+
const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
|
|
230
|
+
const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
|
|
231
|
+
const body = body_len > 0 ? readBytes(body_ptr, body_len) : undefined;
|
|
232
|
+
const headers = parseHeaders(headersJson);
|
|
233
|
+
const controller = new AbortController;
|
|
234
|
+
const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
|
|
235
|
+
try {
|
|
236
|
+
const response = await fetch(url, {
|
|
237
|
+
method,
|
|
238
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
239
|
+
body: method !== "GET" && method !== "HEAD" ? body : undefined,
|
|
240
|
+
signal: controller.signal
|
|
241
|
+
});
|
|
242
|
+
if (timeout)
|
|
243
|
+
clearTimeout(timeout);
|
|
244
|
+
new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
|
|
245
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
246
|
+
return writeBytes(buf_ptr, buf_max, bytes);
|
|
247
|
+
} catch (err) {
|
|
248
|
+
if (timeout)
|
|
249
|
+
clearTimeout(timeout);
|
|
250
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
251
|
+
console.error(`wasm fetch failed: ${url} (${msg})`);
|
|
252
|
+
return -1;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const Suspending = WebAssembly.Suspending;
|
|
256
|
+
if (typeof Suspending !== "function") {
|
|
257
|
+
return {
|
|
258
|
+
fetch: (_url_ptr, _url_len, _method_ptr, _method_len, _headers_ptr, _headers_len, _body_ptr, _body_len, _timeout_ms, _status_out, _buf_ptr, _buf_max) => -1
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
fetch: new Suspending(doFetch)
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
196
266
|
// src/wasm/core.ts
|
|
197
267
|
var CallbackType = {
|
|
198
268
|
Event: 0,
|
|
@@ -291,7 +361,7 @@ class ZxBridgeCore {
|
|
|
291
361
|
const url = readString(urlPtr, urlLen);
|
|
292
362
|
const method = methodLen > 0 ? readString(methodPtr, methodLen) : "GET";
|
|
293
363
|
const headersJson = headersLen > 0 ? readString(headersPtr, headersLen) : "{}";
|
|
294
|
-
const body = bodyLen > 0 ?
|
|
364
|
+
const body = bodyLen > 0 ? getMemoryView().subarray(bodyPtr, bodyPtr + bodyLen) : undefined;
|
|
295
365
|
let headers = {};
|
|
296
366
|
try {
|
|
297
367
|
headers = JSON.parse(headersJson);
|
|
@@ -315,8 +385,8 @@ class ZxBridgeCore {
|
|
|
315
385
|
fetch(url, fetchOptions).then(async (response) => {
|
|
316
386
|
if (timeout)
|
|
317
387
|
clearTimeout(timeout);
|
|
318
|
-
const
|
|
319
|
-
this._notifyFetchComplete(fetchId, response.status,
|
|
388
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
389
|
+
this._notifyFetchComplete(fetchId, response.status, bytes, false);
|
|
320
390
|
}).catch((error) => {
|
|
321
391
|
if (timeout)
|
|
322
392
|
clearTimeout(timeout);
|
|
@@ -327,7 +397,7 @@ class ZxBridgeCore {
|
|
|
327
397
|
}
|
|
328
398
|
_notifyFetchComplete(fetchId, statusCode, body, isError) {
|
|
329
399
|
const handler = this.#fetchCompleteHandler;
|
|
330
|
-
const encoded = textEncoder.encode(body);
|
|
400
|
+
const encoded = typeof body === "string" ? textEncoder.encode(body) : body;
|
|
331
401
|
const ptr = this._alloc(encoded.length);
|
|
332
402
|
writeBytes(ptr, encoded);
|
|
333
403
|
invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
|
|
@@ -384,6 +454,11 @@ class ZxBridgeCore {
|
|
|
384
454
|
static createImportObject(bridgeRef) {
|
|
385
455
|
return {
|
|
386
456
|
...jsz.importObject(),
|
|
457
|
+
__zx_net: createFetchImports(() => {
|
|
458
|
+
if (!jsz.memory)
|
|
459
|
+
throw new Error("WASM memory is not ready");
|
|
460
|
+
return jsz.memory;
|
|
461
|
+
}),
|
|
387
462
|
__zx: {
|
|
388
463
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
389
464
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
@@ -793,6 +868,11 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
793
868
|
static createImportObject(bridgeRef) {
|
|
794
869
|
return {
|
|
795
870
|
...jsz.importObject(),
|
|
871
|
+
__zx_net: createFetchImports(() => {
|
|
872
|
+
if (!jsz.memory)
|
|
873
|
+
throw new Error("WASM memory is not ready");
|
|
874
|
+
return jsz.memory;
|
|
875
|
+
}),
|
|
796
876
|
__zx: {
|
|
797
877
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
798
878
|
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
package/wasm/init.dev.js
CHANGED
|
@@ -178,6 +178,76 @@ class ZigJS {
|
|
|
178
178
|
return decoder.decode(data);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
+
// src/fetch.ts
|
|
182
|
+
function createFetchImports(getMemory) {
|
|
183
|
+
const encoder2 = new TextEncoder;
|
|
184
|
+
const decoder2 = new TextDecoder;
|
|
185
|
+
function readStr(ptr, len) {
|
|
186
|
+
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
187
|
+
}
|
|
188
|
+
function writeBytes(buf_ptr, buf_max, data) {
|
|
189
|
+
if (data.length > buf_max)
|
|
190
|
+
return -2;
|
|
191
|
+
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
192
|
+
return data.length;
|
|
193
|
+
}
|
|
194
|
+
function readBytes(ptr, len) {
|
|
195
|
+
return new Uint8Array(getMemory().buffer, ptr, len);
|
|
196
|
+
}
|
|
197
|
+
function parseHeaders(headersJson) {
|
|
198
|
+
let headers = {};
|
|
199
|
+
try {
|
|
200
|
+
headers = JSON.parse(headersJson);
|
|
201
|
+
} catch {
|
|
202
|
+
for (const line of headersJson.split(`
|
|
203
|
+
`)) {
|
|
204
|
+
const colonIdx = line.indexOf(":");
|
|
205
|
+
if (colonIdx > 0) {
|
|
206
|
+
headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return headers;
|
|
211
|
+
}
|
|
212
|
+
async function doFetch(url_ptr, url_len, method_ptr, method_len, headers_ptr, headers_len, body_ptr, body_len, timeout_ms, status_out, buf_ptr, buf_max) {
|
|
213
|
+
const url = readStr(url_ptr, url_len);
|
|
214
|
+
const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
|
|
215
|
+
const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
|
|
216
|
+
const body = body_len > 0 ? readBytes(body_ptr, body_len) : undefined;
|
|
217
|
+
const headers = parseHeaders(headersJson);
|
|
218
|
+
const controller = new AbortController;
|
|
219
|
+
const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
|
|
220
|
+
try {
|
|
221
|
+
const response = await fetch(url, {
|
|
222
|
+
method,
|
|
223
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
224
|
+
body: method !== "GET" && method !== "HEAD" ? body : undefined,
|
|
225
|
+
signal: controller.signal
|
|
226
|
+
});
|
|
227
|
+
if (timeout)
|
|
228
|
+
clearTimeout(timeout);
|
|
229
|
+
new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
|
|
230
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
231
|
+
return writeBytes(buf_ptr, buf_max, bytes);
|
|
232
|
+
} catch (err) {
|
|
233
|
+
if (timeout)
|
|
234
|
+
clearTimeout(timeout);
|
|
235
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
236
|
+
console.error(`wasm fetch failed: ${url} (${msg})`);
|
|
237
|
+
return -1;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const Suspending = WebAssembly.Suspending;
|
|
241
|
+
if (typeof Suspending !== "function") {
|
|
242
|
+
return {
|
|
243
|
+
fetch: (_url_ptr, _url_len, _method_ptr, _method_len, _headers_ptr, _headers_len, _body_ptr, _body_len, _timeout_ms, _status_out, _buf_ptr, _buf_max) => -1
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
fetch: new Suspending(doFetch)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
181
251
|
// src/wasm/core.ts
|
|
182
252
|
var CallbackType = {
|
|
183
253
|
Event: 0,
|
|
@@ -276,7 +346,7 @@ class ZxBridgeCore {
|
|
|
276
346
|
const url = readString(urlPtr, urlLen);
|
|
277
347
|
const method = methodLen > 0 ? readString(methodPtr, methodLen) : "GET";
|
|
278
348
|
const headersJson = headersLen > 0 ? readString(headersPtr, headersLen) : "{}";
|
|
279
|
-
const body = bodyLen > 0 ?
|
|
349
|
+
const body = bodyLen > 0 ? getMemoryView().subarray(bodyPtr, bodyPtr + bodyLen) : undefined;
|
|
280
350
|
let headers = {};
|
|
281
351
|
try {
|
|
282
352
|
headers = JSON.parse(headersJson);
|
|
@@ -300,8 +370,8 @@ class ZxBridgeCore {
|
|
|
300
370
|
fetch(url, fetchOptions).then(async (response) => {
|
|
301
371
|
if (timeout)
|
|
302
372
|
clearTimeout(timeout);
|
|
303
|
-
const
|
|
304
|
-
this._notifyFetchComplete(fetchId, response.status,
|
|
373
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
374
|
+
this._notifyFetchComplete(fetchId, response.status, bytes, false);
|
|
305
375
|
}).catch((error) => {
|
|
306
376
|
if (timeout)
|
|
307
377
|
clearTimeout(timeout);
|
|
@@ -312,7 +382,7 @@ class ZxBridgeCore {
|
|
|
312
382
|
}
|
|
313
383
|
_notifyFetchComplete(fetchId, statusCode, body, isError) {
|
|
314
384
|
const handler = this.#fetchCompleteHandler;
|
|
315
|
-
const encoded = textEncoder.encode(body);
|
|
385
|
+
const encoded = typeof body === "string" ? textEncoder.encode(body) : body;
|
|
316
386
|
const ptr = this._alloc(encoded.length);
|
|
317
387
|
writeBytes(ptr, encoded);
|
|
318
388
|
invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
|
|
@@ -369,6 +439,11 @@ class ZxBridgeCore {
|
|
|
369
439
|
static createImportObject(bridgeRef) {
|
|
370
440
|
return {
|
|
371
441
|
...jsz.importObject(),
|
|
442
|
+
__zx_net: createFetchImports(() => {
|
|
443
|
+
if (!jsz.memory)
|
|
444
|
+
throw new Error("WASM memory is not ready");
|
|
445
|
+
return jsz.memory;
|
|
446
|
+
}),
|
|
372
447
|
__zx: {
|
|
373
448
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
374
449
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
@@ -755,6 +830,11 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
755
830
|
static createImportObject(bridgeRef) {
|
|
756
831
|
return {
|
|
757
832
|
...jsz.importObject(),
|
|
833
|
+
__zx_net: createFetchImports(() => {
|
|
834
|
+
if (!jsz.memory)
|
|
835
|
+
throw new Error("WASM memory is not ready");
|
|
836
|
+
return jsz.memory;
|
|
837
|
+
}),
|
|
758
838
|
__zx: {
|
|
759
839
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
760
840
|
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
package/wasm/init.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)){let E=B.indexOf(":");if(E>0)T[B.slice(0,E)]=B.slice(E+1)}}let z=new AbortController,N=V>0?setTimeout(()=>z.abort(),V):null,k={method:W,headers:Object.keys(T).length>0?T:void 0,body:W!=="GET"&&W!=="HEAD"?Z:void 0,signal:z.signal};fetch(X,k).then(async(B)=>{if(N)clearTimeout(N);let E=await B.text();this._notifyFetchComplete(U,B.status,E,!1)}).catch((B)=>{if(N)clearTimeout(N);let o=B.name==="AbortError"?"Request timeout":B.message??"Fetch failed";this._notifyFetchComplete(U,0,o,!0)})}_notifyFetchComplete(K,$,q,Q){let F=this.#F,D=S.encode(q),Y=this._alloc(D.length);M(Y,D),A(F,K,$,Y,D.length,Q?1:0)}setTimeout(K,$){setTimeout(()=>{this.#$(g.Timeout,K,null)},$)}setInterval(K,$){let q=setInterval(()=>{this.#$(g.Interval,K,null)},$);this.#K.set(K,q)}clearInterval(K){let $=this.#K.get(K);if($!==void 0)clearInterval($),this.#K.delete(K)}dispose(){for(let K of this.#K.values())clearInterval(K);this.#K.clear()}_writeStringToWasm(K){return this._writeBytesToWasm(S.encode(K))}_writeBytesToWasm(K){let $=this._alloc(K.length);return M($,K),{ptr:$,len:K.length}}static log(K,$,q){let Q=y.decode(P().subarray($,$+q));switch(K){case 0:console.error(Q);break;case 1:console.warn(Q);break;case 3:console.debug(Q);break;default:console.log(Q);break}}static createImportObject(K){return{...H.importObject(),__zx:{_log:($,q,Q)=>x.log($,q,Q),_fetchAsync:($,q,Q,F,D,Y,J,V,U,X)=>{K.current?.fetchAsync($,q,Q,F,D,Y,J,V,U,X)},_setTimeout:($,q)=>{K.current?.setTimeout($,q)},_setInterval:($,q)=>{K.current?.setInterval($,q)},_clearInterval:($)=>{K.current?.clearInterval($)}}}}}function d(K){let $=K;return typeof $.getSync==="function"&&typeof $.putSync==="function"&&typeof $.deleteSync==="function"&&typeof $.listSync==="function"}function i(K,$){let q=new TextEncoder,Q=new TextDecoder;function F(V,U){return Q.decode(new Uint8Array($().buffer,V,U))}function D(V,U,X){if(X.length>U)return-2;return new Uint8Array($().buffer,V,X.length).set(X),X.length}function Y(V){return K[V]??K.default??null}let J=WebAssembly.Suspending;if(typeof J!=="function"){let V=function(U){let X=Y(U);return X&&d(X)?X:null};return{kv_get:(U,X,W,G,Z,T)=>{let z=V(F(U,X));if(!z)return-1;let N=z.getSync(F(W,G));if(N===null)return-1;return D(Z,T,q.encode(N))},kv_put:(U,X,W,G,Z,T)=>{let z=V(F(U,X));if(!z)return 0;return z.putSync(F(W,G),F(Z,T)),0},kv_delete:(U,X,W,G)=>{let Z=V(F(U,X));if(!Z)return 0;return Z.deleteSync(F(W,G)),0},kv_list:(U,X,W,G,Z,T)=>{let z=V(F(U,X));if(!z)return D(Z,T,q.encode("[]"));let N=F(W,G),k=z.listSync(N.length>0?{prefix:N}:void 0);return D(Z,T,q.encode(JSON.stringify(k.keys.map((B)=>B.name))))}}}return{kv_get:new J(async(V,U,X,W,G,Z)=>{let T=Y(F(V,U));if(!T)return-1;let z=await T.get(F(X,W));if(z===null)return-1;return D(G,Z,q.encode(z))}),kv_put:new J(async(V,U,X,W,G,Z)=>{let T=Y(F(V,U));if(!T)return-1;return await T.put(F(X,W),F(G,Z)),0}),kv_delete:new J(async(V,U,X,W)=>{let G=Y(F(V,U));if(!G)return-1;return await G.delete(F(X,W)),0}),kv_list:new J(async(V,U,X,W,G,Z)=>{let T=Y(F(V,U));if(!T)return D(G,Z,q.encode("[]"));let z=F(X,W),N=await T.list(z.length>0?{prefix:z}:void 0);return D(G,Z,q.encode(JSON.stringify(N.keys.map((k)=>k.name))))})}}function e(){if(typeof indexedDB>"u")throw Error("IndexedDB is not available in this environment");return indexedDB}function s(K){return new Promise(($,q)=>{K.onsuccess=()=>$(K.result),K.onerror=()=>q(K.error??Error("IndexedDB request failed"))})}function h(K){return new Promise(($,q)=>{K.oncomplete=()=>$(),K.onabort=()=>q(K.error??Error("IndexedDB transaction aborted")),K.onerror=()=>q(K.error??Error("IndexedDB transaction failed"))})}function KK(K={}){let $=K.databaseName??"ziex-kv",q=K.storeName??"kv",Q=K.namespace??"default",F=new Promise((Y,J)=>{let V=e().open($,1);V.onupgradeneeded=()=>{let U=V.result;if(!U.objectStoreNames.contains(q))U.createObjectStore(q)},V.onsuccess=()=>Y(V.result),V.onerror=()=>J(V.error??Error("Failed to open IndexedDB"))}),D=(Y)=>`${Q}:${Y}`;return{async get(Y){let V=(await F).transaction(q,"readonly"),U=V.objectStore(q),X=await s(U.get(D(Y)));return await h(V),console.debug(`KV GET - Key: ${Y}, Value: ${X}`),typeof X==="string"?X:null},async put(Y,J){let U=(await F).transaction(q,"readwrite");U.objectStore(q).put(J,D(Y)),await h(U),console.debug(`KV PUT - Key: ${Y}, Value: ${J}`)},async delete(Y){let V=(await F).transaction(q,"readwrite");V.objectStore(q).delete(D(Y)),await h(V)},async list(Y){let V=(await F).transaction(q,"readonly"),U=V.objectStore(q),X=await s(U.getAllKeys());await h(V);let W=D(Y?.prefix??"");return{keys:X.filter((G)=>typeof G==="string"&&G.startsWith(W)).map((G)=>({name:G.slice(Q.length+1)}))}}}}function $K(){if(typeof localStorage>"u")throw Error("localStorage is not available in this environment");return localStorage}function qK(K={}){let $=$K(),q=K.namespace??"default",Q=K.storagePrefix??"ziex-kv",F=(Y)=>`${Q}:${q}:${Y}`,D=F("");return{getSync(Y){return $.getItem(F(Y))},async get(Y){return this.getSync(Y)},putSync(Y,J){$.setItem(F(Y),J)},async put(Y,J){this.putSync(Y,J)},deleteSync(Y){$.removeItem(F(Y))},async delete(Y){this.deleteSync(Y)},listSync(Y){let J=D+(Y?.prefix??""),V=[];for(let U=0;U<$.length;U+=1){let X=$.key(U);if(!X||!X.startsWith(J))continue;V.push({name:X.slice(D.length)})}return{keys:V}},async list(Y){return this.listSync(Y)}}}function FK(){return typeof WebAssembly.Suspending==="function"&&typeof WebAssembly.promising==="function"}function l(K={}){return{[K.namespace??"default"]:FK()?KK(K):qK(K)}}class u extends x{#K=new Map;#q;#F;#$;#Q;#Y;#D;constructor(K){super(K);this.#q=C(K.__zx_ws_onopen),this.#F=C(K.__zx_ws_onmessage),this.#$=C(K.__zx_ws_onerror),this.#Q=C(K.__zx_ws_onclose),this.#Y=K.__zx_eventbridge,this.#D=C(K.__zx_eventbridge_async??K.__zx_eventbridge)}eventMaySuspend(K,$){return!!((L.get(K)??0)&1<<$)}setEventHandlerMode(K,$,q){let Q=1<<$,F=L.get(K)??0,D=q?F|Q:F&~Q;if(D===0)L.delete(K);else L.set(K,D)}clearEventHandlerModes(K){L.delete(K)}submitFormActionAsync(K,$,q,Q){let F=new FormData(K);F.append("__$states",q),fetch(window.location.href,{method:"POST",headers:{"x-action":String($>>>0)},body:F}).then(async(D)=>{let Y=await D.text();this._notifyFetchComplete(Q,D.status,Y,!1)}).catch((D)=>{let Y=D instanceof Error?D.message:"Fetch failed";this._notifyFetchComplete(Q,0,Y,!0)})}wsConnect(K,$,q,Q,F){let D=j($,q),Y=F>0?j(Q,F):"",J=Y?Y.split(",").map((V)=>V.trim()).filter(Boolean):void 0;try{let V=J&&J.length>0?new WebSocket(D,J):new WebSocket(D);V.binaryType="arraybuffer",V.onopen=()=>{let U=this.#q;if(!U)return;let X=V.protocol||"",{ptr:W,len:G}=this._writeStringToWasm(X);A(U,K,W,G)},V.onmessage=(U)=>{let X=this.#F;if(!X)return;let W=U.data instanceof ArrayBuffer,G=W?new Uint8Array(U.data):S.encode(U.data),{ptr:Z,len:T}=this._writeBytesToWasm(G);A(X,K,Z,T,W?1:0)},V.onerror=(U)=>{let X=this.#$;if(!X)return;let{ptr:W,len:G}=this._writeStringToWasm("WebSocket error");A(X,K,W,G)},V.onclose=(U)=>{let X=this.#Q;if(!X)return;let W=U.reason||"",{ptr:G,len:Z}=this._writeStringToWasm(W);A(X,K,U.code,G,Z,U.wasClean?1:0),this.#K.delete(K)},this.#K.set(K,V)}catch(V){let U=this.#$;if(U){let X=V instanceof Error?V.message:"WebSocket connection failed",{ptr:W,len:G}=this._writeStringToWasm(X);A(U,K,W,G)}}}wsSend(K,$,q,Q){let F=this.#K.get(K);if(!F||F.readyState!==WebSocket.OPEN)return;let D=P();if(Q)F.send(D.slice($,$+q));else F.send(y.decode(D.subarray($,$+q)))}wsClose(K,$,q,Q){let F=this.#K.get(K);if(!F)return;let D=Q>0?j(q,Q):void 0;try{if(D)F.close($,D);else F.close($)}catch{F.close()}}dispose(){super.dispose(),L.clear();for(let K of this.#K.values())try{K.close()}catch{}this.#K.clear()}eventbridge(K,$,q){let Q=R(q);if(this.eventMaySuspend(K,$)){A(this.#D,K,$,Q);return}A(this.#Y,K,$,Q)}static createImportObject(K){return{...H.importObject(),__zx:{_log:($,q,Q)=>x.log($,q,Q),_setEventHandlerMode:($,q,Q)=>{K.current?.setEventHandlerMode($,q,Q!==0)},_clearEventHandlerModes:($)=>{K.current?.clearEventHandlerModes($)},_fetchAsync:($,q,Q,F,D,Y,J,V,U,X)=>{K.current?.fetchAsync($,q,Q,F,D,Y,J,V,U,X)},_setTimeout:($,q)=>{K.current?.setTimeout($,q)},_setInterval:($,q)=>{K.current?.setInterval($,q)},_clearInterval:($)=>{K.current?.clearInterval($)},_wsConnect:($,q,Q,F,D)=>{K.current?.wsConnect($,q,Q,F,D)},_wsSend:($,q,Q,F)=>{K.current?.wsSend($,q,Q,F)},_wsClose:($,q,Q,F)=>{K.current?.wsClose($,q,Q,F)},_ce:($,q)=>{let Q=YK[$],F=$>=QK?document.createElementNS("http://www.w3.org/2000/svg",Q):document.createElement(Q);return F.__zx_ref=Number(q),O.set(q,F),R(F)},_ct:($,q,Q)=>{let F=j($,q),D=document.createTextNode(F);return D.__zx_ref=Number(Q),O.set(Q,D),R(D)},_sa:($,q,Q,F,D)=>{O.get($)?.setAttribute(j(q,Q),j(F,D))},_sp:($,q,Q,F,D)=>{let Y=O.get($);if(Y){let J=j(q,Q),V=j(F,D);if(J==="checked"||J==="selected"||J==="muted")Y[J]=V!=="false";else Y[J]=V}},_ra:($,q,Q)=>{O.get($)?.removeAttribute(j(q,Q))},_snv:($,q,Q)=>{let F=O.get($);if(F)F.nodeValue=j(q,Q)},_srh:($,q,Q)=>{let F=O.get($);if(F)F.innerHTML=j(q,Q)},_ac:($,q)=>{let Q=O.get($),F=O.get(q);if(Q&&F)Q.appendChild(F)},_ib:($,q,Q)=>{let F=O.get($),D=O.get(q),Y=O.get(Q)??null;if(F&&D)F.insertBefore(D,Y)},_rc:($,q)=>{let Q=O.get($),F=O.get(q);if(Q&&F)Q.removeChild(F),f(F)},_rpc:($,q,Q)=>{let F=O.get($),D=O.get(q),Y=O.get(Q);if(F&&D&&Y)F.replaceChild(D,Y),f(Y)},_getLocationHref:($,q)=>{let Q=S.encode(window.location.href),F=Math.min(Q.length,q);return M($,Q.subarray(0,F)),F},_getFormData:($,q,Q)=>{let F=O.get($);if(!F||!(F instanceof HTMLFormElement))return 0;let D=new FormData(F),Y=new URLSearchParams(D).toString(),J=S.encode(Y),V=Math.min(J.length,Q);return M(q,J.subarray(0,V)),V},_submitFormAction:($,q)=>{let Q=O.get($);if(!Q||!(Q instanceof HTMLFormElement))return;let F=new FormData(Q);fetch(window.location.href,{method:"POST",headers:{"x-action":String(q>>>0)},body:F}).catch(()=>{})},_submitFormActionAsync:($,q,Q,F,D)=>{let Y=O.get($);if(!Y||!(Y instanceof HTMLFormElement))return;let J=F>0?j(Q,F):"[]";K.current?.submitFormActionAsync(Y,q,J,D)}}}}}var O=new Map;function f(K){let $=K.__zx_ref;if($!==void 0)O.delete(BigInt($));let q=K.childNodes;for(let Q=0;Q<q.length;Q++)f(q[Q])}var QK=140,YK=["aside","fragment","iframe","slot","img","html","base","head","link","meta","script","style","title","address","article","body","h1","h6","footer","header","h2","h3","h4","h5","hgroup","nav","section","dd","dl","dt","div","figcaption","figure","hr","li","ol","ul","menu","main","p","picture","pre","a","abbr","b","bdi","bdo","br","cite","code","data","time","dfn","em","i","kbd","mark","q","blockquote","rp","ruby","rt","rtc","rb","s","del","ins","samp","small","span","strong","sub","sup","u","var","wbr","area","map","audio","source","track","video","embed","object","param","canvas","noscript","caption","table","col","colgroup","tbody","tr","thead","tfoot","td","th","button","datalist","option","fieldset","label","form","input","keygen","legend","meter","optgroup","select","output","progress","textarea","details","dialog","menuitem","summary","content","element","shadow","template","acronym","applet","basefont","font","big","blink","center","command","dir","frame","frameset","isindex","listing","marquee","noembed","plaintext","spacer","strike","tt","xmp","animate","animateMotion","animateTransform","circle","clipPath","defs","desc","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","svg","switch","symbol","text","textPath","tspan","use","view"],DK=[{domType:"click",eventTypeId:0},{domType:"dblclick",eventTypeId:1},{domType:"input",eventTypeId:2},{domType:"change",eventTypeId:3},{domType:"submit",eventTypeId:4},{domType:"focusin",eventTypeId:5},{domType:"focusout",eventTypeId:6},{domType:"keydown",eventTypeId:7},{domType:"keyup",eventTypeId:8},{domType:"keypress",eventTypeId:9},{domType:"mouseenter",eventTypeId:10},{domType:"mouseleave",eventTypeId:11},{domType:"mousedown",eventTypeId:12},{domType:"mouseup",eventTypeId:13},{domType:"mousemove",eventTypeId:14},{domType:"touchstart",eventTypeId:15},{domType:"touchend",eventTypeId:16},{domType:"touchmove",eventTypeId:17},{domType:"scroll",eventTypeId:18}],L=new Map;function VK(K,$="body"){let q=document.querySelector($);if(!q)return()=>{};let Q=[];for(let F of DK){let D=(J)=>{let V=J.target;while(V&&V!==document.body){let U=V.__zx_ref;if(U!==void 0){if(K.eventbridge(BigInt(U),F.eventTypeId,J),J.cancelBubble)break}V=V.parentElement}},Y={passive:F.domType.startsWith("touch")||F.domType==="scroll"};q.addEventListener(F.domType,D,Y),Q.push(()=>q.removeEventListener(F.domType,D,Y))}return()=>{for(let F of Q)F()}}var UK="/assets/_/main.wasm",c=null;function XK(K={}){return{url:K.url,eventDelegationRoot:K.eventDelegationRoot,importObject:K.importObject,kv:K.kv}}async function a(K={}){let $=XK(K);if(c)c.dispose(),c=null;let q=K.url??document.getElementById("__$wasmlink")?.href??UK,Q={current:null},F=null,D=K.kv??l(),Y={__zx_kv:i(D,()=>{if(F)return F;if(H.memory)return H.memory;throw Error("WASM memory is not ready")})},J=Object.assign({},u.createImportObject(Q),Y,K.importObject),V=await WebAssembly.instantiateStreaming(fetch(q),J),{instance:U}=V;F=U.exports.memory,H.memory=F;let X=new u(U.exports);Q.current=X,O.clear();let W=VK(X,K.eventDelegationRoot??"body"),G=C(U.exports.mainClient);return A(G),c={options:$,dispose:()=>{W(),X.dispose(),O.clear()}},{source:V,bridge:X}}(()=>a())();
|
|
1
|
+
var L={nan:0,null:1,true:2,false:3,undefined:4,globalThis:5,runtime:6};var n=new TextEncoder,FK=new TextDecoder("utf-8");class I{memory;values=[NaN,null,!0,!1,void 0,globalThis,this];idPool=[];importObject(){return{"zig-js":{valueGet:this.valueGet.bind(this),valueSet:this.valueSet.bind(this),valueDeinit:this.valueDeinit.bind(this),valueObjectCreate:this.valueObjectCreate.bind(this),valueStringCreate:this.valueStringCreate.bind(this),valueStringLen:this.valueStringLen.bind(this),valueStringCopy:this.valueStringCopy.bind(this),valueNew:this.valueNew.bind(this),funcApply:this.funcApply.bind(this)}}}valueGet(K,$,U,q){let D=this.loadValue($),Y=this.loadString(U,q),F=Reflect.get(D,Y);this.storeValue(K,F)}valueSet(K,$,U,q){let D=this.loadValue(K),Y=this.loadString($,U),F=this.loadRef(q);Reflect.set(D,Y,F)}valueDeinit(K){if(K>6)this.values[K]=null,this.idPool.push(K)}valueObjectCreate(K){this.storeValue(K,{})}valueStringCreate(K,$,U){let q=this.loadString($,U);this.storeValue(K,q)}valueStringLen(K){let $=this.loadValue(K);return n.encode($).byteLength}valueStringCopy(K,$,U){if(this.memory==null)return;let q=this.loadValue(K),D=n.encode(q);if(D.byteLength>U)return;if(D.length===0)return;new Uint8Array(this.memory.buffer,$,D.length).set(D)}valueNew(K,$,U,q){let D=this.loadValue($),Y=[];for(let J=0;J<q;J++)Y.push(this.loadRef(U+J*8));let F=Reflect.construct(D,Y);this.storeValue(K,F)}funcApply(K,$,U,q,D){let Y=this.loadValue($),F=this.loadRef(U),J=[];for(let Q=0;Q<D;Q++)J.push(this.loadRef(q+Q*8));let V=Reflect.apply(Y,F,J);this.storeValue(K,V)}loadValue(K){return this.values[K]}deleteValue(K){let $=this.values[K];return this.valueDeinit(K),$}loadRef(K){if(this.memory==null)return;let U=new DataView(this.memory.buffer).getFloat64(K,!0);if(!isNaN(U))return U;let q=this.loadRefId(K);return this.values[q]}loadRefId(K){if(this.memory==null)return 0;return new DataView(this.memory.buffer).getUint32(K,!0)}storeValue(K,$){if(this.memory==null)return;let U=new DataView(this.memory.buffer);if(typeof $==="number"){if(isNaN($))U.setUint32(K,L.nan,!0),U.setUint32(K+4,2146959360,!0);else U.setFloat64(K,$,!0);return}if($===null){U.setUint32(K,L.null,!0),U.setUint32(K+4,2146959360,!0);return}if($===void 0){U.setUint32(K,L.undefined,!0),U.setUint32(K+4,2146959360,!0);return}if(typeof $==="boolean"){U.setUint32(K,$?L.true:L.false,!0),U.setUint32(K+4,2146959360,!0);return}if(typeof $==="bigint"){U.setFloat64(K,Number($),!0);return}let q=this.idPool.pop();if(q===void 0)q=this.values.length;this.values[q]=$;let D=0;switch(typeof $){case"object":D=1;break;case"string":D=2;break;case"symbol":D=3;break;case"function":D=4;break}U.setUint32(K,Number(q),!0),U.setUint32(K+4,2146959360|D,!0)}loadString(K,$){if(this.memory==null)return"";let q=new Uint8ClampedArray(this.memory.buffer,K,Number($)).slice();return FK.decode(q)}}function _(K){let $=new TextEncoder,U=new TextDecoder;function q(Q,X){return U.decode(new Uint8Array(K().buffer,Q,X))}function D(Q,X,G){if(G.length>X)return-2;return new Uint8Array(K().buffer,Q,G.length).set(G),G.length}function Y(Q,X){return new Uint8Array(K().buffer,Q,X)}function F(Q){let X={};try{X=JSON.parse(Q)}catch{for(let G of Q.split(`
|
|
2
|
+
`)){let T=G.indexOf(":");if(T>0)X[G.slice(0,T)]=G.slice(T+1)}}return X}async function J(Q,X,G,T,O,W,Z,B,C,N,S,h){let s=q(Q,X),b=T>0?q(G,T):"GET",DK=W>0?q(O,W):"{}",qK=B>0?Y(Z,B):void 0,l=F(DK),a=new AbortController,y=C>0?setTimeout(()=>a.abort(),C):null;try{let M=await fetch(s,{method:b,headers:Object.keys(l).length>0?l:void 0,body:b!=="GET"&&b!=="HEAD"?qK:void 0,signal:a.signal});if(y)clearTimeout(y);new DataView(K().buffer).setUint16(N,M.status,!0);let m=new Uint8Array(await M.arrayBuffer());return D(S,h,m)}catch(M){if(y)clearTimeout(y);let m=M instanceof Error?M.message:String(M);return console.error(`wasm fetch failed: ${s} (${m})`),-1}}let V=WebAssembly.Suspending;if(typeof V!=="function")return{fetch:(Q,X,G,T,O,W,Z,B,C,N,S,h)=>-1};return{fetch:new V(J)}}var v={Event:0,FetchSuccess:1,FetchError:2,Timeout:3,Interval:4,WebSocketOpen:5,WebSocketMessage:6,WebSocketError:7,WebSocketClose:8},j=new I,d=new ArrayBuffer(8),QK=new DataView(d);function P(K){let $=j.memory;return j.memory={buffer:d},j.storeValue(0,K),j.memory=$,QK.getBigUint64(0,!0)}var k=new TextDecoder,u=new TextEncoder,o=null,t=null;function R(){let K=j.memory.buffer;if(K!==t)t=K,o=new Uint8Array(K);return o}var r=new Map;function YK(K,$){return K*65536+$}function H(K,$){let U=YK(K,$),q=r.get(U);if(q!==void 0)return q;let D=k.decode(R().subarray(K,K+$));return r.set(U,D),D}function c(K,$){R().set($,K)}function E(K){if(!K)return;let $=WebAssembly.promising;if(typeof $!=="function")return K;return $(K)}function z(K,...$){if(!K)return;let U=K(...$);if(U&&typeof U.then==="function")U.then(void 0,(q)=>{console.error(q)})}class x{#K=new Map;_alloc;#U;#D;constructor(K){this._alloc=K.__zx_alloc,this.#U=E(K.__zx_cb);let $=E(K.__zx_fetch_complete);if(!$)throw Error("__zx_fetch_complete not exported from WASM");if(this.#D=$,K.memory)j.memory=K.memory}#$(K,$,U){let q=this.#U;if(!q){console.warn("__zx_cb not exported from WASM");return}let D=P(U);z(q,K,$,D)}fetchAsync(K,$,U,q,D,Y,F,J,V,Q){let X=H(K,$),G=q>0?H(U,q):"GET",T=Y>0?H(D,Y):"{}",O=J>0?R().subarray(F,F+J):void 0,W={};try{W=JSON.parse(T)}catch{for(let N of T.split(`
|
|
3
|
+
`)){let S=N.indexOf(":");if(S>0)W[N.slice(0,S)]=N.slice(S+1)}}let Z=new AbortController,B=V>0?setTimeout(()=>Z.abort(),V):null,C={method:G,headers:Object.keys(W).length>0?W:void 0,body:G!=="GET"&&G!=="HEAD"?O:void 0,signal:Z.signal};fetch(X,C).then(async(N)=>{if(B)clearTimeout(B);let S=new Uint8Array(await N.arrayBuffer());this._notifyFetchComplete(Q,N.status,S,!1)}).catch((N)=>{if(B)clearTimeout(B);let h=N.name==="AbortError"?"Request timeout":N.message??"Fetch failed";this._notifyFetchComplete(Q,0,h,!0)})}_notifyFetchComplete(K,$,U,q){let D=this.#D,Y=typeof U==="string"?u.encode(U):U,F=this._alloc(Y.length);c(F,Y),z(D,K,$,F,Y.length,q?1:0)}setTimeout(K,$){setTimeout(()=>{this.#$(v.Timeout,K,null)},$)}setInterval(K,$){let U=setInterval(()=>{this.#$(v.Interval,K,null)},$);this.#K.set(K,U)}clearInterval(K){let $=this.#K.get(K);if($!==void 0)clearInterval($),this.#K.delete(K)}dispose(){for(let K of this.#K.values())clearInterval(K);this.#K.clear()}_writeStringToWasm(K){return this._writeBytesToWasm(u.encode(K))}_writeBytesToWasm(K){let $=this._alloc(K.length);return c($,K),{ptr:$,len:K.length}}static log(K,$,U){let q=k.decode(R().subarray($,$+U));switch(K){case 0:console.error(q);break;case 1:console.warn(q);break;case 3:console.debug(q);break;default:console.log(q);break}}static createImportObject(K){return{...j.importObject(),__zx_net:_(()=>{if(!j.memory)throw Error("WASM memory is not ready");return j.memory}),__zx:{_log:($,U,q)=>x.log($,U,q),_fetchAsync:($,U,q,D,Y,F,J,V,Q,X)=>{K.current?.fetchAsync($,U,q,D,Y,F,J,V,Q,X)},_setTimeout:($,U)=>{K.current?.setTimeout($,U)},_setInterval:($,U)=>{K.current?.setInterval($,U)},_clearInterval:($)=>{K.current?.clearInterval($)}}}}}function VK(K){let $=K;return typeof $.getSync==="function"&&typeof $.putSync==="function"&&typeof $.deleteSync==="function"&&typeof $.listSync==="function"}function e(K,$){let U=new TextEncoder,q=new TextDecoder;function D(V,Q){return q.decode(new Uint8Array($().buffer,V,Q))}function Y(V,Q,X){if(X.length>Q)return-2;return new Uint8Array($().buffer,V,X.length).set(X),X.length}function F(V){return K[V]??K.default??null}let J=WebAssembly.Suspending;if(typeof J!=="function"){let V=function(Q){let X=F(Q);return X&&VK(X)?X:null};return{kv_get:(Q,X,G,T,O,W)=>{let Z=V(D(Q,X));if(!Z)return-1;let B=Z.getSync(D(G,T));if(B===null)return-1;return Y(O,W,U.encode(B))},kv_put:(Q,X,G,T,O,W)=>{let Z=V(D(Q,X));if(!Z)return 0;return Z.putSync(D(G,T),D(O,W)),0},kv_delete:(Q,X,G,T)=>{let O=V(D(Q,X));if(!O)return 0;return O.deleteSync(D(G,T)),0},kv_list:(Q,X,G,T,O,W)=>{let Z=V(D(Q,X));if(!Z)return Y(O,W,U.encode("[]"));let B=D(G,T),C=Z.listSync(B.length>0?{prefix:B}:void 0);return Y(O,W,U.encode(JSON.stringify(C.keys.map((N)=>N.name))))}}}return{kv_get:new J(async(V,Q,X,G,T,O)=>{let W=F(D(V,Q));if(!W)return-1;let Z=await W.get(D(X,G));if(Z===null)return-1;return Y(T,O,U.encode(Z))}),kv_put:new J(async(V,Q,X,G,T,O)=>{let W=F(D(V,Q));if(!W)return-1;return await W.put(D(X,G),D(T,O)),0}),kv_delete:new J(async(V,Q,X,G)=>{let T=F(D(V,Q));if(!T)return-1;return await T.delete(D(X,G)),0}),kv_list:new J(async(V,Q,X,G,T,O)=>{let W=F(D(V,Q));if(!W)return Y(T,O,U.encode("[]"));let Z=D(X,G),B=await W.list(Z.length>0?{prefix:Z}:void 0);return Y(T,O,U.encode(JSON.stringify(B.keys.map((C)=>C.name))))})}}function XK(){if(typeof indexedDB>"u")throw Error("IndexedDB is not available in this environment");return indexedDB}function KK(K){return new Promise(($,U)=>{K.onsuccess=()=>$(K.result),K.onerror=()=>U(K.error??Error("IndexedDB request failed"))})}function g(K){return new Promise(($,U)=>{K.oncomplete=()=>$(),K.onabort=()=>U(K.error??Error("IndexedDB transaction aborted")),K.onerror=()=>U(K.error??Error("IndexedDB transaction failed"))})}function JK(K={}){let $=K.databaseName??"ziex-kv",U=K.storeName??"kv",q=K.namespace??"default",D=new Promise((F,J)=>{let V=XK().open($,1);V.onupgradeneeded=()=>{let Q=V.result;if(!Q.objectStoreNames.contains(U))Q.createObjectStore(U)},V.onsuccess=()=>F(V.result),V.onerror=()=>J(V.error??Error("Failed to open IndexedDB"))}),Y=(F)=>`${q}:${F}`;return{async get(F){let V=(await D).transaction(U,"readonly"),Q=V.objectStore(U),X=await KK(Q.get(Y(F)));return await g(V),console.debug(`KV GET - Key: ${F}, Value: ${X}`),typeof X==="string"?X:null},async put(F,J){let Q=(await D).transaction(U,"readwrite");Q.objectStore(U).put(J,Y(F)),await g(Q),console.debug(`KV PUT - Key: ${F}, Value: ${J}`)},async delete(F){let V=(await D).transaction(U,"readwrite");V.objectStore(U).delete(Y(F)),await g(V)},async list(F){let V=(await D).transaction(U,"readonly"),Q=V.objectStore(U),X=await KK(Q.getAllKeys());await g(V);let G=Y(F?.prefix??"");return{keys:X.filter((T)=>typeof T==="string"&&T.startsWith(G)).map((T)=>({name:T.slice(q.length+1)}))}}}}function GK(){if(typeof localStorage>"u")throw Error("localStorage is not available in this environment");return localStorage}function TK(K={}){let $=GK(),U=K.namespace??"default",q=K.storagePrefix??"ziex-kv",D=(F)=>`${q}:${U}:${F}`,Y=D("");return{getSync(F){return $.getItem(D(F))},async get(F){return this.getSync(F)},putSync(F,J){$.setItem(D(F),J)},async put(F,J){this.putSync(F,J)},deleteSync(F){$.removeItem(D(F))},async delete(F){this.deleteSync(F)},listSync(F){let J=Y+(F?.prefix??""),V=[];for(let Q=0;Q<$.length;Q+=1){let X=$.key(Q);if(!X||!X.startsWith(J))continue;V.push({name:X.slice(Y.length)})}return{keys:V}},async list(F){return this.listSync(F)}}}function WK(){return typeof WebAssembly.Suspending==="function"&&typeof WebAssembly.promising==="function"}function $K(K={}){return{[K.namespace??"default"]:WK()?JK(K):TK(K)}}class p extends x{#K=new Map;#U;#D;#$;#q;#F;#Q;constructor(K){super(K);this.#U=E(K.__zx_ws_onopen),this.#D=E(K.__zx_ws_onmessage),this.#$=E(K.__zx_ws_onerror),this.#q=E(K.__zx_ws_onclose),this.#F=K.__zx_eventbridge,this.#Q=E(K.__zx_eventbridge_async??K.__zx_eventbridge)}eventMaySuspend(K,$){return!!((w.get(K)??0)&1<<$)}setEventHandlerMode(K,$,U){let q=1<<$,D=w.get(K)??0,Y=U?D|q:D&~q;if(Y===0)w.delete(K);else w.set(K,Y)}clearEventHandlerModes(K){w.delete(K)}submitFormActionAsync(K,$,U,q){let D=new FormData(K);D.append("__$states",U),fetch(window.location.href,{method:"POST",headers:{"x-action":String($>>>0)},body:D}).then(async(Y)=>{let F=await Y.text();this._notifyFetchComplete(q,Y.status,F,!1)}).catch((Y)=>{let F=Y instanceof Error?Y.message:"Fetch failed";this._notifyFetchComplete(q,0,F,!0)})}wsConnect(K,$,U,q,D){let Y=H($,U),F=D>0?H(q,D):"",J=F?F.split(",").map((V)=>V.trim()).filter(Boolean):void 0;try{let V=J&&J.length>0?new WebSocket(Y,J):new WebSocket(Y);V.binaryType="arraybuffer",V.onopen=()=>{let Q=this.#U;if(!Q)return;let X=V.protocol||"",{ptr:G,len:T}=this._writeStringToWasm(X);z(Q,K,G,T)},V.onmessage=(Q)=>{let X=this.#D;if(!X)return;let G=Q.data instanceof ArrayBuffer,T=G?new Uint8Array(Q.data):u.encode(Q.data),{ptr:O,len:W}=this._writeBytesToWasm(T);z(X,K,O,W,G?1:0)},V.onerror=(Q)=>{let X=this.#$;if(!X)return;let{ptr:G,len:T}=this._writeStringToWasm("WebSocket error");z(X,K,G,T)},V.onclose=(Q)=>{let X=this.#q;if(!X)return;let G=Q.reason||"",{ptr:T,len:O}=this._writeStringToWasm(G);z(X,K,Q.code,T,O,Q.wasClean?1:0),this.#K.delete(K)},this.#K.set(K,V)}catch(V){let Q=this.#$;if(Q){let X=V instanceof Error?V.message:"WebSocket connection failed",{ptr:G,len:T}=this._writeStringToWasm(X);z(Q,K,G,T)}}}wsSend(K,$,U,q){let D=this.#K.get(K);if(!D||D.readyState!==WebSocket.OPEN)return;let Y=R();if(q)D.send(Y.slice($,$+U));else D.send(k.decode(Y.subarray($,$+U)))}wsClose(K,$,U,q){let D=this.#K.get(K);if(!D)return;let Y=q>0?H(U,q):void 0;try{if(Y)D.close($,Y);else D.close($)}catch{D.close()}}dispose(){super.dispose(),w.clear();for(let K of this.#K.values())try{K.close()}catch{}this.#K.clear()}eventbridge(K,$,U){let q=P(U);if(this.eventMaySuspend(K,$)){z(this.#Q,K,$,q);return}z(this.#F,K,$,q)}static createImportObject(K){return{...j.importObject(),__zx_net:_(()=>{if(!j.memory)throw Error("WASM memory is not ready");return j.memory}),__zx:{_log:($,U,q)=>x.log($,U,q),_setEventHandlerMode:($,U,q)=>{K.current?.setEventHandlerMode($,U,q!==0)},_clearEventHandlerModes:($)=>{K.current?.clearEventHandlerModes($)},_fetchAsync:($,U,q,D,Y,F,J,V,Q,X)=>{K.current?.fetchAsync($,U,q,D,Y,F,J,V,Q,X)},_setTimeout:($,U)=>{K.current?.setTimeout($,U)},_setInterval:($,U)=>{K.current?.setInterval($,U)},_clearInterval:($)=>{K.current?.clearInterval($)},_wsConnect:($,U,q,D,Y)=>{K.current?.wsConnect($,U,q,D,Y)},_wsSend:($,U,q,D)=>{K.current?.wsSend($,U,q,D)},_wsClose:($,U,q,D)=>{K.current?.wsClose($,U,q,D)},_ce:($,U)=>{let q=AK[$],D=$>=OK?document.createElementNS("http://www.w3.org/2000/svg",q):document.createElement(q);return D.__zx_ref=Number(U),A.set(U,D),P(D)},_ct:($,U,q)=>{let D=H($,U),Y=document.createTextNode(D);return Y.__zx_ref=Number(q),A.set(q,Y),P(Y)},_sa:($,U,q,D,Y)=>{A.get($)?.setAttribute(H(U,q),H(D,Y))},_sp:($,U,q,D,Y)=>{let F=A.get($);if(F){let J=H(U,q),V=H(D,Y);if(J==="checked"||J==="selected"||J==="muted")F[J]=V!=="false";else F[J]=V}},_ra:($,U,q)=>{A.get($)?.removeAttribute(H(U,q))},_snv:($,U,q)=>{let D=A.get($);if(D)D.nodeValue=H(U,q)},_srh:($,U,q)=>{let D=A.get($);if(D)D.innerHTML=H(U,q)},_ac:($,U)=>{let q=A.get($),D=A.get(U);if(q&&D)q.appendChild(D)},_ib:($,U,q)=>{let D=A.get($),Y=A.get(U),F=A.get(q)??null;if(D&&Y)D.insertBefore(Y,F)},_rc:($,U)=>{let q=A.get($),D=A.get(U);if(q&&D)q.removeChild(D),i(D)},_rpc:($,U,q)=>{let D=A.get($),Y=A.get(U),F=A.get(q);if(D&&Y&&F)D.replaceChild(Y,F),i(F)},_getLocationHref:($,U)=>{let q=u.encode(window.location.href),D=Math.min(q.length,U);return c($,q.subarray(0,D)),D},_getFormData:($,U,q)=>{let D=A.get($);if(!D||!(D instanceof HTMLFormElement))return 0;let Y=new FormData(D),F=new URLSearchParams(Y).toString(),J=u.encode(F),V=Math.min(J.length,q);return c(U,J.subarray(0,V)),V},_submitFormAction:($,U)=>{let q=A.get($);if(!q||!(q instanceof HTMLFormElement))return;let D=new FormData(q);fetch(window.location.href,{method:"POST",headers:{"x-action":String(U>>>0)},body:D}).catch(()=>{})},_submitFormActionAsync:($,U,q,D,Y)=>{let F=A.get($);if(!F||!(F instanceof HTMLFormElement))return;let J=D>0?H(q,D):"[]";K.current?.submitFormActionAsync(F,U,J,Y)}}}}}var A=new Map;function i(K){let $=K.__zx_ref;if($!==void 0)A.delete(BigInt($));let U=K.childNodes;for(let q=0;q<U.length;q++)i(U[q])}var OK=140,AK=["aside","fragment","iframe","slot","img","html","base","head","link","meta","script","style","title","address","article","body","h1","h6","footer","header","h2","h3","h4","h5","hgroup","nav","section","dd","dl","dt","div","figcaption","figure","hr","li","ol","ul","menu","main","p","picture","pre","a","abbr","b","bdi","bdo","br","cite","code","data","time","dfn","em","i","kbd","mark","q","blockquote","rp","ruby","rt","rtc","rb","s","del","ins","samp","small","span","strong","sub","sup","u","var","wbr","area","map","audio","source","track","video","embed","object","param","canvas","noscript","caption","table","col","colgroup","tbody","tr","thead","tfoot","td","th","button","datalist","option","fieldset","label","form","input","keygen","legend","meter","optgroup","select","output","progress","textarea","details","dialog","menuitem","summary","content","element","shadow","template","acronym","applet","basefont","font","big","blink","center","command","dir","frame","frameset","isindex","listing","marquee","noembed","plaintext","spacer","strike","tt","xmp","animate","animateMotion","animateTransform","circle","clipPath","defs","desc","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","svg","switch","symbol","text","textPath","tspan","use","view"],ZK=[{domType:"click",eventTypeId:0},{domType:"dblclick",eventTypeId:1},{domType:"input",eventTypeId:2},{domType:"change",eventTypeId:3},{domType:"submit",eventTypeId:4},{domType:"focusin",eventTypeId:5},{domType:"focusout",eventTypeId:6},{domType:"keydown",eventTypeId:7},{domType:"keyup",eventTypeId:8},{domType:"keypress",eventTypeId:9},{domType:"mouseenter",eventTypeId:10},{domType:"mouseleave",eventTypeId:11},{domType:"mousedown",eventTypeId:12},{domType:"mouseup",eventTypeId:13},{domType:"mousemove",eventTypeId:14},{domType:"touchstart",eventTypeId:15},{domType:"touchend",eventTypeId:16},{domType:"touchmove",eventTypeId:17},{domType:"scroll",eventTypeId:18}],w=new Map;function jK(K,$="body"){let U=document.querySelector($);if(!U)return()=>{};let q=[];for(let D of ZK){let Y=(J)=>{let V=J.target;while(V&&V!==document.body){let Q=V.__zx_ref;if(Q!==void 0){if(K.eventbridge(BigInt(Q),D.eventTypeId,J),J.cancelBubble)break}V=V.parentElement}},F={passive:D.domType.startsWith("touch")||D.domType==="scroll"};U.addEventListener(D.domType,Y,F),q.push(()=>U.removeEventListener(D.domType,Y,F))}return()=>{for(let D of q)D()}}var HK="/assets/_/main.wasm",f=null;function BK(K={}){return{url:K.url,eventDelegationRoot:K.eventDelegationRoot,importObject:K.importObject,kv:K.kv}}async function UK(K={}){let $=BK(K);if(f)f.dispose(),f=null;let U=K.url??document.getElementById("__$wasmlink")?.href??HK,q={current:null},D=null,Y=K.kv??$K(),F={__zx_kv:e(Y,()=>{if(D)return D;if(j.memory)return j.memory;throw Error("WASM memory is not ready")})},J=Object.assign({},p.createImportObject(q),F,K.importObject),V=await WebAssembly.instantiateStreaming(fetch(U),J),{instance:Q}=V;D=Q.exports.memory,j.memory=D;let X=new p(Q.exports);q.current=X,A.clear();let G=jK(X,K.eventDelegationRoot??"body"),T=E(Q.exports.mainClient);return z(T),f={options:$,dispose:()=>{G(),X.dispose(),A.clear()}},{source:V,bridge:X}}(()=>UK())();
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|