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.
Files changed (35) hide show
  1. package/README.md +19 -25
  2. package/cloudflare/index.js +93 -8
  3. package/index.js +78 -4
  4. package/package.json +2 -2
  5. package/pkg/ziex/src/fetch.d.ts +5 -0
  6. package/{wasm → pkg/ziex/src/wasm}/core.d.ts +2 -2
  7. package/vendor/jsz/js/src/index.d.ts +1 -0
  8. package/vendor/jsz/js/src/zigjs.d.ts +107 -0
  9. package/wasm/index.js +84 -4
  10. package/wasm/init.dev.js +84 -4
  11. package/wasm/init.js +3 -2
  12. /package/{app.d.ts → pkg/ziex/src/app.d.ts} +0 -0
  13. /package/{aws-lambda → pkg/ziex/src/aws-lambda}/index.d.ts +0 -0
  14. /package/{browser → pkg/ziex/src/browser}/kv.d.ts +0 -0
  15. /package/{cloudflare → pkg/ziex/src/cloudflare}/app.d.ts +0 -0
  16. /package/{cloudflare → pkg/ziex/src/cloudflare}/db.d.ts +0 -0
  17. /package/{cloudflare → pkg/ziex/src/cloudflare}/do.d.ts +0 -0
  18. /package/{cloudflare → pkg/ziex/src/cloudflare}/index.d.ts +0 -0
  19. /package/{cloudflare → pkg/ziex/src/cloudflare}/kv.d.ts +0 -0
  20. /package/{cloudflare → pkg/ziex/src/cloudflare}/worker.d.ts +0 -0
  21. /package/{db.d.ts → pkg/ziex/src/db.d.ts} +0 -0
  22. /package/{index.d.ts → pkg/ziex/src/index.d.ts} +0 -0
  23. /package/{kv.d.ts → pkg/ziex/src/kv.d.ts} +0 -0
  24. /package/{react → pkg/ziex/src/react}/dom.d.ts +0 -0
  25. /package/{react → pkg/ziex/src/react}/index.d.ts +0 -0
  26. /package/{react → pkg/ziex/src/react}/types.d.ts +0 -0
  27. /package/{runtime.d.ts → pkg/ziex/src/runtime.d.ts} +0 -0
  28. /package/{vercel → pkg/ziex/src/vercel}/index.d.ts +0 -0
  29. /package/{wasi.d.ts → pkg/ziex/src/wasi.d.ts} +0 -0
  30. /package/{wasm → pkg/ziex/src/wasm}/dom.d.ts +0 -0
  31. /package/{wasm → pkg/ziex/src/wasm}/index.d.ts +0 -0
  32. /package/{wasm → pkg/ziex/src/wasm}/init.d.ts +0 -0
  33. /package/{wasm → pkg/ziex/src/wasm}/types.d.ts +0 -0
  34. /package/{wasm → pkg/ziex/src/wasm}/wasi.d.ts +0 -0
  35. /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
