ziex 0.1.0-dev.786 → 0.1.0-dev.804

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/wasm/init.js CHANGED
@@ -167,7 +167,7 @@ class ZigJS {
167
167
  return decoder.decode(data);
168
168
  }
169
169
  }
170
- // src/wasm/index.ts
170
+ // src/wasm/core.ts
171
171
  var CallbackType = {
172
172
  Event: 0,
173
173
  FetchSuccess: 1,
@@ -218,25 +218,17 @@ function writeBytes(ptr, data) {
218
218
  getMemoryView().set(data, ptr);
219
219
  }
220
220
 
221
- class ZxBridge {
221
+ class ZxBridgeCore {
222
222
  #intervals = new Map;
223
- #websockets = new Map;
224
- #alloc;
223
+ _alloc;
225
224
  #handler;
226
225
  #fetchCompleteHandler;
227
- #wsOnOpenHandler;
228
- #wsOnMessageHandler;
229
- #wsOnErrorHandler;
230
- #wsOnCloseHandler;
231
226
  constructor(exports) {
232
- this.#alloc = exports.__zx_alloc;
227
+ this._alloc = exports.__zx_alloc;
233
228
  this.#handler = exports.__zx_cb;
234
229
  this.#fetchCompleteHandler = exports.__zx_fetch_complete;
235
- this.#wsOnOpenHandler = exports.__zx_ws_onopen;
236
- this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
237
- this.#wsOnErrorHandler = exports.__zx_ws_onerror;
238
- this.#wsOnCloseHandler = exports.__zx_ws_onclose;
239
- this.#eventbridge = exports.__zx_eventbridge;
230
+ if (exports.memory)
231
+ jsz.memory = exports.memory;
240
232
  }
241
233
  #invoke(type, id, data) {
242
234
  const handler = this.#handler;
@@ -276,19 +268,19 @@ class ZxBridge {
276
268
  if (timeout)
277
269
  clearTimeout(timeout);
278
270
  const text = await response.text();
279
- this.#notifyFetchComplete(fetchId, response.status, text, false);
271
+ this._notifyFetchComplete(fetchId, response.status, text, false);
280
272
  }).catch((error) => {
281
273
  if (timeout)
282
274
  clearTimeout(timeout);
283
275
  const isAbort = error.name === "AbortError";
284
276
  const errorMsg = isAbort ? "Request timeout" : error.message ?? "Fetch failed";
285
- this.#notifyFetchComplete(fetchId, 0, errorMsg, true);
277
+ this._notifyFetchComplete(fetchId, 0, errorMsg, true);
286
278
  });
287
279
  }
288
- #notifyFetchComplete(fetchId, statusCode, body, isError) {
280
+ _notifyFetchComplete(fetchId, statusCode, body, isError) {
289
281
  const handler = this.#fetchCompleteHandler;
290
282
  const encoded = textEncoder.encode(body);
291
- const ptr = this.#alloc(encoded.length);
283
+ const ptr = this._alloc(encoded.length);
292
284
  writeBytes(ptr, encoded);
293
285
  handler(fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
294
286
  }
@@ -310,6 +302,83 @@ class ZxBridge {
310
302
  this.#intervals.delete(callbackId);
311
303
  }
312
304
  }
305
+ _writeStringToWasm(str) {
306
+ return this._writeBytesToWasm(textEncoder.encode(str));
307
+ }
308
+ _writeBytesToWasm(data) {
309
+ const ptr = this._alloc(data.length);
310
+ writeBytes(ptr, data);
311
+ return { ptr, len: data.length };
312
+ }
313
+ static log(level, ptr, len) {
314
+ const msg = textDecoder.decode(getMemoryView().subarray(ptr, ptr + len));
315
+ switch (level) {
316
+ case 0:
317
+ console.error(msg);
318
+ break;
319
+ case 1:
320
+ console.warn(msg);
321
+ break;
322
+ case 3:
323
+ console.debug(msg);
324
+ break;
325
+ default:
326
+ console.log(msg);
327
+ break;
328
+ }
329
+ }
330
+ static createImportObject(bridgeRef) {
331
+ return {
332
+ ...jsz.importObject(),
333
+ __zx: {
334
+ _log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
335
+ _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
336
+ bridgeRef.current?.fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId);
337
+ },
338
+ _setTimeout: (callbackId, delayMs) => {
339
+ bridgeRef.current?.setTimeout(callbackId, delayMs);
340
+ },
341
+ _setInterval: (callbackId, intervalMs) => {
342
+ bridgeRef.current?.setInterval(callbackId, intervalMs);
343
+ },
344
+ _clearInterval: (callbackId) => {
345
+ bridgeRef.current?.clearInterval(callbackId);
346
+ }
347
+ }
348
+ };
349
+ }
350
+ }
351
+ // src/wasm/index.ts
352
+ class ZxBridge extends ZxBridgeCore {
353
+ #websockets = new Map;
354
+ #wsOnOpenHandler;
355
+ #wsOnMessageHandler;
356
+ #wsOnErrorHandler;
357
+ #wsOnCloseHandler;
358
+ #eventbridge;
359
+ constructor(exports) {
360
+ super(exports);
361
+ this.#wsOnOpenHandler = exports.__zx_ws_onopen;
362
+ this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
363
+ this.#wsOnErrorHandler = exports.__zx_ws_onerror;
364
+ this.#wsOnCloseHandler = exports.__zx_ws_onclose;
365
+ this.#eventbridge = exports.__zx_eventbridge;
366
+ }
367
+ submitFormActionAsync(form, statesJson, fetchId) {
368
+ const formData = new FormData(form);
369
+ formData.append("__zx_states", statesJson);
370
+ fetch(window.location.href, {
371
+ method: "POST",
372
+ headers: { "X-ZX-Action": "1" },
373
+ body: formData
374
+ }).then(async (response) => {
375
+ const text = await response.text();
376
+ this._notifyFetchComplete(fetchId, response.status, text, false);
377
+ }).catch((error) => {
378
+ const msg = error instanceof Error ? error.message : "Fetch failed";
379
+ this._notifyFetchComplete(fetchId, 0, msg, true);
380
+ });
381
+ }
313
382
  wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) {
314
383
  const url = readString(urlPtr, urlLen);
315
384
  const protocolsStr = protocolsLen > 0 ? readString(protocolsPtr, protocolsLen) : "";
@@ -322,7 +391,7 @@ class ZxBridge {
322
391
  if (!handler)
323
392
  return;
324
393
  const protocol = ws.protocol || "";
325
- const { ptr, len } = this.#writeStringToWasm(protocol);
394
+ const { ptr, len } = this._writeStringToWasm(protocol);
326
395
  handler(wsId, ptr, len);
327
396
  };
328
397
  ws.onmessage = (event) => {
@@ -330,21 +399,15 @@ class ZxBridge {
330
399
  if (!handler)
331
400
  return;
332
401
  const isBinary = event.data instanceof ArrayBuffer;
333
- let data;
334
- if (isBinary) {
335
- data = new Uint8Array(event.data);
336
- } else {
337
- data = textEncoder.encode(event.data);
338
- }
339
- const { ptr, len } = this.#writeBytesToWasm(data);
402
+ const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
403
+ const { ptr, len } = this._writeBytesToWasm(data);
340
404
  handler(wsId, ptr, len, isBinary ? 1 : 0);
341
405
  };
342
- ws.onerror = (event) => {
406
+ ws.onerror = (_event) => {
343
407
  const handler = this.#wsOnErrorHandler;
344
408
  if (!handler)
345
409
  return;
346
- const msg = "WebSocket error";
347
- const { ptr, len } = this.#writeStringToWasm(msg);
410
+ const { ptr, len } = this._writeStringToWasm("WebSocket error");
348
411
  handler(wsId, ptr, len);
349
412
  };
350
413
  ws.onclose = (event) => {
@@ -352,7 +415,7 @@ class ZxBridge {
352
415
  if (!handler)
353
416
  return;
354
417
  const reason = event.reason || "";
355
- const { ptr, len } = this.#writeStringToWasm(reason);
418
+ const { ptr, len } = this._writeStringToWasm(reason);
356
419
  handler(wsId, event.code, ptr, len, event.wasClean ? 1 : 0);
357
420
  this.#websockets.delete(wsId);
358
421
  };
@@ -361,7 +424,7 @@ class ZxBridge {
361
424
  const handler = this.#wsOnErrorHandler;
362
425
  if (handler) {
363
426
  const msg = error instanceof Error ? error.message : "WebSocket connection failed";
364
- const { ptr, len } = this.#writeStringToWasm(msg);
427
+ const { ptr, len } = this._writeStringToWasm(msg);
365
428
  handler(wsId, ptr, len);
366
429
  }
367
430
  }
@@ -383,25 +446,14 @@ class ZxBridge {
383
446
  return;
384
447
  const reason = reasonLen > 0 ? readString(reasonPtr, reasonLen) : undefined;
385
448
  try {
386
- if (reason) {
449
+ if (reason)
387
450
  ws.close(code, reason);
388
- } else {
451
+ else
389
452
  ws.close(code);
390
- }
391
453
  } catch {
392
454
  ws.close();
393
455
  }
394
456
  }
395
- #writeStringToWasm(str) {
396
- const encoded = textEncoder.encode(str);
397
- return this.#writeBytesToWasm(encoded);
398
- }
399
- #writeBytesToWasm(data) {
400
- const ptr = this.#alloc(data.length);
401
- writeBytes(ptr, data);
402
- return { ptr, len: data.length };
403
- }
404
- #eventbridge;
405
457
  eventbridge(velementId, eventTypeId, event) {
406
458
  if (!this.#eventbridge)
407
459
  return;
@@ -412,6 +464,7 @@ class ZxBridge {
412
464
  return {
413
465
  ...jsz.importObject(),
414
466
  __zx: {
467
+ _log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
415
468
  _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
416
469
  bridgeRef.current?.fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId);
417
470
  },
@@ -487,6 +540,41 @@ class ZxBridge {
487
540
  parent.replaceChild(newChild, oldChild);
488
541
  cleanupDomNodes(oldChild);
489
542
  }
543
+ },
544
+ _getLocationHref: (bufPtr, bufLen) => {
545
+ const bytes = textEncoder.encode(window.location.href);
546
+ const len = Math.min(bytes.length, bufLen);
547
+ writeBytes(bufPtr, bytes.subarray(0, len));
548
+ return len;
549
+ },
550
+ _getFormData: (vnodeId, bufPtr, bufLen) => {
551
+ const form = domNodes.get(vnodeId);
552
+ if (!form || !(form instanceof HTMLFormElement))
553
+ return 0;
554
+ const formData = new FormData(form);
555
+ const urlEncoded = new URLSearchParams(formData).toString();
556
+ const bytes = textEncoder.encode(urlEncoded);
557
+ const len = Math.min(bytes.length, bufLen);
558
+ writeBytes(bufPtr, bytes.subarray(0, len));
559
+ return len;
560
+ },
561
+ _submitFormAction: (vnodeId) => {
562
+ const form = domNodes.get(vnodeId);
563
+ if (!form || !(form instanceof HTMLFormElement))
564
+ return;
565
+ const formData = new FormData(form);
566
+ fetch(window.location.href, {
567
+ method: "POST",
568
+ headers: { "X-ZX-Action": "1" },
569
+ body: formData
570
+ }).catch(() => {});
571
+ },
572
+ _submitFormActionAsync: (vnodeId, statesPtr, statesLen, fetchId) => {
573
+ const form = domNodes.get(vnodeId);
574
+ if (!form || !(form instanceof HTMLFormElement))
575
+ return;
576
+ const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
577
+ bridgeRef.current?.submitFormActionAsync(form, statesJson, fetchId);
490
578
  }
491
579
  }
492
580
  };
package/wasm/wasi.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * WASI/edge WASM bridge — zero dependencies on ZigJS (jsz) or browser globals.
3
+ *
4
+ * Import this (and only this) from edge/server runtimes. It provides the
5
+ * minimal __zx import namespace needed by server-side WASM: log, fetch, and
6
+ * timers. The jsz importObject is intentionally omitted — the server binary
7
+ * does not use jsz value-passing.
8
+ */
9
+ export declare class ZxWasiBridge {
10
+ #private;
11
+ constructor(exports: WebAssembly.Exports);
12
+ log(level: number, ptr: number, len: number): void;
13
+ fetchAsync(urlPtr: number, urlLen: number, methodPtr: number, methodLen: number, headersPtr: number, headersLen: number, bodyPtr: number, bodyLen: number, timeoutMs: number, fetchId: bigint): void;
14
+ setTimeout(callbackId: bigint, delayMs: number): void;
15
+ setInterval(callbackId: bigint, intervalMs: number): void;
16
+ clearInterval(callbackId: bigint): void;
17
+ /**
18
+ * Create the WASI import object for WASM instantiation.
19
+ *
20
+ * Returns only the `__zx` namespace (log, fetch, timers).
21
+ * Does NOT include jsz.importObject() — the server binary does not use jsz.
22
+ */
23
+ static createImportObject(bridgeRef: {
24
+ current: ZxWasiBridge | null;
25
+ }): {
26
+ __zx: Record<string, unknown>;
27
+ };
28
+ }