ziex 0.1.0-dev.1458 → 0.1.0-dev.1567

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.
@@ -1,231 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/runtime/index.ts
8
- var runtime_exports = {};
9
- __export(runtime_exports, {
10
- attachWebSocket: () => attachWebSocket,
11
- buildWsImports: () => buildWsImports,
12
- run: () => run
13
- });
14
-
15
- // src/wasm/wasi.ts
16
- var decoder = new TextDecoder();
17
- var encoder = new TextEncoder();
18
- var ZxWasiBridge = class {
19
- #alloc;
20
- #fetchCompleteHandler;
21
- #memory;
22
- #cb;
23
- #intervals = /* @__PURE__ */ new Map();
24
- // Cached memory view - invalidated when the WASM buffer grows.
25
- #memView = null;
26
- #memBuf = null;
27
- constructor(exports) {
28
- this.#memory = exports.memory;
29
- this.#alloc = exports.__zx_alloc;
30
- this.#fetchCompleteHandler = exports.__zx_fetch_complete;
31
- this.#cb = exports.__zx_cb;
32
- }
33
- #view() {
34
- const buf = this.#memory.buffer;
35
- if (buf !== this.#memBuf) {
36
- this.#memBuf = buf;
37
- this.#memView = new Uint8Array(buf);
38
- }
39
- return this.#memView;
40
- }
41
- #readString(ptr, len) {
42
- const start = ptr >>> 0;
43
- const length = len >>> 0;
44
- if (length === 0) return "";
45
- const view = this.#view();
46
- if (start + length > view.byteLength) return "";
47
- return decoder.decode(view.subarray(start, start + length));
48
- }
49
- #writeBytes(ptr, data) {
50
- const start = ptr >>> 0;
51
- const view = this.#view();
52
- if (start + data.length > view.byteLength) return;
53
- view.set(data, start);
54
- }
55
- log(level, ptr, len) {
56
- const msg = decoder.decode(this.#view().subarray(ptr, ptr + len));
57
- switch (level) {
58
- case 0:
59
- console.error(msg);
60
- break;
61
- case 1:
62
- console.warn(msg);
63
- break;
64
- case 3:
65
- console.debug(msg);
66
- break;
67
- default:
68
- console.log(msg);
69
- break;
70
- }
71
- }
72
- fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
73
- const url = this.#readString(urlPtr, urlLen);
74
- const method = methodLen > 0 ? this.#readString(methodPtr, methodLen) : "GET";
75
- const headersJson = headersLen > 0 ? this.#readString(headersPtr, headersLen) : "{}";
76
- const body = bodyLen > 0 ? this.#view().subarray(bodyPtr, bodyPtr + bodyLen) : void 0;
77
- let headers = {};
78
- try {
79
- headers = JSON.parse(headersJson);
80
- } catch {
81
- for (const line of headersJson.split("\n")) {
82
- const i = line.indexOf(":");
83
- if (i > 0) headers[line.slice(0, i)] = line.slice(i + 1);
84
- }
85
- }
86
- const controller = new AbortController();
87
- const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
88
- fetch(url, {
89
- method,
90
- headers: Object.keys(headers).length > 0 ? headers : void 0,
91
- body: method !== "GET" && method !== "HEAD" ? body : void 0,
92
- signal: controller.signal
93
- }).then(async (res) => {
94
- if (timeout) clearTimeout(timeout);
95
- const bytes = new Uint8Array(await res.arrayBuffer());
96
- this.#notifyFetchComplete(fetchId, res.status, bytes, false);
97
- }).catch((err) => {
98
- if (timeout) clearTimeout(timeout);
99
- const msg = err.name === "AbortError" ? "Request timeout" : err.message ?? "Fetch failed";
100
- this.#notifyFetchComplete(fetchId, 0, msg, true);
101
- });
102
- }
103
- #notifyFetchComplete(fetchId, status, body, isError) {
104
- const encoded = typeof body === "string" ? encoder.encode(body) : body;
105
- const ptr = this.#alloc(encoded.length);
106
- this.#writeBytes(ptr, encoded);
107
- this.#fetchCompleteHandler(fetchId, status, ptr, encoded.length, isError ? 1 : 0);
108
- }
109
- setTimeout(callbackId, delayMs) {
110
- setTimeout(() => this.#cb?.(3, callbackId, 0n), delayMs);
111
- }
112
- setInterval(callbackId, intervalMs) {
113
- const handle = setInterval(() => this.#cb?.(4, callbackId, 0n), intervalMs);
114
- this.#intervals.set(callbackId, handle);
115
- }
116
- clearInterval(callbackId) {
117
- const handle = this.#intervals.get(callbackId);
118
- if (handle !== void 0) {
119
- clearInterval(handle);
120
- this.#intervals.delete(callbackId);
121
- }
122
- }
123
- /**
124
- * Create the WASI import object for WASM instantiation.
125
- *
126
- * Returns only the `__zx` namespace (log, fetch, timers).
127
- * Does NOT include jsz.importObject() - the server binary does not use jsz.
128
- */
129
- static createImportObject(bridgeRef) {
130
- return {
131
- __zx: {
132
- _log: (level, ptr, len) => {
133
- bridgeRef[0]?.log(level, ptr, len);
134
- },
135
- _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
136
- bridgeRef[0]?.fetchAsync(
137
- urlPtr,
138
- urlLen,
139
- methodPtr,
140
- methodLen,
141
- headersPtr,
142
- headersLen,
143
- bodyPtr,
144
- bodyLen,
145
- timeoutMs,
146
- fetchId
147
- );
148
- },
149
- _setTimeout: (callbackId, delayMs) => {
150
- bridgeRef[0]?.setTimeout(callbackId, delayMs);
151
- },
152
- _setInterval: (callbackId, intervalMs) => {
153
- bridgeRef[0]?.setInterval(callbackId, intervalMs);
154
- },
155
- _clearInterval: (callbackId) => {
156
- bridgeRef[0]?.clearInterval(callbackId);
157
- }
158
- }
159
- };
160
- }
161
- };
162
-
163
- // src/runtime/fetch.ts
164
- function createFetchImports(getMemory) {
165
- const encoder3 = new TextEncoder();
166
- const decoder3 = new TextDecoder();
167
- function readStr(ptr, len) {
168
- return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
169
- }
170
- function writeBytes2(buf_ptr, buf_max, data) {
171
- if (data.length > buf_max) return -2;
172
- new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
173
- return data.length;
174
- }
175
- function readBytes(ptr, len) {
176
- return new Uint8Array(getMemory().buffer, ptr, len);
177
- }
178
- function parseHeaders(headersJson) {
179
- let headers = {};
180
- try {
181
- headers = JSON.parse(headersJson);
182
- } catch {
183
- for (const line of headersJson.split("\n")) {
184
- const colonIdx = line.indexOf(":");
185
- if (colonIdx > 0) {
186
- headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
187
- }
188
- }
189
- }
190
- return headers;
191
- }
192
- 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) {
193
- const url = readStr(url_ptr, url_len);
194
- const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
195
- const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
196
- const body = body_len > 0 ? readBytes(body_ptr, body_len) : void 0;
197
- const headers = parseHeaders(headersJson);
198
- const controller = new AbortController();
199
- const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
200
- try {
201
- const response = await fetch(url, {
202
- method,
203
- headers: Object.keys(headers).length > 0 ? headers : void 0,
204
- body: method !== "GET" && method !== "HEAD" ? body : void 0,
205
- signal: controller.signal
206
- });
207
- if (timeout) clearTimeout(timeout);
208
- new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
209
- const bytes = new Uint8Array(await response.arrayBuffer());
210
- return writeBytes2(buf_ptr, buf_max, bytes);
211
- } catch (err) {
212
- if (timeout) clearTimeout(timeout);
213
- const msg = err instanceof Error ? err.message : String(err);
214
- console.error(`wasm fetch failed: ${url} (${msg})`);
215
- return -1;
216
- }
217
- }
218
- const Suspending = WebAssembly.Suspending;
219
- if (typeof Suspending !== "function") {
220
- return {
221
- 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
222
- };
223
- }
224
- return {
225
- fetch: new Suspending(doFetch)
226
- };
227
- }
228
-
229
1
  // ../../vendor/jsz/js/src/zigjs.ts
230
2
  var NAN_PREFIX = 2146959360;
