ziex 0.1.0-dev.785 → 0.1.0-dev.787

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.
@@ -9,26 +9,879 @@ var __export = (target, all) => {
9
9
  });
10
10
  };
11
11
 
12
+ // ../../vendor/jsz/js/src/zigjs.ts
13
+ var NAN_PREFIX = 2146959360;
14
+ var predefined = {
15
+ nan: 0,
16
+ null: 1,
17
+ true: 2,
18
+ false: 3,
19
+ undefined: 4,
20
+ globalThis: 5,
21
+ runtime: 6
22
+ };
23
+ var PREDEFINED_ID_MAX = 6;
24
+ var encoder = new TextEncoder;
25
+ var decoder = new TextDecoder("utf-8");
26
+
27
+ class ZigJS {
28
+ memory;
29
+ values = [NaN, null, true, false, undefined, globalThis, this];
30
+ idPool = [];
31
+ importObject() {
32
+ return {
33
+ "zig-js": {
34
+ valueGet: this.valueGet.bind(this),
35
+ valueSet: this.valueSet.bind(this),
36
+ valueDeinit: this.valueDeinit.bind(this),
37
+ valueObjectCreate: this.valueObjectCreate.bind(this),
38
+ valueStringCreate: this.valueStringCreate.bind(this),
39
+ valueStringLen: this.valueStringLen.bind(this),
40
+ valueStringCopy: this.valueStringCopy.bind(this),
41
+ valueNew: this.valueNew.bind(this),
42
+ funcApply: this.funcApply.bind(this)
43
+ }
44
+ };
45
+ }
46
+ valueGet(out, id, ptr, len) {
47
+ const val = this.loadValue(id);
48
+ const str = this.loadString(ptr, len);
49
+ const result = Reflect.get(val, str);
50
+ this.storeValue(out, result);
51
+ }
52
+ valueSet(id, ptr, len, refAddr) {
53
+ const obj = this.loadValue(id);
54
+ const str = this.loadString(ptr, len);
55
+ const val = this.loadRef(refAddr);
56
+ Reflect.set(obj, str, val);
57
+ }
58
+ valueDeinit(id) {
59
+ if (id > PREDEFINED_ID_MAX) {
60
+ this.values[id] = null;
61
+ this.idPool.push(id);
62
+ }
63
+ }
64
+ valueObjectCreate(out) {
65
+ this.storeValue(out, new Object);
66
+ }
67
+ valueStringCreate(out, ptr, len) {
68
+ const str = this.loadString(ptr, len);
69
+ this.storeValue(out, str);
70
+ }
71
+ valueStringLen(id) {
72
+ const val = this.loadValue(id);
73
+ const buf = encoder.encode(val);
74
+ return buf.byteLength;
75
+ }
76
+ valueStringCopy(id, ptr, max) {
77
+ if (this.memory == null)
78
+ return;
79
+ const val = this.loadValue(id);
80
+ const bytes = encoder.encode(val);
81
+ if (bytes.byteLength > max)
82
+ return;
83
+ new Uint8Array(this.memory.buffer, ptr, bytes.length).set(bytes);
84
+ }
85
+ valueNew(out, id, argsAddr, argsLen) {
86
+ const fn = this.loadValue(id);
87
+ const args = [];
88
+ for (let i = 0;i < argsLen; i++) {
89
+ args.push(this.loadRef(argsAddr + i * 8));
90
+ }
91
+ const result = Reflect.construct(fn, args);
92
+ this.storeValue(out, result);
93
+ }
94
+ funcApply(out, id, thisRefAddr, argsAddr, argsLen) {
95
+ const fn = this.loadValue(id);
96
+ const thisVal = this.loadRef(thisRefAddr);
97
+ const args = [];
98
+ for (let i = 0;i < argsLen; i++) {
99
+ args.push(this.loadRef(argsAddr + i * 8));
100
+ }
101
+ const result = Reflect.apply(fn, thisVal, args);
102
+ this.storeValue(out, result);
103
+ }
104
+ loadValue(id) {
105
+ return this.values[id];
106
+ }
107
+ deleteValue(id) {
108
+ const val = this.values[id];
109
+ this.valueDeinit(id);
110
+ return val;
111
+ }
112
+ loadRef(refAddr) {
113
+ if (this.memory == null)
114
+ return;
115
+ const view = new DataView(this.memory.buffer);
116
+ const floatVal = view.getFloat64(refAddr, true);
117
+ if (!isNaN(floatVal))
118
+ return floatVal;
119
+ const id = this.loadRefId(refAddr);
120
+ return this.values[id];
121
+ }
122
+ loadRefId(refAddr) {
123
+ if (this.memory == null)
124
+ return 0;
125
+ return new DataView(this.memory.buffer).getUint32(refAddr, true);
126
+ }
127
+ storeValue(out, val) {
128
+ if (this.memory == null)
129
+ return;
130
+ const view = new DataView(this.memory.buffer);
131
+ if (typeof val === "number") {
132
+ if (isNaN(val)) {
133
+ view.setUint32(out, predefined.nan, true);
134
+ view.setUint32(out + 4, NAN_PREFIX, true);
135
+ } else {
136
+ view.setFloat64(out, val, true);
137
+ }
138
+ return;
139
+ }
140
+ if (val === null) {
141
+ view.setUint32(out, predefined.null, true);
142
+ view.setUint32(out + 4, NAN_PREFIX, true);
143
+ return;
144
+ }
145
+ if (val === undefined) {
146
+ view.setUint32(out, predefined.undefined, true);
147
+ view.setUint32(out + 4, NAN_PREFIX, true);
148
+ return;
149
+ }
150
+ let id = this.idPool.pop();
151
+ if (id === undefined) {
152
+ id = this.values.length;
153
+ }
154
+ this.values[id] = val;
155
+ let typeId = 0;
156
+ switch (typeof val) {
157
+ case "object":
158
+ typeId = 1;
159
+ break;
160
+ case "string":
161
+ typeId = 2;
162
+ break;
163
+ case "symbol":
164
+ typeId = 3;
165
+ break;
166
+ case "function":
167
+ typeId = 4;
168
+ break;
169
+ }
170
+ view.setUint32(out, Number(id), true);
171
+ view.setUint32(out + 4, NAN_PREFIX | typeId, true);
172
+ }
173
+ loadString(ptr, len) {
174
+ if (this.memory == null)
175
+ return "";
176
+ const arr = new Uint8ClampedArray(this.memory.buffer, ptr, Number(len));
177
+ const data = arr.slice();
178
+ return decoder.decode(data);
179
+ }
180
+ }
181
+ // src/wasm/index.ts
182
+ var CallbackType = {
183
+ Event: 0,
184
+ FetchSuccess: 1,
185
+ FetchError: 2,
186
+ Timeout: 3,
187
+ Interval: 4,
188
+ WebSocketOpen: 5,
189
+ WebSocketMessage: 6,
190
+ WebSocketError: 7,
191
+ WebSocketClose: 8
192
+ };
193
+ var jsz = new ZigJS;
194
+ var tempRefBuffer = new ArrayBuffer(8);
195
+ var tempRefView = new DataView(tempRefBuffer);
196
+ function storeValueGetRef(val) {
197
+ const originalMemory = jsz.memory;
198
+ jsz.memory = { buffer: tempRefBuffer };
199
+ jsz.storeValue(0, val);
200
+ jsz.memory = originalMemory;
201
+ return tempRefView.getBigUint64(0, true);
202
+ }
203
+ var textDecoder = new TextDecoder;
204
+ var textEncoder = new TextEncoder;
205
+ var memoryView = null;
206
+ var memoryBuffer = null;
207
+ function getMemoryView() {
208
+ const buf = jsz.memory.buffer;
209
+ if (buf !== memoryBuffer) {
210
+ memoryBuffer = buf;
211
+ memoryView = new Uint8Array(buf);
212
+ }
213
+ return memoryView;
214
+ }
215
+ var stringCache = new Map;
216
+ function stringCacheKey(ptr, len) {
217
+ return ptr * 65536 + len;
218
+ }
219
+ function readString(ptr, len) {
220
+ const key = stringCacheKey(ptr, len);
221
+ const cached = stringCache.get(key);
222
+ if (cached !== undefined)
223
+ return cached;
224
+ const str = textDecoder.decode(getMemoryView().subarray(ptr, ptr + len));
225
+ stringCache.set(key, str);
226
+ return str;
227
+ }
228
+ function writeBytes(ptr, data) {
229
+ getMemoryView().set(data, ptr);
230
+ }
231
+
232
+ class ZxBridge {
233
+ #intervals = new Map;
234
+ #websockets = new Map;
235
+ #alloc;
236
+ #handler;
237
+ #fetchCompleteHandler;
238
+ #wsOnOpenHandler;
239
+ #wsOnMessageHandler;
240
+ #wsOnErrorHandler;
241
+ #wsOnCloseHandler;
242
+ constructor(exports) {
243
+ this.#alloc = exports.__zx_alloc;
244
+ this.#handler = exports.__zx_cb;
245
+ this.#fetchCompleteHandler = exports.__zx_fetch_complete;
246
+ this.#wsOnOpenHandler = exports.__zx_ws_onopen;
247
+ this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
248
+ this.#wsOnErrorHandler = exports.__zx_ws_onerror;
249
+ this.#wsOnCloseHandler = exports.__zx_ws_onclose;
250
+ this.#eventbridge = exports.__zx_eventbridge;
251
+ }
252
+ #invoke(type, id, data) {
253
+ const handler = this.#handler;
254
+ if (!handler) {
255
+ console.warn("__zx_cb not exported from WASM");
256
+ return;
257
+ }
258
+ const dataRef = storeValueGetRef(data);
259
+ handler(type, id, dataRef);
260
+ }
261
+ fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
262
+ const url = readString(urlPtr, urlLen);
263
+ const method = methodLen > 0 ? readString(methodPtr, methodLen) : "GET";
264
+ const headersJson = headersLen > 0 ? readString(headersPtr, headersLen) : "{}";
265
+ const body = bodyLen > 0 ? readString(bodyPtr, bodyLen) : undefined;
266
+ let headers = {};
267
+ try {
268
+ headers = JSON.parse(headersJson);
269
+ } catch {
270
+ for (const line of headersJson.split(`
271
+ `)) {
272
+ const colonIdx = line.indexOf(":");
273
+ if (colonIdx > 0) {
274
+ headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
275
+ }
276
+ }
277
+ }
278
+ const controller = new AbortController;
279
+ const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
280
+ const fetchOptions = {
281
+ method,
282
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
283
+ body: method !== "GET" && method !== "HEAD" ? body : undefined,
284
+ signal: controller.signal
285
+ };
286
+ fetch(url, fetchOptions).then(async (response) => {
287
+ if (timeout)
288
+ clearTimeout(timeout);
289
+ const text = await response.text();
290
+ this.#notifyFetchComplete(fetchId, response.status, text, false);
291
+ }).catch((error) => {
292
+ if (timeout)
293
+ clearTimeout(timeout);
294
+ const isAbort = error.name === "AbortError";
295
+ const errorMsg = isAbort ? "Request timeout" : error.message ?? "Fetch failed";
296
+ this.#notifyFetchComplete(fetchId, 0, errorMsg, true);
297
+ });
298
+ }
299
+ #notifyFetchComplete(fetchId, statusCode, body, isError) {
300
+ const handler = this.#fetchCompleteHandler;
301
+ const encoded = textEncoder.encode(body);
302
+ const ptr = this.#alloc(encoded.length);
303
+ writeBytes(ptr, encoded);
304
+ handler(fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
305
+ }
306
+ submitFormActionAsync(form, statesJson, fetchId) {
307
+ const formData = new FormData(form);
308
+ formData.append("__zx_states", statesJson);
309
+ fetch(window.location.href, {
310
+ method: "POST",
311
+ headers: { "X-ZX-Action": "1" },
312
+ body: formData
313
+ }).then(async (response) => {
314
+ const text = await response.text();
315
+ this.#notifyFetchComplete(fetchId, response.status, text, false);
316
+ }).catch((error) => {
317
+ const msg = error instanceof Error ? error.message : "Fetch failed";
318
+ this.#notifyFetchComplete(fetchId, 0, msg, true);
319
+ });
320
+ }
321
+ setTimeout(callbackId, delayMs) {
322
+ setTimeout(() => {
323
+ this.#invoke(CallbackType.Timeout, callbackId, null);
324
+ }, delayMs);
325
+ }
326
+ setInterval(callbackId, intervalMs) {
327
+ const handle = setInterval(() => {
328
+ this.#invoke(CallbackType.Interval, callbackId, null);
329
+ }, intervalMs);
330
+ this.#intervals.set(callbackId, handle);
331
+ }
332
+ clearInterval(callbackId) {
333
+ const handle = this.#intervals.get(callbackId);
334
+ if (handle !== undefined) {
335
+ clearInterval(handle);
336
+ this.#intervals.delete(callbackId);
337
+ }
338
+ }
339
+ wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) {
340
+ const url = readString(urlPtr, urlLen);
341
+ const protocolsStr = protocolsLen > 0 ? readString(protocolsPtr, protocolsLen) : "";
342
+ const protocols = protocolsStr ? protocolsStr.split(",").map((p) => p.trim()).filter(Boolean) : undefined;
343
+ try {
344
+ const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
345
+ ws.binaryType = "arraybuffer";
346
+ ws.onopen = () => {
347
+ const handler = this.#wsOnOpenHandler;
348
+ if (!handler)
349
+ return;
350
+ const protocol = ws.protocol || "";
351
+ const { ptr, len } = this.#writeStringToWasm(protocol);
352
+ handler(wsId, ptr, len);
353
+ };
354
+ ws.onmessage = (event) => {
355
+ const handler = this.#wsOnMessageHandler;
356
+ if (!handler)
357
+ return;
358
+ const isBinary = event.data instanceof ArrayBuffer;
359
+ let data;
360
+ if (isBinary) {
361
+ data = new Uint8Array(event.data);
362
+ } else {
363
+ data = textEncoder.encode(event.data);
364
+ }
365
+ const { ptr, len } = this.#writeBytesToWasm(data);
366
+ handler(wsId, ptr, len, isBinary ? 1 : 0);
367
+ };
368
+ ws.onerror = (event) => {
369
+ const handler = this.#wsOnErrorHandler;
370
+ if (!handler)
371
+ return;
372
+ const msg = "WebSocket error";
373
+ const { ptr, len } = this.#writeStringToWasm(msg);
374
+ handler(wsId, ptr, len);
375
+ };
376
+ ws.onclose = (event) => {
377
+ const handler = this.#wsOnCloseHandler;
378
+ if (!handler)
379
+ return;
380
+ const reason = event.reason || "";
381
+ const { ptr, len } = this.#writeStringToWasm(reason);
382
+ handler(wsId, event.code, ptr, len, event.wasClean ? 1 : 0);
383
+ this.#websockets.delete(wsId);
384
+ };
385
+ this.#websockets.set(wsId, ws);
386
+ } catch (error) {
387
+ const handler = this.#wsOnErrorHandler;
388
+ if (handler) {
389
+ const msg = error instanceof Error ? error.message : "WebSocket connection failed";
390
+ const { ptr, len } = this.#writeStringToWasm(msg);
391
+ handler(wsId, ptr, len);
392
+ }
393
+ }
394
+ }
395
+ wsSend(wsId, dataPtr, dataLen, isBinary) {
396
+ const ws = this.#websockets.get(wsId);
397
+ if (!ws || ws.readyState !== WebSocket.OPEN)
398
+ return;
399
+ const memory = getMemoryView();
400
+ if (isBinary) {
401
+ ws.send(memory.slice(dataPtr, dataPtr + dataLen));
402
+ } else {
403
+ ws.send(textDecoder.decode(memory.subarray(dataPtr, dataPtr + dataLen)));
404
+ }
405
+ }
406
+ wsClose(wsId, code, reasonPtr, reasonLen) {
407
+ const ws = this.#websockets.get(wsId);
408
+ if (!ws)
409
+ return;
410
+ const reason = reasonLen > 0 ? readString(reasonPtr, reasonLen) : undefined;
411
+ try {
412
+ if (reason) {
413
+ ws.close(code, reason);
414
+ } else {
415
+ ws.close(code);
416
+ }
417
+ } catch {
418
+ ws.close();
419
+ }
420
+ }
421
+ #writeStringToWasm(str) {
422
+ const encoded = textEncoder.encode(str);
423
+ return this.#writeBytesToWasm(encoded);
424
+ }
425
+ #writeBytesToWasm(data) {
426
+ const ptr = this.#alloc(data.length);
427
+ writeBytes(ptr, data);
428
+ return { ptr, len: data.length };
429
+ }
430
+ #eventbridge;
431
+ eventbridge(velementId, eventTypeId, event) {
432
+ if (!this.#eventbridge)
433
+ return;
434
+ const eventRef = storeValueGetRef(event);
435
+ this.#eventbridge(velementId, eventTypeId, eventRef);
436
+ }
437
+ static createImportObject(bridgeRef) {
438
+ return {
439
+ ...jsz.importObject(),
440
+ __zx: {
441
+ _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
442
+ bridgeRef.current?.fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId);
443
+ },
444
+ _setTimeout: (callbackId, delayMs) => {
445
+ bridgeRef.current?.setTimeout(callbackId, delayMs);
446
+ },
447
+ _setInterval: (callbackId, intervalMs) => {
448
+ bridgeRef.current?.setInterval(callbackId, intervalMs);
449
+ },
450
+ _clearInterval: (callbackId) => {
451
+ bridgeRef.current?.clearInterval(callbackId);
452
+ },
453
+ _wsConnect: (wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) => {
454
+ bridgeRef.current?.wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen);
455
+ },
456
+ _wsSend: (wsId, dataPtr, dataLen, isBinary) => {
457
+ bridgeRef.current?.wsSend(wsId, dataPtr, dataLen, isBinary);
458
+ },
459
+ _wsClose: (wsId, code, reasonPtr, reasonLen) => {
460
+ bridgeRef.current?.wsClose(wsId, code, reasonPtr, reasonLen);
461
+ },
462
+ _ce: (id, vnodeId) => {
463
+ const tagName = TAG_NAMES[id];
464
+ const el = id >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
465
+ el.__zx_ref = Number(vnodeId);
466
+ domNodes.set(vnodeId, el);
467
+ return storeValueGetRef(el);
468
+ },
469
+ _ct: (ptr, len, vnodeId) => {
470
+ const text = readString(ptr, len);
471
+ const node = document.createTextNode(text);
472
+ node.__zx_ref = Number(vnodeId);
473
+ domNodes.set(vnodeId, node);
474
+ return storeValueGetRef(node);
475
+ },
476
+ _sa: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
477
+ domNodes.get(vnodeId)?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
478
+ },
479
+ _ra: (vnodeId, namePtr, nameLen) => {
480
+ domNodes.get(vnodeId)?.removeAttribute(readString(namePtr, nameLen));
481
+ },
482
+ _snv: (vnodeId, ptr, len) => {
483
+ const node = domNodes.get(vnodeId);
484
+ if (node)
485
+ node.nodeValue = readString(ptr, len);
486
+ },
487
+ _ac: (parentId, childId) => {
488
+ const parent = domNodes.get(parentId);
489
+ const child = domNodes.get(childId);
490
+ if (parent && child)
491
+ parent.appendChild(child);
492
+ },
493
+ _ib: (parentId, childId, refId) => {
494
+ const parent = domNodes.get(parentId);
495
+ const child = domNodes.get(childId);
496
+ const ref = domNodes.get(refId) ?? null;
497
+ if (parent && child)
498
+ parent.insertBefore(child, ref);
499
+ },
500
+ _rc: (parentId, childId) => {
501
+ const parent = domNodes.get(parentId);
502
+ const child = domNodes.get(childId);
503
+ if (parent && child) {
504
+ parent.removeChild(child);
505
+ cleanupDomNodes(child);
506
+ }
507
+ },
508
+ _rpc: (parentId, newId, oldId) => {
509
+ const parent = domNodes.get(parentId);
510
+ const newChild = domNodes.get(newId);
511
+ const oldChild = domNodes.get(oldId);
512
+ if (parent && newChild && oldChild) {
513
+ parent.replaceChild(newChild, oldChild);
514
+ cleanupDomNodes(oldChild);
515
+ }
516
+ },
517
+ _getLocationHref: (bufPtr, bufLen) => {
518
+ const bytes = textEncoder.encode(window.location.href);
519
+ const len = Math.min(bytes.length, bufLen);
520
+ writeBytes(bufPtr, bytes.subarray(0, len));
521
+ return len;
522
+ },
523
+ _getFormData: (vnodeId, bufPtr, bufLen) => {
524
+ const form = domNodes.get(vnodeId);
525
+ if (!form || !(form instanceof HTMLFormElement))
526
+ return 0;
527
+ const formData = new FormData(form);
528
+ const urlEncoded = new URLSearchParams(formData).toString();
529
+ const bytes = textEncoder.encode(urlEncoded);
530
+ const len = Math.min(bytes.length, bufLen);
531
+ writeBytes(bufPtr, bytes.subarray(0, len));
532
+ return len;
533
+ },
534
+ _submitFormAction: (vnodeId) => {
535
+ const form = domNodes.get(vnodeId);
536
+ if (!form || !(form instanceof HTMLFormElement))
537
+ return;
538
+ const formData = new FormData(form);
539
+ fetch(window.location.href, {
540
+ method: "POST",
541
+ headers: { "X-ZX-Action": "1" },
542
+ body: formData
543
+ }).catch(() => {});
544
+ },
545
+ _submitFormActionAsync: (vnodeId, statesPtr, statesLen, fetchId) => {
546
+ const form = domNodes.get(vnodeId);
547
+ if (!form || !(form instanceof HTMLFormElement))
548
+ return;
549
+ const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
550
+ bridgeRef.current?.submitFormActionAsync(form, statesJson, fetchId);
551
+ }
552
+ }
553
+ };
554
+ }
555
+ }
556
+ var domNodes = new Map;
557
+ function cleanupDomNodes(node) {
558
+ const ref = node.__zx_ref;
559
+ if (ref !== undefined)
560
+ domNodes.delete(BigInt(ref));
561
+ const children = node.childNodes;
562
+ for (let i = 0;i < children.length; i++)
563
+ cleanupDomNodes(children[i]);
564
+ }
565
+ var SVG_TAG_START_INDEX = 140;
566
+ var TAG_NAMES = [
567
+ "aside",
568
+ "fragment",
569
+ "iframe",
570
+ "slot",
571
+ "img",
572
+ "html",
573
+ "base",
574
+ "head",
575
+ "link",
576
+ "meta",
577
+ "script",
578
+ "style",
579
+ "title",
580
+ "address",
581
+ "article",
582
+ "body",
583
+ "h1",
584
+ "h6",
585
+ "footer",
586
+ "header",
587
+ "h2",
588
+ "h3",
589
+ "h4",
590
+ "h5",
591
+ "hgroup",
592
+ "nav",
593
+ "section",
594
+ "dd",
595
+ "dl",
596
+ "dt",
597
+ "div",
598
+ "figcaption",
599
+ "figure",
600
+ "hr",
601
+ "li",
602
+ "ol",
603
+ "ul",
604
+ "menu",
605
+ "main",
606
+ "p",
607
+ "picture",
608
+ "pre",
609
+ "a",
610
+ "abbr",
611
+ "b",
612
+ "bdi",
613
+ "bdo",
614
+ "br",
615
+ "cite",
616
+ "code",
617
+ "data",
618
+ "time",
619
+ "dfn",
620
+ "em",
621
+ "i",
622
+ "kbd",
623
+ "mark",
624
+ "q",
625
+ "blockquote",
626
+ "rp",
627
+ "ruby",
628
+ "rt",
629
+ "rtc",
630
+ "rb",
631
+ "s",
632
+ "del",
633
+ "ins",
634
+ "samp",
635
+ "small",
636
+ "span",
637
+ "strong",
638
+ "sub",
639
+ "sup",
640
+ "u",
641
+ "var",
642
+ "wbr",
643
+ "area",
644
+ "map",
645
+ "audio",
646
+ "source",
647
+ "track",
648
+ "video",
649
+ "embed",
650
+ "object",
651
+ "param",
652
+ "canvas",
653
+ "noscript",
654
+ "caption",
655
+ "table",
656
+ "col",
657
+ "colgroup",
658
+ "tbody",
659
+ "tr",
660
+ "thead",
661
+ "tfoot",
662
+ "td",
663
+ "th",
664
+ "button",
665
+ "datalist",
666
+ "option",
667
+ "fieldset",
668
+ "label",
669
+ "form",
670
+ "input",
671
+ "keygen",
672
+ "legend",
673
+ "meter",
674
+ "optgroup",
675
+ "select",
676
+ "output",
677
+ "progress",
678
+ "textarea",
679
+ "details",
680
+ "dialog",
681
+ "menuitem",
682
+ "summary",
683
+ "content",
684
+ "element",
685
+ "shadow",
686
+ "template",
687
+ "acronym",
688
+ "applet",
689
+ "basefont",
690
+ "font",
691
+ "big",
692
+ "blink",
693
+ "center",
694
+ "command",
695
+ "dir",
696
+ "frame",
697
+ "frameset",
698
+ "isindex",
699
+ "listing",
700
+ "marquee",
701
+ "noembed",
702
+ "plaintext",
703
+ "spacer",
704
+ "strike",
705
+ "tt",
706
+ "xmp",
707
+ "animate",
708
+ "animateMotion",
709
+ "animateTransform",
710
+ "circle",
711
+ "clipPath",
712
+ "defs",
713
+ "desc",
714
+ "ellipse",
715
+ "feBlend",
716
+ "feColorMatrix",
717
+ "feComponentTransfer",
718
+ "feComposite",
719
+ "feConvolveMatrix",
720
+ "feDiffuseLighting",
721
+ "feDisplacementMap",
722
+ "feDistantLight",
723
+ "feDropShadow",
724
+ "feFlood",
725
+ "feFuncA",
726
+ "feFuncB",
727
+ "feFuncG",
728
+ "feFuncR",
729
+ "feGaussianBlur",
730
+ "feImage",
731
+ "feMerge",
732
+ "feMergeNode",
733
+ "feMorphology",
734
+ "feOffset",
735
+ "fePointLight",
736
+ "feSpecularLighting",
737
+ "feSpotLight",
738
+ "feTile",
739
+ "feTurbulence",
740
+ "filter",
741
+ "foreignObject",
742
+ "g",
743
+ "image",
744
+ "line",
745
+ "linearGradient",
746
+ "marker",
747
+ "mask",
748
+ "metadata",
749
+ "mpath",
750
+ "path",
751
+ "pattern",
752
+ "polygon",
753
+ "polyline",
754
+ "radialGradient",
755
+ "rect",
756
+ "set",
757
+ "stop",
758
+ "svg",
759
+ "switch",
760
+ "symbol",
761
+ "text",
762
+ "textPath",
763
+ "tspan",
764
+ "use",
765
+ "view"
766
+ ];
767
+ var DELEGATED_EVENTS = [
768
+ "click",
769
+ "dblclick",
770
+ "input",
771
+ "change",
772
+ "submit",
773
+ "focus",
774
+ "blur",
775
+ "keydown",
776
+ "keyup",
777
+ "keypress",
778
+ "mouseenter",
779
+ "mouseleave",
780
+ "mousedown",
781
+ "mouseup",
782
+ "mousemove",
783
+ "touchstart",
784
+ "touchend",
785
+ "touchmove",
786
+ "scroll"
787
+ ];
788
+ var EVENT_TYPE_MAP = {
789
+ click: 0,
790
+ dblclick: 1,
791
+ input: 2,
792
+ change: 3,
793
+ submit: 4,
794
+ focus: 5,
795
+ blur: 6,
796
+ keydown: 7,
797
+ keyup: 8,
798
+ keypress: 9,
799
+ mouseenter: 10,
800
+ mouseleave: 11,
801
+ mousedown: 12,
802
+ mouseup: 13,
803
+ mousemove: 14,
804
+ touchstart: 15,
805
+ touchend: 16,
806
+ touchmove: 17,
807
+ scroll: 18
808
+ };
809
+ function initEventDelegation(bridge, rootSelector = "body") {
810
+ const root = document.querySelector(rootSelector);
811
+ if (!root)
812
+ return;
813
+ for (const eventType of DELEGATED_EVENTS) {
814
+ root.addEventListener(eventType, (event) => {
815
+ let target = event.target;
816
+ while (target && target !== document.body) {
817
+ const zxRef = target.__zx_ref;
818
+ if (zxRef !== undefined) {
819
+ bridge.eventbridge(BigInt(zxRef), EVENT_TYPE_MAP[eventType] ?? 0, event);
820
+ if (event.cancelBubble)
821
+ break;
822
+ }
823
+ target = target.parentElement;
824
+ }
825
+ }, { passive: eventType.startsWith("touch") || eventType === "scroll" });
826
+ }
827
+ }
828
+ var DEFAULT_URL = "/assets/main.wasm";
829
+ async function init(options = {}) {
830
+ const url = options.url ?? DEFAULT_URL;
831
+ const bridgeRef = { current: null };
832
+ const importObject = Object.assign({}, ZxBridge.createImportObject(bridgeRef), options.importObject);
833
+ const source = await WebAssembly.instantiateStreaming(fetch(url), importObject);
834
+ const { instance } = source;
835
+ jsz.memory = instance.exports.memory;
836
+ const bridge = new ZxBridge(instance.exports);
837
+ bridgeRef.current = bridge;
838
+ initEventDelegation(bridge, options.eventDelegationRoot ?? "body");
839
+ const main = instance.exports.mainClient;
840
+ if (typeof main === "function")
841
+ main();
842
+ return { source, bridge };
843
+ }
844
+
12
845
  // src/cloudflare/worker.ts