- The `0.1.0` release will indicate that Ziex is production-ready, with all major features fully implemented, and will receive patch releases for bug fixes.
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
- * [VSCode](https://marketplace.visualstudio.com/items?itemName=ziex.ziex)/[VSCode Forks](https://open-vsx.org/extension/ziex/ziex)
190
- * [Neovim](/ide/neovim/)
191
- * [Helix](/ide/helix/)
192
- * [Zed](/ide/zed/)
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
 
@@ -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 ? readString(bodyPtr, bodyLen) : undefined;
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 text = await response.text();
319
- this._notifyFetchComplete(fetchId, response.status, text, false);
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.#readString(bodyPtr, bodyLen) : undefined;
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
- this.#notifyFetchComplete(fetchId, res.status, await res.text(), false);
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.#readString(bodyPtr, bodyLen) : undefined;
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
- this.#notifyFetchComplete(fetchId, res.status, await res.text(), false);
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.1309",
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.1309"
40
+ "@ziex/cli": "0.1.0-dev.1360"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "react": {
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Create a `fetch` import object for blocking WASM fetch via JSPI.
3
+ * When JSPI is unavailable the import always returns -1 (network error).
4
+ */
5
+ export declare function createFetchImports(getMemory: () => WebAssembly.Memory): Record<string, unknown>;
@@ -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 ? readString(bodyPtr, bodyLen) : undefined;
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 text = await response.text();
319
- this._notifyFetchComplete(fetchId, response.status, text, false);
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 ? readString(bodyPtr, bodyLen) : undefined;
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 text = await response.text();
304
- this._notifyFetchComplete(fetchId, response.status, text, false);
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 w={nan:0,null:1,true:2,false:3,undefined:4,globalThis:5,runtime:6};var I=new TextEncoder,n=new TextDecoder("utf-8");class _{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,$,q,Q){let F=this.loadValue($),D=this.loadString(q,Q),Y=Reflect.get(F,D);this.storeValue(K,Y)}valueSet(K,$,q,Q){let F=this.loadValue(K),D=this.loadString($,q),Y=this.loadRef(Q);Reflect.set(F,D,Y)}valueDeinit(K){if(K>6)this.values[K]=null,this.idPool.push(K)}valueObjectCreate(K){this.storeValue(K,{})}valueStringCreate(K,$,q){let Q=this.loadString($,q);this.storeValue(K,Q)}valueStringLen(K){let $=this.loadValue(K);return I.encode($).byteLength}valueStringCopy(K,$,q){if(this.memory==null)return;let Q=this.loadValue(K),F=I.encode(Q);if(F.byteLength>q)return;if(F.length===0)return;new Uint8Array(this.memory.buffer,$,F.length).set(F)}valueNew(K,$,q,Q){let F=this.loadValue($),D=[];for(let J=0;J<Q;J++)D.push(this.loadRef(q+J*8));let Y=Reflect.construct(F,D);this.storeValue(K,Y)}funcApply(K,$,q,Q,F){let D=this.loadValue($),Y=this.loadRef(q),J=[];for(let U=0;U<F;U++)J.push(this.loadRef(Q+U*8));let V=Reflect.apply(D,Y,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 q=new DataView(this.memory.buffer).getFloat64(K,!0);if(!isNaN(q))return q;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 q=new DataView(this.memory.buffer);if(typeof $==="number"){if(isNaN($))q.setUint32(K,w.nan,!0),q.setUint32(K+4,2146959360,!0);else q.setFloat64(K,$,!0);return}if($===null){q.setUint32(K,w.null,!0),q.setUint32(K+4,2146959360,!0);return}if($===void 0){q.setUint32(K,w.undefined,!0),q.setUint32(K+4,2146959360,!0);return}if(typeof $==="boolean"){q.setUint32(K,$?w.true:w.false,!0),q.setUint32(K+4,2146959360,!0);return}if(typeof $==="bigint"){q.setFloat64(K,Number($),!0);return}let Q=this.idPool.pop();if(Q===void 0)Q=this.values.length;this.values[Q]=$;let F=0;switch(typeof $){case"object":F=1;break;case"string":F=2;break;case"symbol":F=3;break;case"function":F=4;break}q.setUint32(K,Number(Q),!0),q.setUint32(K+4,2146959360|F,!0)}loadString(K,$){if(this.memory==null)return"";let Q=new Uint8ClampedArray(this.memory.buffer,K,Number($)).slice();return n.decode(Q)}}var g={Event:0,FetchSuccess:1,FetchError:2,Timeout:3,Interval:4,WebSocketOpen:5,WebSocketMessage:6,WebSocketError:7,WebSocketClose:8},H=new _,p=new ArrayBuffer(8),t=new DataView(p);function R(K){let $=H.memory;return H.memory={buffer:p},H.storeValue(0,K),H.memory=$,t.getBigUint64(0,!0)}var y=new TextDecoder,S=new TextEncoder,b=null,m=null;function P(){let K=H.memory.buffer;if(K!==m)m=K,b=new Uint8Array(K);return b}var v=new Map;function r(K,$){return K*65536+$}function j(K,$){let q=r(K,$),Q=v.get(q);if(Q!==void 0)return Q;let F=y.decode(P().subarray(K,K+$));return v.set(q,F),F}function M(K,$){P().set($,K)}function C(K){if(!K)return;let $=WebAssembly.promising;if(typeof $!=="function")return K;return $(K)}function A(K,...$){if(!K)return;let q=K(...$);if(q&&typeof q.then==="function")q.then(void 0,(Q)=>{console.error(Q)})}class x{#K=new Map;_alloc;#q;#F;constructor(K){this._alloc=K.__zx_alloc,this.#q=C(K.__zx_cb);let $=C(K.__zx_fetch_complete);if(!$)throw Error("__zx_fetch_complete not exported from WASM");if(this.#F=$,K.memory)H.memory=K.memory}#$(K,$,q){let Q=this.#q;if(!Q){console.warn("__zx_cb not exported from WASM");return}let F=R(q);A(Q,K,$,F)}fetchAsync(K,$,q,Q,F,D,Y,J,V,U){let X=j(K,$),W=Q>0?j(q,Q):"GET",G=D>0?j(F,D):"{}",Z=J>0?j(Y,J):void 0,T={};try{T=JSON.parse(G)}catch{for(let B of G.split(`
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