231
3
  var predefined = {
@@ -238,8 +10,8 @@ var predefined = {
238
10
  "runtime": 6
239
11
  };
240
12
  var PREDEFINED_ID_MAX = 6;
241
- var encoder2 = new TextEncoder();
242
- var decoder2 = new TextDecoder("utf-8");
13
+ var encoder = new TextEncoder();
14
+ var decoder = new TextDecoder("utf-8");
243
15
  var ZigJS = class {
244
16
  constructor() {
245
17
  /**
@@ -323,7 +95,7 @@ var ZigJS = class {
323
95
  * */
324
96
  valueStringLen(id) {
325
97
  const val = this.loadValue(id);
326
- const buf = encoder2.encode(val);
98
+ const buf = encoder.encode(val);
327
99
  return buf.byteLength;
328
100
  }
329
101
  /**
@@ -335,7 +107,7 @@ var ZigJS = class {
335
107
  const cap = max >>> 0;
336
108
  const val = this.loadValue(id);
337
109
  if (typeof val !== "string") return;
338
- const bytes = encoder2.encode(val);
110
+ const bytes = encoder.encode(val);
339
111
  if (bytes.byteLength > cap || bytes.length === 0) return;
340
112
  const buf = this.memory.buffer;
341
113
  if (dest + bytes.length > buf.byteLength) return;
@@ -471,58 +243,148 @@ var ZigJS = class {
471
243
  if (length === 0 || start + length > buf.byteLength) return "";
472
244
  const arr = new Uint8ClampedArray(buf, start, length);
473
245
  const data = arr.slice();
474
- return decoder2.decode(data);
246
+ return decoder.decode(data);
475
247
  }
476
248
  };
477
249
 
478
- // src/wasm/core.ts
479
- var jsz = new ZigJS();
480
- var tempRefBuffer = new ArrayBuffer(8);
481
- var tempRefView = new DataView(tempRefBuffer);
482
- function storeValueGetRef(val) {
483
- const originalMemory = jsz.memory;
484
- jsz.memory = { buffer: tempRefBuffer };
485
- jsz.storeValue(0, val);
486
- jsz.memory = originalMemory;
487
- return tempRefView.getBigUint64(0, true);
488
- }
489
- function loadValueFromRef(ref) {
490
- tempRefView.setBigUint64(0, ref, true);
491
- const originalMemory = jsz.memory;
492
- jsz.memory = { buffer: tempRefBuffer };
493
- const val = jsz.loadRef(0);
494
- jsz.memory = originalMemory;
495
- return val;
496
- }
497
- function releaseValueRef(ref) {
498
- tempRefView.setBigUint64(0, ref, true);
499
- if (!Number.isNaN(tempRefView.getFloat64(0, true))) return;
500
- const id = tempRefView.getUint32(0, true);
501
- if (id > 6) jsz.deleteValue(id);
502
- }
503
- var textDecoder = new TextDecoder();
504
- var textEncoder = new TextEncoder();
505
- var memoryView = null;
506
- var memoryBuffer = null;
507
- function getMemoryView() {
508
- const buf = jsz.memory.buffer;
509
- if (buf !== memoryBuffer) {
510
- memoryBuffer = buf;
511
- memoryView = new Uint8Array(buf);
250
+ // src/runtime/fetch.ts
251
+ function createFetchImports(getMemory) {
252
+ const encoder3 = new TextEncoder();
253
+ const decoder3 = new TextDecoder();
254
+ function readStr2(ptr, len) {
255
+ return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
512
256
  }
513
- return memoryView;
514
- }
515
- function readString(ptr, len) {
516
- const start = ptr >>> 0;
517
- const length = len >>> 0;
518
- if (length === 0) return "";
519
- const view = getMemoryView();
520
- if (start + length > view.byteLength) return "";
521
- return textDecoder.decode(view.subarray(start, start + length));
522
- }
523
- function writeBytes(ptr, data) {
524
- const start = ptr >>> 0;
525
- const view = getMemoryView();
257
+ function writeBytes2(buf_ptr, buf_max, data) {
258
+ if (data.length > buf_max) return -2;
259
+ new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
260
+ return data.length;
261
+ }
262
+ function readBytes(ptr, len) {
263
+ return new Uint8Array(getMemory().buffer, ptr, len);
264
+ }
265
+ function parseHeaders(headersJson) {
266
+ let headers = {};
267
+ try {
268
+ headers = JSON.parse(headersJson);
269
+ } catch {
270
+ for (const line of headersJson.split("\n")) {
271
+ const colonIdx = line.indexOf(":");
272
+ if (colonIdx > 0) {
273
+ headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
274
+ }
275
+ }
276
+ }
277
+ return headers;
278
+ }
279
+ 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) {
280
+ const url = readStr2(url_ptr, url_len);
281
+ const method = method_len > 0 ? readStr2(method_ptr, method_len) : "GET";
282
+ const headersJson = headers_len > 0 ? readStr2(headers_ptr, headers_len) : "{}";
283
+ const body = body_len > 0 ? readBytes(body_ptr, body_len) : void 0;
284
+ const headers = parseHeaders(headersJson);
285
+ const controller = new AbortController();
286
+ const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
287
+ try {
288
+ const response = await fetch(url, {
289
+ method,
290
+ headers: Object.keys(headers).length > 0 ? headers : void 0,
291
+ body: method !== "GET" && method !== "HEAD" ? body : void 0,
292
+ signal: controller.signal
293
+ });
294
+ if (timeout) clearTimeout(timeout);
295
+ new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
296
+ const bytes = new Uint8Array(await response.arrayBuffer());
297
+ return writeBytes2(buf_ptr, buf_max, bytes);
298
+ } catch (err) {
299
+ if (timeout) clearTimeout(timeout);
300
+ const msg = err instanceof Error ? err.message : String(err);
301
+ console.error(`wasm fetch failed: ${url} (${msg})`);
302
+ return -1;
303
+ }
304
+ }
305
+ const Suspending2 = WebAssembly.Suspending;
306
+ if (typeof Suspending2 !== "function") {
307
+ return {
308
+ 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
309
+ };
310
+ }
311
+ return {
312
+ fetch: new Suspending2(doFetch)
313
+ };
314
+ }
315
+
316
+ // src/wasm/constants.ts
317
+ var DOM_CMD_HEADER_SIZE = 8;
318
+ var DOM_CMD_RECORD_SIZE = 24;
319
+ var DomOp_CreateElement = 1;
320
+ var DomOp_CreateText = 2;
321
+ var DomOp_HydrateInsert = 3;
322
+ var DomOp_SetAttr = 4;
323
+ var DomOp_SetProp = 5;
324
+ var DomOp_RemoveAttr = 6;
325
+ var DomOp_SetNodeValue = 7;
326
+ var DomOp_SetInnerHtml = 8;
327
+ var DomOp_AppendChild = 9;
328
+ var DomOp_InsertBefore = 10;
329
+ var DomOp_RemoveChild = 11;
330
+ var DomOp_ReplaceChild = 12;
331
+ var CallbackType_FetchSuccess = 1;
332
+ var CallbackType_FetchError = 2;
333
+ var CallbackType_Timeout = 3;
334
+ var CallbackType_Interval = 4;
335
+ var CallbackType_WebSocketOpen = 5;
336
+ var CallbackType_WebSocketMessage = 6;
337
+ var CallbackType_WebSocketError = 7;
338
+ var CallbackType_WebSocketClose = 8;
339
+
340
+ // src/wasm/core.ts
341
+ var jsz = new ZigJS();
342
+ var tempRefBuffer = new ArrayBuffer(8);
343
+ var tempRefView = new DataView(tempRefBuffer);
344
+ function storeValueGetRef(val) {
345
+ const originalMemory = jsz.memory;
346
+ jsz.memory = { buffer: tempRefBuffer };
347
+ jsz.storeValue(0, val);
348
+ jsz.memory = originalMemory;
349
+ return tempRefView.getBigUint64(0, true);
350
+ }
351
+ function loadValueFromRef(ref) {
352
+ tempRefView.setBigUint64(0, ref, true);
353
+ const originalMemory = jsz.memory;
354
+ jsz.memory = { buffer: tempRefBuffer };
355
+ const val = jsz.loadRef(0);
356
+ jsz.memory = originalMemory;
357
+ return val;
358
+ }
359
+ function releaseValueRef(ref) {
360
+ tempRefView.setBigUint64(0, ref, true);
361
+ if (!Number.isNaN(tempRefView.getFloat64(0, true))) return;
362
+ const id = tempRefView.getUint32(0, true);
363
+ if (id > 6) jsz.deleteValue(id);
364
+ }
365
+ var textDecoder = new TextDecoder();
366
+ var textEncoder = new TextEncoder();
367
+ var memoryView = null;
368
+ var memoryBuffer = null;
369
+ function getMemoryView() {
370
+ const buf = jsz.memory.buffer;
371
+ if (buf !== memoryBuffer) {
372
+ memoryBuffer = buf;
373
+ memoryView = new Uint8Array(buf);
374
+ }
375
+ return memoryView;
376
+ }
377
+ function readString(ptr, len) {
378
+ const start = ptr >>> 0;
379
+ const length = len >>> 0;
380
+ if (length === 0) return "";
381
+ const view = getMemoryView();
382
+ if (start + length > view.byteLength) return "";
383
+ return textDecoder.decode(view.subarray(start, start + length));
384
+ }
385
+ function writeBytes(ptr, data) {
386
+ const start = ptr >>> 0;
387
+ const view = getMemoryView();
526
388
  if (start + data.length > view.byteLength) return;
527
389
  view.set(data, start);
528
390
  }
@@ -544,30 +406,26 @@ function invokeWasmExport(fn, ...args) {
544
406
  var ZxBridgeCore = class _ZxBridgeCore {
545
407
  #intervals = /* @__PURE__ */ new Map();
546
408
  #handler;
547
- #fetchCompleteHandler;
548
409
  constructor(exports) {
549
410
  this._alloc = exports.__zx_alloc;
550
411
  this.#handler = wrapPromisingExport(exports.__zx_cb);
551
- const fetchCompleteHandler = wrapPromisingExport(exports.__zx_fetch_complete);
552
- if (!fetchCompleteHandler) {
553
- throw new Error("__zx_fetch_complete not exported from WASM");
412
+ if (!this.#handler) {
413
+ console.warn("__zx_cb not exported from WASM");
554
414
  }
555
- this.#fetchCompleteHandler = fetchCompleteHandler;
556
415
  if (exports.memory) jsz.memory = exports.memory;
557
416
  }
558
417
  /** Invoke the unified callback handler */
559
- #invoke(type, id, data) {
418
+ _invoke(type, id, a = 0n, b = 0n, c = 0n) {
560
419
  const handler = this.#handler;
561
420
  if (!handler) {
562
421
  console.warn("__zx_cb not exported from WASM");
563
422
  return;
564
423
  }
565
- const dataRef = storeValueGetRef(data);
566
- invokeWasmExport(handler, type, id, dataRef);
424
+ invokeWasmExport(handler, type, id, a, b, c);
567
425
  }
568
426
  /**
569
427
  * Async fetch with full options support.
570
- * Calls __zx_fetch_complete when done.
428
+ * Completes via `__zx_cb(fetch_success|fetch_error, ...)`.
571
429
  */
572
430
  fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
573
431
  const url = readString(urlPtr, urlLen);
@@ -606,23 +464,23 @@ var ZxBridgeCore = class _ZxBridgeCore {
606
464
  }
607
465
  /** Notify WASM that a fetch completed. `body` is raw bytes on success, text on error. */
608
466
  _notifyFetchComplete(fetchId, statusCode, body, isError) {
609
- const handler = this.#fetchCompleteHandler;
610
467
  const encoded = typeof body === "string" ? textEncoder.encode(body) : body;
611
468
  const ptr = this._alloc(encoded.length) >>> 0;
612
469
  if (!ptr && encoded.length > 0) return;
613
470
  writeBytes(ptr, encoded);
614
- invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
471
+ const type = isError ? CallbackType_FetchError : CallbackType_FetchSuccess;
472
+ this._invoke(type, fetchId, BigInt(statusCode), BigInt(ptr), BigInt(encoded.length));
615
473
  }
616
474
  /** Set a timeout and callback when it fires */
617
475
  setTimeout(callbackId, delayMs) {
618
476
  setTimeout(() => {
619
- this.#invoke(3, callbackId, null);
477
+ this._invoke(CallbackType_Timeout, callbackId);
620
478
  }, delayMs);
621
479
  }
622
480
  /** Set an interval and callback each time it fires */
623
481
  setInterval(callbackId, intervalMs) {
624
482
  const handle = setInterval(() => {
625
- this.#invoke(4, callbackId, null);
483
+ this._invoke(CallbackType_Interval, callbackId);
626
484
  }, intervalMs);
627
485
  this.#intervals.set(callbackId, handle);
628
486
  }
@@ -738,1027 +596,658 @@ function bindWasmAlloc(allocRef, exports) {
738
596
  }
739
597
 
740
598
  // src/runtime/kv/extern.ts
599
+ var Suspending = WebAssembly.Suspending;
600
+ var jspi = typeof Suspending === "function";
601
+ var miss = jspi ? -1 : 0;
741
602
  function putOptions(ttlSeconds) {
742
603
  if (ttlSeconds < 60) return void 0;
743
604
  return { expirationTtl: ttlSeconds };
744
605
  }
606
+ function kvDel(binding, key) {
607
+ const b = binding;
608
+ return (b.del ?? b.delete).call(b, key);
609
+ }
745
610
  function isSyncKVNamespace(binding) {
746
- const candidate = binding;
747
- return typeof candidate.getSync === "function" && typeof candidate.putSync === "function" && typeof candidate.deleteSync === "function" && typeof candidate.listSync === "function";
611
+ return typeof binding.get === "function" && binding.get.constructor.name !== "AsyncFunction";
748
612
  }
749
- function createKVImports(bindings, getMemory, allocRef) {
750
- const encoder3 = new TextEncoder();
751
- const decoder3 = new TextDecoder();
752
- function readStr(ptr, len) {
753
- return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
754
- }
755
- function binding(ns) {
756
- return bindings[ns] ?? bindings["default"] ?? null;
613
+ function listOpts(prefix) {
614
+ return prefix.length > 0 ? { prefix } : void 0;
615
+ }
616
+ function maybeThen(r, f) {
617
+ return r instanceof Promise ? r.then(f) : f(r);
618
+ }
619
+ function readStr(getMemory, ptr, len) {
620
+ return textDecoder.decode(new Uint8Array(getMemory().buffer, ptr, len));
621
+ }
622
+ function resolve(bindings, ns) {
623
+ const b = bindings[ns] ?? bindings["default"] ?? null;
624
+ if (!b || jspi) return b;
625
+ return isSyncKVNamespace(b) ? b : null;
626
+ }
627
+ function encodeGet(getMemory, allocRef, value, out_ptr) {
628
+ if (value === null) return -1;
629
+ return writeBytesOut(getMemory, allocRef, out_ptr, textEncoder.encode(value));
630
+ }
631
+ function encodeList(getMemory, allocRef, names, out_ptr) {
632
+ if (names.length === 0) {
633
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
634
+ return 0;
757
635
  }
758
- const Suspending = WebAssembly.Suspending;
759
- if (typeof Suspending !== "function") {
760
- let syncBinding2 = function(ns) {
761
- const candidate = binding(ns);
762
- return candidate && isSyncKVNamespace(candidate) ? candidate : null;
763
- };
764
- var syncBinding = syncBinding2;
765
- return {
766
- kv_get: (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
767
- const b = syncBinding2(readStr(ns_ptr, ns_len));
768
- if (!b) return -1;
769
- const value = b.getSync(readStr(key_ptr, key_len));
770
- if (value === null) return -1;
771
- return writeBytesOut(getMemory, allocRef, out_ptr, encoder3.encode(value));
772
- },
773
- kv_put: (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
774
- const b = syncBinding2(readStr(ns_ptr, ns_len));
775
- if (!b) return 0;
776
- b.putSync(readStr(key_ptr, key_len), readStr(val_ptr, val_len), putOptions(ttl_seconds));
777
- return 0;
778
- },
779
- kv_delete: (ns_ptr, ns_len, key_ptr, key_len) => {
780
- const b = syncBinding2(readStr(ns_ptr, ns_len));
781
- if (!b) return 0;
782
- b.deleteSync(readStr(key_ptr, key_len));
783
- return 0;
784
- },
785
- kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
786
- const b = syncBinding2(readStr(ns_ptr, ns_len));
787
- if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
788
- const prefix = readStr(pfx_ptr, pfx_len);
789
- const result = b.listSync(prefix.length > 0 ? { prefix } : void 0);
790
- return writeJsonOut(getMemory, allocRef, out_ptr, result.keys.map((k) => k.name));
791
- }
792
- };
636
+ return writeJsonOut(getMemory, allocRef, out_ptr, names);
637
+ }
638
+ function get(b, key, out_ptr, getMemory, allocRef) {
639
+ return maybeThen(b.get(key), (v) => encodeGet(getMemory, allocRef, v, out_ptr));
640
+ }
641
+ function put(b, key, val, ttl) {
642
+ return maybeThen(b.put(key, val, putOptions(ttl)), () => 0);
643
+ }
644
+ function del(b, key) {
645
+ return maybeThen(kvDel(b, key), () => 0);
646
+ }
647
+ function list(b, prefix, out_ptr, getMemory, allocRef) {
648
+ return maybeThen(
649
+ b.list(listOpts(prefix)),
650
+ (result) => encodeList(getMemory, allocRef, result.keys.map((k) => k.name), out_ptr)
651
+ );
652
+ }
653
+ function wrapImport(impl) {
654
+ if (!jspi) {
655
+ return ((...args) => {
656
+ const r = impl(...args);
657
+ if (r instanceof Promise) throw new Error("async kv binding requires JSPI");
658
+ return r;
659
+ });
793
660
  }
661
+ return new Suspending(impl);
662
+ }
663
+ function createKVImports(bindings, getMemory, allocRef) {
794
664
  return {
795
- kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
796
- const b = binding(readStr(ns_ptr, ns_len));
665
+ kv_get: wrapImport((ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
666
+ const b = resolve(bindings, readStr(getMemory, ns_ptr, ns_len));
797
667
  if (!b) return -1;
798
- const value = await b.get(readStr(key_ptr, key_len));
799
- if (value === null) return -1;
800
- return writeBytesOut(getMemory, allocRef, out_ptr, encoder3.encode(value));
668
+ return get(b, readStr(getMemory, key_ptr, key_len), out_ptr, getMemory, allocRef);
801
669
  }),
802
- kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
803
- const b = binding(readStr(ns_ptr, ns_len));
804
- if (!b) return -1;
805
- await b.put(readStr(key_ptr, key_len), readStr(val_ptr, val_len), putOptions(ttl_seconds));
806
- return 0;
670
+ kv_put: wrapImport((ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
671
+ const b = resolve(bindings, readStr(getMemory, ns_ptr, ns_len));
672
+ if (!b) return miss;
673
+ return put(
674
+ b,
675
+ readStr(getMemory, key_ptr, key_len),
676
+ readStr(getMemory, val_ptr, val_len),
677
+ ttl_seconds
678
+ );
807
679
  }),
808
- kv_delete: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len) => {
809
- const b = binding(readStr(ns_ptr, ns_len));
810
- if (!b) return -1;
811
- await b.delete(readStr(key_ptr, key_len));
812
- return 0;
680
+ kv_delete: wrapImport((ns_ptr, ns_len, key_ptr, key_len) => {
681
+ const b = resolve(bindings, readStr(getMemory, ns_ptr, ns_len));
682
+ if (!b) return miss;
683
+ return del(b, readStr(getMemory, key_ptr, key_len));
813
684
  }),
814
- kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, out_ptr) => {
815
- const b = binding(readStr(ns_ptr, ns_len));
685
+ kv_list: wrapImport((ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
686
+ const b = resolve(bindings, readStr(getMemory, ns_ptr, ns_len));
816
687
  if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
817
- const prefix = readStr(prefix_ptr, prefix_len);
818
- const result = await b.list(prefix.length > 0 ? { prefix } : void 0);
819
- const names = result.keys.map((k) => k.name);
820
- if (names.length === 0) {
821
- new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
822
- return 0;
823
- }
824
- return writeJsonOut(getMemory, allocRef, out_ptr, names);
688
+ return list(b, readStr(getMemory, pfx_ptr, pfx_len), out_ptr, getMemory, allocRef);
825
689
  })
826
690
  };
827
691
  }
828
692
 
829
- // src/runtime/db/extern.ts
830
- function decodeBlob(base64) {
831
- const binary = atob(base64);
832
- const bytes = new Uint8Array(binary.length);
833
- for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
834
- return bytes;
835
- }
836
- function toDbValue(value) {
837
- switch (value.kind) {
838
- case "null":
839
- return null;
840
- case "integer":
841
- return value.integer;
842
- case "float":
843
- return value.float;
844
- case "text":
845
- return value.text;
846
- case "blob":
847
- return decodeBlob(value.blob);
848
- case "boolean":
849
- return value.boolean;
693
+ // src/runtime/kv/localstorage.ts
694
+ var namespace = "default";
695
+ var storagePrefix = "ziex-kv";
696
+ var namespacePrefix = `${storagePrefix}:${namespace}:`;
697
+ function storage() {
698
+ if (typeof localStorage === "undefined") {
699
+ throw new Error("localStorage is not available in this environment");
850
700
  }
701
+ return localStorage;
851
702
  }
852
- function toPositionalBindings(json) {
853
- switch (json.kind) {
854
- case "none":
855
- return [];
856
- case "positional":
857
- return json.values.map(toDbValue);
858
- case "named":
859
- throw new Error("named SQL bindings are not supported yet");
860
- }
703
+ function get2(key) {
704
+ return storage().getItem(`${storagePrefix}:${namespace}:${key}`);
861
705
  }
862
- function toWireValue(value) {
863
- if (value === null || value === void 0) return { kind: "null" };
864
- if (typeof value === "string") return { kind: "text", text: value };
865
- if (typeof value === "boolean") return { kind: "boolean", boolean: value };
866
- if (typeof value === "number") {
867
- return Number.isInteger(value) ? { kind: "integer", integer: value } : { kind: "float", float: value };
868
- }
869
- if (value instanceof ArrayBuffer) {
870
- const bytes = new Uint8Array(value);
871
- let binary = "";
872
- for (const byte of bytes) binary += String.fromCharCode(byte);
873
- return { kind: "blob", blob: btoa(binary) };
874
- }
875
- if (ArrayBuffer.isView(value)) {
876
- const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
877
- let binary = "";
878
- for (const byte of bytes) binary += String.fromCharCode(byte);
879
- return { kind: "blob", blob: btoa(binary) };
706
+ function put2(key, value) {
707
+ storage().setItem(`${storagePrefix}:${namespace}:${key}`, value);
708
+ }
709
+ function del2(key) {
710
+ storage().removeItem(`${storagePrefix}:${namespace}:${key}`);
711
+ }
712
+ function list2(options) {
713
+ const ls = storage();
714
+ const prefix = namespacePrefix + (options?.prefix ?? "");
715
+ const keys = [];
716
+ for (let i = 0; i < ls.length; i += 1) {
717
+ const key = ls.key(i);
718
+ if (!key || !key.startsWith(prefix)) continue;
719
+ keys.push({ name: key.slice(namespacePrefix.length) });
720
+ }
721
+ return { keys };
722
+ }
723
+
724
+ // src/runtime/kv/indexdb.ts
725
+ var databaseName = "ziex-kv";
726
+ var storeName = "kv";
727
+ var namespace2 = "default";
728
+ var dbPromise;
729
+ function openDb() {
730
+ if (!dbPromise) {
731
+ if (typeof indexedDB === "undefined") {
732
+ return Promise.reject(new Error("IndexedDB is not available in this environment"));
733
+ }
734
+ dbPromise = new Promise((resolve2, reject) => {
735
+ const request = indexedDB.open(databaseName, 1);
736
+ request.onupgradeneeded = () => {
737
+ const db = request.result;
738
+ if (!db.objectStoreNames.contains(storeName)) {
739
+ db.createObjectStore(storeName);
740
+ }
741
+ };
742
+ request.onsuccess = () => resolve2(request.result);
743
+ request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
744
+ });
880
745
  }
881
- return { kind: "text", text: String(value) };
746
+ return dbPromise;
882
747
  }
883
- function objectToWireRow(record) {
748
+ function requestToPromise(request) {
749
+ return new Promise((resolve2, reject) => {
750
+ request.onsuccess = () => resolve2(request.result);
751
+ request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
752
+ });
753
+ }
754
+ function transactionToPromise(transaction) {
755
+ return new Promise((resolve2, reject) => {
756
+ transaction.oncomplete = () => resolve2();
757
+ transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
758
+ transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
759
+ });
760
+ }
761
+ async function get3(key) {
762
+ const db = await openDb();
763
+ const tx = db.transaction(storeName, "readonly");
764
+ const value = await requestToPromise(tx.objectStore(storeName).get(`${namespace2}:${key}`));
765
+ await transactionToPromise(tx);
766
+ return typeof value === "string" ? value : null;
767
+ }
768
+ async function put3(key, value) {
769
+ const db = await openDb();
770
+ const tx = db.transaction(storeName, "readwrite");
771
+ tx.objectStore(storeName).put(value, `${namespace2}:${key}`);
772
+ await transactionToPromise(tx);
773
+ }
774
+ async function del3(key) {
775
+ const db = await openDb();
776
+ const tx = db.transaction(storeName, "readwrite");
777
+ tx.objectStore(storeName).delete(`${namespace2}:${key}`);
778
+ await transactionToPromise(tx);
779
+ }
780
+ async function list3(options) {
781
+ const db = await openDb();
782
+ const tx = db.transaction(storeName, "readonly");
783
+ const keys = await requestToPromise(tx.objectStore(storeName).getAllKeys());
784
+ await transactionToPromise(tx);
785
+ const prefix = `${namespace2}:${options?.prefix ?? ""}`;
884
786
  return {
885
- fields: Object.entries(record).map(([name, value]) => ({
886
- name,
887
- value: toWireValue(value)
888
- }))
787
+ keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace2.length + 1) }))
889
788
  };
890
789
  }
891
- function valuesToWireRows(rows) {
892
- return rows.map((row) => row.map((value) => toWireValue(value)));
790
+
791
+ // src/runtime/kv.ts
792
+ var hasJspi = typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
793
+ function createBrowserKVBindings(options = {}) {
794
+ const namespace3 = options.namespace ?? "default";
795
+ return {
796
+ [namespace3]: hasJspi && !options.forceLocalStorage ? { get: get3, put: put3, del: del3, list: list3 } : { get: get2, put: put2, del: del2, list: list2 }
797
+ };
893
798
  }
894
- function createDbImports(bindings, getMemory, allocRef) {
895
- const decoder3 = new TextDecoder();
896
- function readStr(ptr, len) {
897
- return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
898
- }
899
- function binding(ns) {
900
- return bindings[ns] ?? bindings["default"] ?? null;
901
- }
902
- async function statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len) {
903
- const database = binding(readStr(ns_ptr, ns_len));
904
- if (!database) return null;
905
- const sql = readStr(sql_ptr, sql_len);
906
- const bindingsJson = JSON.parse(readStr(bindings_ptr, bindings_len));
907
- return database.prepare(sql).bind(...toPositionalBindings(bindingsJson));
908
- }
909
- const Suspending = WebAssembly.Suspending;
910
- if (typeof Suspending !== "function") {
911
- return {
912
- db_open: (_ns, _ns_len) => -1,
913
- db_run: (_a, _b, _c, _d, _e, _f, _g) => -1,
914
- db_get: (_a, _b, _c, _d, _e, _f, _g) => -1,
915
- db_all: (_a, _b, _c, _d, _e, _f, _g) => -1,
916
- db_values: (_a, _b, _c, _d, _e, _f, _g) => -1
917
- };
799
+
800
+ // src/runtime/kv/memory.ts
801
+ var store = /* @__PURE__ */ new Map();
802
+ async function get4(key) {
803
+ const entry = store.get(key);
804
+ if (!entry) return null;
805
+ const expiresAt = entry[1];
806
+ if (expiresAt !== void 0 && Date.now() >= expiresAt) {
807
+ store.delete(key);
808
+ return null;
809
+ }
810
+ return entry[0];
811
+ }
812
+ async function put4(key, value, options) {
813
+ let expiresAt;
814
+ if (options?.expiration !== void 0) {
815
+ expiresAt = options.expiration * 1e3;
816
+ } else if (options?.expirationTtl !== void 0) {
817
+ expiresAt = Date.now() + options.expirationTtl * 1e3;
818
+ }
819
+ store.set(key, [value, expiresAt]);
820
+ }
821
+ async function del4(key) {
822
+ store.delete(key);
823
+ }
824
+ async function list4(options) {
825
+ const keys = [];
826
+ for (const name of [...store.keys()]) {
827
+ if (options?.prefix && !name.startsWith(options.prefix)) continue;
828
+ if (await get4(name) !== null) keys.push({ name });
918
829
  }
919
- return {
920
- db_open: (ns_ptr, ns_len) => binding(readStr(ns_ptr, ns_len)) ? 0 : -1,
921
- db_run: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
922
- const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
923
- if (!stmt) return -1;
924
- const result = await stmt.run();
925
- return writeJsonOut(getMemory, allocRef, out_ptr, {
926
- last_insert_rowid: result.meta?.last_row_id ?? 0,
927
- changes: result.meta?.changes ?? 0
928
- });
929
- }),
930
- db_get: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
931
- const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
932
- if (!stmt) return -1;
933
- const row = await stmt.first();
934
- if (!row) {
935
- new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
936
- return 0;
937
- }
938
- return writeJsonOut(getMemory, allocRef, out_ptr, [objectToWireRow(row)]);
939
- }),
940
- db_all: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
941
- const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
942
- if (!stmt) return -1;
943
- const result = await stmt.all();
944
- const rows = (result.results ?? []).map(objectToWireRow);
945
- if (rows.length === 0) {
946
- new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
947
- return 0;
948
- }
949
- return writeJsonOut(getMemory, allocRef, out_ptr, rows);
950
- }),
951
- db_values: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
952
- const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
953
- if (!stmt) return -1;
954
- const rows = await stmt.raw();
955
- if (rows.length === 0) {
956
- new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
957
- return 0;
958
- }
959
- return writeJsonOut(getMemory, allocRef, out_ptr, valuesToWireRows(rows));
960
- })
961
- };
830
+ return { keys };
962
831
  }
963
832
 
964
- // src/runtime/wasi.ts
965
- var ProcExit = class extends Error {
966
- constructor(code) {
967
- super(`proc_exit(${code})`);
968
- this.code = code;
833
+ // src/wasm/generated/tags.ts
834
+ var TAG_NAMES = [
835
+ "aside",
836
+ "fragment",
837
+ "iframe",
838
+ "slot",
839
+ "img",
840
+ "html",
841
+ "base",
842
+ "head",
843
+ "link",
844
+ "meta",
845
+ "script",
846
+ "style",
847
+ "title",
848
+ "address",
849
+ "article",
850
+ "body",
851
+ "h1",
852
+ "h6",
853
+ "footer",
854
+ "header",
855
+ "h2",
856
+ "h3",
857
+ "h4",
858
+ "h5",
859
+ "hgroup",
860
+ "nav",
861
+ "section",
862
+ "dd",
863
+ "dl",
864
+ "dt",
865
+ "div",
866
+ "figcaption",
867
+ "figure",
868
+ "hr",
869
+ "li",
870
+ "ol",
871
+ "ul",
872
+ "menu",
873
+ "main",
874
+ "p",
875
+ "picture",
876
+ "pre",
877
+ "a",
878
+ "abbr",
879
+ "b",
880
+ "bdi",
881
+ "bdo",
882
+ "br",
883
+ "cite",
884
+ "code",
885
+ "data",
886
+ "time",
887
+ "dfn",
888
+ "em",
889
+ "i",
890
+ "kbd",
891
+ "mark",
892
+ "q",
893
+ "blockquote",
894
+ "rp",
895
+ "ruby",
896
+ "rt",
897
+ "rtc",
898
+ "rb",
899
+ "s",
900
+ "del",
901
+ "ins",
902
+ "samp",
903
+ "small",
904
+ "span",
905
+ "strong",
906
+ "sub",
907
+ "sup",
908
+ "u",
909
+ "var",
910
+ "wbr",
911
+ "area",
912
+ "map",
913
+ "audio",
914
+ "source",
915
+ "track",
916
+ "video",
917
+ "embed",
918
+ "object",
919
+ "param",
920
+ "canvas",
921
+ "noscript",
922
+ "caption",
923
+ "table",
924
+ "col",
925
+ "colgroup",
926
+ "tbody",
927
+ "tr",
928
+ "thead",
929
+ "tfoot",
930
+ "td",
931
+ "th",
932
+ "button",
933
+ "datalist",
934
+ "option",
935
+ "fieldset",
936
+ "label",
937
+ "form",
938
+ "input",
939
+ "keygen",
940
+ "legend",
941
+ "meter",
942
+ "optgroup",
943
+ "select",
944
+ "output",
945
+ "progress",
946
+ "textarea",
947
+ "details",
948
+ "dialog",
949
+ "menuitem",
950
+ "summary",
951
+ "content",
952
+ "element",
953
+ "shadow",
954
+ "template",
955
+ "acronym",
956
+ "applet",
957
+ "basefont",
958
+ "font",
959
+ "big",
960
+ "blink",
961
+ "center",
962
+ "command",
963
+ "dir",
964
+ "frame",
965
+ "frameset",
966
+ "isindex",
967
+ "listing",
968
+ "marquee",
969
+ "noembed",
970
+ "plaintext",
971
+ "spacer",
972
+ "strike",
973
+ "tt",
974
+ "xmp",
975
+ "animate",
976
+ "animateMotion",
977
+ "animateTransform",
978
+ "circle",
979
+ "clipPath",
980
+ "defs",
981
+ "desc",
982
+ "ellipse",
983
+ "feBlend",
984
+ "feColorMatrix",
985
+ "feComponentTransfer",
986
+ "feComposite",
987
+ "feConvolveMatrix",
988
+ "feDiffuseLighting",
989
+ "feDisplacementMap",
990
+ "feDistantLight",
991
+ "feDropShadow",
992
+ "feFlood",
993
+ "feFuncA",
994
+ "feFuncB",
995
+ "feFuncG",
996
+ "feFuncR",
997
+ "feGaussianBlur",
998
+ "feImage",
999
+ "feMerge",
1000
+ "feMergeNode",
1001
+ "feMorphology",
1002
+ "feOffset",
1003
+ "fePointLight",
1004
+ "feSpecularLighting",
1005
+ "feSpotLight",
1006
+ "feTile",
1007
+ "feTurbulence",
1008
+ "filter",
1009
+ "foreignObject",
1010
+ "g",
1011
+ "image",
1012
+ "line",
1013
+ "linearGradient",
1014
+ "marker",
1015
+ "mask",
1016
+ "metadata",
1017
+ "mpath",
1018
+ "path",
1019
+ "pattern",
1020
+ "polygon",
1021
+ "polyline",
1022
+ "radialGradient",
1023
+ "rect",
1024
+ "set",
1025
+ "stop",
1026
+ "svg",
1027
+ "switch",
1028
+ "symbol",
1029
+ "text",
1030
+ "textPath",
1031
+ "tspan",
1032
+ "use",
1033
+ "view",
1034
+ "custom"
1035
+ ];
1036
+
1037
+ // src/wasm/generated/tag_indices.ts
1038
+ var SVG_TAG_START_INDEX = 140;
1039
+ var CUSTOM_TAG_INDEX = 199;
1040
+
1041
+ // src/wasm/dom_cmd.ts
1042
+ var BOOL_PROPS = /* @__PURE__ */ new Set([
1043
+ "checked",
1044
+ "selected",
1045
+ "muted",
1046
+ "defaultChecked",
1047
+ "indeterminate"
1048
+ ]);
1049
+ function enqueueAfterConnect(queue, el, kind) {
1050
+ for (let i = 0; i < queue.length; i++) {
1051
+ const job = queue[i];
1052
+ if (job.el === el && job.kind === kind) return;
1053
+ }
1054
+ queue.push({ el, kind });
1055
+ }
1056
+ function runAfterConnect(queue) {
1057
+ for (let i = 0; i < queue.length; i++) {
1058
+ const job = queue[i];
1059
+ if (!job.el.isConnected) continue;
1060
+ switch (job.kind) {
1061
+ case "focus": {
1062
+ if (typeof job.el.focus !== "function") break;
1063
+ try {
1064
+ job.el.focus({ preventScroll: true });
1065
+ } catch {
1066
+ job.el.focus();
1067
+ }
1068
+ break;
1069
+ }
1070
+ }
969
1071
  }
970
- };
971
- function createWasiImports({
972
- request,
973
- stdinData,
974
- onStdout
975
- }) {
976
- const encoder3 = new TextEncoder();
977
- const url = new URL(request.url);
978
- const argStrings = [
979
- "wasm",
980
- "--pathname",
981
- url.pathname,
982
- "--method",
983
- request.method,
984
- "--search",
985
- url.search,
986
- "--url",
987
- url.href
988
- ];
989
- request.headers.forEach((value, name) => {
990
- if (value) argStrings.push("--header", `${name}:${value}`);
991
- });
992
- const encodedArgs = argStrings.map((a) => encoder3.encode(a + "\0"));
993
- const argBufSize = encodedArgs.reduce((s, a) => s + a.length, 0);
994
- let wasmMemory = null;
995
- const setMemory = (m2) => {
996
- wasmMemory = m2;
997
- };
998
- const stdoutChunks = [];
999
- let stderrMeta = "";
1000
- let stderrPartial = "";
1001
- const stderrDecoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
1002
- function processStderrChunk(chunk) {
1003
- const text = stderrDecoder.decode(chunk, { stream: true });
1004
- const lines = (stderrPartial + text).split("\n");
1005
- stderrPartial = lines.pop() ?? "";
1006
- for (const line of lines) {
1007
- if (line.startsWith("__ZIEX_META__:")) {
1008
- stderrMeta += line + "\n";
1009
- } else if (line.length > 0) {
1010
- console.error("[ziex]", line);
1011
- }
1072
+ }
1073
+ function assignProp(el, name, val) {
1074
+ if (BOOL_PROPS.has(name)) {
1075
+ const on = val !== "false";
1076
+ el[name] = on;
1077
+ if (name === "defaultChecked" && "checked" in el) {
1078
+ el.checked = on;
1012
1079
  }
1080
+ return;
1013
1081
  }
1014
- let stdinOffset = 0;
1015
- function v() {
1016
- return new DataView(wasmMemory.buffer);
1017
- }
1018
- function m() {
1019
- return new Uint8Array(wasmMemory.buffer);
1082
+ if (name === "defaultValue") {
1083
+ el.defaultValue = val;
1084
+ if (typeof el.value === "string" && (el.value === "" || el.value === el.defaultValue)) {
1085
+ el.value = val;
1086
+ }
1087
+ return;
1020
1088
  }
1021
- const wasiImport = {
1022
- args_sizes_get(argc_ptr, argv_buf_size_ptr) {
1023
- v().setUint32(argc_ptr, encodedArgs.length, true);
1024
- v().setUint32(argv_buf_size_ptr, argBufSize, true);
1025
- return 0;
1026
- },
1027
- args_get(argv_ptr, argv_buf_ptr) {
1028
- const dv = v();
1029
- const mem = m();
1030
- let offset = argv_buf_ptr;
1031
- for (const arg of encodedArgs) {
1032
- dv.setUint32(argv_ptr, offset, true);
1033
- mem.set(arg, offset);
1034
- argv_ptr += 4;
1035
- offset += arg.length;
1089
+ el[name] = val;
1090
+ }
1091
+ function flushDomCmds(ptr, len, ctx) {
1092
+ const start = ptr >>> 0;
1093
+ const length = len >>> 0;
1094
+ if (length < DOM_CMD_HEADER_SIZE) return;
1095
+ const mem = getMemoryView();
1096
+ if (start + length > mem.byteLength) return;
1097
+ const view = new DataView(mem.buffer, mem.byteOffset + start, length);
1098
+ const count = view.getUint32(0, true);
1099
+ const recordsBytes = count * DOM_CMD_RECORD_SIZE;
1100
+ if (DOM_CMD_HEADER_SIZE + recordsBytes > length) return;
1101
+ const { domNodes: domNodes2, cleanupDomNodes: cleanupDomNodes2 } = ctx;
1102
+ const afterConnect = [];
1103
+ for (let i = 0; i < count; i++) {
1104
+ const off = DOM_CMD_HEADER_SIZE + i * DOM_CMD_RECORD_SIZE;
1105
+ const op = view.getUint8(off);
1106
+ const p0 = view.getUint32(off + 4, true);
1107
+ const p1 = view.getUint32(off + 8, true);
1108
+ const p2 = view.getUint32(off + 12, true);
1109
+ const p3 = view.getUint32(off + 16, true);
1110
+ const p4 = view.getUint32(off + 20, true);
1111
+ switch (op) {
1112
+ case DomOp_CreateElement: {
1113
+ const isCustom = p0 === CUSTOM_TAG_INDEX;
1114
+ const tagName = isCustom ? readString(p2, p3) : TAG_NAMES[p0];
1115
+ const el = !isCustom && p0 >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
1116
+ el.__zx_ref = p1;
1117
+ domNodes2.set(p1, el);
1118
+ break;
1036
1119
  }
1037
- return 0;
1038
- },
1039
- environ_sizes_get(count_ptr, buf_size_ptr) {
1040
- v().setUint32(count_ptr, 0, true);
1041
- v().setUint32(buf_size_ptr, 0, true);
1042
- return 0;
1043
- },
1044
- environ_get(_environ_ptr, _environ_buf_ptr) {
1045
- return 0;
1046
- },
1047
- fd_write(fd, iovs_ptr, iovs_len, nwritten_ptr) {
1048
- const dv = v();
1049
- const mem = m();
1050
- let written = 0;
1051
- for (let i = 0; i < iovs_len; i++) {
1052
- const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
1053
- const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
1054
- const chunk = mem.slice(buf_ptr, buf_ptr + buf_len);
1055
- if (fd === 1) {
1056
- if (onStdout) onStdout(chunk);
1057
- else stdoutChunks.push(chunk);
1058
- } else if (fd === 2) processStderrChunk(chunk);
1059
- written += buf_len;
1120
+ case DomOp_CreateText: {
1121
+ const node = document.createTextNode(readString(p0, p1));
1122
+ node.__zx_ref = p2;
1123
+ domNodes2.set(p2, node);
1124
+ break;
1060
1125
  }
1061
- dv.setUint32(nwritten_ptr, written, true);
1062
- return 0;
1063
- },
1064
- fd_read(fd, iovs_ptr, iovs_len, nread_ptr) {
1065
- const dv = v();
1066
- const mem = m();
1067
- const stdin = stdinData ?? new Uint8Array(0);
1068
- let totalRead = 0;
1069
- for (let i = 0; i < iovs_len; i++) {
1070
- const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
1071
- const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
1072
- if (fd === 0 && stdinOffset < stdin.length) {
1073
- const toRead = Math.min(buf_len, stdin.length - stdinOffset);
1074
- mem.set(stdin.subarray(stdinOffset, stdinOffset + toRead), buf_ptr);
1075
- stdinOffset += toRead;
1076
- totalRead += toRead;
1126
+ case DomOp_HydrateInsert: {
1127
+ const child = domNodes2.get(p0);
1128
+ const ref = BigInt(p1) | BigInt(p2) << 32n;
1129
+ const end = loadValueFromRef(ref);
1130
+ if (!child || !end?.parentNode) break;
1131
+ end.parentNode.insertBefore(child, end);
1132
+ break;
1133
+ }
1134
+ case DomOp_SetAttr: {
1135
+ const el = domNodes2.get(p0);
1136
+ if (!el) break;
1137
+ const name = readString(p1, p2);
1138
+ const val = readString(p3, p4);
1139
+ el.setAttribute(name, val);
1140
+ if (name === "autofocus") {
1141
+ enqueueAfterConnect(afterConnect, el, "focus");
1077
1142
  }
1143
+ break;
1078
1144
  }
1079
- dv.setUint32(nread_ptr, totalRead, true);
1080
- return 0;
1081
- },
1082
- fd_fdstat_get(_fd, fdstat_ptr) {
1083
- const dv = v();
1084
- dv.setUint8(fdstat_ptr, 2);
1085
- dv.setUint8(fdstat_ptr + 1, 0);
1086
- dv.setUint16(fdstat_ptr + 2, 0, true);
1087
- dv.setUint32(fdstat_ptr + 4, 0, true);
1088
- dv.setBigUint64(fdstat_ptr + 8, 0n, true);
1089
- dv.setBigUint64(fdstat_ptr + 16, 0n, true);
1090
- return 0;
1091
- },
1092
- fd_prestat_get(_fd, _bufptr) {
1093
- return 8;
1094
- },
1095
- fd_prestat_dir_name(_fd, _path, _path_len) {
1096
- return 8;
1097
- },
1098
- fd_close(_fd) {
1099
- return 0;
1100
- },
1101
- fd_pread(_fd, _iovs, _iovs_len, _offset, nread_ptr) {
1102
- v().setUint32(nread_ptr, 0, true);
1103
- return 0;
1104
- },
1105
- fd_pwrite(_fd, _iovs, _iovs_len, _offset, nwritten_ptr) {
1106
- v().setUint32(nwritten_ptr, 0, true);
1107
- return 0;
1108
- },
1109
- fd_filestat_get(_fd, filestat_ptr) {
1110
- const dv = v();
1111
- dv.setBigUint64(filestat_ptr, 0n, true);
1112
- dv.setBigUint64(filestat_ptr + 8, 0n, true);
1113
- dv.setUint8(filestat_ptr + 16, 2);
1114
- dv.setBigUint64(filestat_ptr + 24, 1n, true);
1115
- dv.setBigUint64(filestat_ptr + 32, 0n, true);
1116
- dv.setBigUint64(filestat_ptr + 40, 0n, true);
1117
- dv.setBigUint64(filestat_ptr + 48, 0n, true);
1118
- dv.setBigUint64(filestat_ptr + 56, 0n, true);
1119
- return 0;
1120
- },
1121
- fd_filestat_set_size(_fd, _size) {
1122
- return 76;
1123
- },
1124
- fd_filestat_set_times(_fd, _atim, _mtim, _fst_flags) {
1125
- return 76;
1126
- },
1127
- fd_fdstat_set_flags(_fd, _flags) {
1128
- return 0;
1129
- },
1130
- fd_fdstat_set_rights(_fd, _rights_base, _rights_inheriting) {
1131
- return 0;
1132
- },
1133
- fd_sync(_fd) {
1134
- return 0;
1135
- },
1136
- fd_datasync(_fd) {
1137
- return 0;
1138
- },
1139
- fd_advise(_fd, _offset, _len, _advice) {
1140
- return 0;
1141
- },
1142
- fd_allocate(_fd, _offset, _len) {
1143
- return 76;
1144
- },
1145
- fd_tell(_fd, offset_ptr) {
1146
- v().setBigUint64(offset_ptr, 0n, true);
1147
- return 0;
1148
- },
1149
- fd_renumber(_from, _to) {
1150
- return 0;
1151
- },
1152
- path_filestat_set_times(_fd, _flags, _path, _path_len, _atim, _mtim, _fst_flags) {
1153
- return 76;
1154
- },
1155
- path_link(_old_fd, _old_flags, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
1156
- return 76;
1157
- },
1158
- path_symlink(_old_path, _old_path_len, _fd, _new_path, _new_path_len) {
1159
- return 76;
1160
- },
1161
- proc_raise(_sig) {
1162
- return 0;
1163
- },
1164
- sock_recv(_fd, _ri_data, _ri_data_len, _ri_flags, ro_datalen_ptr, ro_flags_ptr) {
1165
- v().setUint32(ro_datalen_ptr, 0, true);
1166
- v().setUint32(ro_flags_ptr, 0, true);
1167
- return 76;
1168
- },
1169
- sock_send(_fd, _si_data, _si_data_len, _si_flags, so_datalen_ptr) {
1170
- v().setUint32(so_datalen_ptr, 0, true);
1171
- return 76;
1172
- },
1173
- sock_shutdown(_fd, _how) {
1174
- return 76;
1175
- },
1176
- fd_seek(_fd, _offset, _whence, newoffset_ptr) {
1177
- v().setBigInt64(newoffset_ptr, 0n, true);
1178
- return 0;
1179
- },
1180
- proc_exit(code) {
1181
- throw new ProcExit(code);
1182
- },
1183
- sched_yield() {
1184
- return 0;
1185
- },
1186
- clock_time_get(_id, _precision, time_ptr) {
1187
- v().setBigUint64(time_ptr, BigInt(Date.now()) * 1000000n, true);
1188
- return 0;
1189
- },
1190
- clock_res_get(_id, res_ptr) {
1191
- v().setBigUint64(res_ptr, 1000000n, true);
1192
- return 0;
1193
- },
1194
- random_get(buf_ptr, buf_len) {
1195
- crypto.getRandomValues(new Uint8Array(wasmMemory.buffer, buf_ptr, buf_len));
1196
- return 0;
1197
- },
1198
- path_open(_fd, _dirflags, _path, _path_len, _oflags, _rights_base, _rights_inheriting, _fdflags, opened_fd_ptr) {
1199
- v().setInt32(opened_fd_ptr, -1, true);
1200
- return 76;
1201
- },
1202
- path_create_directory(_fd, _path, _path_len) {
1203
- return 76;
1204
- },
1205
- path_unlink_file(_fd, _path, _path_len) {
1206
- return 76;
1207
- },
1208
- path_remove_directory(_fd, _path, _path_len) {
1209
- return 76;
1210
- },
1211
- path_rename(_fd, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
1212
- return 76;
1213
- },
1214
- path_filestat_get(_fd, _flags, _path, _path_len, filestat_ptr) {
1215
- new Uint8Array(wasmMemory.buffer, filestat_ptr, 64).fill(0);
1216
- return 76;
1217
- },
1218
- path_readlink(_fd, _path, _path_len, _buf, _buf_len, nread_ptr) {
1219
- v().setUint32(nread_ptr, 0, true);
1220
- return 76;
1221
- },
1222
- fd_readdir(_fd, _buf, _buf_len, _cookie, bufused_ptr) {
1223
- v().setUint32(bufused_ptr, 0, true);
1224
- return 76;
1225
- },
1226
- // Stub for poll_oneoff - no blocking I/O in edge runtimes.
1227
- poll_oneoff(_in, _out, _nsubscriptions, nevents_ptr) {
1228
- v().setUint32(nevents_ptr, 0, true);
1229
- return 0;
1230
- }
1231
- };
1232
- function collectOutput() {
1233
- const remaining = stderrDecoder.decode(void 0, { stream: false });
1234
- const tail = stderrPartial + remaining;
1235
- if (tail.length > 0) {
1236
- if (tail.startsWith("__ZIEX_META__:")) stderrMeta += tail;
1237
- else console.error("[ziex]", tail);
1238
- stderrPartial = "";
1239
- }
1240
- return {
1241
- stdout: mergeUint8Arrays(stdoutChunks),
1242
- stderrText: stderrMeta
1243
- };
1244
- }
1245
- return { wasiImport, setMemory, collectOutput };
1246
- }
1247
- function mergeUint8Arrays(arrays) {
1248
- const totalLen = arrays.reduce((sum, arr) => sum + arr.length, 0);
1249
- const result = new Uint8Array(totalLen);
1250
- let offset = 0;
1251
- for (const arr of arrays) {
1252
- result.set(arr, offset);
1253
- offset += arr.length;
1254
- }
1255
- return result;
1256
- }
1257
-
1258
- // src/runtime/kv.ts
1259
- var kv_exports = {};
1260
- __export(kv_exports, {
1261
- createBrowserKVBindings: () => createBrowserKVBindings,
1262
- createIndexedDbKV: () => createIndexedDbKV,
1263
- createKVImports: () => createKVImports,
1264
- createLocalStorageKV: () => createLocalStorageKV,
1265
- createMemoryKV: () => createMemoryKV,
1266
- hasJSPI: () => hasJSPI
1267
- });
1268
-
1269
- // src/runtime/kv/memory.ts
1270
- function createMemoryKV() {
1271
- const store = /* @__PURE__ */ new Map();
1272
- function read(key) {
1273
- const entry = store.get(key);
1274
- if (!entry) return null;
1275
- const expiresAt = entry[1];
1276
- if (expiresAt !== void 0 && Date.now() >= expiresAt) {
1277
- store.delete(key);
1278
- return null;
1279
- }
1280
- return entry[0];
1281
- }
1282
- function write(key, value, options) {
1283
- let expiresAt;
1284
- if (options?.expiration !== void 0) {
1285
- expiresAt = options.expiration * 1e3;
1286
- } else if (options?.expirationTtl !== void 0) {
1287
- expiresAt = Date.now() + options.expirationTtl * 1e3;
1288
- }
1289
- store.set(key, [value, expiresAt]);
1290
- }
1291
- return {
1292
- async get(key) {
1293
- return read(key);
1294
- },
1295
- async put(key, value, options) {
1296
- write(key, value, options);
1297
- },
1298
- async delete(key) {
1299
- store.delete(key);
1300
- },
1301
- async list(options) {
1302
- const keys = [...store.keys()].filter((k) => {
1303
- if (options?.prefix && !k.startsWith(options.prefix)) return false;
1304
- return read(k) !== null;
1305
- }).map((name) => ({ name }));
1306
- return { keys };
1307
- }
1308
- };
1309
- }
1310
-
1311
- // src/runtime/kv/localstorage.ts
1312
- function getLocalStorage() {
1313
- if (typeof localStorage === "undefined") {
1314
- throw new Error("localStorage is not available in this environment");
1315
- }
1316
- return localStorage;
1317
- }
1318
- function createLocalStorageKV(options = {}) {
1319
- const storage = getLocalStorage();
1320
- const namespace = options.namespace ?? "default";
1321
- const storagePrefix = options.storagePrefix ?? "ziex-kv";
1322
- const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
1323
- const namespacePrefix = scopedKey("");
1324
- return {
1325
- getSync(key) {
1326
- return storage.getItem(scopedKey(key));
1327
- },
1328
- async get(key) {
1329
- return this.getSync(key);
1330
- },
1331
- putSync(key, value) {
1332
- storage.setItem(scopedKey(key), value);
1333
- },
1334
- async put(key, value) {
1335
- this.putSync(key, value);
1336
- },
1337
- deleteSync(key) {
1338
- storage.removeItem(scopedKey(key));
1339
- },
1340
- async delete(key) {
1341
- this.deleteSync(key);
1342
- },
1343
- listSync(options2) {
1344
- const prefix = namespacePrefix + (options2?.prefix ?? "");
1345
- const keys = [];
1346
- for (let i = 0; i < storage.length; i += 1) {
1347
- const key = storage.key(i);
1348
- if (!key || !key.startsWith(prefix)) continue;
1349
- keys.push({ name: key.slice(namespacePrefix.length) });
1145
+ case DomOp_SetProp: {
1146
+ const el = domNodes2.get(p0);
1147
+ if (el) assignProp(el, readString(p1, p2), readString(p3, p4));
1148
+ break;
1350
1149
  }
1351
- return { keys };
1352
- },
1353
- async list(options2) {
1354
- return this.listSync(options2);
1355
- }
1356
- };
1357
- }
1358
-
1359
- // src/runtime/kv/indexdb.ts
1360
- function getIndexedDb() {
1361
- if (typeof indexedDB === "undefined") {
1362
- throw new Error("IndexedDB is not available in this environment");
1363
- }
1364
- return indexedDB;
1365
- }
1366
- function requestToPromise(request) {
1367
- return new Promise((resolve, reject) => {
1368
- request.onsuccess = () => resolve(request.result);
1369
- request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
1370
- });
1371
- }
1372
- function transactionToPromise(transaction) {
1373
- return new Promise((resolve, reject) => {
1374
- transaction.oncomplete = () => resolve();
1375
- transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
1376
- transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
1377
- });
1378
- }
1379
- function createIndexedDbKV(options = {}) {
1380
- const databaseName = options.databaseName ?? "ziex-kv";
1381
- const storeName = options.storeName ?? "kv";
1382
- const namespace = options.namespace ?? "default";
1383
- const dbPromise = new Promise((resolve, reject) => {
1384
- const request = getIndexedDb().open(databaseName, 1);
1385
- request.onupgradeneeded = () => {
1386
- const db = request.result;
1387
- if (!db.objectStoreNames.contains(storeName)) {
1388
- db.createObjectStore(storeName);
1150
+ case DomOp_RemoveAttr: {
1151
+ domNodes2.get(p0)?.removeAttribute(readString(p1, p2));
1152
+ break;
1389
1153
  }
1390
- };
1391
- request.onsuccess = () => resolve(request.result);
1392
- request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
1393
- });
1394
- const scopedKey = (key) => `${namespace}:${key}`;
1395
- return {
1396
- async get(key) {
1397
- const db = await dbPromise;
1398
- const tx = db.transaction(storeName, "readonly");
1399
- const store = tx.objectStore(storeName);
1400
- const value = await requestToPromise(store.get(scopedKey(key)));
1401
- await transactionToPromise(tx);
1402
- return typeof value === "string" ? value : null;
1403
- },
1404
- async put(key, value) {
1405
- const db = await dbPromise;
1406
- const tx = db.transaction(storeName, "readwrite");
1407
- tx.objectStore(storeName).put(value, scopedKey(key));
1408
- await transactionToPromise(tx);
1409
- },
1410
- async delete(key) {
1411
- const db = await dbPromise;
1412
- const tx = db.transaction(storeName, "readwrite");
1413
- tx.objectStore(storeName).delete(scopedKey(key));
1414
- await transactionToPromise(tx);
1415
- },
1416
- async list(options2) {
1417
- const db = await dbPromise;
1418
- const tx = db.transaction(storeName, "readonly");
1419
- const store = tx.objectStore(storeName);
1420
- const keys = await requestToPromise(store.getAllKeys());
1421
- await transactionToPromise(tx);
1422
- const prefix = scopedKey(options2?.prefix ?? "");
1423
- return {
1424
- keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace.length + 1) }))
1425
- };
1426
- }
1427
- };
1428
- }
1429
-
1430
- // src/runtime/kv.ts
1431
- function hasJSPI() {
1432
- return typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
1433
- }
1434
- function createBrowserKVBindings(options = {}) {
1435
- const namespace = options.namespace ?? "default";
1436
- return {
1437
- [namespace]: hasJSPI() ? createIndexedDbKV(options) : createLocalStorageKV(options)
1438
- };
1439
- }
1440
-
1441
- // src/runtime/index.ts
1442
- function buildWsImports(Suspending, mem, decoder3, ws) {
1443
- const readStr = (ptr, len) => decoder3.decode(new Uint8Array(mem().buffer, ptr, len));
1444
- return {
1445
- ws_upgrade: () => {
1446
- ws.upgraded = true;
1447
- },
1448
- ws_write: (ptr, len) => {
1449
- const data = new Uint8Array(mem().buffer, ptr, len).slice();
1450
- if (!ws.server) {
1451
- ws.pendingWrites.push(data);
1452
- } else {
1453
- ws.server.send(data);
1154
+ case DomOp_SetNodeValue: {
1155
+ const node = domNodes2.get(p0);
1156
+ if (node) node.nodeValue = readString(p1, p2);
1157
+ break;
1454
1158
  }
1455
- },
1456
- ws_close: (code, reason_ptr, reason_len) => {
1457
- ws.server?.close(code, decoder3.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
1458
- },
1459
- ws_recv: Suspending ? new Suspending(async (buf_ptr, buf_max) => {
1460
- if (ws._resolveFirstSuspend) {
1461
- const fn = ws._resolveFirstSuspend;
1462
- ws._resolveFirstSuspend = void 0;
1463
- fn();
1159
+ case DomOp_SetInnerHtml: {
1160
+ const el = domNodes2.get(p0);
1161
+ if (el) el.innerHTML = readString(p1, p2);
1162
+ break;
1464
1163
  }
1465
- const deliver = (bytes) => {
1466
- if (bytes === null) return -1;
1467
- const n = Math.min(bytes.length, buf_max);
1468
- new Uint8Array(mem().buffer, buf_ptr, n).set(bytes.subarray(0, n));
1469
- return n;
1470
- };
1471
- if (ws.messageQueue.length > 0) return deliver(ws.messageQueue.shift());
1472
- return new Promise((resolve) => {
1473
- ws.recvResolve = (bytes) => resolve(deliver(bytes));
1474
- });
1475
- }) : (_buf_ptr, _buf_max) => -1,
1476
- // Pub/sub - delegates to optional callbacks (real in DO, no-ops otherwise)
1477
- ws_subscribe: (ptr, len) => {
1478
- ws.subscribe?.(readStr(ptr, len));
1479
- },
1480
- ws_unsubscribe: (ptr, len) => {
1481
- ws.unsubscribe?.(readStr(ptr, len));
1482
- },
1483
- ws_publish: (topic_ptr, topic_len, data_ptr, data_len) => {
1484
- const topic = readStr(topic_ptr, topic_len);
1485
- const data = new Uint8Array(mem().buffer, data_ptr, data_len).slice();
1486
- return ws.publish?.(topic, data) ?? 0;
1487
- },
1488
- ws_is_subscribed: (ptr, len) => ws.isSubscribed?.(readStr(ptr, len)) ? 1 : 0
1489
- };
1490
- }
1491
- function attachWebSocket(ws) {
1492
- const WebSocketPairCtor = globalThis.WebSocketPair;
1493
- const pair = new WebSocketPairCtor();
1494
- const client = pair[0];
1495
- const server = pair[1];
1496
- ws.server = server;
1497
- server.accept();
1498
- for (const data of ws.pendingWrites) server.send(data);
1499
- ws.pendingWrites = [];
1500
- server.addEventListener("message", (event) => {
1501
- const data = typeof event.data === "string" ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
1502
- if (ws.recvResolve) {
1503
- const res = ws.recvResolve;
1504
- ws.recvResolve = null;
1505
- res(data);
1506
- } else {
1507
- ws.messageQueue.push(data);
1508
- }
1509
- });
1510
- server.addEventListener("close", () => {
1511
- if (ws.recvResolve) {
1512
- const res = ws.recvResolve;
1513
- ws.recvResolve = null;
1514
- res(null);
1515
- }
1516
- });
1517
- return { client };
1518
- }
1519
- function buildSysImports(jspi, Suspending) {
1520
- return {
1521
- sleep_ms: jspi ? new Suspending(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {
1522
- }
1523
- };
1524
- }
1525
- function executeWasm(instance, jspi, Suspending, wsState) {
1526
- if (!jspi) {
1527
- try {
1528
- instance.exports._start();
1529
- } catch (e) {
1530
- if (!(e instanceof ProcExit)) throw e;
1531
- }
1532
- return Promise.resolve();
1533
- }
1534
- const start = WebAssembly.promising(instance.exports._start);
1535
- return start().catch((e) => {
1536
- if (e instanceof Error && e.message.startsWith("proc_exit")) return;
1537
- throw e;
1538
- }).finally(() => {
1539
- if (wsState.recvResolve) {
1540
- const res = wsState.recvResolve;
1541
- wsState.recvResolve = null;
1542
- res(null);
1543
- }
1544
- });
1545
- }
1546
- function parseZiexMeta(stderrText) {
1547
- const meta = { status: 200, headers: new Headers(), streaming: false };
1548
- const metaPrefix = "__ZIEX_META__:";
1549
- const metaLine = stderrText.split("\n").find((line) => line.startsWith(metaPrefix));
1550
- if (metaLine) {
1551
- try {
1552
- const parsed = JSON.parse(metaLine.slice(metaPrefix.length));
1553
- if (parsed.status) meta.status = parsed.status;
1554
- if (parsed.streaming === true) meta.streaming = true;
1555
- if (Array.isArray(parsed.headers)) {
1556
- for (const [name, value] of parsed.headers) {
1557
- meta.headers.append(name, value);
1164
+ case DomOp_AppendChild: {
1165
+ const parent = domNodes2.get(p0);
1166
+ const child = domNodes2.get(p1);
1167
+ if (parent && child) parent.appendChild(child);
1168
+ break;
1169
+ }
1170
+ case DomOp_InsertBefore: {
1171
+ const parent = domNodes2.get(p0);
1172
+ const child = domNodes2.get(p1);
1173
+ const refNode = domNodes2.get(p2) ?? null;
1174
+ if (parent && child) parent.insertBefore(child, refNode);
1175
+ break;
1176
+ }
1177
+ case DomOp_RemoveChild: {
1178
+ const parent = domNodes2.get(p0);
1179
+ const child = domNodes2.get(p1);
1180
+ if (parent && child) {
1181
+ parent.removeChild(child);
1182
+ cleanupDomNodes2(child);
1183
+ }
1184
+ break;
1185
+ }
1186
+ case DomOp_ReplaceChild: {
1187
+ const parent = domNodes2.get(p0);
1188
+ const newChild = domNodes2.get(p1);
1189
+ const oldChild = domNodes2.get(p2);
1190
+ if (parent && newChild && oldChild) {
1191
+ parent.replaceChild(newChild, oldChild);
1192
+ cleanupDomNodes2(oldChild);
1558
1193
  }
1194
+ break;
1559
1195
  }
1560
- } catch {
1196
+ default:
1197
+ break;
1561
1198
  }
1562
1199
  }
1563
- return meta;
1200
+ runAfterConnect(afterConnect);
1564
1201
  }
1565
- async function run({
1566
- request,
1567
- env,
1568
- ctx,
1569
- module,
1570
- kv: kvBindings,
1571
- db: dbBindings,
1572
- imports,
1573
- wasi,
1574
- websocket: doNamespace
1575
- }) {
1576
- if (doNamespace && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
1577
- const id = doNamespace.idFromName(new URL(request.url).pathname);
1578
- return doNamespace.get(id).fetch(request);
1579
- }
1580
- const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
1581
- const stdoutChunks = [];
1582
- let streamWriter = null;
1583
- const { wasiImport, setMemory, collectOutput } = createWasiImports({
1584
- request,
1585
- stdinData,
1586
- onStdout: (chunk) => {
1587
- if (streamWriter) void streamWriter.write(chunk);
1588
- else stdoutChunks.push(chunk);
1589
- }
1590
- });
1591
- let wasmMemory = null;
1592
- const mem = () => wasmMemory;
1593
- const bridgeRef = [null];
1594
- const allocRef = [null];
1595
- const Suspending = WebAssembly.Suspending;
1596
- const jspi = typeof Suspending === "function";
1597
- const wsState = {
1598
- upgraded: false,
1599
- server: null,
1600
- pendingWrites: [],
1601
- messageQueue: [],
1602
- recvResolve: null
1603
- };
1604
- const importObject = {
1605
- wasi_snapshot_preview1: { ...wasi?.wasiImport, ...wasiImport },
1606
- __zx_sys: buildSysImports(jspi, Suspending),
1607
- __zx_ws: buildWsImports(jspi ? Suspending : null, mem, new TextDecoder(), wsState),
1608
- __zx_net: createFetchImports(mem),
1609
- ...imports ? imports(mem) : {},
1610
- ...ZxWasiBridge.createImportObject(bridgeRef)
1611
- };
1612
- if (true) {
1613
- importObject.__zx_kv = createKVImports(
1614
- kvBindings ?? { default: createMemoryKV() },
1615
- mem,
1616
- allocRef
1202
+
1203
+ // src/wasm/generated/events.ts
1204
+ var DELEGATED_EVENTS = [
1205
+ "click",
1206
+ "dblclick",
1207
+ "input",
1208
+ "change",
1209
+ "submit",
1210
+ "focusin",
1211
+ "focusout",
1212
+ "keydown",
1213
+ "keyup",
1214
+ "keypress",
1215
+ "mouseenter",
1216
+ "mouseleave",
1217
+ "mousedown",
1218
+ "mouseup",
1219
+ "mousemove",
1220
+ "touchstart",
1221
+ "touchend",
1222
+ "touchmove",
1223
+ "scroll",
1224
+ "wheel",
1225
+ "pointerdown",
1226
+ "pointermove",
1227
+ "pointerup",
1228
+ "pointercancel",
1229
+ "pointerenter",
1230
+ "pointerleave",
1231
+ "lostpointercapture"
1232
+ ];
1233
+
1234
+ // src/wasm/generated/event_bits.ts
1235
+ var HIGH_FREQ_EVENT_BITS = 3031040;
1236
+
1237
+ // src/wasm/index.ts
1238
+ var ZxBridge = class extends ZxBridgeCore {
1239
+ #websockets = /* @__PURE__ */ new Map();
1240
+ #eventbridge;
1241
+ #eventbridgeAsync;
1242
+ constructor(exports) {
1243
+ super(exports);
1244
+ this.#eventbridge = exports.__zx_eventbridge;
1245
+ this.#eventbridgeAsync = wrapPromisingExport(
1246
+ exports.__zx_eventbridge_async ?? exports.__zx_eventbridge
1617
1247
  );
1618
1248
  }
1619
- if (true) {
1620
- importObject.__zx_db = createDbImports(
1621
- dbBindings ?? {},
1622
- mem,
1623
- allocRef
1624
- );
1625
- }
1626
- const instance = new WebAssembly.Instance(module, importObject);
1627
- wasmMemory = instance.exports.memory;
1628
- setMemory(wasmMemory);
1629
- bridgeRef[0] = new ZxWasiBridge(instance.exports);
1630
- bindWasmAlloc(allocRef, instance.exports);
1631
- const wasmPromise = executeWasm(instance, jspi, Suspending, wsState);
1632
- if (wsState.upgraded) {
1633
- const server = attachWebSocket(wsState);
1634
- ctx?.waitUntil(wasmPromise);
1635
- return new Response(null, { status: 101, webSocket: server.client });
1636
- }
1637
- const { stderrText: earlyStderrText } = collectOutput();
1638
- const earlyMeta = parseZiexMeta(earlyStderrText);
1639
- if (earlyMeta.streaming) {
1640
- const { readable, writable } = new TransformStream();
1641
- streamWriter = writable.getWriter();
1642
- for (const chunk of stdoutChunks) void streamWriter.write(chunk);
1643
- stdoutChunks.length = 0;
1644
- void wasmPromise.finally(() => streamWriter?.close());
1645
- return new Response(readable, { status: earlyMeta.status, headers: earlyMeta.headers });
1646
- }
1647
- await wasmPromise;
1648
- const { stderrText } = collectOutput();
1649
- const meta = parseZiexMeta(stderrText);
1650
- const body = mergeUint8Arrays(stdoutChunks);
1651
- meta.headers.delete("transfer-encoding");
1652
- const nullBody = meta.status === 101 || meta.status === 204 || meta.status === 205 || meta.status === 304;
1653
- if (nullBody) {
1654
- meta.headers.delete("content-length");
1655
- return new Response(null, { status: meta.status, headers: meta.headers });
1656
- }
1657
- if (!meta.headers.has("content-length")) meta.headers.set("content-length", String(body.byteLength));
1658
- return new Response(body.buffer, { status: meta.status, headers: meta.headers });
1659
- }
1660
-
1661
- // src/app.ts
1662
- async function resolveModule(input) {
1663
- if (typeof input === "string") {
1664
- if (input.startsWith("http://") || input.startsWith("https://")) {
1665
- return WebAssembly.compileStreaming(fetch(input));
1666
- }
1667
- const url = input.startsWith("/") ? `file://${input}` : input;
1668
- return WebAssembly.compile(await fetch(url).then((r) => r.arrayBuffer()));
1669
- }
1670
- if (input instanceof URL) {
1671
- return WebAssembly.compileStreaming(fetch(input));
1672
- }
1673
- if (input instanceof Response) {
1674
- return WebAssembly.compileStreaming(input);
1675
- }
1676
- if (input instanceof ArrayBuffer) {
1677
- return WebAssembly.compile(input);
1678
- }
1679
- if (ArrayBuffer.isView(input)) {
1680
- return WebAssembly.compile(input.buffer);
1681
- }
1682
- return input;
1683
- }
1684
- var Ziex = class {
1685
- constructor(options) {
1686
- this.resolved = null;
1687
- /**
1688
- * Fetch handler called by the runtime on every request.
1689
- *
1690
- * Arrow function so `this` is always the class instance, even when the
1691
- * runtime extracts `fetch` from the exported object (e.g. Bun).
1692
- */
1693
- this.fetch = async (request, env, ctx) => {
1694
- const module = await this.getModule();
1695
- const { wasi, imports, websocket } = this.options;
1696
- return run({
1697
- request,
1698
- env,
1699
- ctx,
1700
- module,
1701
- wasi,
1702
- imports,
1703
- kv: this.resolveKV(env),
1704
- db: this.resolveDB(env),
1705
- websocket: websocket !== void 0 ? env[websocket] : void 0
1706
- });
1707
- };
1708
- this.options = options;
1709
- }
1710
- async getModule() {
1711
- if (!this.resolved) this.resolved = await resolveModule(this.options.module);
1712
- return this.resolved;
1713
- }
1714
- resolveKV(env) {
1715
- const { kv } = this.options;
1716
- if (kv === void 0) return void 0;
1717
- if (typeof kv === "object" && kv !== null) {
1718
- const result = {};
1719
- for (const [name, key] of Object.entries(kv)) {
1720
- result[name] = env[key];
1721
- }
1722
- return result;
1723
- }
1724
- return { default: env[kv] };
1725
- }
1726
- resolveDB(env) {
1727
- const { db } = this.options;
1728
- if (db === void 0) return void 0;
1729
- if (typeof db === "object" && db !== null) {
1730
- const result = {};
1731
- for (const [name, key] of Object.entries(db)) {
1732
- result[name] = env[key];
1733
- }
1734
- return result;
1735
- }
1736
- return { default: env[db] };
1737
- }
1738
- };
1739
-
1740
- // src/wasm/index.ts
1741
- var ZxBridge = class extends ZxBridgeCore {
1742
- #websockets = /* @__PURE__ */ new Map();
1743
- #wsOnOpenHandler;
1744
- #wsOnMessageHandler;
1745
- #wsOnErrorHandler;
1746
- #wsOnCloseHandler;
1747
- #eventbridge;
1748
- #eventbridgeAsync;
1749
- constructor(exports) {
1750
- super(exports);
1751
- this.#wsOnOpenHandler = wrapPromisingExport(exports.__zx_ws_onopen);
1752
- this.#wsOnMessageHandler = wrapPromisingExport(exports.__zx_ws_onmessage);
1753
- this.#wsOnErrorHandler = wrapPromisingExport(exports.__zx_ws_onerror);
1754
- this.#wsOnCloseHandler = wrapPromisingExport(exports.__zx_ws_onclose);
1755
- this.#eventbridge = exports.__zx_eventbridge;
1756
- this.#eventbridgeAsync = wrapPromisingExport(
1757
- exports.__zx_eventbridge_async ?? exports.__zx_eventbridge
1758
- );
1759
- }
1760
- hasEventHandler(velementId, eventTypeId) {
1761
- return !!((eventHandlersPresent.get(velementId) ?? 0) & 1 << eventTypeId);
1249
+ hasEventHandler(velementId, eventTypeId) {
1250
+ return !!((eventHandlersPresent.get(velementId) ?? 0) & 1 << eventTypeId);
1762
1251
  }
1763
1252
  eventMaySuspend(velementId, eventTypeId) {
1764
1253
  return !!((eventHandlersSuspend.get(velementId) ?? 0) & 1 << eventTypeId);
@@ -1777,8 +1266,8 @@ var ZxBridge = class extends ZxBridgeCore {
1777
1266
  const present = eventHandlersPresent.get(velementId) ?? 0;
1778
1267
  eventHandlersPresent.delete(velementId);
1779
1268
  eventHandlersSuspend.delete(velementId);
1780
- for (const eventTypeId of HIGH_FREQ_EVENT_IDS) {
1781
- if (present & 1 << eventTypeId) maybeRemoveHighFreqListener(eventTypeId);
1269
+ for (let bits = present & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
1270
+ maybeRemoveHighFreqListener(31 - Math.clz32(bits));
1782
1271
  }
1783
1272
  }
1784
1273
  /** Submit a form action with bound-state round-trip. */
@@ -1800,7 +1289,7 @@ var ZxBridge = class extends ZxBridgeCore {
1800
1289
  }
1801
1290
  /**
1802
1291
  * Create and connect a WebSocket.
1803
- * Calls __zx_ws_onopen, __zx_ws_onmessage, __zx_ws_onerror, __zx_ws_onclose.
1292
+ * Completes via `__zx_cb(ws_open|ws_message|ws_error|ws_close, ...)`.
1804
1293
  */
1805
1294
  wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) {
1806
1295
  const url = readString(urlPtr, urlLen);
@@ -1810,42 +1299,32 @@ var ZxBridge = class extends ZxBridgeCore {
1810
1299
  const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
1811
1300
  ws.binaryType = "arraybuffer";
1812
1301
  ws.onopen = () => {
1813
- const handler = this.#wsOnOpenHandler;
1814
- if (!handler) return;
1815
1302
  const protocol = ws.protocol || "";
1816
1303
  const [ptr, len] = this._writeStringToWasm(protocol);
1817
- invokeWasmExport(handler, wsId, ptr, len);
1304
+ this._invoke(CallbackType_WebSocketOpen, wsId, BigInt(ptr), BigInt(len));
1818
1305
  };
1819
1306
  ws.onmessage = (event) => {
1820
- const handler = this.#wsOnMessageHandler;
1821
- if (!handler) return;
1822
1307
  const isBinary = event.data instanceof ArrayBuffer;
1823
1308
  const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
1824
1309
  const [ptr, len] = this.writeBytesToWasm(data);
1825
- invokeWasmExport(handler, wsId, ptr, len, isBinary ? 1 : 0);
1310
+ this._invoke(CallbackType_WebSocketMessage, wsId, BigInt(ptr), BigInt(len), BigInt(isBinary ? 1 : 0));
1826
1311
  };
1827
1312
  ws.onerror = (_event) => {
1828
- const handler = this.#wsOnErrorHandler;
1829
- if (!handler) return;
1830
1313
  const [ptr, len] = this._writeStringToWasm("WebSocket error");
1831
- invokeWasmExport(handler, wsId, ptr, len);
1314
+ this._invoke(CallbackType_WebSocketError, wsId, BigInt(ptr), BigInt(len));
1832
1315
  };
1833
1316
  ws.onclose = (event) => {
1834
- const handler = this.#wsOnCloseHandler;
1835
- if (!handler) return;
1836
1317
  const reason = event.reason || "";
1837
1318
  const [ptr, len] = this._writeStringToWasm(reason);
1838
- invokeWasmExport(handler, wsId, event.code, ptr, len, event.wasClean ? 1 : 0);
1319
+ const c = BigInt(len) | BigInt(event.wasClean ? 1 : 0) << 32n;
1320
+ this._invoke(CallbackType_WebSocketClose, wsId, BigInt(event.code), BigInt(ptr), c);
1839
1321
  this.#websockets.delete(wsId);
1840
1322
  };
1841
1323
  this.#websockets.set(wsId, ws);
1842
1324
  } catch (error) {
1843
- const handler = this.#wsOnErrorHandler;
1844
- if (handler) {
1845
- const msg = error instanceof Error ? error.message : "WebSocket connection failed";
1846
- const [ptr, len] = this._writeStringToWasm(msg);
1847
- invokeWasmExport(handler, wsId, ptr, len);
1848
- }
1325
+ const msg = error instanceof Error ? error.message : "WebSocket connection failed";
1326
+ const [ptr, len] = this._writeStringToWasm(msg);
1327
+ this._invoke(CallbackType_WebSocketError, wsId, BigInt(ptr), BigInt(len));
1849
1328
  }
1850
1329
  }
1851
1330
  /** Send data over WebSocket */
@@ -1946,79 +1425,11 @@ var ZxBridge = class extends ZxBridgeCore {
1946
1425
  _wsClose: (wsId, code, reasonPtr, reasonLen) => {
1947
1426
  bridgeRef[0]?.wsClose(wsId, code, reasonPtr, reasonLen);
1948
1427
  },
1949
- _ce: (id, vnodeId) => {
1950
- const nid = Number(vnodeId);
1951
- const tagName = TAG_NAMES[id];
1952
- const el = id >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
1953
- el.__zx_ref = nid;
1954
- domNodes.set(nid, el);
1955
- },
1956
- _ct: (ptr, len, vnodeId) => {
1957
- const nid = Number(vnodeId);
1958
- const node = document.createTextNode(readString(ptr, len));
1959
- node.__zx_ref = nid;
1960
- domNodes.set(nid, node);
1961
- },
1962
- /** Insert vnode before a jsz-held end comment (hydration). */
1963
- _ih: (vnodeId, endCommentRef) => {
1964
- const child = domNodes.get(Number(vnodeId));
1965
- const end = loadValueFromRef(endCommentRef);
1966
- if (!child || !end?.parentNode) return;
1967
- end.parentNode.insertBefore(child, end);
1968
- },
1969
- _sa: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
1970
- domNodes.get(Number(vnodeId))?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
1971
- },
1972
- _sp: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
1973
- const el = domNodes.get(Number(vnodeId));
1974
- if (el) {
1975
- const name = readString(namePtr, nameLen);
1976
- const val = readString(valPtr, valLen);
1977
- if (name === "checked" || name === "selected" || name === "muted") {
1978
- el[name] = val !== "false";
1979
- } else {
1980
- el[name] = val;
1981
- }
1982
- }
1983
- },
1984
- _ra: (vnodeId, namePtr, nameLen) => {
1985
- domNodes.get(Number(vnodeId))?.removeAttribute(readString(namePtr, nameLen));
1986
- },
1987
- _snv: (vnodeId, ptr, len) => {
1988
- const node = domNodes.get(Number(vnodeId));
1989
- if (node) node.nodeValue = readString(ptr, len);
1990
- },
1991
- _srh: (vnodeId, ptr, len) => {
1992
- const el = domNodes.get(Number(vnodeId));
1993
- if (el) el.innerHTML = readString(ptr, len);
1994
- },
1995
- _ac: (parentId, childId) => {
1996
- const parent = domNodes.get(Number(parentId));
1997
- const child = domNodes.get(Number(childId));
1998
- if (parent && child) parent.appendChild(child);
1999
- },
2000
- _ib: (parentId, childId, refId) => {
2001
- const parent = domNodes.get(Number(parentId));
2002
- const child = domNodes.get(Number(childId));
2003
- const ref = domNodes.get(Number(refId)) ?? null;
2004
- if (parent && child) parent.insertBefore(child, ref);
2005
- },
2006
- _rc: (parentId, childId) => {
2007
- const parent = domNodes.get(Number(parentId));
2008
- const child = domNodes.get(Number(childId));
2009
- if (parent && child) {
2010
- parent.removeChild(child);
2011
- cleanupDomNodes(child);
2012
- }
2013
- },
2014
- _rpc: (parentId, newId, oldId) => {
2015
- const parent = domNodes.get(Number(parentId));
2016
- const newChild = domNodes.get(Number(newId));
2017
- const oldChild = domNodes.get(Number(oldId));
2018
- if (parent && newChild && oldChild) {
2019
- parent.replaceChild(newChild, oldChild);
2020
- cleanupDomNodes(oldChild);
2021
- }
1428
+ _flush: (ptr, len) => {
1429
+ flushDomCmds(ptr, len, {
1430
+ domNodes,
1431
+ cleanupDomNodes
1432
+ });
2022
1433
  },
2023
1434
  _getLocationHref: (bufPtr, bufLen) => {
2024
1435
  const bytes = textEncoder.encode(window.location.href);
@@ -2057,6 +1468,10 @@ var ZxBridge = class extends ZxBridgeCore {
2057
1468
  if (!form || !(form instanceof HTMLFormElement)) return;
2058
1469
  const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
2059
1470
  bridgeRef[0]?.submitFormActionAsync(form, actionId, statesJson, fetchId);
1471
+ },
1472
+ _formReset: (vnodeId) => {
1473
+ const form = domNodes.get(Number(vnodeId));
1474
+ if (form instanceof HTMLFormElement) form.reset();
2060
1475
  }
2061
1476
  }
2062
1477
  };
@@ -2083,247 +1498,10 @@ function cleanupDomNodes(node) {
2083
1498
  const children = n.childNodes;
2084
1499
  for (let i = 0; i < children.length; i++) stack.push(children[i]);
2085
1500
  }
2086
- for (const eventTypeId of HIGH_FREQ_EVENT_IDS) {
2087
- if (highFreqBits & 1 << eventTypeId) maybeRemoveHighFreqListener(eventTypeId);
1501
+ for (let bits = highFreqBits & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
1502
+ maybeRemoveHighFreqListener(31 - Math.clz32(bits));
2088
1503
  }
2089
1504
  }
2090
- var SVG_TAG_START_INDEX = 140;
2091
- var TAG_NAMES = [
2092
- "aside",
2093
- "fragment",
2094
- "iframe",
2095
- "slot",
2096
- "img",
2097
- "html",
2098
- "base",
2099
- "head",
2100
- "link",
2101
- "meta",
2102
- "script",
2103
- "style",
2104
- "title",
2105
- "address",
2106
- "article",
2107
- "body",
2108
- "h1",
2109
- "h6",
2110
- "footer",
2111
- "header",
2112
- "h2",
2113
- "h3",
2114
- "h4",
2115
- "h5",
2116
- "hgroup",
2117
- "nav",
2118
- "section",
2119
- "dd",
2120
- "dl",
2121
- "dt",
2122
- "div",
2123
- "figcaption",
2124
- "figure",
2125
- "hr",
2126
- "li",
2127
- "ol",
2128
- "ul",
2129
- "menu",
2130
- "main",
2131
- "p",
2132
- "picture",
2133
- "pre",
2134
- "a",
2135
- "abbr",
2136
- "b",
2137
- "bdi",
2138
- "bdo",
2139
- "br",
2140
- "cite",
2141
- "code",
2142
- "data",
2143
- "time",
2144
- "dfn",
2145
- "em",
2146
- "i",
2147
- "kbd",
2148
- "mark",
2149
- "q",
2150
- "blockquote",
2151
- "rp",
2152
- "ruby",
2153
- "rt",
2154
- "rtc",
2155
- "rb",
2156
- "s",
2157
- "del",
2158
- "ins",
2159
- "samp",
2160
- "small",
2161
- "span",
2162
- "strong",
2163
- "sub",
2164
- "sup",
2165
- "u",
2166
- "var",
2167
- "wbr",
2168
- "area",
2169
- "map",
2170
- "audio",
2171
- "source",
2172
- "track",
2173
- "video",
2174
- "embed",
2175
- "object",
2176
- "param",
2177
- "canvas",
2178
- "noscript",
2179
- "caption",
2180
- "table",
2181
- "col",
2182
- "colgroup",
2183
- "tbody",
2184
- "tr",
2185
- "thead",
2186
- "tfoot",
2187
- "td",
2188
- "th",
2189
- "button",
2190
- "datalist",
2191
- "option",
2192
- "fieldset",
2193
- "label",
2194
- "form",
2195
- "input",
2196
- "keygen",
2197
- "legend",
2198
- "meter",
2199
- "optgroup",
2200
- "select",
2201
- "output",
2202
- "progress",
2203
- "textarea",
2204
- "details",
2205
- "dialog",
2206
- "menuitem",
2207
- "summary",
2208
- "content",
2209
- "element",
2210
- "shadow",
2211
- "template",
2212
- "acronym",
2213
- "applet",
2214
- "basefont",
2215
- "font",
2216
- "big",
2217
- "blink",
2218
- "center",
2219
- "command",
2220
- "dir",
2221
- "frame",
2222
- "frameset",
2223
- "isindex",
2224
- "listing",
2225
- "marquee",
2226
- "noembed",
2227
- "plaintext",
2228
- "spacer",
2229
- "strike",
2230
- "tt",
2231
- "xmp",
2232
- // SVG Tags
2233
- "animate",
2234
- "animateMotion",
2235
- "animateTransform",
2236
- "circle",
2237
- "clipPath",
2238
- "defs",
2239
- "desc",
2240
- "ellipse",
2241
- "feBlend",
2242
- "feColorMatrix",
2243
- "feComponentTransfer",
2244
- "feComposite",
2245
- "feConvolveMatrix",
2246
- "feDiffuseLighting",
2247
- "feDisplacementMap",
2248
- "feDistantLight",
2249
- "feDropShadow",
2250
- "feFlood",
2251
- "feFuncA",
2252
- "feFuncB",
2253
- "feFuncG",
2254
- "feFuncR",
2255
- "feGaussianBlur",
2256
- "feImage",
2257
- "feMerge",
2258
- "feMergeNode",
2259
- "feMorphology",
2260
- "feOffset",
2261
- "fePointLight",
2262
- "feSpecularLighting",
2263
- "feSpotLight",
2264
- "feTile",
2265
- "feTurbulence",
2266
- "filter",
2267
- "foreignObject",
2268
- "g",
2269
- "image",
2270
- "line",
2271
- "linearGradient",
2272
- "marker",
2273
- "mask",
2274
- "metadata",
2275
- "mpath",
2276
- "path",
2277
- "pattern",
2278
- "polygon",
2279
- "polyline",
2280
- "radialGradient",
2281
- "rect",
2282
- "set",
2283
- "stop",
2284
- "svg",
2285
- "switch",
2286
- "symbol",
2287
- "text",
2288
- "textPath",
2289
- "tspan",
2290
- "use",
2291
- "view"
2292
- ];
2293
- var DELEGATED_EVENTS = [
2294
- "click",
2295
- "dblclick",
2296
- "input",
2297
- "change",
2298
- "submit",
2299
- // focus/blur do not bubble - listen to focusin/focusout instead.
2300
- "focusin",
2301
- "focusout",
2302
- "keydown",
2303
- "keyup",
2304
- "keypress",
2305
- "mouseenter",
2306
- "mouseleave",
2307
- "mousedown",
2308
- "mouseup",
2309
- "mousemove",
2310
- "touchstart",
2311
- "touchend",
2312
- "touchmove",
2313
- "scroll",
2314
- "wheel",
2315
- "pointerdown",
2316
- "pointermove",
2317
- "pointerup",
2318
- "pointercancel"
2319
- ];
2320
- var HIGH_FREQ_EVENT_IDS = new Set([
2321
- DELEGATED_EVENTS.indexOf("mousemove"),
2322
- DELEGATED_EVENTS.indexOf("pointermove"),
2323
- DELEGATED_EVENTS.indexOf("wheel"),
2324
- DELEGATED_EVENTS.indexOf("scroll"),
2325
- DELEGATED_EVENTS.indexOf("touchmove")
2326
- ].filter((id) => id >= 0));
2327
1505
  var delegationState = null;
2328
1506
  function makeDelegatedListener(bridge, eventTypeId) {
2329
1507
  return (event) => {
@@ -2342,86 +1520,921 @@ function makeDelegatedListener(bridge, eventTypeId) {
2342
1520
  }
2343
1521
  target = target.parentElement;
2344
1522
  }
2345
- if (eventRef !== void 0) {
2346
- const ref = eventRef;
2347
- if (pending.length > 0) {
2348
- Promise.all(pending).finally(() => releaseValueRef(ref));
2349
- } else {
2350
- releaseValueRef(ref);
2351
- }
1523
+ if (eventRef !== void 0) {
1524
+ const ref = eventRef;
1525
+ if (pending.length > 0) {
1526
+ Promise.all(pending).finally(() => releaseValueRef(ref));
1527
+ } else {
1528
+ releaseValueRef(ref);
1529
+ }
1530
+ }
1531
+ };
1532
+ }
1533
+ function ensureDelegatedListener(eventTypeId) {
1534
+ const state = delegationState;
1535
+ if (!state || state.attached.has(eventTypeId)) return;
1536
+ const domType = DELEGATED_EVENTS[eventTypeId];
1537
+ if (!domType) return;
1538
+ const passive = domType.startsWith("touch") || domType === "scroll";
1539
+ const options = { passive };
1540
+ const listener = makeDelegatedListener(state.bridge, eventTypeId);
1541
+ state.root.addEventListener(domType, listener, options);
1542
+ state.attached.set(eventTypeId, { listener, options });
1543
+ }
1544
+ function anyHandlerForType(eventTypeId) {
1545
+ const bit = 1 << eventTypeId;
1546
+ for (const mask of eventHandlersPresent.values()) {
1547
+ if (mask & bit) return true;
1548
+ }
1549
+ return false;
1550
+ }
1551
+ function maybeRemoveHighFreqListener(eventTypeId) {
1552
+ if ((HIGH_FREQ_EVENT_BITS & 1 << eventTypeId) === 0) return;
1553
+ if (anyHandlerForType(eventTypeId)) return;
1554
+ const state = delegationState;
1555
+ if (!state) return;
1556
+ const entry = state.attached.get(eventTypeId);
1557
+ if (!entry) return;
1558
+ const domType = DELEGATED_EVENTS[eventTypeId];
1559
+ state.root.removeEventListener(domType, entry.listener, entry.options);
1560
+ state.attached.delete(eventTypeId);
1561
+ }
1562
+
1563
+ // src/runtime/db/extern.ts
1564
+ function decodeBlob(base64) {
1565
+ const binary = atob(base64);
1566
+ const bytes = new Uint8Array(binary.length);
1567
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
1568
+ return bytes;
1569
+ }
1570
+ function toDbValue(value) {
1571
+ switch (value.kind) {
1572
+ case "null":
1573
+ return null;
1574
+ case "integer":
1575
+ return value.integer;
1576
+ case "float":
1577
+ return value.float;
1578
+ case "text":
1579
+ return value.text;
1580
+ case "blob":
1581
+ return decodeBlob(value.blob);
1582
+ case "boolean":
1583
+ return value.boolean;
1584
+ }
1585
+ }
1586
+ function toPositionalBindings(json) {
1587
+ switch (json.kind) {
1588
+ case "none":
1589
+ return [];
1590
+ case "positional":
1591
+ return json.values.map(toDbValue);
1592
+ case "named":
1593
+ throw new Error("named SQL bindings are not supported yet");
1594
+ }
1595
+ }
1596
+ function toWireValue(value) {
1597
+ if (value === null || value === void 0) return { kind: "null" };
1598
+ if (typeof value === "string") return { kind: "text", text: value };
1599
+ if (typeof value === "boolean") return { kind: "boolean", boolean: value };
1600
+ if (typeof value === "number") {
1601
+ return Number.isInteger(value) ? { kind: "integer", integer: value } : { kind: "float", float: value };
1602
+ }
1603
+ if (value instanceof ArrayBuffer) {
1604
+ const bytes = new Uint8Array(value);
1605
+ let binary = "";
1606
+ for (const byte of bytes) binary += String.fromCharCode(byte);
1607
+ return { kind: "blob", blob: btoa(binary) };
1608
+ }
1609
+ if (ArrayBuffer.isView(value)) {
1610
+ const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1611
+ let binary = "";
1612
+ for (const byte of bytes) binary += String.fromCharCode(byte);
1613
+ return { kind: "blob", blob: btoa(binary) };
1614
+ }
1615
+ return { kind: "text", text: String(value) };
1616
+ }
1617
+ function objectToWireRow(record) {
1618
+ return {
1619
+ fields: Object.entries(record).map(([name, value]) => ({
1620
+ name,
1621
+ value: toWireValue(value)
1622
+ }))
1623
+ };
1624
+ }
1625
+ function valuesToWireRows(rows) {
1626
+ return rows.map((row) => row.map((value) => toWireValue(value)));
1627
+ }
1628
+ function createDbImports(bindings, getMemory, allocRef) {
1629
+ const decoder3 = new TextDecoder();
1630
+ function readStr2(ptr, len) {
1631
+ return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
1632
+ }
1633
+ function binding(ns) {
1634
+ return bindings[ns] ?? bindings["default"] ?? null;
1635
+ }
1636
+ async function statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len) {
1637
+ const database = binding(readStr2(ns_ptr, ns_len));
1638
+ if (!database) return null;
1639
+ const sql = readStr2(sql_ptr, sql_len);
1640
+ const bindingsJson = JSON.parse(readStr2(bindings_ptr, bindings_len));
1641
+ return database.prepare(sql).bind(...toPositionalBindings(bindingsJson));
1642
+ }
1643
+ const Suspending2 = WebAssembly.Suspending;
1644
+ if (typeof Suspending2 !== "function") {
1645
+ return {
1646
+ db_open: (_ns, _ns_len) => -1,
1647
+ db_run: (_a, _b, _c, _d, _e, _f, _g) => -1,
1648
+ db_get: (_a, _b, _c, _d, _e, _f, _g) => -1,
1649
+ db_all: (_a, _b, _c, _d, _e, _f, _g) => -1,
1650
+ db_values: (_a, _b, _c, _d, _e, _f, _g) => -1
1651
+ };
1652
+ }
1653
+ return {
1654
+ db_open: (ns_ptr, ns_len) => binding(readStr2(ns_ptr, ns_len)) ? 0 : -1,
1655
+ db_run: new Suspending2(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
1656
+ const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
1657
+ if (!stmt) return -1;
1658
+ const result = await stmt.run();
1659
+ return writeJsonOut(getMemory, allocRef, out_ptr, {
1660
+ last_insert_rowid: result.meta?.last_row_id ?? 0,
1661
+ changes: result.meta?.changes ?? 0
1662
+ });
1663
+ }),
1664
+ db_get: new Suspending2(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
1665
+ const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
1666
+ if (!stmt) return -1;
1667
+ const row = await stmt.first();
1668
+ if (!row) {
1669
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
1670
+ return 0;
1671
+ }
1672
+ return writeJsonOut(getMemory, allocRef, out_ptr, [objectToWireRow(row)]);
1673
+ }),
1674
+ db_all: new Suspending2(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
1675
+ const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
1676
+ if (!stmt) return -1;
1677
+ const result = await stmt.all();
1678
+ const rows = (result.results ?? []).map(objectToWireRow);
1679
+ if (rows.length === 0) {
1680
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
1681
+ return 0;
1682
+ }
1683
+ return writeJsonOut(getMemory, allocRef, out_ptr, rows);
1684
+ }),
1685
+ db_values: new Suspending2(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
1686
+ const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
1687
+ if (!stmt) return -1;
1688
+ const rows = await stmt.raw();
1689
+ if (rows.length === 0) {
1690
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
1691
+ return 0;
1692
+ }
1693
+ return writeJsonOut(getMemory, allocRef, out_ptr, valuesToWireRows(rows));
1694
+ })
1695
+ };
1696
+ }
1697
+
1698
+ // src/runtime/wasi.ts
1699
+ var ProcExit = class extends Error {
1700
+ constructor(code) {
1701
+ super(`proc_exit(${code})`);
1702
+ this.code = code;
1703
+ }
1704
+ };
1705
+ function createWasiImports({
1706
+ request,
1707
+ stdinData
1708
+ }) {
1709
+ const encoder3 = new TextEncoder();
1710
+ const url = new URL(request.url);
1711
+ const argStrings = [
1712
+ "wasm",
1713
+ "--pathname",
1714
+ url.pathname,
1715
+ "--method",
1716
+ request.method,
1717
+ "--search",
1718
+ url.search,
1719
+ "--url",
1720
+ url.href
1721
+ ];
1722
+ request.headers.forEach((value, name) => {
1723
+ if (value) argStrings.push("--header", `${name}:${value}`);
1724
+ });
1725
+ const encodedArgs = argStrings.map((a) => encoder3.encode(a + "\0"));
1726
+ const argBufSize = encodedArgs.reduce((s, a) => s + a.length, 0);
1727
+ let wasmMemory = null;
1728
+ const setMemory = (m2) => {
1729
+ wasmMemory = m2;
1730
+ };
1731
+ let stderrPartial = "";
1732
+ const stderrDecoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
1733
+ function processStderrChunk(chunk) {
1734
+ const text = stderrDecoder.decode(chunk, { stream: true });
1735
+ const lines = (stderrPartial + text).split("\n");
1736
+ stderrPartial = lines.pop() ?? "";
1737
+ for (const line of lines) {
1738
+ if (line.length > 0) {
1739
+ console.error("[ziex]", line);
1740
+ }
1741
+ }
1742
+ }
1743
+ let stdinOffset = 0;
1744
+ function v() {
1745
+ return new DataView(wasmMemory.buffer);
1746
+ }
1747
+ function m() {
1748
+ return new Uint8Array(wasmMemory.buffer);
1749
+ }
1750
+ const wasiImport = {
1751
+ args_sizes_get(argc_ptr, argv_buf_size_ptr) {
1752
+ v().setUint32(argc_ptr, encodedArgs.length, true);
1753
+ v().setUint32(argv_buf_size_ptr, argBufSize, true);
1754
+ return 0;
1755
+ },
1756
+ args_get(argv_ptr, argv_buf_ptr) {
1757
+ const dv = v();
1758
+ const mem = m();
1759
+ let offset = argv_buf_ptr;
1760
+ for (const arg of encodedArgs) {
1761
+ dv.setUint32(argv_ptr, offset, true);
1762
+ mem.set(arg, offset);
1763
+ argv_ptr += 4;
1764
+ offset += arg.length;
1765
+ }
1766
+ return 0;
1767
+ },
1768
+ environ_sizes_get(count_ptr, buf_size_ptr) {
1769
+ v().setUint32(count_ptr, 0, true);
1770
+ v().setUint32(buf_size_ptr, 0, true);
1771
+ return 0;
1772
+ },
1773
+ environ_get(_environ_ptr, _environ_buf_ptr) {
1774
+ return 0;
1775
+ },
1776
+ fd_write(fd, iovs_ptr, iovs_len, nwritten_ptr) {
1777
+ const dv = v();
1778
+ const mem = m();
1779
+ let written = 0;
1780
+ for (let i = 0; i < iovs_len; i++) {
1781
+ const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
1782
+ const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
1783
+ const chunk = mem.slice(buf_ptr, buf_ptr + buf_len);
1784
+ if (fd === 2) processStderrChunk(chunk);
1785
+ written += buf_len;
1786
+ }
1787
+ dv.setUint32(nwritten_ptr, written, true);
1788
+ return 0;
1789
+ },
1790
+ fd_read(fd, iovs_ptr, iovs_len, nread_ptr) {
1791
+ const dv = v();
1792
+ const mem = m();
1793
+ const stdin = stdinData ?? new Uint8Array(0);
1794
+ let totalRead = 0;
1795
+ for (let i = 0; i < iovs_len; i++) {
1796
+ const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
1797
+ const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
1798
+ if (fd === 0 && stdinOffset < stdin.length) {
1799
+ const toRead = Math.min(buf_len, stdin.length - stdinOffset);
1800
+ mem.set(stdin.subarray(stdinOffset, stdinOffset + toRead), buf_ptr);
1801
+ stdinOffset += toRead;
1802
+ totalRead += toRead;
1803
+ }
1804
+ }
1805
+ dv.setUint32(nread_ptr, totalRead, true);
1806
+ return 0;
1807
+ },
1808
+ fd_fdstat_get(_fd, fdstat_ptr) {
1809
+ const dv = v();
1810
+ dv.setUint8(fdstat_ptr, 2);
1811
+ dv.setUint8(fdstat_ptr + 1, 0);
1812
+ dv.setUint16(fdstat_ptr + 2, 0, true);
1813
+ dv.setUint32(fdstat_ptr + 4, 0, true);
1814
+ dv.setBigUint64(fdstat_ptr + 8, 0n, true);
1815
+ dv.setBigUint64(fdstat_ptr + 16, 0n, true);
1816
+ return 0;
1817
+ },
1818
+ fd_prestat_get(_fd, _bufptr) {
1819
+ return 8;
1820
+ },
1821
+ fd_prestat_dir_name(_fd, _path, _path_len) {
1822
+ return 8;
1823
+ },
1824
+ fd_close(_fd) {
1825
+ return 0;
1826
+ },
1827
+ fd_pread(_fd, _iovs, _iovs_len, _offset, nread_ptr) {
1828
+ v().setUint32(nread_ptr, 0, true);
1829
+ return 0;
1830
+ },
1831
+ fd_pwrite(_fd, _iovs, _iovs_len, _offset, nwritten_ptr) {
1832
+ v().setUint32(nwritten_ptr, 0, true);
1833
+ return 0;
1834
+ },
1835
+ fd_filestat_get(_fd, filestat_ptr) {
1836
+ const dv = v();
1837
+ dv.setBigUint64(filestat_ptr, 0n, true);
1838
+ dv.setBigUint64(filestat_ptr + 8, 0n, true);
1839
+ dv.setUint8(filestat_ptr + 16, 2);
1840
+ dv.setBigUint64(filestat_ptr + 24, 1n, true);
1841
+ dv.setBigUint64(filestat_ptr + 32, 0n, true);
1842
+ dv.setBigUint64(filestat_ptr + 40, 0n, true);
1843
+ dv.setBigUint64(filestat_ptr + 48, 0n, true);
1844
+ dv.setBigUint64(filestat_ptr + 56, 0n, true);
1845
+ return 0;
1846
+ },
1847
+ fd_filestat_set_size(_fd, _size) {
1848
+ return 76;
1849
+ },
1850
+ fd_filestat_set_times(_fd, _atim, _mtim, _fst_flags) {
1851
+ return 76;
1852
+ },
1853
+ fd_fdstat_set_flags(_fd, _flags) {
1854
+ return 0;
1855
+ },
1856
+ fd_fdstat_set_rights(_fd, _rights_base, _rights_inheriting) {
1857
+ return 0;
1858
+ },
1859
+ fd_sync(_fd) {
1860
+ return 0;
1861
+ },
1862
+ fd_datasync(_fd) {
1863
+ return 0;
1864
+ },
1865
+ fd_advise(_fd, _offset, _len, _advice) {
1866
+ return 0;
1867
+ },
1868
+ fd_allocate(_fd, _offset, _len) {
1869
+ return 76;
1870
+ },
1871
+ fd_tell(_fd, offset_ptr) {
1872
+ v().setBigUint64(offset_ptr, 0n, true);
1873
+ return 0;
1874
+ },
1875
+ fd_renumber(_from, _to) {
1876
+ return 0;
1877
+ },
1878
+ path_filestat_set_times(_fd, _flags, _path, _path_len, _atim, _mtim, _fst_flags) {
1879
+ return 76;
1880
+ },
1881
+ path_link(_old_fd, _old_flags, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
1882
+ return 76;
1883
+ },
1884
+ path_symlink(_old_path, _old_path_len, _fd, _new_path, _new_path_len) {
1885
+ return 76;
1886
+ },
1887
+ proc_raise(_sig) {
1888
+ return 0;
1889
+ },
1890
+ sock_recv(_fd, _ri_data, _ri_data_len, _ri_flags, ro_datalen_ptr, ro_flags_ptr) {
1891
+ v().setUint32(ro_datalen_ptr, 0, true);
1892
+ v().setUint32(ro_flags_ptr, 0, true);
1893
+ return 76;
1894
+ },
1895
+ sock_send(_fd, _si_data, _si_data_len, _si_flags, so_datalen_ptr) {
1896
+ v().setUint32(so_datalen_ptr, 0, true);
1897
+ return 76;
1898
+ },
1899
+ sock_shutdown(_fd, _how) {
1900
+ return 76;
1901
+ },
1902
+ fd_seek(_fd, _offset, _whence, newoffset_ptr) {
1903
+ v().setBigInt64(newoffset_ptr, 0n, true);
1904
+ return 0;
1905
+ },
1906
+ proc_exit(code) {
1907
+ throw new ProcExit(code);
1908
+ },
1909
+ sched_yield() {
1910
+ return 0;
1911
+ },
1912
+ clock_time_get(_id, _precision, time_ptr) {
1913
+ v().setBigUint64(time_ptr, BigInt(Date.now()) * 1000000n, true);
1914
+ return 0;
1915
+ },
1916
+ clock_res_get(_id, res_ptr) {
1917
+ v().setBigUint64(res_ptr, 1000000n, true);
1918
+ return 0;
1919
+ },
1920
+ random_get(buf_ptr, buf_len) {
1921
+ crypto.getRandomValues(new Uint8Array(wasmMemory.buffer, buf_ptr, buf_len));
1922
+ return 0;
1923
+ },
1924
+ path_open(_fd, _dirflags, _path, _path_len, _oflags, _rights_base, _rights_inheriting, _fdflags, opened_fd_ptr) {
1925
+ v().setInt32(opened_fd_ptr, -1, true);
1926
+ return 76;
1927
+ },
1928
+ path_create_directory(_fd, _path, _path_len) {
1929
+ return 76;
1930
+ },
1931
+ path_unlink_file(_fd, _path, _path_len) {
1932
+ return 76;
1933
+ },
1934
+ path_remove_directory(_fd, _path, _path_len) {
1935
+ return 76;
1936
+ },
1937
+ path_rename(_fd, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
1938
+ return 76;
1939
+ },
1940
+ path_filestat_get(_fd, _flags, _path, _path_len, filestat_ptr) {
1941
+ new Uint8Array(wasmMemory.buffer, filestat_ptr, 64).fill(0);
1942
+ return 76;
1943
+ },
1944
+ path_readlink(_fd, _path, _path_len, _buf, _buf_len, nread_ptr) {
1945
+ v().setUint32(nread_ptr, 0, true);
1946
+ return 76;
1947
+ },
1948
+ fd_readdir(_fd, _buf, _buf_len, _cookie, bufused_ptr) {
1949
+ v().setUint32(bufused_ptr, 0, true);
1950
+ return 76;
1951
+ },
1952
+ poll_oneoff(_in, _out, _nsubscriptions, nevents_ptr) {
1953
+ v().setUint32(nevents_ptr, 0, true);
1954
+ return 0;
1955
+ }
1956
+ };
1957
+ return { wasiImport, setMemory };
1958
+ }
1959
+ function mergeUint8Arrays(arrays) {
1960
+ const totalLen = arrays.reduce((sum, arr) => sum + arr.length, 0);
1961
+ const result = new Uint8Array(totalLen);
1962
+ let offset = 0;
1963
+ for (const arr of arrays) {
1964
+ result.set(arr, offset);
1965
+ offset += arr.length;
1966
+ }
1967
+ return result;
1968
+ }
1969
+
1970
+ // src/wasm/wasi.ts
1971
+ var decoder2 = new TextDecoder();
1972
+ var encoder2 = new TextEncoder();
1973
+ var ZxWasiBridge = class {
1974
+ #alloc;
1975
+ #memory;
1976
+ #cb;
1977
+ #intervals = /* @__PURE__ */ new Map();
1978
+ // Cached memory view - invalidated when the WASM buffer grows.
1979
+ #memView = null;
1980
+ #memBuf = null;
1981
+ constructor(exports) {
1982
+ this.#memory = exports.memory;
1983
+ this.#alloc = exports.__zx_alloc;
1984
+ this.#cb = exports.__zx_cb;
1985
+ }
1986
+ #view() {
1987
+ const buf = this.#memory.buffer;
1988
+ if (buf !== this.#memBuf) {
1989
+ this.#memBuf = buf;
1990
+ this.#memView = new Uint8Array(buf);
1991
+ }
1992
+ return this.#memView;
1993
+ }
1994
+ #readString(ptr, len) {
1995
+ const start = ptr >>> 0;
1996
+ const length = len >>> 0;
1997
+ if (length === 0) return "";
1998
+ const view = this.#view();
1999
+ if (start + length > view.byteLength) return "";
2000
+ return decoder2.decode(view.subarray(start, start + length));
2001
+ }
2002
+ #writeBytes(ptr, data) {
2003
+ const start = ptr >>> 0;
2004
+ const view = this.#view();
2005
+ if (start + data.length > view.byteLength) return;
2006
+ view.set(data, start);
2007
+ }
2008
+ #invoke(type, id, a = 0n, b = 0n, c = 0n) {
2009
+ this.#cb?.(type, id, a, b, c);
2010
+ }
2011
+ log(level, ptr, len) {
2012
+ const msg = decoder2.decode(this.#view().subarray(ptr, ptr + len));
2013
+ switch (level) {
2014
+ case 0:
2015
+ console.error(msg);
2016
+ break;
2017
+ case 1:
2018
+ console.warn(msg);
2019
+ break;
2020
+ case 3:
2021
+ console.debug(msg);
2022
+ break;
2023
+ default:
2024
+ console.log(msg);
2025
+ break;
2026
+ }
2027
+ }
2028
+ fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
2029
+ const url = this.#readString(urlPtr, urlLen);
2030
+ const method = methodLen > 0 ? this.#readString(methodPtr, methodLen) : "GET";
2031
+ const headersJson = headersLen > 0 ? this.#readString(headersPtr, headersLen) : "{}";
2032
+ const body = bodyLen > 0 ? this.#view().subarray(bodyPtr, bodyPtr + bodyLen) : void 0;
2033
+ let headers = {};
2034
+ try {
2035
+ headers = JSON.parse(headersJson);
2036
+ } catch {
2037
+ for (const line of headersJson.split("\n")) {
2038
+ const i = line.indexOf(":");
2039
+ if (i > 0) headers[line.slice(0, i)] = line.slice(i + 1);
2040
+ }
2041
+ }
2042
+ const controller = new AbortController();
2043
+ const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
2044
+ fetch(url, {
2045
+ method,
2046
+ headers: Object.keys(headers).length > 0 ? headers : void 0,
2047
+ body: method !== "GET" && method !== "HEAD" ? body : void 0,
2048
+ signal: controller.signal
2049
+ }).then(async (res) => {
2050
+ if (timeout) clearTimeout(timeout);
2051
+ const bytes = new Uint8Array(await res.arrayBuffer());
2052
+ this.#notifyFetchComplete(fetchId, res.status, bytes, false);
2053
+ }).catch((err) => {
2054
+ if (timeout) clearTimeout(timeout);
2055
+ const msg = err.name === "AbortError" ? "Request timeout" : err.message ?? "Fetch failed";
2056
+ this.#notifyFetchComplete(fetchId, 0, msg, true);
2057
+ });
2058
+ }
2059
+ #notifyFetchComplete(fetchId, status, body, isError) {
2060
+ const encoded = typeof body === "string" ? encoder2.encode(body) : body;
2061
+ const ptr = this.#alloc(encoded.length);
2062
+ this.#writeBytes(ptr, encoded);
2063
+ const type = isError ? CallbackType_FetchError : CallbackType_FetchSuccess;
2064
+ this.#invoke(type, fetchId, BigInt(status), BigInt(ptr), BigInt(encoded.length));
2065
+ }
2066
+ setTimeout(callbackId, delayMs) {
2067
+ setTimeout(() => this.#invoke(CallbackType_Timeout, callbackId), delayMs);
2068
+ }
2069
+ setInterval(callbackId, intervalMs) {
2070
+ const handle = setInterval(() => this.#invoke(CallbackType_Interval, callbackId), intervalMs);
2071
+ this.#intervals.set(callbackId, handle);
2072
+ }
2073
+ clearInterval(callbackId) {
2074
+ const handle = this.#intervals.get(callbackId);
2075
+ if (handle !== void 0) {
2076
+ clearInterval(handle);
2077
+ this.#intervals.delete(callbackId);
2078
+ }
2079
+ }
2080
+ /**
2081
+ * Create the WASI import object for WASM instantiation.
2082
+ *
2083
+ * Returns only the `__zx` namespace (log, fetch, timers).
2084
+ * Does NOT include jsz.importObject() - the server binary does not use jsz.
2085
+ */
2086
+ static createImportObject(bridgeRef) {
2087
+ return {
2088
+ __zx: {
2089
+ _log: (level, ptr, len) => {
2090
+ bridgeRef[0]?.log(level, ptr, len);
2091
+ },
2092
+ _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
2093
+ bridgeRef[0]?.fetchAsync(
2094
+ urlPtr,
2095
+ urlLen,
2096
+ methodPtr,
2097
+ methodLen,
2098
+ headersPtr,
2099
+ headersLen,
2100
+ bodyPtr,
2101
+ bodyLen,
2102
+ timeoutMs,
2103
+ fetchId
2104
+ );
2105
+ },
2106
+ _setTimeout: (callbackId, delayMs) => {
2107
+ bridgeRef[0]?.setTimeout(callbackId, delayMs);
2108
+ },
2109
+ _setInterval: (callbackId, intervalMs) => {
2110
+ bridgeRef[0]?.setInterval(callbackId, intervalMs);
2111
+ },
2112
+ _clearInterval: (callbackId) => {
2113
+ bridgeRef[0]?.clearInterval(callbackId);
2114
+ }
2115
+ }
2116
+ };
2117
+ }
2118
+ };
2119
+
2120
+ // src/runtime/index.ts
2121
+ function buildHttpImports(mem, http) {
2122
+ const decoder3 = new TextDecoder();
2123
+ return {
2124
+ commit: (status, meta_ptr, meta_len) => {
2125
+ http.status = status >>> 0;
2126
+ http.committed = true;
2127
+ http.headers = new Headers();
2128
+ http.streaming = false;
2129
+ if (meta_len > 0) {
2130
+ try {
2131
+ const raw = decoder3.decode(new Uint8Array(mem().buffer, meta_ptr >>> 0, meta_len >>> 0));
2132
+ const parsed = JSON.parse(raw);
2133
+ if (parsed.streaming === true) http.streaming = true;
2134
+ if (Array.isArray(parsed.headers)) {
2135
+ for (const [name, value] of parsed.headers) {
2136
+ http.headers.append(name, value);
2137
+ }
2138
+ }
2139
+ } catch {
2140
+ }
2141
+ }
2142
+ },
2143
+ write: (ptr, len) => {
2144
+ if (len <= 0) return;
2145
+ const chunk = new Uint8Array(mem().buffer, ptr >>> 0, len >>> 0).slice();
2146
+ if (http.streamWriter) void http.streamWriter.write(chunk);
2147
+ else http.bodyChunks.push(chunk);
2148
+ },
2149
+ end: () => {
2150
+ http.ended = true;
2151
+ if (http.streamWriter) {
2152
+ void http.streamWriter.close();
2153
+ http.streamWriter = null;
2154
+ }
2155
+ }
2156
+ };
2157
+ }
2158
+ function buildWsImports(Suspending2, mem, decoder3, ws) {
2159
+ const readStr2 = (ptr, len) => decoder3.decode(new Uint8Array(mem().buffer, ptr, len));
2160
+ return {
2161
+ ws_upgrade: () => {
2162
+ ws.upgraded = true;
2163
+ },
2164
+ ws_write: (ptr, len) => {
2165
+ const data = new Uint8Array(mem().buffer, ptr, len).slice();
2166
+ if (!ws.server) {
2167
+ ws.pendingWrites.push(data);
2168
+ } else {
2169
+ ws.server.send(data);
2170
+ }
2171
+ },
2172
+ ws_close: (code, reason_ptr, reason_len) => {
2173
+ ws.server?.close(code, decoder3.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
2174
+ },
2175
+ ws_recv: Suspending2 ? new Suspending2(async (buf_ptr, buf_max) => {
2176
+ if (ws._resolveFirstSuspend) {
2177
+ const fn = ws._resolveFirstSuspend;
2178
+ ws._resolveFirstSuspend = void 0;
2179
+ fn();
2180
+ }
2181
+ const deliver = (bytes) => {
2182
+ if (bytes === null) return -1;
2183
+ const n = Math.min(bytes.length, buf_max);
2184
+ new Uint8Array(mem().buffer, buf_ptr, n).set(bytes.subarray(0, n));
2185
+ return n;
2186
+ };
2187
+ if (ws.messageQueue.length > 0) return deliver(ws.messageQueue.shift());
2188
+ return new Promise((resolve2) => {
2189
+ ws.recvResolve = (bytes) => resolve2(deliver(bytes));
2190
+ });
2191
+ }) : (_buf_ptr, _buf_max) => -1,
2192
+ // Pub/sub - delegates to optional callbacks (real in DO, no-ops otherwise)
2193
+ ws_subscribe: (ptr, len) => {
2194
+ ws.subscribe?.(readStr2(ptr, len));
2195
+ },
2196
+ ws_unsubscribe: (ptr, len) => {
2197
+ ws.unsubscribe?.(readStr2(ptr, len));
2198
+ },
2199
+ ws_publish: (topic_ptr, topic_len, data_ptr, data_len) => {
2200
+ const topic = readStr2(topic_ptr, topic_len);
2201
+ const data = new Uint8Array(mem().buffer, data_ptr, data_len).slice();
2202
+ return ws.publish?.(topic, data) ?? 0;
2203
+ },
2204
+ ws_is_subscribed: (ptr, len) => ws.isSubscribed?.(readStr2(ptr, len)) ? 1 : 0
2205
+ };
2206
+ }
2207
+ function attachWebSocket(ws) {
2208
+ const WebSocketPairCtor = globalThis.WebSocketPair;
2209
+ const pair = new WebSocketPairCtor();
2210
+ const client = pair[0];
2211
+ const server = pair[1];
2212
+ ws.server = server;
2213
+ server.accept();
2214
+ for (const data of ws.pendingWrites) server.send(data);
2215
+ ws.pendingWrites = [];
2216
+ server.addEventListener("message", (event) => {
2217
+ const data = typeof event.data === "string" ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
2218
+ if (ws.recvResolve) {
2219
+ const res = ws.recvResolve;
2220
+ ws.recvResolve = null;
2221
+ res(data);
2222
+ } else {
2223
+ ws.messageQueue.push(data);
2224
+ }
2225
+ });
2226
+ server.addEventListener("close", () => {
2227
+ if (ws.recvResolve) {
2228
+ const res = ws.recvResolve;
2229
+ ws.recvResolve = null;
2230
+ res(null);
2352
2231
  }
2353
- };
2232
+ });
2233
+ return { client };
2354
2234
  }
2355
- function ensureDelegatedListener(eventTypeId) {
2356
- const state = delegationState;
2357
- if (!state || state.attached.has(eventTypeId)) return;
2358
- const domType = DELEGATED_EVENTS[eventTypeId];
2359
- if (!domType) return;
2360
- const passive = domType.startsWith("touch") || domType === "scroll";
2361
- const options = { passive };
2362
- const listener = makeDelegatedListener(state.bridge, eventTypeId);
2363
- state.root.addEventListener(domType, listener, options);
2364
- state.attached.set(eventTypeId, { listener, options });
2235
+ function buildSysImports(jspi2, Suspending2) {
2236
+ return {
2237
+ sleep_ms: jspi2 ? new Suspending2(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {
2238
+ }
2239
+ };
2365
2240
  }
2366
- function anyHandlerForType(eventTypeId) {
2367
- const bit = 1 << eventTypeId;
2368
- for (const mask of eventHandlersPresent.values()) {
2369
- if (mask & bit) return true;
2241
+ function executeWasm(instance, jspi2, Suspending2, wsState) {
2242
+ if (!jspi2) {
2243
+ try {
2244
+ instance.exports._start();
2245
+ } catch (e) {
2246
+ if (!(e instanceof ProcExit)) throw e;
2247
+ }
2248
+ return Promise.resolve();
2370
2249
  }
2371
- return false;
2250
+ const start = WebAssembly.promising(instance.exports._start);
2251
+ return start().catch((e) => {
2252
+ if (e instanceof Error && e.message.startsWith("proc_exit")) return;
2253
+ throw e;
2254
+ }).finally(() => {
2255
+ if (wsState.recvResolve) {
2256
+ const res = wsState.recvResolve;
2257
+ wsState.recvResolve = null;
2258
+ res(null);
2259
+ }
2260
+ });
2372
2261
  }
2373
- function maybeRemoveHighFreqListener(eventTypeId) {
2374
- if (!HIGH_FREQ_EVENT_IDS.has(eventTypeId)) return;
2375
- if (anyHandlerForType(eventTypeId)) return;
2376
- const state = delegationState;
2377
- if (!state) return;
2378
- const entry = state.attached.get(eventTypeId);
2379
- if (!entry) return;
2380
- const domType = DELEGATED_EVENTS[eventTypeId];
2381
- state.root.removeEventListener(domType, entry.listener, entry.options);
2382
- state.attached.delete(eventTypeId);
2262
+ async function run({
2263
+ request,
2264
+ env,
2265
+ ctx,
2266
+ module,
2267
+ kv: kvBindings,
2268
+ db: dbBindings,
2269
+ imports,
2270
+ wasi,
2271
+ sticky
2272
+ }) {
2273
+ if (sticky && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
2274
+ const id = sticky.idFromName(new URL(request.url).pathname);
2275
+ return sticky.get(id).fetch(request);
2276
+ }
2277
+ const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
2278
+ const httpState = {
2279
+ committed: false,
2280
+ ended: false,
2281
+ status: 200,
2282
+ streaming: false,
2283
+ headers: new Headers(),
2284
+ bodyChunks: [],
2285
+ streamWriter: null
2286
+ };
2287
+ const { wasiImport, setMemory } = createWasiImports({
2288
+ request,
2289
+ stdinData
2290
+ });
2291
+ let wasmMemory = null;
2292
+ const mem = () => wasmMemory;
2293
+ const bridgeRef = [null];
2294
+ const allocRef = [null];
2295
+ const Suspending2 = WebAssembly.Suspending;
2296
+ const jspi2 = typeof Suspending2 === "function";
2297
+ const wsState = {
2298
+ upgraded: false,
2299
+ server: null,
2300
+ pendingWrites: [],
2301
+ messageQueue: [],
2302
+ recvResolve: null
2303
+ };
2304
+ const importObject = {
2305
+ wasi_snapshot_preview1: { ...wasi?.wasiImport, ...wasiImport },
2306
+ __zx_sys: buildSysImports(jspi2, Suspending2),
2307
+ __zx_ws: buildWsImports(jspi2 ? Suspending2 : null, mem, new TextDecoder(), wsState),
2308
+ __zx_http: buildHttpImports(mem, httpState),
2309
+ __zx_net: createFetchImports(mem),
2310
+ ...imports ? imports(mem) : {},
2311
+ ...ZxWasiBridge.createImportObject(bridgeRef)
2312
+ };
2313
+ if (true) {
2314
+ importObject.__zx_kv = createKVImports(
2315
+ kvBindings ?? { default: { get: get4, put: put4, del: del4, list: list4 } },
2316
+ mem,
2317
+ allocRef
2318
+ );
2319
+ }
2320
+ if (true) {
2321
+ importObject.__zx_db = createDbImports(
2322
+ dbBindings ?? {},
2323
+ mem,
2324
+ allocRef
2325
+ );
2326
+ }
2327
+ const instance = new WebAssembly.Instance(module, importObject);
2328
+ wasmMemory = instance.exports.memory;
2329
+ setMemory(wasmMemory);
2330
+ bridgeRef[0] = new ZxWasiBridge(instance.exports);
2331
+ bindWasmAlloc(allocRef, instance.exports);
2332
+ const wasmPromise = executeWasm(instance, jspi2, Suspending2, wsState);
2333
+ if (wsState.upgraded) {
2334
+ const server = attachWebSocket(wsState);
2335
+ ctx?.waitUntil(wasmPromise);
2336
+ return new Response(null, { status: 101, webSocket: server.client });
2337
+ }
2338
+ if (httpState.committed && httpState.streaming) {
2339
+ const { readable, writable } = new TransformStream();
2340
+ httpState.streamWriter = writable.getWriter();
2341
+ for (const chunk of httpState.bodyChunks) void httpState.streamWriter.write(chunk);
2342
+ httpState.bodyChunks.length = 0;
2343
+ void wasmPromise.finally(() => {
2344
+ if (httpState.streamWriter) {
2345
+ void httpState.streamWriter.close();
2346
+ httpState.streamWriter = null;
2347
+ }
2348
+ });
2349
+ return new Response(readable, { status: httpState.status, headers: httpState.headers });
2350
+ }
2351
+ await wasmPromise;
2352
+ const status = httpState.status;
2353
+ const headers = httpState.headers;
2354
+ headers.delete("transfer-encoding");
2355
+ const nullBody = status === 101 || status === 204 || status === 205 || status === 304;
2356
+ if (nullBody) {
2357
+ headers.delete("content-length");
2358
+ return new Response(null, { status, headers });
2359
+ }
2360
+ const body = mergeUint8Arrays(httpState.bodyChunks);
2361
+ if (!headers.has("content-length")) headers.set("content-length", String(body.byteLength));
2362
+ return new Response(body.buffer, { status, headers });
2383
2363
  }
2384
2364
 
2385
- // src/platforms/cloudflare/do.ts
2386
- function createWebSocketDO(module, options) {
2387
- return class ZxWebSocketDO {
2365
+ // src/platforms/cloudflare/stateful.ts
2366
+ var textDecoder2 = new TextDecoder();
2367
+ function deliverToWasm(conn, data) {
2368
+ if (conn.recvResolve) {
2369
+ const res = conn.recvResolve;
2370
+ conn.recvResolve = null;
2371
+ res(data);
2372
+ return;
2373
+ }
2374
+ if (data) conn.messageQueue.push(data);
2375
+ }
2376
+ function attachWebSocketPair(ws) {
2377
+ const WebSocketPairCtor = globalThis.WebSocketPair;
2378
+ const pair = new WebSocketPairCtor();
2379
+ const [client, server] = Object.values(pair);
2380
+ ws.server = server;
2381
+ server.accept();
2382
+ const pending = ws.pendingWrites;
2383
+ ws.pendingWrites = [];
2384
+ queueMicrotask(() => {
2385
+ for (const data of pending) {
2386
+ try {
2387
+ server.send(textDecoder2.decode(data));
2388
+ } catch {
2389
+ }
2390
+ }
2391
+ });
2392
+ server.addEventListener("message", (event) => {
2393
+ const data = typeof event.data === "string" ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
2394
+ deliverToWasm(ws, data);
2395
+ });
2396
+ server.addEventListener("close", () => {
2397
+ deliverToWasm(ws, null);
2398
+ });
2399
+ return client;
2400
+ }
2401
+ function createStatefulFetch(module, options) {
2402
+ return class StatefulFetch {
2388
2403
  constructor(state, env) {
2389
- /** All active connections in this room, keyed by their server-side WebSocket. */
2390
2404
  this.connections = /* @__PURE__ */ new Map();
2391
- this.doState = state;
2405
+ this.state = state;
2392
2406
  this.env = env;
2393
2407
  }
2394
2408
  async fetch(request) {
2395
- const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
2409
+ const isUpgrade = request.headers.get("upgrade")?.toLowerCase() === "websocket";
2410
+ const stdinData = !isUpgrade && request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
2396
2411
  const { wasiImport, setMemory } = createWasiImports({ request, stdinData });
2397
2412
  let wasmMemory = null;
2398
2413
  const mem = () => wasmMemory;
2399
2414
  const bridgeRef = [null];
2400
2415
  const bridgeImports = ZxBridge.createImportObject(bridgeRef);
2401
- const Suspending = WebAssembly.Suspending;
2402
- const jspi = typeof Suspending === "function";
2416
+ const Suspending2 = WebAssembly.Suspending;
2417
+ const jspi2 = typeof Suspending2 === "function";
2418
+ if (!jspi2) {
2419
+ return new Response("Sticky WebSocket fetch requires WebAssembly JSPI", { status: 501 });
2420
+ }
2403
2421
  const decoder3 = new TextDecoder();
2404
- let _resolveFirstSuspend;
2405
- const firstSuspendPromise = new Promise((resolve) => {
2406
- _resolveFirstSuspend = resolve;
2407
- });
2408
- let wasmExited = false;
2409
2422
  const connState = {
2410
2423
  upgraded: false,
2411
2424
  server: null,
2412
2425
  pendingWrites: [],
2413
2426
  messageQueue: [],
2414
2427
  recvResolve: null,
2415
- _resolveFirstSuspend,
2416
2428
  topics: /* @__PURE__ */ new Set(),
2417
2429
  subscribe: (topic) => connState.topics.add(topic),
2418
2430
  unsubscribe: (topic) => connState.topics.delete(topic),
2419
2431
  publish: (topic, data) => {
2420
2432
  let count = 0;
2421
- for (const [ws, conn] of this.connections) {
2433
+ const text = textDecoder2.decode(data);
2434
+ for (const [sock, conn] of this.connections) {
2422
2435
  if (conn.topics.has(topic)) {
2423
2436
  try {
2424
- ws.send(data);
2437
+ sock.send(text);
2425
2438
  count++;
2426
2439
  } catch {
2427
2440
  }
@@ -2436,10 +2449,20 @@ function createWebSocketDO(module, options) {
2436
2449
  isSubscribed: (topic) => connState.topics.has(topic)
2437
2450
  };
2438
2451
  const sysImports = {
2439
- sleep_ms: jspi ? new Suspending(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {
2440
- }
2452
+ sleep_ms: new Suspending2(
2453
+ async (ms) => new Promise((r) => setTimeout(r, ms))
2454
+ )
2455
+ };
2456
+ const wsImports = buildWsImports(Suspending2, mem, decoder3, connState);
2457
+ const httpState = {
2458
+ committed: false,
2459
+ ended: false,
2460
+ status: 200,
2461
+ streaming: false,
2462
+ headers: new Headers(),
2463
+ bodyChunks: [],
2464
+ streamWriter: null
2441
2465
  };
2442
- const wsImports = buildWsImports(jspi ? Suspending : null, mem, decoder3, connState);
2443
2466
  const kvBindings = options?.kv?.(this.env);
2444
2467
  const dbBindings = options?.db?.(this.env);
2445
2468
  const allocRef = [null];
@@ -2447,23 +2470,20 @@ function createWebSocketDO(module, options) {
2447
2470
  wasi_snapshot_preview1: wasiImport,
2448
2471
  __zx_sys: sysImports,
2449
2472
  __zx_ws: wsImports,
2473
+ __zx_http: buildHttpImports(mem, httpState),
2450
2474
  __zx_net: createFetchImports(mem),
2451
2475
  ...options?.imports ? options.imports(mem) : {},
2452
2476
  ...bridgeImports
2453
2477
  };
2454
2478
  if (true) {
2455
2479
  importObject.__zx_kv = createKVImports(
2456
- kvBindings ?? { default: createMemoryKV() },
2480
+ kvBindings ?? { default: { get: get4, put: put4, del: del4, list: list4 } },
2457
2481
  mem,
2458
2482
  allocRef
2459
2483
  );
2460
2484
  }
2461
2485
  if (true) {
2462
- importObject.__zx_db = createDbImports(
2463
- dbBindings ?? {},
2464
- mem,
2465
- allocRef
2466
- );
2486
+ importObject.__zx_db = createDbImports(dbBindings ?? {}, mem, allocRef);
2467
2487
  }
2468
2488
  const instance = new WebAssembly.Instance(module, importObject);
2469
2489
  wasmMemory = instance.exports.memory;
@@ -2472,31 +2492,142 @@ function createWebSocketDO(module, options) {
2472
2492
  bindWasmAlloc(allocRef, instance.exports);
2473
2493
  const start = WebAssembly.promising(instance.exports._start);
2474
2494
  const wasmPromise = start().catch((e) => {
2475
- wasmExited = true;
2476
2495
  if (e instanceof Error && e.message.startsWith("proc_exit")) return;
2477
- console.error("[ZxWebSocketDO] WASM error:", e);
2496
+ console.error("[StatefulFetch] WASM error:", e);
2478
2497
  }).finally(() => {
2479
2498
  if (connState.server) this.connections.delete(connState.server);
2480
- if (connState.recvResolve) {
2481
- const res = connState.recvResolve;
2482
- connState.recvResolve = null;
2483
- res(null);
2484
- }
2499
+ deliverToWasm(connState, null);
2485
2500
  });
2486
- await Promise.race([firstSuspendPromise, wasmPromise]);
2487
- if (!connState.upgraded || wasmExited) {
2501
+ if (!connState.upgraded) {
2502
+ await wasmPromise;
2488
2503
  return new Response("WebSocket upgrade expected", { status: 426 });
2489
2504
  }
2490
- const { client } = attachWebSocket(connState);
2505
+ const client = attachWebSocketPair(connState);
2491
2506
  this.connections.set(connState.server, connState);
2492
- this.doState.waitUntil(wasmPromise);
2507
+ this.state.waitUntil(wasmPromise);
2493
2508
  return new Response(null, { status: 101, webSocket: client });
2494
2509
  }
2495
2510
  };
2496
2511
  }
2512
+
2513
+ // src/app.ts
2514
+ async function resolveModule(input) {
2515
+ if (typeof input === "string") {
2516
+ if (input.startsWith("http://") || input.startsWith("https://")) {
2517
+ return WebAssembly.compileStreaming(fetch(input));
2518
+ }
2519
+ const url = input.startsWith("/") ? `file://${input}` : input;
2520
+ return WebAssembly.compile(await fetch(url).then((r) => r.arrayBuffer()));
2521
+ }
2522
+ if (input instanceof URL) {
2523
+ return WebAssembly.compileStreaming(fetch(input));
2524
+ }
2525
+ if (input instanceof Response) {
2526
+ return WebAssembly.compileStreaming(input);
2527
+ }
2528
+ if (input instanceof ArrayBuffer) {
2529
+ return WebAssembly.compile(input);
2530
+ }
2531
+ if (ArrayBuffer.isView(input)) {
2532
+ return WebAssembly.compile(input.buffer);
2533
+ }
2534
+ return input;
2535
+ }
2536
+ var Ziex = class {
2537
+ constructor(options) {
2538
+ this.resolved = null;
2539
+ /**
2540
+ * Fetch handler called by the runtime on every request.
2541
+ *
2542
+ * Arrow function so `this` is always the class instance, even when the
2543
+ * runtime extracts `fetch` from the exported object (e.g. Bun).
2544
+ */
2545
+ this.fetch = async (request, env, ctx) => {
2546
+ const module = await this.getModule();
2547
+ const { wasi, imports, sticky } = this.options;
2548
+ return run({
2549
+ request,
2550
+ env,
2551
+ ctx,
2552
+ module,
2553
+ wasi,
2554
+ imports,
2555
+ kv: this.resolveKV(env),
2556
+ db: this.resolveDB(env),
2557
+ sticky: sticky !== void 0 ? env[sticky] : void 0
2558
+ });
2559
+ };
2560
+ this.options = options;
2561
+ }
2562
+ async getModule() {
2563
+ if (!this.resolved) this.resolved = await resolveModule(this.options.module);
2564
+ return this.resolved;
2565
+ }
2566
+ /**
2567
+ * Enable sticky upgrade forwarding and return host config for platform adapters
2568
+ * (e.g. Cloudflare {@linkcode stateful}).
2569
+ *
2570
+ * Requires `options.module` to already be a compiled `WebAssembly.Module`.
2571
+ */
2572
+ stickyHost(binding) {
2573
+ this.options.sticky = binding;
2574
+ const mod = this.options.module;
2575
+ if (mod instanceof ArrayBuffer || ArrayBuffer.isView(mod) || mod instanceof Response || mod instanceof URL || typeof mod === "string") {
2576
+ throw new Error(
2577
+ 'sticky handlers require a compiled WebAssembly.Module (e.g. `import module from "./app.wasm"` under wrangler)'
2578
+ );
2579
+ }
2580
+ return {
2581
+ module: mod,
2582
+ imports: this.options.imports,
2583
+ kv: (env) => this.resolveKV(env),
2584
+ db: (env) => this.resolveDB(env)
2585
+ };
2586
+ }
2587
+ resolveKV(env) {
2588
+ const { kv } = this.options;
2589
+ if (kv === void 0) return void 0;
2590
+ if (typeof kv === "object" && kv !== null) {
2591
+ const result = {};
2592
+ for (const [name, key] of Object.entries(kv)) {
2593
+ result[name] = env[key];
2594
+ }
2595
+ return result;
2596
+ }
2597
+ return { default: env[kv] };
2598
+ }
2599
+ resolveDB(env) {
2600
+ const { db } = this.options;
2601
+ if (db === void 0) return void 0;
2602
+ if (typeof db === "object" && db !== null) {
2603
+ const result = {};
2604
+ for (const [name, key] of Object.entries(db)) {
2605
+ result[name] = env[key];
2606
+ }
2607
+ return result;
2608
+ }
2609
+ return { default: env[db] };
2610
+ }
2611
+ };
2612
+
2613
+ // src/platforms/cloudflare/app.ts
2614
+ function stateful(app, options) {
2615
+ const host = app.stickyHost(options.binding);
2616
+ return createStatefulFetch(host.module, {
2617
+ kv: (env) => host.kv(env) ?? { default: { get: get4, put: put4, del: del4, list: list4 } },
2618
+ db: (env) => host.db(env) ?? {},
2619
+ imports: host.imports
2620
+ });
2621
+ }
2497
2622
  export {
2498
2623
  Ziex,
2499
- createWebSocketDO,
2500
- kv_exports as kv,
2501
- runtime_exports as worker
2624
+ createBrowserKVBindings,
2625
+ createKVImports,
2626
+ del4 as del,
2627
+ get4 as get,
2628
+ hasJspi,
2629
+ list4 as list,
2630
+ put4 as put,
2631
+ resolveModule,
2632
+ stateful
2502
2633
  };