13
846
  var exports_worker = {};
14
847
  __export(exports_worker, {
15
848
  run: () => run,
16
849
  respond: () => respond,
17
- prepare: () => prepare
850
+ prepare: () => prepare,
851
+ createWebSocketDO: () => createWebSocketDO
18
852
  });
19
853
 
20
854
  // src/cloudflare/kv.ts
21
855
  var exports_kv = {};
22
856
  __export(exports_kv, {
857
+ createMemoryKV: () => createMemoryKV,
23
858
  createKVImports: () => createKVImports
24
859
  });
860
+ function createMemoryKV() {
861
+ const store = new Map;
862
+ return {
863
+ async get(key) {
864
+ return store.get(key) ?? null;
865
+ },
866
+ async put(key, value) {
867
+ store.set(key, value);
868
+ },
869
+ async delete(key) {
870
+ store.delete(key);
871
+ },
872
+ async list(options) {
873
+ const keys = [...store.keys()].filter((k) => !options?.prefix || k.startsWith(options.prefix)).map((name) => ({ name }));
874
+ return { keys };
875
+ }
876
+ };
877
+ }
25
878
  function createKVImports(bindings, getMemory) {
26
- const encoder = new TextEncoder;
27
- const decoder = new TextDecoder;
879
+ const encoder2 = new TextEncoder;
880
+ const decoder2 = new TextDecoder;
28
881
  function readStr(ptr, len) {
29
- return decoder.decode(new Uint8Array(getMemory().buffer, ptr, len));
882
+ return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
30
883
  }
31
- function writeBytes(buf_ptr, buf_max, data) {
884
+ function writeBytes2(buf_ptr, buf_max, data) {
32
885
  if (data.length > buf_max)
33
886
  return -2;
34
887
  new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
@@ -38,6 +891,14 @@ function createKVImports(bindings, getMemory) {
38
891
  return bindings[ns] ?? bindings["default"] ?? null;
39
892
  }
40
893
  const Suspending = WebAssembly.Suspending;
894
+ if (typeof Suspending !== "function") {
895
+ return {
896
+ kv_get: (_ns, _nsLen, _key, _keyLen, _buf, _max) => -1,
897
+ kv_put: (_ns, _nsLen, _key, _keyLen, _val, _valLen) => 0,
898
+ kv_delete: (_ns, _nsLen, _key, _keyLen) => 0,
899
+ kv_list: (_ns, _nsLen, _pfx, _pfxLen, buf_ptr, buf_max) => writeBytes2(buf_ptr, buf_max, encoder2.encode("[]"))
900
+ };
901
+ }
41
902
  return {
42
903
  kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, buf_ptr, buf_max) => {
43
904
  const b = binding(readStr(ns_ptr, ns_len));
@@ -46,7 +907,7 @@ function createKVImports(bindings, getMemory) {
46
907
  const value = await b.get(readStr(key_ptr, key_len));
47
908
  if (value === null)
48
909
  return -1;
49
- return writeBytes(buf_ptr, buf_max, encoder.encode(value));
910
+ return writeBytes2(buf_ptr, buf_max, encoder2.encode(value));
50
911
  }),
51
912
  kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len) => {
52
913
  const b = binding(readStr(ns_ptr, ns_len));
@@ -65,10 +926,10 @@ function createKVImports(bindings, getMemory) {
65
926
  kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, buf_ptr, buf_max) => {
66
927
  const b = binding(readStr(ns_ptr, ns_len));
67
928
  if (!b)
68
- return writeBytes(buf_ptr, buf_max, encoder.encode("[]"));
929
+ return writeBytes2(buf_ptr, buf_max, encoder2.encode("[]"));
69
930
  const prefix = readStr(prefix_ptr, prefix_len);
70
931
  const result = await b.list(prefix.length > 0 ? { prefix } : undefined);
71
- return writeBytes(buf_ptr, buf_max, encoder.encode(JSON.stringify(result.keys.map((k) => k.name))));
932
+ return writeBytes2(buf_ptr, buf_max, encoder2.encode(JSON.stringify(result.keys.map((k) => k.name))));
72
933
  })
73
934
  };
74
935
  }
@@ -83,10 +944,11 @@ class ProcExit extends Error {
83
944
  }
84
945
  function createWasiImports({
85
946
  request,
86
- stdinData
947
+ stdinData,
948
+ onStdout
87
949
  }) {
88
- const encoder = new TextEncoder;
89
- const decoder = new TextDecoder;
950
+ const encoder2 = new TextEncoder;
951
+ const decoder2 = new TextDecoder;
90
952
  const url = new URL(request.url);
91
953
  const argStrings = [
92
954
  "wasm",
@@ -97,12 +959,11 @@ function createWasiImports({
97
959
  "--search",
98
960
  url.search
99
961
  ];
100
- for (const name of FORWARDED_HEADERS) {
101
- const value = request.headers.get(name);
962
+ request.headers.forEach((value, name) => {
102
963
  if (value)
103
964
  argStrings.push("--header", `${name}:${value}`);
104
- }
105
- const encodedArgs = argStrings.map((a) => encoder.encode(a + "\x00"));
965
+ });
966
+ const encodedArgs = argStrings.map((a) => encoder2.encode(a + "\x00"));
106
967
  const argBufSize = encodedArgs.reduce((s, a) => s + a.length, 0);
107
968
  let wasmMemory = null;
108
969
  const setMemory = (m2) => {
@@ -151,9 +1012,12 @@ function createWasiImports({
151
1012
  const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
152
1013
  const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
153
1014
  const chunk = mem.slice(buf_ptr, buf_ptr + buf_len);
154
- if (fd === 1)
155
- stdoutChunks.push(chunk);
156
- else if (fd === 2)
1015
+ if (fd === 1) {
1016
+ if (onStdout)
1017
+ onStdout(chunk);
1018
+ else
1019
+ stdoutChunks.push(chunk);
1020
+ } else if (fd === 2)
157
1021
  stderrChunks.push(chunk);
158
1022
  written += buf_len;
159
1023
  }
@@ -262,65 +1126,284 @@ function createWasiImports({
262
1126
  fd_readdir(_fd, _buf, _buf_len, _cookie, bufused_ptr) {
263
1127
  v().setUint32(bufused_ptr, 0, true);
264
1128
  return 76;
1129
+ },
1130
+ poll_oneoff(_in, _out, _nsubscriptions, nevents_ptr) {
1131
+ v().setUint32(nevents_ptr, 0, true);
1132
+ return 0;
265
1133
  }
266
1134
  };
267
1135
  function collectOutput() {
268
1136
  return {
269
1137
  stdout: mergeUint8Arrays(stdoutChunks),
270
- stderrText: decoder.decode(mergeUint8Arrays(stderrChunks))
1138
+ stderrText: decoder2.decode(mergeUint8Arrays(stderrChunks))
271
1139
  };
272
1140
  }
273
1141
  return { wasiImport, setMemory, collectOutput };
274
1142
  }
275
- function buildResponse({
276
- stdout,
277
- stderrText
278
- }) {
279
- const meta = parseEdgeMeta(stderrText);
280
- return new Response(stdout.buffer, {
281
- status: meta.status,
282
- headers: meta.headers
283
- });
284
- }
285
1143
  async function run({
286
1144
  request,
287
1145
  env,
288
1146
  ctx,
289
1147
  module,
290
1148
  kv: kvBindings,
291
- imports
1149
+ imports,
1150
+ wasi,
1151
+ websocket: doNamespace
292
1152
  }) {
1153
+ if (doNamespace && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
1154
+ const id = doNamespace.idFromName(new URL(request.url).pathname);
1155
+ return doNamespace.get(id).fetch(request);
1156
+ }
293
1157
  const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : undefined;
294
- const { wasiImport, setMemory, collectOutput } = createWasiImports({ request, stdinData });
1158
+ const { readable, writable } = new TransformStream;
1159
+ const stdoutWriter = writable.getWriter();
1160
+ const { wasiImport, setMemory, collectOutput } = createWasiImports({
1161
+ request,
1162
+ stdinData,
1163
+ onStdout: (chunk) => {
1164
+ stdoutWriter.write(chunk);
1165
+ }
1166
+ });
295
1167
  let wasmMemory = null;
296
1168
  const mem = () => wasmMemory;
1169
+ const bridgeRef = { current: null };
1170
+ const bridgeImports = ZxBridge.createImportObject(bridgeRef);
1171
+ const decoder2 = new TextDecoder;
1172
+ const Suspending = WebAssembly.Suspending;
1173
+ const jspi = typeof Suspending === "function";
1174
+ const sysImports = {
1175
+ sleep_ms: jspi ? new Suspending(async (ms) => new Promise((resolve) => setTimeout(resolve, ms))) : (_ms) => {}
1176
+ };
1177
+ const wsState = {
1178
+ upgraded: false,
1179
+ server: null,
1180
+ pendingWrites: [],
1181
+ messageQueue: [],
1182
+ recvResolve: null
1183
+ };
1184
+ const wsImports = buildWsImports(jspi ? Suspending : null, mem, decoder2, wsState);
297
1185
  const instance = new WebAssembly.Instance(module, {
298
- wasi_snapshot_preview1: wasiImport,
299
- ...kvBindings ? { __zx_kv: createKVImports(kvBindings, mem) } : {},
300
- ...imports ? imports(mem) : {}
1186
+ wasi_snapshot_preview1: { ...wasi?.wasiImport, ...wasiImport },
1187
+ __zx_sys: sysImports,
1188
+ __zx_ws: wsImports,
1189
+ __zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
1190
+ ...imports ? imports(mem) : {},
1191
+ ...bridgeImports
301
1192
  });
302
1193
  wasmMemory = instance.exports.memory;
303
1194
  setMemory(wasmMemory);
304
- const start = WebAssembly.promising(instance.exports._start);
305
- try {
306
- await start();
307
- } catch (e) {
308
- if (!(e instanceof Error) || !e.message.startsWith("proc_exit"))
1195
+ const bridge = new ZxBridge(instance.exports);
1196
+ bridgeRef.current = bridge;
1197
+ let wasmPromise;
1198
+ if (jspi) {
1199
+ const start = WebAssembly.promising(instance.exports._start);
1200
+ wasmPromise = start().catch((e) => {
1201
+ if (e instanceof Error && e.message.startsWith("proc_exit"))
1202
+ return;
309
1203
  throw e;
1204
+ }).finally(() => {
1205
+ stdoutWriter.close();
1206
+ if (wsState.recvResolve) {
1207
+ const res = wsState.recvResolve;
1208
+ wsState.recvResolve = null;
1209
+ res(null);
1210
+ }
1211
+ });
1212
+ } else {
1213
+ try {
1214
+ instance.exports._start();
1215
+ } catch (e) {
1216
+ if (!(e instanceof ProcExit))
1217
+ throw e;
1218
+ }
1219
+ stdoutWriter.close();
1220
+ wasmPromise = Promise.resolve();
310
1221
  }
311
- return buildResponse(collectOutput());
1222
+ if (wsState.upgraded) {
1223
+ const server = attachWebSocket(wsState);
1224
+ ctx?.waitUntil(wasmPromise);
1225
+ return new Response(null, { status: 101, webSocket: server.client });
1226
+ }
1227
+ const { stderrText } = collectOutput();
1228
+ const meta = parseEdgeMeta(stderrText);
1229
+ return new Response(readable, {
1230
+ status: meta.status,
1231
+ headers: meta.headers
1232
+ });
1233
+ }
1234
+ function buildWsImports(Suspending, mem, decoder2, ws) {
1235
+ const readStr = (ptr, len) => decoder2.decode(new Uint8Array(mem().buffer, ptr, len));
1236
+ return {
1237
+ ws_upgrade: () => {
1238
+ ws.upgraded = true;
1239
+ },
1240
+ ws_write: (ptr, len) => {
1241
+ const data = new Uint8Array(mem().buffer, ptr, len).slice();
1242
+ if (!ws.server) {
1243
+ ws.pendingWrites.push(data);
1244
+ } else {
1245
+ ws.server.send(data);
1246
+ }
1247
+ },
1248
+ ws_close: (code, reason_ptr, reason_len) => {
1249
+ ws.server?.close(code, decoder2.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
1250
+ },
1251
+ ws_recv: Suspending ? new Suspending(async (buf_ptr, buf_max) => {
1252
+ if (ws._resolveFirstSuspend) {
1253
+ const fn = ws._resolveFirstSuspend;
1254
+ ws._resolveFirstSuspend = undefined;
1255
+ fn();
1256
+ }
1257
+ const deliver = (bytes) => {
1258
+ if (bytes === null)
1259
+ return -1;
1260
+ const n = Math.min(bytes.length, buf_max);
1261
+ new Uint8Array(mem().buffer, buf_ptr, n).set(bytes.subarray(0, n));
1262
+ return n;
1263
+ };
1264
+ if (ws.messageQueue.length > 0)
1265
+ return deliver(ws.messageQueue.shift());
1266
+ return new Promise((resolve) => {
1267
+ ws.recvResolve = (bytes) => resolve(deliver(bytes));
1268
+ });
1269
+ }) : (_buf_ptr, _buf_max) => -1,
1270
+ ws_subscribe: (ptr, len) => {
1271
+ ws.subscribe?.(readStr(ptr, len));
1272
+ },
1273
+ ws_unsubscribe: (ptr, len) => {
1274
+ ws.unsubscribe?.(readStr(ptr, len));
1275
+ },
1276
+ ws_publish: (topic_ptr, topic_len, data_ptr, data_len) => {
1277
+ const topic = readStr(topic_ptr, topic_len);
1278
+ const data = new Uint8Array(mem().buffer, data_ptr, data_len).slice();
1279
+ return ws.publish?.(topic, data) ?? 0;
1280
+ },
1281
+ ws_is_subscribed: (ptr, len) => ws.isSubscribed?.(readStr(ptr, len)) ? 1 : 0
1282
+ };
1283
+ }
1284
+ function attachWebSocket(ws) {
1285
+ const WebSocketPairCtor = globalThis.WebSocketPair;
1286
+ const pair = new WebSocketPairCtor;
1287
+ const client = pair[0];
1288
+ const server = pair[1];
1289
+ ws.server = server;
1290
+ server.accept();
1291
+ for (const data of ws.pendingWrites)
1292
+ server.send(data);
1293
+ ws.pendingWrites = [];
1294
+ server.addEventListener("message", (event) => {
1295
+ const data = typeof event.data === "string" ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
1296
+ if (ws.recvResolve) {
1297
+ const res = ws.recvResolve;
1298
+ ws.recvResolve = null;
1299
+ res(data);
1300
+ } else {
1301
+ ws.messageQueue.push(data);
1302
+ }
1303
+ });
1304
+ server.addEventListener("close", () => {
1305
+ if (ws.recvResolve) {
1306
+ const res = ws.recvResolve;
1307
+ ws.recvResolve = null;
1308
+ res(null);
1309
+ }
1310
+ });
1311
+ return { client };
1312
+ }
1313
+ function createWebSocketDO(module, options) {
1314
+ return class ZxWebSocketDO {
1315
+ doState;
1316
+ env;
1317
+ connections = new Map;
1318
+ constructor(state, env) {
1319
+ this.doState = state;
1320
+ this.env = env;
1321
+ }
1322
+ async fetch(request) {
1323
+ const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : undefined;
1324
+ const { wasiImport, setMemory } = createWasiImports({ request, stdinData });
1325
+ let wasmMemory = null;
1326
+ const mem = () => wasmMemory;
1327
+ const bridgeRef = { current: null };
1328
+ const bridgeImports = ZxBridge.createImportObject(bridgeRef);
1329
+ const Suspending = WebAssembly.Suspending;
1330
+ const jspi = typeof Suspending === "function";
1331
+ const decoder2 = new TextDecoder;
1332
+ let _resolveFirstSuspend;
1333
+ const firstSuspendPromise = new Promise((resolve) => {
1334
+ _resolveFirstSuspend = resolve;
1335
+ });
1336
+ let wasmExited = false;
1337
+ const connState = {
1338
+ upgraded: false,
1339
+ server: null,
1340
+ pendingWrites: [],
1341
+ messageQueue: [],
1342
+ recvResolve: null,
1343
+ _resolveFirstSuspend,
1344
+ topics: new Set,
1345
+ subscribe: (topic) => connState.topics.add(topic),
1346
+ unsubscribe: (topic) => connState.topics.delete(topic),
1347
+ publish: (topic, data) => {
1348
+ let count = 0;
1349
+ for (const [ws, conn] of this.connections) {
1350
+ if (conn.topics.has(topic)) {
1351
+ try {
1352
+ ws.send(data);
1353
+ count++;
1354
+ } catch {}
1355
+ }
1356
+ }
1357
+ if (!connState.server && connState.topics.has(topic)) {
1358
+ connState.pendingWrites.push(data.slice());
1359
+ count++;
1360
+ }
1361
+ return count;
1362
+ },
1363
+ isSubscribed: (topic) => connState.topics.has(topic)
1364
+ };
1365
+ const sysImports = {
1366
+ sleep_ms: jspi ? new Suspending(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {}
1367
+ };
1368
+ const wsImports = buildWsImports(jspi ? Suspending : null, mem, decoder2, connState);
1369
+ const kvBindings = options?.kv?.(this.env);
1370
+ const instance = new WebAssembly.Instance(module, {
1371
+ wasi_snapshot_preview1: wasiImport,
1372
+ __zx_sys: sysImports,
1373
+ __zx_ws: wsImports,
1374
+ __zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
1375
+ ...options?.imports ? options.imports(mem) : {},
1376
+ ...bridgeImports
1377
+ });
1378
+ wasmMemory = instance.exports.memory;
1379
+ setMemory(wasmMemory);
1380
+ bridgeRef.current = new ZxBridge(instance.exports);
1381
+ const start = WebAssembly.promising(instance.exports._start);
1382
+ const wasmPromise = start().catch((e) => {
1383
+ wasmExited = true;
1384
+ if (e instanceof Error && e.message.startsWith("proc_exit"))
1385
+ return;
1386
+ console.error("[ZxWebSocketDO] WASM error:", e);
1387
+ }).finally(() => {
1388
+ if (connState.server)
1389
+ this.connections.delete(connState.server);
1390
+ if (connState.recvResolve) {
1391
+ const res = connState.recvResolve;
1392
+ connState.recvResolve = null;
1393
+ res(null);
1394
+ }
1395
+ });
1396
+ await Promise.race([firstSuspendPromise, wasmPromise]);
1397
+ if (!connState.upgraded || wasmExited) {
1398
+ return new Response("WebSocket upgrade expected", { status: 426 });
1399
+ }
1400
+ const { client } = attachWebSocket(connState);
1401
+ this.connections.set(connState.server, connState);
1402
+ this.doState.waitUntil(wasmPromise);
1403
+ return new Response(null, { status: 101, webSocket: client });
1404
+ }
1405
+ };
312
1406
  }
313
- var FORWARDED_HEADERS = [
314
- "content-type",
315
- "accept",
316
- "authorization",
317
- "cookie",
318
- "user-agent",
319
- "referer",
320
- "x-forwarded-for",
321
- "x-forwarded-proto",
322
- "x-real-ip"
323
- ];
324
1407
  function parseEdgeMeta(stderrText) {
325
1408
  const meta = { status: 200, headers: new Headers };
326
1409
  const metaPrefix = "__EDGE_META__:";
@@ -376,12 +1459,9 @@ function prepare({
376
1459
  "--search",
377
1460
  url.search
378
1461
  ];
379
- for (const name of FORWARDED_HEADERS) {
380
- const value = request.headers.get(name);
381
- if (value) {
382
- args.push("--header", `${name}:${value}`);
383
- }
384
- }
1462
+ request.headers.forEach((value, name) => {
1463
+ args.push("--header", `${name}:${value}`);
1464
+ });
385
1465
  const stdin = request.body ?? undefined;
386
1466
  return { args, stdout, stderr, stdin };
387
1467
  }
@@ -405,7 +1485,29 @@ async function respond({
405
1485
  headers: meta.headers
406
1486
  });
407
1487
  }
1488
+ // src/cloudflare/app.ts
1489
+ class Ziex {
1490
+ options;
1491
+ constructor(options) {
1492
+ this.options = options;
1493
+ }
1494
+ fetch(request, env, ctx) {
1495
+ const { module, wasi, imports, kv, websocket } = this.options;
1496
+ return run({
1497
+ request,
1498
+ env,
1499
+ ctx,
1500
+ module,
1501
+ wasi,
1502
+ imports,
1503
+ kv: kv?.(env),
1504
+ websocket: websocket?.(env)
1505
+ });
1506
+ }
1507
+ }
408
1508
  export {
409
1509
  exports_worker as worker,
410
- exports_kv as kv
1510
+ exports_kv as kv,
1511
+ createWebSocketDO,
1512
+ Ziex
411
1513
  };