ziex 0.1.0-dev.1466 → 0.1.0-dev.1568
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -9
- package/app.d.ts +37 -22
- package/build.zig.zon +1 -1
- package/index.d.ts +1 -1
- package/index.js +239 -218
- package/package.json +2 -2
- package/platforms/aws-lambda/index.d.ts +1 -1
- package/platforms/cloudflare/app.d.ts +31 -1
- package/platforms/cloudflare/index.d.ts +5 -4
- package/platforms/cloudflare/index.js +1722 -1645
- package/platforms/cloudflare/kv.d.ts +4 -2
- package/platforms/cloudflare/stateful.d.ts +26 -0
- package/platforms/cloudflare/worker.d.ts +1 -2
- package/platforms/vercel/index.d.ts +1 -1
- package/runtime/index.d.ts +20 -10
- package/runtime/kv/indexdb.d.ts +11 -3
- package/runtime/kv/localstorage.d.ts +11 -3
- package/runtime/kv/memory.d.ts +13 -6
- package/runtime/kv.d.ts +16 -18
- package/runtime/kv.js +178 -241
- package/runtime/wasi.d.ts +2 -7
- package/wasm/dom_cmd.d.ts +0 -9
- package/wasm/index.js +224 -188
- package/wasm/init.dev.js +224 -188
- package/wasm/init.js +3 -3
- package/platforms/cloudflare/do.d.ts +0 -50
|
@@ -1,257 +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/constants.ts
|
|
16
|
-
var DOM_CMD_HEADER_SIZE = 8;
|
|
17
|
-
var DOM_CMD_RECORD_SIZE = 24;
|
|
18
|
-
var DomOp_CreateElement = 1;
|
|
19
|
-
var DomOp_CreateText = 2;
|
|
20
|
-
var DomOp_HydrateInsert = 3;
|
|
21
|
-
var DomOp_SetAttr = 4;
|
|
22
|
-
var DomOp_SetProp = 5;
|
|
23
|
-
var DomOp_RemoveAttr = 6;
|
|
24
|
-
var DomOp_SetNodeValue = 7;
|
|
25
|
-
var DomOp_SetInnerHtml = 8;
|
|
26
|
-
var DomOp_AppendChild = 9;
|
|
27
|
-
var DomOp_InsertBefore = 10;
|
|
28
|
-
var DomOp_RemoveChild = 11;
|
|
29
|
-
var DomOp_ReplaceChild = 12;
|
|
30
|
-
var CallbackType_FetchSuccess = 1;
|
|
31
|
-
var CallbackType_FetchError = 2;
|
|
32
|
-
var CallbackType_Timeout = 3;
|
|
33
|
-
var CallbackType_Interval = 4;
|
|
34
|
-
var CallbackType_WebSocketOpen = 5;
|
|
35
|
-
var CallbackType_WebSocketMessage = 6;
|
|
36
|
-
var CallbackType_WebSocketError = 7;
|
|
37
|
-
var CallbackType_WebSocketClose = 8;
|
|
38
|
-
|
|
39
|
-
// src/wasm/wasi.ts
|
|
40
|
-
var decoder = new TextDecoder();
|
|
41
|
-
var encoder = new TextEncoder();
|
|
42
|
-
var ZxWasiBridge = class {
|
|
43
|
-
#alloc;
|
|
44
|
-
#memory;
|
|
45
|
-
#cb;
|
|
46
|
-
#intervals = /* @__PURE__ */ new Map();
|
|
47
|
-
// Cached memory view - invalidated when the WASM buffer grows.
|
|
48
|
-
#memView = null;
|
|
49
|
-
#memBuf = null;
|
|
50
|
-
constructor(exports) {
|
|
51
|
-
this.#memory = exports.memory;
|
|
52
|
-
this.#alloc = exports.__zx_alloc;
|
|
53
|
-
this.#cb = exports.__zx_cb;
|
|
54
|
-
}
|
|
55
|
-
#view() {
|
|
56
|
-
const buf = this.#memory.buffer;
|
|
57
|
-
if (buf !== this.#memBuf) {
|
|
58
|
-
this.#memBuf = buf;
|
|
59
|
-
this.#memView = new Uint8Array(buf);
|
|
60
|
-
}
|
|
61
|
-
return this.#memView;
|
|
62
|
-
}
|
|
63
|
-
#readString(ptr, len) {
|
|
64
|
-
const start = ptr >>> 0;
|
|
65
|
-
const length = len >>> 0;
|
|
66
|
-
if (length === 0) return "";
|
|
67
|
-
const view = this.#view();
|
|
68
|
-
if (start + length > view.byteLength) return "";
|
|
69
|
-
return decoder.decode(view.subarray(start, start + length));
|
|
70
|
-
}
|
|
71
|
-
#writeBytes(ptr, data) {
|
|
72
|
-
const start = ptr >>> 0;
|
|
73
|
-
const view = this.#view();
|
|
74
|
-
if (start + data.length > view.byteLength) return;
|
|
75
|
-
view.set(data, start);
|
|
76
|
-
}
|
|
77
|
-
#invoke(type, id, a = 0n, b = 0n, c = 0n) {
|
|
78
|
-
this.#cb?.(type, id, a, b, c);
|
|
79
|
-
}
|
|
80
|
-
log(level, ptr, len) {
|
|
81
|
-
const msg = decoder.decode(this.#view().subarray(ptr, ptr + len));
|
|
82
|
-
switch (level) {
|
|
83
|
-
case 0:
|
|
84
|
-
console.error(msg);
|
|
85
|
-
break;
|
|
86
|
-
case 1:
|
|
87
|
-
console.warn(msg);
|
|
88
|
-
break;
|
|
89
|
-
case 3:
|
|
90
|
-
console.debug(msg);
|
|
91
|
-
break;
|
|
92
|
-
default:
|
|
93
|
-
console.log(msg);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
|
|
98
|
-
const url = this.#readString(urlPtr, urlLen);
|
|
99
|
-
const method = methodLen > 0 ? this.#readString(methodPtr, methodLen) : "GET";
|
|
100
|
-
const headersJson = headersLen > 0 ? this.#readString(headersPtr, headersLen) : "{}";
|
|
101
|
-
const body = bodyLen > 0 ? this.#view().subarray(bodyPtr, bodyPtr + bodyLen) : void 0;
|
|
102
|
-
let headers = {};
|
|
103
|
-
try {
|
|
104
|
-
headers = JSON.parse(headersJson);
|
|
105
|
-
} catch {
|
|
106
|
-
for (const line of headersJson.split("\n")) {
|
|
107
|
-
const i = line.indexOf(":");
|
|
108
|
-
if (i > 0) headers[line.slice(0, i)] = line.slice(i + 1);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
const controller = new AbortController();
|
|
112
|
-
const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
113
|
-
fetch(url, {
|
|
114
|
-
method,
|
|
115
|
-
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
116
|
-
body: method !== "GET" && method !== "HEAD" ? body : void 0,
|
|
117
|
-
signal: controller.signal
|
|
118
|
-
}).then(async (res) => {
|
|
119
|
-
if (timeout) clearTimeout(timeout);
|
|
120
|
-
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
121
|
-
this.#notifyFetchComplete(fetchId, res.status, bytes, false);
|
|
122
|
-
}).catch((err) => {
|
|
123
|
-
if (timeout) clearTimeout(timeout);
|
|
124
|
-
const msg = err.name === "AbortError" ? "Request timeout" : err.message ?? "Fetch failed";
|
|
125
|
-
this.#notifyFetchComplete(fetchId, 0, msg, true);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
#notifyFetchComplete(fetchId, status, body, isError) {
|
|
129
|
-
const encoded = typeof body === "string" ? encoder.encode(body) : body;
|
|
130
|
-
const ptr = this.#alloc(encoded.length);
|
|
131
|
-
this.#writeBytes(ptr, encoded);
|
|
132
|
-
const type = isError ? CallbackType_FetchError : CallbackType_FetchSuccess;
|
|
133
|
-
this.#invoke(type, fetchId, BigInt(status), BigInt(ptr), BigInt(encoded.length));
|
|
134
|
-
}
|
|
135
|
-
setTimeout(callbackId, delayMs) {
|
|
136
|
-
setTimeout(() => this.#invoke(CallbackType_Timeout, callbackId), delayMs);
|
|
137
|
-
}
|
|
138
|
-
setInterval(callbackId, intervalMs) {
|
|
139
|
-
const handle = setInterval(() => this.#invoke(CallbackType_Interval, callbackId), intervalMs);
|
|
140
|
-
this.#intervals.set(callbackId, handle);
|
|
141
|
-
}
|
|
142
|
-
clearInterval(callbackId) {
|
|
143
|
-
const handle = this.#intervals.get(callbackId);
|
|
144
|
-
if (handle !== void 0) {
|
|
145
|
-
clearInterval(handle);
|
|
146
|
-
this.#intervals.delete(callbackId);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Create the WASI import object for WASM instantiation.
|
|
151
|
-
*
|
|
152
|
-
* Returns only the `__zx` namespace (log, fetch, timers).
|
|
153
|
-
* Does NOT include jsz.importObject() - the server binary does not use jsz.
|
|
154
|
-
*/
|
|
155
|
-
static createImportObject(bridgeRef) {
|
|
156
|
-
return {
|
|
157
|
-
__zx: {
|
|
158
|
-
_log: (level, ptr, len) => {
|
|
159
|
-
bridgeRef[0]?.log(level, ptr, len);
|
|
160
|
-
},
|
|
161
|
-
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
162
|
-
bridgeRef[0]?.fetchAsync(
|
|
163
|
-
urlPtr,
|
|
164
|
-
urlLen,
|
|
165
|
-
methodPtr,
|
|
166
|
-
methodLen,
|
|
167
|
-
headersPtr,
|
|
168
|
-
headersLen,
|
|
169
|
-
bodyPtr,
|
|
170
|
-
bodyLen,
|
|
171
|
-
timeoutMs,
|
|
172
|
-
fetchId
|
|
173
|
-
);
|
|
174
|
-
},
|
|
175
|
-
_setTimeout: (callbackId, delayMs) => {
|
|
176
|
-
bridgeRef[0]?.setTimeout(callbackId, delayMs);
|
|
177
|
-
},
|
|
178
|
-
_setInterval: (callbackId, intervalMs) => {
|
|
179
|
-
bridgeRef[0]?.setInterval(callbackId, intervalMs);
|
|
180
|
-
},
|
|
181
|
-
_clearInterval: (callbackId) => {
|
|
182
|
-
bridgeRef[0]?.clearInterval(callbackId);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// src/runtime/fetch.ts
|
|
190
|
-
function createFetchImports(getMemory) {
|
|
191
|
-
const encoder3 = new TextEncoder();
|
|
192
|
-
const decoder3 = new TextDecoder();
|
|
193
|
-
function readStr(ptr, len) {
|
|
194
|
-
return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
195
|
-
}
|
|
196
|
-
function writeBytes2(buf_ptr, buf_max, data) {
|
|
197
|
-
if (data.length > buf_max) return -2;
|
|
198
|
-
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
199
|
-
return data.length;
|
|
200
|
-
}
|
|
201
|
-
function readBytes(ptr, len) {
|
|
202
|
-
return new Uint8Array(getMemory().buffer, ptr, len);
|
|
203
|
-
}
|
|
204
|
-
function parseHeaders(headersJson) {
|
|
205
|
-
let headers = {};
|
|
206
|
-
try {
|
|
207
|
-
headers = JSON.parse(headersJson);
|
|
208
|
-
} catch {
|
|
209
|
-
for (const line of headersJson.split("\n")) {
|
|
210
|
-
const colonIdx = line.indexOf(":");
|
|
211
|
-
if (colonIdx > 0) {
|
|
212
|
-
headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return headers;
|
|
217
|
-
}
|
|
218
|
-
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) {
|
|
219
|
-
const url = readStr(url_ptr, url_len);
|
|
220
|
-
const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
|
|
221
|
-
const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
|
|
222
|
-
const body = body_len > 0 ? readBytes(body_ptr, body_len) : void 0;
|
|
223
|
-
const headers = parseHeaders(headersJson);
|
|
224
|
-
const controller = new AbortController();
|
|
225
|
-
const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
|
|
226
|
-
try {
|
|
227
|
-
const response = await fetch(url, {
|
|
228
|
-
method,
|
|
229
|
-
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
230
|
-
body: method !== "GET" && method !== "HEAD" ? body : void 0,
|
|
231
|
-
signal: controller.signal
|
|
232
|
-
});
|
|
233
|
-
if (timeout) clearTimeout(timeout);
|
|
234
|
-
new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
|
|
235
|
-
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
236
|
-
return writeBytes2(buf_ptr, buf_max, bytes);
|
|
237
|
-
} catch (err) {
|
|
238
|
-
if (timeout) clearTimeout(timeout);
|
|
239
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
240
|
-
console.error(`wasm fetch failed: ${url} (${msg})`);
|
|
241
|
-
return -1;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const Suspending = WebAssembly.Suspending;
|
|
245
|
-
if (typeof Suspending !== "function") {
|
|
246
|
-
return {
|
|
247
|
-
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
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
fetch: new Suspending(doFetch)
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
|
|
255
1
|
// ../../vendor/jsz/js/src/zigjs.ts
|
|
256
2
|
var NAN_PREFIX = 2146959360;
|
|
257
3
|
var predefined = {
|
|
@@ -264,8 +10,8 @@ var predefined = {
|
|
|
264
10
|
"runtime": 6
|
|
265
11
|
};
|
|
266
12
|
var PREDEFINED_ID_MAX = 6;
|
|
267
|
-
var
|
|
268
|
-
var
|
|
13
|
+
var encoder = new TextEncoder();
|
|
14
|
+
var decoder = new TextDecoder("utf-8");
|
|
269
15
|
var ZigJS = class {
|
|
270
16
|
constructor() {
|
|
271
17
|
/**
|
|
@@ -349,7 +95,7 @@ var ZigJS = class {
|
|
|
349
95
|
* */
|
|
350
96
|
valueStringLen(id) {
|
|
351
97
|
const val = this.loadValue(id);
|
|
352
|
-
const buf =
|
|
98
|
+
const buf = encoder.encode(val);
|
|
353
99
|
return buf.byteLength;
|
|
354
100
|
}
|
|
355
101
|
/**
|
|
@@ -361,7 +107,7 @@ var ZigJS = class {
|
|
|
361
107
|
const cap = max >>> 0;
|
|
362
108
|
const val = this.loadValue(id);
|
|
363
109
|
if (typeof val !== "string") return;
|
|
364
|
-
const bytes =
|
|
110
|
+
const bytes = encoder.encode(val);
|
|
365
111
|
if (bytes.byteLength > cap || bytes.length === 0) return;
|
|
366
112
|
const buf = this.memory.buffer;
|
|
367
113
|
if (dest + bytes.length > buf.byteLength) return;
|
|
@@ -497,31 +243,121 @@ var ZigJS = class {
|
|
|
497
243
|
if (length === 0 || start + length > buf.byteLength) return "";
|
|
498
244
|
const arr = new Uint8ClampedArray(buf, start, length);
|
|
499
245
|
const data = arr.slice();
|
|
500
|
-
return
|
|
246
|
+
return decoder.decode(data);
|
|
501
247
|
}
|
|
502
248
|
};
|
|
503
249
|
|
|
504
|
-
// src/
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
function
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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));
|
|
256
|
+
}
|
|
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);
|
|
525
361
|
if (!Number.isNaN(tempRefView.getFloat64(0, true))) return;
|
|
526
362
|
const id = tempRefView.getUint32(0, true);
|
|
527
363
|
if (id > 6) jsz.deleteValue(id);
|
|
@@ -760,1005 +596,239 @@ function bindWasmAlloc(allocRef, exports) {
|
|
|
760
596
|
}
|
|
761
597
|
|
|
762
598
|
// src/runtime/kv/extern.ts
|
|
599
|
+
var Suspending = WebAssembly.Suspending;
|
|
600
|
+
var jspi = typeof Suspending === "function";
|
|
601
|
+
var miss = jspi ? -1 : 0;
|
|
763
602
|
function putOptions(ttlSeconds) {
|
|
764
603
|
if (ttlSeconds < 60) return void 0;
|
|
765
604
|
return { expirationTtl: ttlSeconds };
|
|
766
605
|
}
|
|
606
|
+
function kvDel(binding, key) {
|
|
607
|
+
const b = binding;
|
|
608
|
+
return (b.del ?? b.delete).call(b, key);
|
|
609
|
+
}
|
|
767
610
|
function isSyncKVNamespace(binding) {
|
|
768
|
-
|
|
769
|
-
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";
|
|
770
612
|
}
|
|
771
|
-
function
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
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;
|
|
779
635
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
b.deleteSync(readStr(key_ptr, key_len));
|
|
805
|
-
return 0;
|
|
806
|
-
},
|
|
807
|
-
kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
|
|
808
|
-
const b = syncBinding2(readStr(ns_ptr, ns_len));
|
|
809
|
-
if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
|
|
810
|
-
const prefix = readStr(pfx_ptr, pfx_len);
|
|
811
|
-
const result = b.listSync(prefix.length > 0 ? { prefix } : void 0);
|
|
812
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, result.keys.map((k) => k.name));
|
|
813
|
-
}
|
|
814
|
-
};
|
|
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
|
+
});
|
|
815
660
|
}
|
|
661
|
+
return new Suspending(impl);
|
|
662
|
+
}
|
|
663
|
+
function createKVImports(bindings, getMemory, allocRef) {
|
|
816
664
|
return {
|
|
817
|
-
kv_get:
|
|
818
|
-
const b =
|
|
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));
|
|
819
667
|
if (!b) return -1;
|
|
820
|
-
|
|
821
|
-
if (value === null) return -1;
|
|
822
|
-
return writeBytesOut(getMemory, allocRef, out_ptr, encoder3.encode(value));
|
|
668
|
+
return get(b, readStr(getMemory, key_ptr, key_len), out_ptr, getMemory, allocRef);
|
|
823
669
|
}),
|
|
824
|
-
kv_put:
|
|
825
|
-
const b =
|
|
826
|
-
if (!b) return
|
|
827
|
-
|
|
828
|
-
|
|
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
|
+
);
|
|
829
679
|
}),
|
|
830
|
-
kv_delete:
|
|
831
|
-
const b =
|
|
832
|
-
if (!b) return
|
|
833
|
-
|
|
834
|
-
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));
|
|
835
684
|
}),
|
|
836
|
-
kv_list:
|
|
837
|
-
const b =
|
|
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));
|
|
838
687
|
if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
|
|
839
|
-
|
|
840
|
-
const result = await b.list(prefix.length > 0 ? { prefix } : void 0);
|
|
841
|
-
const names = result.keys.map((k) => k.name);
|
|
842
|
-
if (names.length === 0) {
|
|
843
|
-
new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
|
|
844
|
-
return 0;
|
|
845
|
-
}
|
|
846
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, names);
|
|
688
|
+
return list(b, readStr(getMemory, pfx_ptr, pfx_len), out_ptr, getMemory, allocRef);
|
|
847
689
|
})
|
|
848
690
|
};
|
|
849
691
|
}
|
|
850
692
|
|
|
851
|
-
// src/runtime/
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
function toDbValue(value) {
|
|
859
|
-
switch (value.kind) {
|
|
860
|
-
case "null":
|
|
861
|
-
return null;
|
|
862
|
-
case "integer":
|
|
863
|
-
return value.integer;
|
|
864
|
-
case "float":
|
|
865
|
-
return value.float;
|
|
866
|
-
case "text":
|
|
867
|
-
return value.text;
|
|
868
|
-
case "blob":
|
|
869
|
-
return decodeBlob(value.blob);
|
|
870
|
-
case "boolean":
|
|
871
|
-
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");
|
|
872
700
|
}
|
|
701
|
+
return localStorage;
|
|
873
702
|
}
|
|
874
|
-
function
|
|
875
|
-
|
|
876
|
-
case "none":
|
|
877
|
-
return [];
|
|
878
|
-
case "positional":
|
|
879
|
-
return json.values.map(toDbValue);
|
|
880
|
-
case "named":
|
|
881
|
-
throw new Error("named SQL bindings are not supported yet");
|
|
882
|
-
}
|
|
703
|
+
function get2(key) {
|
|
704
|
+
return storage().getItem(`${storagePrefix}:${namespace}:${key}`);
|
|
883
705
|
}
|
|
884
|
-
function
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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
|
+
});
|
|
902
745
|
}
|
|
903
|
-
return
|
|
746
|
+
return dbPromise;
|
|
904
747
|
}
|
|
905
|
-
function
|
|
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 ?? ""}`;
|
|
906
786
|
return {
|
|
907
|
-
|
|
908
|
-
name,
|
|
909
|
-
value: toWireValue(value)
|
|
910
|
-
}))
|
|
787
|
+
keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace2.length + 1) }))
|
|
911
788
|
};
|
|
912
789
|
}
|
|
913
|
-
|
|
914
|
-
|
|
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
|
+
};
|
|
915
798
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
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 });
|
|
940
829
|
}
|
|
941
|
-
return {
|
|
942
|
-
|
|
943
|
-
db_run: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
|
|
944
|
-
const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
|
|
945
|
-
if (!stmt) return -1;
|
|
946
|
-
const result = await stmt.run();
|
|
947
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, {
|
|
948
|
-
last_insert_rowid: result.meta?.last_row_id ?? 0,
|
|
949
|
-
changes: result.meta?.changes ?? 0
|
|
950
|
-
});
|
|
951
|
-
}),
|
|
952
|
-
db_get: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
|
|
953
|
-
const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
|
|
954
|
-
if (!stmt) return -1;
|
|
955
|
-
const row = await stmt.first();
|
|
956
|
-
if (!row) {
|
|
957
|
-
new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
|
|
958
|
-
return 0;
|
|
959
|
-
}
|
|
960
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, [objectToWireRow(row)]);
|
|
961
|
-
}),
|
|
962
|
-
db_all: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
|
|
963
|
-
const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
|
|
964
|
-
if (!stmt) return -1;
|
|
965
|
-
const result = await stmt.all();
|
|
966
|
-
const rows = (result.results ?? []).map(objectToWireRow);
|
|
967
|
-
if (rows.length === 0) {
|
|
968
|
-
new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
|
|
969
|
-
return 0;
|
|
970
|
-
}
|
|
971
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, rows);
|
|
972
|
-
}),
|
|
973
|
-
db_values: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
|
|
974
|
-
const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
|
|
975
|
-
if (!stmt) return -1;
|
|
976
|
-
const rows = await stmt.raw();
|
|
977
|
-
if (rows.length === 0) {
|
|
978
|
-
new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
|
|
979
|
-
return 0;
|
|
980
|
-
}
|
|
981
|
-
return writeJsonOut(getMemory, allocRef, out_ptr, valuesToWireRows(rows));
|
|
982
|
-
})
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
// src/runtime/wasi.ts
|
|
987
|
-
var ProcExit = class extends Error {
|
|
988
|
-
constructor(code) {
|
|
989
|
-
super(`proc_exit(${code})`);
|
|
990
|
-
this.code = code;
|
|
991
|
-
}
|
|
992
|
-
};
|
|
993
|
-
function createWasiImports({
|
|
994
|
-
request,
|
|
995
|
-
stdinData,
|
|
996
|
-
onStdout
|
|
997
|
-
}) {
|
|
998
|
-
const encoder3 = new TextEncoder();
|
|
999
|
-
const url = new URL(request.url);
|
|
1000
|
-
const argStrings = [
|
|
1001
|
-
"wasm",
|
|
1002
|
-
"--pathname",
|
|
1003
|
-
url.pathname,
|
|
1004
|
-
"--method",
|
|
1005
|
-
request.method,
|
|
1006
|
-
"--search",
|
|
1007
|
-
url.search,
|
|
1008
|
-
"--url",
|
|
1009
|
-
url.href
|
|
1010
|
-
];
|
|
1011
|
-
request.headers.forEach((value, name) => {
|
|
1012
|
-
if (value) argStrings.push("--header", `${name}:${value}`);
|
|
1013
|
-
});
|
|
1014
|
-
const encodedArgs = argStrings.map((a) => encoder3.encode(a + "\0"));
|
|
1015
|
-
const argBufSize = encodedArgs.reduce((s, a) => s + a.length, 0);
|
|
1016
|
-
let wasmMemory = null;
|
|
1017
|
-
const setMemory = (m2) => {
|
|
1018
|
-
wasmMemory = m2;
|
|
1019
|
-
};
|
|
1020
|
-
const stdoutChunks = [];
|
|
1021
|
-
let stderrMeta = "";
|
|
1022
|
-
let stderrPartial = "";
|
|
1023
|
-
const stderrDecoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
|
|
1024
|
-
function processStderrChunk(chunk) {
|
|
1025
|
-
const text = stderrDecoder.decode(chunk, { stream: true });
|
|
1026
|
-
const lines = (stderrPartial + text).split("\n");
|
|
1027
|
-
stderrPartial = lines.pop() ?? "";
|
|
1028
|
-
for (const line of lines) {
|
|
1029
|
-
if (line.startsWith("__ZIEX_META__:")) {
|
|
1030
|
-
stderrMeta += line + "\n";
|
|
1031
|
-
} else if (line.length > 0) {
|
|
1032
|
-
console.error("[ziex]", line);
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
let stdinOffset = 0;
|
|
1037
|
-
function v() {
|
|
1038
|
-
return new DataView(wasmMemory.buffer);
|
|
1039
|
-
}
|
|
1040
|
-
function m() {
|
|
1041
|
-
return new Uint8Array(wasmMemory.buffer);
|
|
1042
|
-
}
|
|
1043
|
-
const wasiImport = {
|
|
1044
|
-
args_sizes_get(argc_ptr, argv_buf_size_ptr) {
|
|
1045
|
-
v().setUint32(argc_ptr, encodedArgs.length, true);
|
|
1046
|
-
v().setUint32(argv_buf_size_ptr, argBufSize, true);
|
|
1047
|
-
return 0;
|
|
1048
|
-
},
|
|
1049
|
-
args_get(argv_ptr, argv_buf_ptr) {
|
|
1050
|
-
const dv = v();
|
|
1051
|
-
const mem = m();
|
|
1052
|
-
let offset = argv_buf_ptr;
|
|
1053
|
-
for (const arg of encodedArgs) {
|
|
1054
|
-
dv.setUint32(argv_ptr, offset, true);
|
|
1055
|
-
mem.set(arg, offset);
|
|
1056
|
-
argv_ptr += 4;
|
|
1057
|
-
offset += arg.length;
|
|
1058
|
-
}
|
|
1059
|
-
return 0;
|
|
1060
|
-
},
|
|
1061
|
-
environ_sizes_get(count_ptr, buf_size_ptr) {
|
|
1062
|
-
v().setUint32(count_ptr, 0, true);
|
|
1063
|
-
v().setUint32(buf_size_ptr, 0, true);
|
|
1064
|
-
return 0;
|
|
1065
|
-
},
|
|
1066
|
-
environ_get(_environ_ptr, _environ_buf_ptr) {
|
|
1067
|
-
return 0;
|
|
1068
|
-
},
|
|
1069
|
-
fd_write(fd, iovs_ptr, iovs_len, nwritten_ptr) {
|
|
1070
|
-
const dv = v();
|
|
1071
|
-
const mem = m();
|
|
1072
|
-
let written = 0;
|
|
1073
|
-
for (let i = 0; i < iovs_len; i++) {
|
|
1074
|
-
const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
|
|
1075
|
-
const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
|
|
1076
|
-
const chunk = mem.slice(buf_ptr, buf_ptr + buf_len);
|
|
1077
|
-
if (fd === 1) {
|
|
1078
|
-
if (onStdout) onStdout(chunk);
|
|
1079
|
-
else stdoutChunks.push(chunk);
|
|
1080
|
-
} else if (fd === 2) processStderrChunk(chunk);
|
|
1081
|
-
written += buf_len;
|
|
1082
|
-
}
|
|
1083
|
-
dv.setUint32(nwritten_ptr, written, true);
|
|
1084
|
-
return 0;
|
|
1085
|
-
},
|
|
1086
|
-
fd_read(fd, iovs_ptr, iovs_len, nread_ptr) {
|
|
1087
|
-
const dv = v();
|
|
1088
|
-
const mem = m();
|
|
1089
|
-
const stdin = stdinData ?? new Uint8Array(0);
|
|
1090
|
-
let totalRead = 0;
|
|
1091
|
-
for (let i = 0; i < iovs_len; i++) {
|
|
1092
|
-
const buf_ptr = dv.getUint32(iovs_ptr + i * 8, true);
|
|
1093
|
-
const buf_len = dv.getUint32(iovs_ptr + i * 8 + 4, true);
|
|
1094
|
-
if (fd === 0 && stdinOffset < stdin.length) {
|
|
1095
|
-
const toRead = Math.min(buf_len, stdin.length - stdinOffset);
|
|
1096
|
-
mem.set(stdin.subarray(stdinOffset, stdinOffset + toRead), buf_ptr);
|
|
1097
|
-
stdinOffset += toRead;
|
|
1098
|
-
totalRead += toRead;
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
dv.setUint32(nread_ptr, totalRead, true);
|
|
1102
|
-
return 0;
|
|
1103
|
-
},
|
|
1104
|
-
fd_fdstat_get(_fd, fdstat_ptr) {
|
|
1105
|
-
const dv = v();
|
|
1106
|
-
dv.setUint8(fdstat_ptr, 2);
|
|
1107
|
-
dv.setUint8(fdstat_ptr + 1, 0);
|
|
1108
|
-
dv.setUint16(fdstat_ptr + 2, 0, true);
|
|
1109
|
-
dv.setUint32(fdstat_ptr + 4, 0, true);
|
|
1110
|
-
dv.setBigUint64(fdstat_ptr + 8, 0n, true);
|
|
1111
|
-
dv.setBigUint64(fdstat_ptr + 16, 0n, true);
|
|
1112
|
-
return 0;
|
|
1113
|
-
},
|
|
1114
|
-
fd_prestat_get(_fd, _bufptr) {
|
|
1115
|
-
return 8;
|
|
1116
|
-
},
|
|
1117
|
-
fd_prestat_dir_name(_fd, _path, _path_len) {
|
|
1118
|
-
return 8;
|
|
1119
|
-
},
|
|
1120
|
-
fd_close(_fd) {
|
|
1121
|
-
return 0;
|
|
1122
|
-
},
|
|
1123
|
-
fd_pread(_fd, _iovs, _iovs_len, _offset, nread_ptr) {
|
|
1124
|
-
v().setUint32(nread_ptr, 0, true);
|
|
1125
|
-
return 0;
|
|
1126
|
-
},
|
|
1127
|
-
fd_pwrite(_fd, _iovs, _iovs_len, _offset, nwritten_ptr) {
|
|
1128
|
-
v().setUint32(nwritten_ptr, 0, true);
|
|
1129
|
-
return 0;
|
|
1130
|
-
},
|
|
1131
|
-
fd_filestat_get(_fd, filestat_ptr) {
|
|
1132
|
-
const dv = v();
|
|
1133
|
-
dv.setBigUint64(filestat_ptr, 0n, true);
|
|
1134
|
-
dv.setBigUint64(filestat_ptr + 8, 0n, true);
|
|
1135
|
-
dv.setUint8(filestat_ptr + 16, 2);
|
|
1136
|
-
dv.setBigUint64(filestat_ptr + 24, 1n, true);
|
|
1137
|
-
dv.setBigUint64(filestat_ptr + 32, 0n, true);
|
|
1138
|
-
dv.setBigUint64(filestat_ptr + 40, 0n, true);
|
|
1139
|
-
dv.setBigUint64(filestat_ptr + 48, 0n, true);
|
|
1140
|
-
dv.setBigUint64(filestat_ptr + 56, 0n, true);
|
|
1141
|
-
return 0;
|
|
1142
|
-
},
|
|
1143
|
-
fd_filestat_set_size(_fd, _size) {
|
|
1144
|
-
return 76;
|
|
1145
|
-
},
|
|
1146
|
-
fd_filestat_set_times(_fd, _atim, _mtim, _fst_flags) {
|
|
1147
|
-
return 76;
|
|
1148
|
-
},
|
|
1149
|
-
fd_fdstat_set_flags(_fd, _flags) {
|
|
1150
|
-
return 0;
|
|
1151
|
-
},
|
|
1152
|
-
fd_fdstat_set_rights(_fd, _rights_base, _rights_inheriting) {
|
|
1153
|
-
return 0;
|
|
1154
|
-
},
|
|
1155
|
-
fd_sync(_fd) {
|
|
1156
|
-
return 0;
|
|
1157
|
-
},
|
|
1158
|
-
fd_datasync(_fd) {
|
|
1159
|
-
return 0;
|
|
1160
|
-
},
|
|
1161
|
-
fd_advise(_fd, _offset, _len, _advice) {
|
|
1162
|
-
return 0;
|
|
1163
|
-
},
|
|
1164
|
-
fd_allocate(_fd, _offset, _len) {
|
|
1165
|
-
return 76;
|
|
1166
|
-
},
|
|
1167
|
-
fd_tell(_fd, offset_ptr) {
|
|
1168
|
-
v().setBigUint64(offset_ptr, 0n, true);
|
|
1169
|
-
return 0;
|
|
1170
|
-
},
|
|
1171
|
-
fd_renumber(_from, _to) {
|
|
1172
|
-
return 0;
|
|
1173
|
-
},
|
|
1174
|
-
path_filestat_set_times(_fd, _flags, _path, _path_len, _atim, _mtim, _fst_flags) {
|
|
1175
|
-
return 76;
|
|
1176
|
-
},
|
|
1177
|
-
path_link(_old_fd, _old_flags, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
|
|
1178
|
-
return 76;
|
|
1179
|
-
},
|
|
1180
|
-
path_symlink(_old_path, _old_path_len, _fd, _new_path, _new_path_len) {
|
|
1181
|
-
return 76;
|
|
1182
|
-
},
|
|
1183
|
-
proc_raise(_sig) {
|
|
1184
|
-
return 0;
|
|
1185
|
-
},
|
|
1186
|
-
sock_recv(_fd, _ri_data, _ri_data_len, _ri_flags, ro_datalen_ptr, ro_flags_ptr) {
|
|
1187
|
-
v().setUint32(ro_datalen_ptr, 0, true);
|
|
1188
|
-
v().setUint32(ro_flags_ptr, 0, true);
|
|
1189
|
-
return 76;
|
|
1190
|
-
},
|
|
1191
|
-
sock_send(_fd, _si_data, _si_data_len, _si_flags, so_datalen_ptr) {
|
|
1192
|
-
v().setUint32(so_datalen_ptr, 0, true);
|
|
1193
|
-
return 76;
|
|
1194
|
-
},
|
|
1195
|
-
sock_shutdown(_fd, _how) {
|
|
1196
|
-
return 76;
|
|
1197
|
-
},
|
|
1198
|
-
fd_seek(_fd, _offset, _whence, newoffset_ptr) {
|
|
1199
|
-
v().setBigInt64(newoffset_ptr, 0n, true);
|
|
1200
|
-
return 0;
|
|
1201
|
-
},
|
|
1202
|
-
proc_exit(code) {
|
|
1203
|
-
throw new ProcExit(code);
|
|
1204
|
-
},
|
|
1205
|
-
sched_yield() {
|
|
1206
|
-
return 0;
|
|
1207
|
-
},
|
|
1208
|
-
clock_time_get(_id, _precision, time_ptr) {
|
|
1209
|
-
v().setBigUint64(time_ptr, BigInt(Date.now()) * 1000000n, true);
|
|
1210
|
-
return 0;
|
|
1211
|
-
},
|
|
1212
|
-
clock_res_get(_id, res_ptr) {
|
|
1213
|
-
v().setBigUint64(res_ptr, 1000000n, true);
|
|
1214
|
-
return 0;
|
|
1215
|
-
},
|
|
1216
|
-
random_get(buf_ptr, buf_len) {
|
|
1217
|
-
crypto.getRandomValues(new Uint8Array(wasmMemory.buffer, buf_ptr, buf_len));
|
|
1218
|
-
return 0;
|
|
1219
|
-
},
|
|
1220
|
-
path_open(_fd, _dirflags, _path, _path_len, _oflags, _rights_base, _rights_inheriting, _fdflags, opened_fd_ptr) {
|
|
1221
|
-
v().setInt32(opened_fd_ptr, -1, true);
|
|
1222
|
-
return 76;
|
|
1223
|
-
},
|
|
1224
|
-
path_create_directory(_fd, _path, _path_len) {
|
|
1225
|
-
return 76;
|
|
1226
|
-
},
|
|
1227
|
-
path_unlink_file(_fd, _path, _path_len) {
|
|
1228
|
-
return 76;
|
|
1229
|
-
},
|
|
1230
|
-
path_remove_directory(_fd, _path, _path_len) {
|
|
1231
|
-
return 76;
|
|
1232
|
-
},
|
|
1233
|
-
path_rename(_fd, _old_path, _old_path_len, _new_fd, _new_path, _new_path_len) {
|
|
1234
|
-
return 76;
|
|
1235
|
-
},
|
|
1236
|
-
path_filestat_get(_fd, _flags, _path, _path_len, filestat_ptr) {
|
|
1237
|
-
new Uint8Array(wasmMemory.buffer, filestat_ptr, 64).fill(0);
|
|
1238
|
-
return 76;
|
|
1239
|
-
},
|
|
1240
|
-
path_readlink(_fd, _path, _path_len, _buf, _buf_len, nread_ptr) {
|
|
1241
|
-
v().setUint32(nread_ptr, 0, true);
|
|
1242
|
-
return 76;
|
|
1243
|
-
},
|
|
1244
|
-
fd_readdir(_fd, _buf, _buf_len, _cookie, bufused_ptr) {
|
|
1245
|
-
v().setUint32(bufused_ptr, 0, true);
|
|
1246
|
-
return 76;
|
|
1247
|
-
},
|
|
1248
|
-
// Stub for poll_oneoff - no blocking I/O in edge runtimes.
|
|
1249
|
-
poll_oneoff(_in, _out, _nsubscriptions, nevents_ptr) {
|
|
1250
|
-
v().setUint32(nevents_ptr, 0, true);
|
|
1251
|
-
return 0;
|
|
1252
|
-
}
|
|
1253
|
-
};
|
|
1254
|
-
function collectOutput() {
|
|
1255
|
-
const remaining = stderrDecoder.decode(void 0, { stream: false });
|
|
1256
|
-
const tail = stderrPartial + remaining;
|
|
1257
|
-
if (tail.length > 0) {
|
|
1258
|
-
if (tail.startsWith("__ZIEX_META__:")) stderrMeta += tail;
|
|
1259
|
-
else console.error("[ziex]", tail);
|
|
1260
|
-
stderrPartial = "";
|
|
1261
|
-
}
|
|
1262
|
-
return {
|
|
1263
|
-
stdout: mergeUint8Arrays(stdoutChunks),
|
|
1264
|
-
stderrText: stderrMeta
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
|
-
return { wasiImport, setMemory, collectOutput };
|
|
1268
|
-
}
|
|
1269
|
-
function mergeUint8Arrays(arrays) {
|
|
1270
|
-
const totalLen = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
1271
|
-
const result = new Uint8Array(totalLen);
|
|
1272
|
-
let offset = 0;
|
|
1273
|
-
for (const arr of arrays) {
|
|
1274
|
-
result.set(arr, offset);
|
|
1275
|
-
offset += arr.length;
|
|
1276
|
-
}
|
|
1277
|
-
return result;
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
// src/runtime/kv.ts
|
|
1281
|
-
var kv_exports = {};
|
|
1282
|
-
__export(kv_exports, {
|
|
1283
|
-
createBrowserKVBindings: () => createBrowserKVBindings,
|
|
1284
|
-
createIndexedDbKV: () => createIndexedDbKV,
|
|
1285
|
-
createKVImports: () => createKVImports,
|
|
1286
|
-
createLocalStorageKV: () => createLocalStorageKV,
|
|
1287
|
-
createMemoryKV: () => createMemoryKV,
|
|
1288
|
-
hasJSPI: () => hasJSPI
|
|
1289
|
-
});
|
|
1290
|
-
|
|
1291
|
-
// src/runtime/kv/memory.ts
|
|
1292
|
-
function createMemoryKV() {
|
|
1293
|
-
const store = /* @__PURE__ */ new Map();
|
|
1294
|
-
function read(key) {
|
|
1295
|
-
const entry = store.get(key);
|
|
1296
|
-
if (!entry) return null;
|
|
1297
|
-
const expiresAt = entry[1];
|
|
1298
|
-
if (expiresAt !== void 0 && Date.now() >= expiresAt) {
|
|
1299
|
-
store.delete(key);
|
|
1300
|
-
return null;
|
|
1301
|
-
}
|
|
1302
|
-
return entry[0];
|
|
1303
|
-
}
|
|
1304
|
-
function write(key, value, options) {
|
|
1305
|
-
let expiresAt;
|
|
1306
|
-
if (options?.expiration !== void 0) {
|
|
1307
|
-
expiresAt = options.expiration * 1e3;
|
|
1308
|
-
} else if (options?.expirationTtl !== void 0) {
|
|
1309
|
-
expiresAt = Date.now() + options.expirationTtl * 1e3;
|
|
1310
|
-
}
|
|
1311
|
-
store.set(key, [value, expiresAt]);
|
|
1312
|
-
}
|
|
1313
|
-
return {
|
|
1314
|
-
async get(key) {
|
|
1315
|
-
return read(key);
|
|
1316
|
-
},
|
|
1317
|
-
async put(key, value, options) {
|
|
1318
|
-
write(key, value, options);
|
|
1319
|
-
},
|
|
1320
|
-
async delete(key) {
|
|
1321
|
-
store.delete(key);
|
|
1322
|
-
},
|
|
1323
|
-
async list(options) {
|
|
1324
|
-
const keys = [...store.keys()].filter((k) => {
|
|
1325
|
-
if (options?.prefix && !k.startsWith(options.prefix)) return false;
|
|
1326
|
-
return read(k) !== null;
|
|
1327
|
-
}).map((name) => ({ name }));
|
|
1328
|
-
return { keys };
|
|
1329
|
-
}
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
// src/runtime/kv/localstorage.ts
|
|
1334
|
-
function getLocalStorage() {
|
|
1335
|
-
if (typeof localStorage === "undefined") {
|
|
1336
|
-
throw new Error("localStorage is not available in this environment");
|
|
1337
|
-
}
|
|
1338
|
-
return localStorage;
|
|
1339
|
-
}
|
|
1340
|
-
function createLocalStorageKV(options = {}) {
|
|
1341
|
-
const storage = getLocalStorage();
|
|
1342
|
-
const namespace = options.namespace ?? "default";
|
|
1343
|
-
const storagePrefix = options.storagePrefix ?? "ziex-kv";
|
|
1344
|
-
const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
|
|
1345
|
-
const namespacePrefix = scopedKey("");
|
|
1346
|
-
return {
|
|
1347
|
-
getSync(key) {
|
|
1348
|
-
return storage.getItem(scopedKey(key));
|
|
1349
|
-
},
|
|
1350
|
-
async get(key) {
|
|
1351
|
-
return this.getSync(key);
|
|
1352
|
-
},
|
|
1353
|
-
putSync(key, value) {
|
|
1354
|
-
storage.setItem(scopedKey(key), value);
|
|
1355
|
-
},
|
|
1356
|
-
async put(key, value) {
|
|
1357
|
-
this.putSync(key, value);
|
|
1358
|
-
},
|
|
1359
|
-
deleteSync(key) {
|
|
1360
|
-
storage.removeItem(scopedKey(key));
|
|
1361
|
-
},
|
|
1362
|
-
async delete(key) {
|
|
1363
|
-
this.deleteSync(key);
|
|
1364
|
-
},
|
|
1365
|
-
listSync(options2) {
|
|
1366
|
-
const prefix = namespacePrefix + (options2?.prefix ?? "");
|
|
1367
|
-
const keys = [];
|
|
1368
|
-
for (let i = 0; i < storage.length; i += 1) {
|
|
1369
|
-
const key = storage.key(i);
|
|
1370
|
-
if (!key || !key.startsWith(prefix)) continue;
|
|
1371
|
-
keys.push({ name: key.slice(namespacePrefix.length) });
|
|
1372
|
-
}
|
|
1373
|
-
return { keys };
|
|
1374
|
-
},
|
|
1375
|
-
async list(options2) {
|
|
1376
|
-
return this.listSync(options2);
|
|
1377
|
-
}
|
|
1378
|
-
};
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
// src/runtime/kv/indexdb.ts
|
|
1382
|
-
function getIndexedDb() {
|
|
1383
|
-
if (typeof indexedDB === "undefined") {
|
|
1384
|
-
throw new Error("IndexedDB is not available in this environment");
|
|
1385
|
-
}
|
|
1386
|
-
return indexedDB;
|
|
1387
|
-
}
|
|
1388
|
-
function requestToPromise(request) {
|
|
1389
|
-
return new Promise((resolve, reject) => {
|
|
1390
|
-
request.onsuccess = () => resolve(request.result);
|
|
1391
|
-
request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
|
|
1392
|
-
});
|
|
1393
|
-
}
|
|
1394
|
-
function transactionToPromise(transaction) {
|
|
1395
|
-
return new Promise((resolve, reject) => {
|
|
1396
|
-
transaction.oncomplete = () => resolve();
|
|
1397
|
-
transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
|
|
1398
|
-
transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
|
|
1399
|
-
});
|
|
1400
|
-
}
|
|
1401
|
-
function createIndexedDbKV(options = {}) {
|
|
1402
|
-
const databaseName = options.databaseName ?? "ziex-kv";
|
|
1403
|
-
const storeName = options.storeName ?? "kv";
|
|
1404
|
-
const namespace = options.namespace ?? "default";
|
|
1405
|
-
const dbPromise = new Promise((resolve, reject) => {
|
|
1406
|
-
const request = getIndexedDb().open(databaseName, 1);
|
|
1407
|
-
request.onupgradeneeded = () => {
|
|
1408
|
-
const db = request.result;
|
|
1409
|
-
if (!db.objectStoreNames.contains(storeName)) {
|
|
1410
|
-
db.createObjectStore(storeName);
|
|
1411
|
-
}
|
|
1412
|
-
};
|
|
1413
|
-
request.onsuccess = () => resolve(request.result);
|
|
1414
|
-
request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
|
|
1415
|
-
});
|
|
1416
|
-
const scopedKey = (key) => `${namespace}:${key}`;
|
|
1417
|
-
return {
|
|
1418
|
-
async get(key) {
|
|
1419
|
-
const db = await dbPromise;
|
|
1420
|
-
const tx = db.transaction(storeName, "readonly");
|
|
1421
|
-
const store = tx.objectStore(storeName);
|
|
1422
|
-
const value = await requestToPromise(store.get(scopedKey(key)));
|
|
1423
|
-
await transactionToPromise(tx);
|
|
1424
|
-
return typeof value === "string" ? value : null;
|
|
1425
|
-
},
|
|
1426
|
-
async put(key, value) {
|
|
1427
|
-
const db = await dbPromise;
|
|
1428
|
-
const tx = db.transaction(storeName, "readwrite");
|
|
1429
|
-
tx.objectStore(storeName).put(value, scopedKey(key));
|
|
1430
|
-
await transactionToPromise(tx);
|
|
1431
|
-
},
|
|
1432
|
-
async delete(key) {
|
|
1433
|
-
const db = await dbPromise;
|
|
1434
|
-
const tx = db.transaction(storeName, "readwrite");
|
|
1435
|
-
tx.objectStore(storeName).delete(scopedKey(key));
|
|
1436
|
-
await transactionToPromise(tx);
|
|
1437
|
-
},
|
|
1438
|
-
async list(options2) {
|
|
1439
|
-
const db = await dbPromise;
|
|
1440
|
-
const tx = db.transaction(storeName, "readonly");
|
|
1441
|
-
const store = tx.objectStore(storeName);
|
|
1442
|
-
const keys = await requestToPromise(store.getAllKeys());
|
|
1443
|
-
await transactionToPromise(tx);
|
|
1444
|
-
const prefix = scopedKey(options2?.prefix ?? "");
|
|
1445
|
-
return {
|
|
1446
|
-
keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace.length + 1) }))
|
|
1447
|
-
};
|
|
1448
|
-
}
|
|
1449
|
-
};
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
// src/runtime/kv.ts
|
|
1453
|
-
function hasJSPI() {
|
|
1454
|
-
return typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
|
|
1455
|
-
}
|
|
1456
|
-
function createBrowserKVBindings(options = {}) {
|
|
1457
|
-
const namespace = options.namespace ?? "default";
|
|
1458
|
-
const isIndexedDb = hasJSPI() && !options.forceLocalStorage;
|
|
1459
|
-
return {
|
|
1460
|
-
[namespace]: isIndexedDb ? createIndexedDbKV(options) : createLocalStorageKV(options)
|
|
1461
|
-
};
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
// src/runtime/index.ts
|
|
1465
|
-
function buildWsImports(Suspending, mem, decoder3, ws) {
|
|
1466
|
-
const readStr = (ptr, len) => decoder3.decode(new Uint8Array(mem().buffer, ptr, len));
|
|
1467
|
-
return {
|
|
1468
|
-
ws_upgrade: () => {
|
|
1469
|
-
ws.upgraded = true;
|
|
1470
|
-
},
|
|
1471
|
-
ws_write: (ptr, len) => {
|
|
1472
|
-
const data = new Uint8Array(mem().buffer, ptr, len).slice();
|
|
1473
|
-
if (!ws.server) {
|
|
1474
|
-
ws.pendingWrites.push(data);
|
|
1475
|
-
} else {
|
|
1476
|
-
ws.server.send(data);
|
|
1477
|
-
}
|
|
1478
|
-
},
|
|
1479
|
-
ws_close: (code, reason_ptr, reason_len) => {
|
|
1480
|
-
ws.server?.close(code, decoder3.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
|
|
1481
|
-
},
|
|
1482
|
-
ws_recv: Suspending ? new Suspending(async (buf_ptr, buf_max) => {
|
|
1483
|
-
if (ws._resolveFirstSuspend) {
|
|
1484
|
-
const fn = ws._resolveFirstSuspend;
|
|
1485
|
-
ws._resolveFirstSuspend = void 0;
|
|
1486
|
-
fn();
|
|
1487
|
-
}
|
|
1488
|
-
const deliver = (bytes) => {
|
|
1489
|
-
if (bytes === null) return -1;
|
|
1490
|
-
const n = Math.min(bytes.length, buf_max);
|
|
1491
|
-
new Uint8Array(mem().buffer, buf_ptr, n).set(bytes.subarray(0, n));
|
|
1492
|
-
return n;
|
|
1493
|
-
};
|
|
1494
|
-
if (ws.messageQueue.length > 0) return deliver(ws.messageQueue.shift());
|
|
1495
|
-
return new Promise((resolve) => {
|
|
1496
|
-
ws.recvResolve = (bytes) => resolve(deliver(bytes));
|
|
1497
|
-
});
|
|
1498
|
-
}) : (_buf_ptr, _buf_max) => -1,
|
|
1499
|
-
// Pub/sub - delegates to optional callbacks (real in DO, no-ops otherwise)
|
|
1500
|
-
ws_subscribe: (ptr, len) => {
|
|
1501
|
-
ws.subscribe?.(readStr(ptr, len));
|
|
1502
|
-
},
|
|
1503
|
-
ws_unsubscribe: (ptr, len) => {
|
|
1504
|
-
ws.unsubscribe?.(readStr(ptr, len));
|
|
1505
|
-
},
|
|
1506
|
-
ws_publish: (topic_ptr, topic_len, data_ptr, data_len) => {
|
|
1507
|
-
const topic = readStr(topic_ptr, topic_len);
|
|
1508
|
-
const data = new Uint8Array(mem().buffer, data_ptr, data_len).slice();
|
|
1509
|
-
return ws.publish?.(topic, data) ?? 0;
|
|
1510
|
-
},
|
|
1511
|
-
ws_is_subscribed: (ptr, len) => ws.isSubscribed?.(readStr(ptr, len)) ? 1 : 0
|
|
1512
|
-
};
|
|
1513
|
-
}
|
|
1514
|
-
function attachWebSocket(ws) {
|
|
1515
|
-
const WebSocketPairCtor = globalThis.WebSocketPair;
|
|
1516
|
-
const pair = new WebSocketPairCtor();
|
|
1517
|
-
const client = pair[0];
|
|
1518
|
-
const server = pair[1];
|
|
1519
|
-
ws.server = server;
|
|
1520
|
-
server.accept();
|
|
1521
|
-
for (const data of ws.pendingWrites) server.send(data);
|
|
1522
|
-
ws.pendingWrites = [];
|
|
1523
|
-
server.addEventListener("message", (event) => {
|
|
1524
|
-
const data = typeof event.data === "string" ? new TextEncoder().encode(event.data) : new Uint8Array(event.data);
|
|
1525
|
-
if (ws.recvResolve) {
|
|
1526
|
-
const res = ws.recvResolve;
|
|
1527
|
-
ws.recvResolve = null;
|
|
1528
|
-
res(data);
|
|
1529
|
-
} else {
|
|
1530
|
-
ws.messageQueue.push(data);
|
|
1531
|
-
}
|
|
1532
|
-
});
|
|
1533
|
-
server.addEventListener("close", () => {
|
|
1534
|
-
if (ws.recvResolve) {
|
|
1535
|
-
const res = ws.recvResolve;
|
|
1536
|
-
ws.recvResolve = null;
|
|
1537
|
-
res(null);
|
|
1538
|
-
}
|
|
1539
|
-
});
|
|
1540
|
-
return { client };
|
|
1541
|
-
}
|
|
1542
|
-
function buildSysImports(jspi, Suspending) {
|
|
1543
|
-
return {
|
|
1544
|
-
sleep_ms: jspi ? new Suspending(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {
|
|
1545
|
-
}
|
|
1546
|
-
};
|
|
1547
|
-
}
|
|
1548
|
-
function executeWasm(instance, jspi, Suspending, wsState) {
|
|
1549
|
-
if (!jspi) {
|
|
1550
|
-
try {
|
|
1551
|
-
instance.exports._start();
|
|
1552
|
-
} catch (e) {
|
|
1553
|
-
if (!(e instanceof ProcExit)) throw e;
|
|
1554
|
-
}
|
|
1555
|
-
return Promise.resolve();
|
|
1556
|
-
}
|
|
1557
|
-
const start = WebAssembly.promising(instance.exports._start);
|
|
1558
|
-
return start().catch((e) => {
|
|
1559
|
-
if (e instanceof Error && e.message.startsWith("proc_exit")) return;
|
|
1560
|
-
throw e;
|
|
1561
|
-
}).finally(() => {
|
|
1562
|
-
if (wsState.recvResolve) {
|
|
1563
|
-
const res = wsState.recvResolve;
|
|
1564
|
-
wsState.recvResolve = null;
|
|
1565
|
-
res(null);
|
|
1566
|
-
}
|
|
1567
|
-
});
|
|
1568
|
-
}
|
|
1569
|
-
function parseZiexMeta(stderrText) {
|
|
1570
|
-
const meta = { status: 200, headers: new Headers(), streaming: false };
|
|
1571
|
-
const metaPrefix = "__ZIEX_META__:";
|
|
1572
|
-
const metaLine = stderrText.split("\n").find((line) => line.startsWith(metaPrefix));
|
|
1573
|
-
if (metaLine) {
|
|
1574
|
-
try {
|
|
1575
|
-
const parsed = JSON.parse(metaLine.slice(metaPrefix.length));
|
|
1576
|
-
if (parsed.status) meta.status = parsed.status;
|
|
1577
|
-
if (parsed.streaming === true) meta.streaming = true;
|
|
1578
|
-
if (Array.isArray(parsed.headers)) {
|
|
1579
|
-
for (const [name, value] of parsed.headers) {
|
|
1580
|
-
meta.headers.append(name, value);
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
} catch {
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
return meta;
|
|
1587
|
-
}
|
|
1588
|
-
async function run({
|
|
1589
|
-
request,
|
|
1590
|
-
env,
|
|
1591
|
-
ctx,
|
|
1592
|
-
module,
|
|
1593
|
-
kv: kvBindings,
|
|
1594
|
-
db: dbBindings,
|
|
1595
|
-
imports,
|
|
1596
|
-
wasi,
|
|
1597
|
-
websocket: doNamespace
|
|
1598
|
-
}) {
|
|
1599
|
-
if (doNamespace && request.headers.get("upgrade")?.toLowerCase() === "websocket") {
|
|
1600
|
-
const id = doNamespace.idFromName(new URL(request.url).pathname);
|
|
1601
|
-
return doNamespace.get(id).fetch(request);
|
|
1602
|
-
}
|
|
1603
|
-
const stdinData = request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
|
|
1604
|
-
const stdoutChunks = [];
|
|
1605
|
-
let streamWriter = null;
|
|
1606
|
-
const { wasiImport, setMemory, collectOutput } = createWasiImports({
|
|
1607
|
-
request,
|
|
1608
|
-
stdinData,
|
|
1609
|
-
onStdout: (chunk) => {
|
|
1610
|
-
if (streamWriter) void streamWriter.write(chunk);
|
|
1611
|
-
else stdoutChunks.push(chunk);
|
|
1612
|
-
}
|
|
1613
|
-
});
|
|
1614
|
-
let wasmMemory = null;
|
|
1615
|
-
const mem = () => wasmMemory;
|
|
1616
|
-
const bridgeRef = [null];
|
|
1617
|
-
const allocRef = [null];
|
|
1618
|
-
const Suspending = WebAssembly.Suspending;
|
|
1619
|
-
const jspi = typeof Suspending === "function";
|
|
1620
|
-
const wsState = {
|
|
1621
|
-
upgraded: false,
|
|
1622
|
-
server: null,
|
|
1623
|
-
pendingWrites: [],
|
|
1624
|
-
messageQueue: [],
|
|
1625
|
-
recvResolve: null
|
|
1626
|
-
};
|
|
1627
|
-
const importObject = {
|
|
1628
|
-
wasi_snapshot_preview1: { ...wasi?.wasiImport, ...wasiImport },
|
|
1629
|
-
__zx_sys: buildSysImports(jspi, Suspending),
|
|
1630
|
-
__zx_ws: buildWsImports(jspi ? Suspending : null, mem, new TextDecoder(), wsState),
|
|
1631
|
-
__zx_net: createFetchImports(mem),
|
|
1632
|
-
...imports ? imports(mem) : {},
|
|
1633
|
-
...ZxWasiBridge.createImportObject(bridgeRef)
|
|
1634
|
-
};
|
|
1635
|
-
if (true) {
|
|
1636
|
-
importObject.__zx_kv = createKVImports(
|
|
1637
|
-
kvBindings ?? { default: createMemoryKV() },
|
|
1638
|
-
mem,
|
|
1639
|
-
allocRef
|
|
1640
|
-
);
|
|
1641
|
-
}
|
|
1642
|
-
if (true) {
|
|
1643
|
-
importObject.__zx_db = createDbImports(
|
|
1644
|
-
dbBindings ?? {},
|
|
1645
|
-
mem,
|
|
1646
|
-
allocRef
|
|
1647
|
-
);
|
|
1648
|
-
}
|
|
1649
|
-
const instance = new WebAssembly.Instance(module, importObject);
|
|
1650
|
-
wasmMemory = instance.exports.memory;
|
|
1651
|
-
setMemory(wasmMemory);
|
|
1652
|
-
bridgeRef[0] = new ZxWasiBridge(instance.exports);
|
|
1653
|
-
bindWasmAlloc(allocRef, instance.exports);
|
|
1654
|
-
const wasmPromise = executeWasm(instance, jspi, Suspending, wsState);
|
|
1655
|
-
if (wsState.upgraded) {
|
|
1656
|
-
const server = attachWebSocket(wsState);
|
|
1657
|
-
ctx?.waitUntil(wasmPromise);
|
|
1658
|
-
return new Response(null, { status: 101, webSocket: server.client });
|
|
1659
|
-
}
|
|
1660
|
-
const { stderrText: earlyStderrText } = collectOutput();
|
|
1661
|
-
const earlyMeta = parseZiexMeta(earlyStderrText);
|
|
1662
|
-
if (earlyMeta.streaming) {
|
|
1663
|
-
const { readable, writable } = new TransformStream();
|
|
1664
|
-
streamWriter = writable.getWriter();
|
|
1665
|
-
for (const chunk of stdoutChunks) void streamWriter.write(chunk);
|
|
1666
|
-
stdoutChunks.length = 0;
|
|
1667
|
-
void wasmPromise.finally(() => streamWriter?.close());
|
|
1668
|
-
return new Response(readable, { status: earlyMeta.status, headers: earlyMeta.headers });
|
|
1669
|
-
}
|
|
1670
|
-
await wasmPromise;
|
|
1671
|
-
const { stderrText } = collectOutput();
|
|
1672
|
-
const meta = parseZiexMeta(stderrText);
|
|
1673
|
-
const body = mergeUint8Arrays(stdoutChunks);
|
|
1674
|
-
meta.headers.delete("transfer-encoding");
|
|
1675
|
-
const nullBody = meta.status === 101 || meta.status === 204 || meta.status === 205 || meta.status === 304;
|
|
1676
|
-
if (nullBody) {
|
|
1677
|
-
meta.headers.delete("content-length");
|
|
1678
|
-
return new Response(null, { status: meta.status, headers: meta.headers });
|
|
1679
|
-
}
|
|
1680
|
-
if (!meta.headers.has("content-length")) meta.headers.set("content-length", String(body.byteLength));
|
|
1681
|
-
return new Response(body.buffer, { status: meta.status, headers: meta.headers });
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
// src/app.ts
|
|
1685
|
-
async function resolveModule(input) {
|
|
1686
|
-
if (typeof input === "string") {
|
|
1687
|
-
if (input.startsWith("http://") || input.startsWith("https://")) {
|
|
1688
|
-
return WebAssembly.compileStreaming(fetch(input));
|
|
1689
|
-
}
|
|
1690
|
-
const url = input.startsWith("/") ? `file://${input}` : input;
|
|
1691
|
-
return WebAssembly.compile(await fetch(url).then((r) => r.arrayBuffer()));
|
|
1692
|
-
}
|
|
1693
|
-
if (input instanceof URL) {
|
|
1694
|
-
return WebAssembly.compileStreaming(fetch(input));
|
|
1695
|
-
}
|
|
1696
|
-
if (input instanceof Response) {
|
|
1697
|
-
return WebAssembly.compileStreaming(input);
|
|
1698
|
-
}
|
|
1699
|
-
if (input instanceof ArrayBuffer) {
|
|
1700
|
-
return WebAssembly.compile(input);
|
|
1701
|
-
}
|
|
1702
|
-
if (ArrayBuffer.isView(input)) {
|
|
1703
|
-
return WebAssembly.compile(input.buffer);
|
|
1704
|
-
}
|
|
1705
|
-
return input;
|
|
1706
|
-
}
|
|
1707
|
-
var Ziex = class {
|
|
1708
|
-
constructor(options) {
|
|
1709
|
-
this.resolved = null;
|
|
1710
|
-
/**
|
|
1711
|
-
* Fetch handler called by the runtime on every request.
|
|
1712
|
-
*
|
|
1713
|
-
* Arrow function so `this` is always the class instance, even when the
|
|
1714
|
-
* runtime extracts `fetch` from the exported object (e.g. Bun).
|
|
1715
|
-
*/
|
|
1716
|
-
this.fetch = async (request, env, ctx) => {
|
|
1717
|
-
const module = await this.getModule();
|
|
1718
|
-
const { wasi, imports, websocket } = this.options;
|
|
1719
|
-
return run({
|
|
1720
|
-
request,
|
|
1721
|
-
env,
|
|
1722
|
-
ctx,
|
|
1723
|
-
module,
|
|
1724
|
-
wasi,
|
|
1725
|
-
imports,
|
|
1726
|
-
kv: this.resolveKV(env),
|
|
1727
|
-
db: this.resolveDB(env),
|
|
1728
|
-
websocket: websocket !== void 0 ? env[websocket] : void 0
|
|
1729
|
-
});
|
|
1730
|
-
};
|
|
1731
|
-
this.options = options;
|
|
1732
|
-
}
|
|
1733
|
-
async getModule() {
|
|
1734
|
-
if (!this.resolved) this.resolved = await resolveModule(this.options.module);
|
|
1735
|
-
return this.resolved;
|
|
1736
|
-
}
|
|
1737
|
-
resolveKV(env) {
|
|
1738
|
-
const { kv } = this.options;
|
|
1739
|
-
if (kv === void 0) return void 0;
|
|
1740
|
-
if (typeof kv === "object" && kv !== null) {
|
|
1741
|
-
const result = {};
|
|
1742
|
-
for (const [name, key] of Object.entries(kv)) {
|
|
1743
|
-
result[name] = env[key];
|
|
1744
|
-
}
|
|
1745
|
-
return result;
|
|
1746
|
-
}
|
|
1747
|
-
return { default: env[kv] };
|
|
1748
|
-
}
|
|
1749
|
-
resolveDB(env) {
|
|
1750
|
-
const { db } = this.options;
|
|
1751
|
-
if (db === void 0) return void 0;
|
|
1752
|
-
if (typeof db === "object" && db !== null) {
|
|
1753
|
-
const result = {};
|
|
1754
|
-
for (const [name, key] of Object.entries(db)) {
|
|
1755
|
-
result[name] = env[key];
|
|
1756
|
-
}
|
|
1757
|
-
return result;
|
|
1758
|
-
}
|
|
1759
|
-
return { default: env[db] };
|
|
1760
|
-
}
|
|
1761
|
-
};
|
|
830
|
+
return { keys };
|
|
831
|
+
}
|
|
1762
832
|
|
|
1763
833
|
// src/wasm/generated/tags.ts
|
|
1764
834
|
var TAG_NAMES = [
|
|
@@ -1969,6 +1039,55 @@ var SVG_TAG_START_INDEX = 140;
|
|
|
1969
1039
|
var CUSTOM_TAG_INDEX = 199;
|
|
1970
1040
|
|
|
1971
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
|
+
}
|
|
1071
|
+
}
|
|
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;
|
|
1079
|
+
}
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
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;
|
|
1088
|
+
}
|
|
1089
|
+
el[name] = val;
|
|
1090
|
+
}
|
|
1972
1091
|
function flushDomCmds(ptr, len, ctx) {
|
|
1973
1092
|
const start = ptr >>> 0;
|
|
1974
1093
|
const length = len >>> 0;
|
|
@@ -1980,6 +1099,7 @@ function flushDomCmds(ptr, len, ctx) {
|
|
|
1980
1099
|
const recordsBytes = count * DOM_CMD_RECORD_SIZE;
|
|
1981
1100
|
if (DOM_CMD_HEADER_SIZE + recordsBytes > length) return;
|
|
1982
1101
|
const { domNodes: domNodes2, cleanupDomNodes: cleanupDomNodes2 } = ctx;
|
|
1102
|
+
const afterConnect = [];
|
|
1983
1103
|
for (let i = 0; i < count; i++) {
|
|
1984
1104
|
const off = DOM_CMD_HEADER_SIZE + i * DOM_CMD_RECORD_SIZE;
|
|
1985
1105
|
const op = view.getUint8(off);
|
|
@@ -2011,266 +1131,963 @@ function flushDomCmds(ptr, len, ctx) {
|
|
|
2011
1131
|
end.parentNode.insertBefore(child, end);
|
|
2012
1132
|
break;
|
|
2013
1133
|
}
|
|
2014
|
-
case DomOp_SetAttr: {
|
|
2015
|
-
domNodes2.get(p0)
|
|
2016
|
-
break;
|
|
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");
|
|
1142
|
+
}
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
case DomOp_SetProp: {
|
|
1146
|
+
const el = domNodes2.get(p0);
|
|
1147
|
+
if (el) assignProp(el, readString(p1, p2), readString(p3, p4));
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
case DomOp_RemoveAttr: {
|
|
1151
|
+
domNodes2.get(p0)?.removeAttribute(readString(p1, p2));
|
|
1152
|
+
break;
|
|
1153
|
+
}
|
|
1154
|
+
case DomOp_SetNodeValue: {
|
|
1155
|
+
const node = domNodes2.get(p0);
|
|
1156
|
+
if (node) node.nodeValue = readString(p1, p2);
|
|
1157
|
+
break;
|
|
1158
|
+
}
|
|
1159
|
+
case DomOp_SetInnerHtml: {
|
|
1160
|
+
const el = domNodes2.get(p0);
|
|
1161
|
+
if (el) el.innerHTML = readString(p1, p2);
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
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);
|
|
1193
|
+
}
|
|
1194
|
+
break;
|
|
1195
|
+
}
|
|
1196
|
+
default:
|
|
1197
|
+
break;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
runAfterConnect(afterConnect);
|
|
1201
|
+
}
|
|
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
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
hasEventHandler(velementId, eventTypeId) {
|
|
1250
|
+
return !!((eventHandlersPresent.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
1251
|
+
}
|
|
1252
|
+
eventMaySuspend(velementId, eventTypeId) {
|
|
1253
|
+
return !!((eventHandlersSuspend.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
1254
|
+
}
|
|
1255
|
+
setEventHandlerMode(velementId, eventTypeId, maySuspend) {
|
|
1256
|
+
const bit = 1 << eventTypeId;
|
|
1257
|
+
const present = (eventHandlersPresent.get(velementId) ?? 0) | bit;
|
|
1258
|
+
eventHandlersPresent.set(velementId, present);
|
|
1259
|
+
const suspendBits = eventHandlersSuspend.get(velementId) ?? 0;
|
|
1260
|
+
const nextSuspend = maySuspend ? suspendBits | bit : suspendBits & ~bit;
|
|
1261
|
+
if (nextSuspend === 0) eventHandlersSuspend.delete(velementId);
|
|
1262
|
+
else eventHandlersSuspend.set(velementId, nextSuspend);
|
|
1263
|
+
ensureDelegatedListener(eventTypeId);
|
|
1264
|
+
}
|
|
1265
|
+
clearEventHandlerModes(velementId) {
|
|
1266
|
+
const present = eventHandlersPresent.get(velementId) ?? 0;
|
|
1267
|
+
eventHandlersPresent.delete(velementId);
|
|
1268
|
+
eventHandlersSuspend.delete(velementId);
|
|
1269
|
+
for (let bits = present & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
|
|
1270
|
+
maybeRemoveHighFreqListener(31 - Math.clz32(bits));
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
/** Submit a form action with bound-state round-trip. */
|
|
1274
|
+
submitFormActionAsync(form, actionId, statesJson, fetchId) {
|
|
1275
|
+
const formData = new FormData(form);
|
|
1276
|
+
formData.append("__$states", statesJson);
|
|
1277
|
+
fetch(window.location.href, {
|
|
1278
|
+
method: "POST",
|
|
1279
|
+
// `>>> 0` reinterprets the i32 from wasm as u32 (ids can exceed 2^31).
|
|
1280
|
+
headers: { "x-action": String(actionId >>> 0) },
|
|
1281
|
+
body: formData
|
|
1282
|
+
}).then(async (response) => {
|
|
1283
|
+
const text = await response.text();
|
|
1284
|
+
this._notifyFetchComplete(fetchId, response.status, text, false);
|
|
1285
|
+
}).catch((error) => {
|
|
1286
|
+
const msg = error instanceof Error ? error.message : "Fetch failed";
|
|
1287
|
+
this._notifyFetchComplete(fetchId, 0, msg, true);
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Create and connect a WebSocket.
|
|
1292
|
+
* Completes via `__zx_cb(ws_open|ws_message|ws_error|ws_close, ...)`.
|
|
1293
|
+
*/
|
|
1294
|
+
wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) {
|
|
1295
|
+
const url = readString(urlPtr, urlLen);
|
|
1296
|
+
const protocolsStr = protocolsLen > 0 ? readString(protocolsPtr, protocolsLen) : "";
|
|
1297
|
+
const protocols = protocolsStr ? protocolsStr.split(",").map((p) => p.trim()).filter(Boolean) : void 0;
|
|
1298
|
+
try {
|
|
1299
|
+
const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
|
|
1300
|
+
ws.binaryType = "arraybuffer";
|
|
1301
|
+
ws.onopen = () => {
|
|
1302
|
+
const protocol = ws.protocol || "";
|
|
1303
|
+
const [ptr, len] = this._writeStringToWasm(protocol);
|
|
1304
|
+
this._invoke(CallbackType_WebSocketOpen, wsId, BigInt(ptr), BigInt(len));
|
|
1305
|
+
};
|
|
1306
|
+
ws.onmessage = (event) => {
|
|
1307
|
+
const isBinary = event.data instanceof ArrayBuffer;
|
|
1308
|
+
const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
|
|
1309
|
+
const [ptr, len] = this.writeBytesToWasm(data);
|
|
1310
|
+
this._invoke(CallbackType_WebSocketMessage, wsId, BigInt(ptr), BigInt(len), BigInt(isBinary ? 1 : 0));
|
|
1311
|
+
};
|
|
1312
|
+
ws.onerror = (_event) => {
|
|
1313
|
+
const [ptr, len] = this._writeStringToWasm("WebSocket error");
|
|
1314
|
+
this._invoke(CallbackType_WebSocketError, wsId, BigInt(ptr), BigInt(len));
|
|
1315
|
+
};
|
|
1316
|
+
ws.onclose = (event) => {
|
|
1317
|
+
const reason = event.reason || "";
|
|
1318
|
+
const [ptr, len] = this._writeStringToWasm(reason);
|
|
1319
|
+
const c = BigInt(len) | BigInt(event.wasClean ? 1 : 0) << 32n;
|
|
1320
|
+
this._invoke(CallbackType_WebSocketClose, wsId, BigInt(event.code), BigInt(ptr), c);
|
|
1321
|
+
this.#websockets.delete(wsId);
|
|
1322
|
+
};
|
|
1323
|
+
this.#websockets.set(wsId, ws);
|
|
1324
|
+
} catch (error) {
|
|
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));
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
/** Send data over WebSocket */
|
|
1331
|
+
wsSend(wsId, dataPtr, dataLen, isBinary) {
|
|
1332
|
+
const ws = this.#websockets.get(wsId);
|
|
1333
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
1334
|
+
const memory = getMemoryView();
|
|
1335
|
+
const start = dataPtr >>> 0;
|
|
1336
|
+
const length = dataLen >>> 0;
|
|
1337
|
+
if (start + length > memory.byteLength) return;
|
|
1338
|
+
if (isBinary) {
|
|
1339
|
+
ws.send(memory.slice(start, start + length));
|
|
1340
|
+
} else {
|
|
1341
|
+
ws.send(textDecoder.decode(memory.subarray(start, start + length)));
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
/** Close WebSocket connection */
|
|
1345
|
+
wsClose(wsId, code, reasonPtr, reasonLen) {
|
|
1346
|
+
const ws = this.#websockets.get(wsId);
|
|
1347
|
+
if (!ws) return;
|
|
1348
|
+
const reason = reasonLen > 0 ? readString(reasonPtr, reasonLen) : void 0;
|
|
1349
|
+
try {
|
|
1350
|
+
if (reason) ws.close(code, reason);
|
|
1351
|
+
else ws.close(code);
|
|
1352
|
+
} catch {
|
|
1353
|
+
ws.close();
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
dispose() {
|
|
1357
|
+
super.dispose();
|
|
1358
|
+
eventHandlersPresent.clear();
|
|
1359
|
+
eventHandlersSuspend.clear();
|
|
1360
|
+
for (const ws of this.#websockets.values()) {
|
|
1361
|
+
try {
|
|
1362
|
+
ws.close();
|
|
1363
|
+
} catch {
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
this.#websockets.clear();
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Dispatch to WASM for one vnode. Caller owns `eventRef` lifetime
|
|
1370
|
+
* (store once per bubble, release after sync/async work completes).
|
|
1371
|
+
*/
|
|
1372
|
+
eventbridge(velementId, eventTypeId, eventRef) {
|
|
1373
|
+
const id = BigInt(velementId >>> 0);
|
|
1374
|
+
if (this.eventMaySuspend(velementId, eventTypeId)) {
|
|
1375
|
+
return invokeWasmExport(this.#eventbridgeAsync, id, eventTypeId, eventRef);
|
|
1376
|
+
}
|
|
1377
|
+
invokeWasmExport(this.#eventbridge, id, eventTypeId, eventRef);
|
|
1378
|
+
}
|
|
1379
|
+
/** Create the full browser import object for WASM instantiation (includes DOM + WebSocket). */
|
|
1380
|
+
static createImportObject(bridgeRef) {
|
|
1381
|
+
return {
|
|
1382
|
+
...jsz.importObject(),
|
|
1383
|
+
__zx_net: createFetchImports(() => {
|
|
1384
|
+
if (!jsz.memory) throw new Error("WASM memory is not ready");
|
|
1385
|
+
return jsz.memory;
|
|
1386
|
+
}),
|
|
1387
|
+
__zx: {
|
|
1388
|
+
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
1389
|
+
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
|
1390
|
+
bridgeRef[0]?.setEventHandlerMode(Number(vnodeId), eventTypeId, maySuspend !== 0);
|
|
1391
|
+
},
|
|
1392
|
+
_clearEventHandlerModes: (vnodeId) => {
|
|
1393
|
+
bridgeRef[0]?.clearEventHandlerModes(Number(vnodeId));
|
|
1394
|
+
},
|
|
1395
|
+
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
1396
|
+
bridgeRef[0]?.fetchAsync(
|
|
1397
|
+
urlPtr,
|
|
1398
|
+
urlLen,
|
|
1399
|
+
methodPtr,
|
|
1400
|
+
methodLen,
|
|
1401
|
+
headersPtr,
|
|
1402
|
+
headersLen,
|
|
1403
|
+
bodyPtr,
|
|
1404
|
+
bodyLen,
|
|
1405
|
+
timeoutMs,
|
|
1406
|
+
fetchId
|
|
1407
|
+
);
|
|
1408
|
+
},
|
|
1409
|
+
_setTimeout: (callbackId, delayMs) => {
|
|
1410
|
+
bridgeRef[0]?.setTimeout(callbackId, delayMs);
|
|
1411
|
+
},
|
|
1412
|
+
_setInterval: (callbackId, intervalMs) => {
|
|
1413
|
+
bridgeRef[0]?.setInterval(callbackId, intervalMs);
|
|
1414
|
+
},
|
|
1415
|
+
_clearInterval: (callbackId) => {
|
|
1416
|
+
bridgeRef[0]?.clearInterval(callbackId);
|
|
1417
|
+
},
|
|
1418
|
+
// WebSocket API
|
|
1419
|
+
_wsConnect: (wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) => {
|
|
1420
|
+
bridgeRef[0]?.wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen);
|
|
1421
|
+
},
|
|
1422
|
+
_wsSend: (wsId, dataPtr, dataLen, isBinary) => {
|
|
1423
|
+
bridgeRef[0]?.wsSend(wsId, dataPtr, dataLen, isBinary);
|
|
1424
|
+
},
|
|
1425
|
+
_wsClose: (wsId, code, reasonPtr, reasonLen) => {
|
|
1426
|
+
bridgeRef[0]?.wsClose(wsId, code, reasonPtr, reasonLen);
|
|
1427
|
+
},
|
|
1428
|
+
_flush: (ptr, len) => {
|
|
1429
|
+
flushDomCmds(ptr, len, {
|
|
1430
|
+
domNodes,
|
|
1431
|
+
cleanupDomNodes
|
|
1432
|
+
});
|
|
1433
|
+
},
|
|
1434
|
+
_getLocationHref: (bufPtr, bufLen) => {
|
|
1435
|
+
const bytes = textEncoder.encode(window.location.href);
|
|
1436
|
+
const len = Math.min(bytes.length, bufLen);
|
|
1437
|
+
writeBytes(bufPtr, bytes.subarray(0, len));
|
|
1438
|
+
return len;
|
|
1439
|
+
},
|
|
1440
|
+
_getFormData: (eventRef, outPtrAddr) => {
|
|
1441
|
+
const event = loadValueFromRef(eventRef);
|
|
1442
|
+
const el = event?.target;
|
|
1443
|
+
const form = el instanceof HTMLFormElement ? el : el?.closest?.("form") ?? null;
|
|
1444
|
+
if (!form) return 0;
|
|
1445
|
+
const entries = [];
|
|
1446
|
+
for (const [k, v] of new FormData(form).entries()) {
|
|
1447
|
+
entries.push(k, String(v));
|
|
1448
|
+
}
|
|
1449
|
+
const bytes = textEncoder.encode(JSON.stringify(entries));
|
|
1450
|
+
const [ptr, len] = bridgeRef[0].writeBytesToWasm(bytes);
|
|
1451
|
+
new DataView(jsz.memory.buffer).setUint32(outPtrAddr, ptr, true);
|
|
1452
|
+
return len;
|
|
1453
|
+
},
|
|
1454
|
+
_submitFormAction: (vnodeId, actionId) => {
|
|
1455
|
+
const form = domNodes.get(Number(vnodeId));
|
|
1456
|
+
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
1457
|
+
const formData = new FormData(form);
|
|
1458
|
+
fetch(window.location.href, {
|
|
1459
|
+
method: "POST",
|
|
1460
|
+
// `>>> 0` reinterprets the i32 from wasm as u32 (ids can exceed 2^31).
|
|
1461
|
+
headers: { "x-action": String(actionId >>> 0) },
|
|
1462
|
+
body: formData
|
|
1463
|
+
}).catch(() => {
|
|
1464
|
+
});
|
|
1465
|
+
},
|
|
1466
|
+
_submitFormActionAsync: (vnodeId, actionId, statesPtr, statesLen, fetchId) => {
|
|
1467
|
+
const form = domNodes.get(Number(vnodeId));
|
|
1468
|
+
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
1469
|
+
const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
|
|
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();
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
var domNodes = /* @__PURE__ */ new Map();
|
|
1481
|
+
var eventHandlersPresent = /* @__PURE__ */ new Map();
|
|
1482
|
+
var eventHandlersSuspend = /* @__PURE__ */ new Map();
|
|
1483
|
+
function cleanupDomNodes(node) {
|
|
1484
|
+
const stack = [node];
|
|
1485
|
+
let highFreqBits = 0;
|
|
1486
|
+
while (stack.length > 0) {
|
|
1487
|
+
const n = stack.pop();
|
|
1488
|
+
const ref = n.__zx_ref;
|
|
1489
|
+
if (typeof ref === "number") {
|
|
1490
|
+
const present = eventHandlersPresent.get(ref);
|
|
1491
|
+
if (present !== void 0) {
|
|
1492
|
+
highFreqBits |= present;
|
|
1493
|
+
eventHandlersPresent.delete(ref);
|
|
1494
|
+
eventHandlersSuspend.delete(ref);
|
|
2017
1495
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
1496
|
+
domNodes.delete(ref);
|
|
1497
|
+
}
|
|
1498
|
+
const children = n.childNodes;
|
|
1499
|
+
for (let i = 0; i < children.length; i++) stack.push(children[i]);
|
|
1500
|
+
}
|
|
1501
|
+
for (let bits = highFreqBits & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
|
|
1502
|
+
maybeRemoveHighFreqListener(31 - Math.clz32(bits));
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
var delegationState = null;
|
|
1506
|
+
function makeDelegatedListener(bridge, eventTypeId) {
|
|
1507
|
+
return (event) => {
|
|
1508
|
+
let eventRef;
|
|
1509
|
+
const pending = [];
|
|
1510
|
+
let target = event.target;
|
|
1511
|
+
while (target && target !== document.body) {
|
|
1512
|
+
const zxRef = target.__zx_ref;
|
|
1513
|
+
if (typeof zxRef === "number" && bridge.hasEventHandler(zxRef, eventTypeId)) {
|
|
1514
|
+
if (eventRef === void 0) eventRef = storeValueGetRef(event);
|
|
1515
|
+
const result = bridge.eventbridge(zxRef, eventTypeId, eventRef);
|
|
1516
|
+
if (result && typeof result.then === "function") {
|
|
1517
|
+
pending.push(result);
|
|
2028
1518
|
}
|
|
2029
|
-
break;
|
|
1519
|
+
if (event.cancelBubble) break;
|
|
2030
1520
|
}
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
1521
|
+
target = target.parentElement;
|
|
1522
|
+
}
|
|
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;
|
|
2034
1671
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
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;
|
|
2039
1682
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
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;
|
|
2044
1692
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
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);
|
|
2050
1740
|
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
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;
|
|
2057
1765
|
}
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
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;
|
|
2066
1786
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
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;
|
|
2074
1803
|
}
|
|
2075
|
-
break;
|
|
2076
1804
|
}
|
|
2077
|
-
|
|
2078
|
-
|
|
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;
|
|
2079
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;
|
|
2080
1966
|
}
|
|
1967
|
+
return result;
|
|
2081
1968
|
}
|
|
2082
1969
|
|
|
2083
|
-
// src/wasm/
|
|
2084
|
-
var
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
"keypress",
|
|
2095
|
-
"mouseenter",
|
|
2096
|
-
"mouseleave",
|
|
2097
|
-
"mousedown",
|
|
2098
|
-
"mouseup",
|
|
2099
|
-
"mousemove",
|
|
2100
|
-
"touchstart",
|
|
2101
|
-
"touchend",
|
|
2102
|
-
"touchmove",
|
|
2103
|
-
"scroll",
|
|
2104
|
-
"wheel",
|
|
2105
|
-
"pointerdown",
|
|
2106
|
-
"pointermove",
|
|
2107
|
-
"pointerup",
|
|
2108
|
-
"pointercancel",
|
|
2109
|
-
"pointerenter",
|
|
2110
|
-
"pointerleave",
|
|
2111
|
-
"lostpointercapture"
|
|
2112
|
-
];
|
|
2113
|
-
|
|
2114
|
-
// src/wasm/generated/event_bits.ts
|
|
2115
|
-
var HIGH_FREQ_EVENT_BITS = 3031040;
|
|
2116
|
-
|
|
2117
|
-
// src/wasm/index.ts
|
|
2118
|
-
var ZxBridge = class extends ZxBridgeCore {
|
|
2119
|
-
#websockets = /* @__PURE__ */ new Map();
|
|
2120
|
-
#eventbridge;
|
|
2121
|
-
#eventbridgeAsync;
|
|
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;
|
|
2122
1981
|
constructor(exports) {
|
|
2123
|
-
|
|
2124
|
-
this.#
|
|
2125
|
-
this.#
|
|
2126
|
-
exports.__zx_eventbridge_async ?? exports.__zx_eventbridge
|
|
2127
|
-
);
|
|
2128
|
-
}
|
|
2129
|
-
hasEventHandler(velementId, eventTypeId) {
|
|
2130
|
-
return !!((eventHandlersPresent.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
2131
|
-
}
|
|
2132
|
-
eventMaySuspend(velementId, eventTypeId) {
|
|
2133
|
-
return !!((eventHandlersSuspend.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
2134
|
-
}
|
|
2135
|
-
setEventHandlerMode(velementId, eventTypeId, maySuspend) {
|
|
2136
|
-
const bit = 1 << eventTypeId;
|
|
2137
|
-
const present = (eventHandlersPresent.get(velementId) ?? 0) | bit;
|
|
2138
|
-
eventHandlersPresent.set(velementId, present);
|
|
2139
|
-
const suspendBits = eventHandlersSuspend.get(velementId) ?? 0;
|
|
2140
|
-
const nextSuspend = maySuspend ? suspendBits | bit : suspendBits & ~bit;
|
|
2141
|
-
if (nextSuspend === 0) eventHandlersSuspend.delete(velementId);
|
|
2142
|
-
else eventHandlersSuspend.set(velementId, nextSuspend);
|
|
2143
|
-
ensureDelegatedListener(eventTypeId);
|
|
2144
|
-
}
|
|
2145
|
-
clearEventHandlerModes(velementId) {
|
|
2146
|
-
const present = eventHandlersPresent.get(velementId) ?? 0;
|
|
2147
|
-
eventHandlersPresent.delete(velementId);
|
|
2148
|
-
eventHandlersSuspend.delete(velementId);
|
|
2149
|
-
for (let bits = present & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
|
|
2150
|
-
maybeRemoveHighFreqListener(31 - Math.clz32(bits));
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
/** Submit a form action with bound-state round-trip. */
|
|
2154
|
-
submitFormActionAsync(form, actionId, statesJson, fetchId) {
|
|
2155
|
-
const formData = new FormData(form);
|
|
2156
|
-
formData.append("__$states", statesJson);
|
|
2157
|
-
fetch(window.location.href, {
|
|
2158
|
-
method: "POST",
|
|
2159
|
-
// `>>> 0` reinterprets the i32 from wasm as u32 (ids can exceed 2^31).
|
|
2160
|
-
headers: { "x-action": String(actionId >>> 0) },
|
|
2161
|
-
body: formData
|
|
2162
|
-
}).then(async (response) => {
|
|
2163
|
-
const text = await response.text();
|
|
2164
|
-
this._notifyFetchComplete(fetchId, response.status, text, false);
|
|
2165
|
-
}).catch((error) => {
|
|
2166
|
-
const msg = error instanceof Error ? error.message : "Fetch failed";
|
|
2167
|
-
this._notifyFetchComplete(fetchId, 0, msg, true);
|
|
2168
|
-
});
|
|
1982
|
+
this.#memory = exports.memory;
|
|
1983
|
+
this.#alloc = exports.__zx_alloc;
|
|
1984
|
+
this.#cb = exports.__zx_cb;
|
|
2169
1985
|
}
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
const url = readString(urlPtr, urlLen);
|
|
2176
|
-
const protocolsStr = protocolsLen > 0 ? readString(protocolsPtr, protocolsLen) : "";
|
|
2177
|
-
const protocols = protocolsStr ? protocolsStr.split(",").map((p) => p.trim()).filter(Boolean) : void 0;
|
|
2178
|
-
try {
|
|
2179
|
-
const ws = protocols && protocols.length > 0 ? new WebSocket(url, protocols) : new WebSocket(url);
|
|
2180
|
-
ws.binaryType = "arraybuffer";
|
|
2181
|
-
ws.onopen = () => {
|
|
2182
|
-
const protocol = ws.protocol || "";
|
|
2183
|
-
const [ptr, len] = this._writeStringToWasm(protocol);
|
|
2184
|
-
this._invoke(CallbackType_WebSocketOpen, wsId, BigInt(ptr), BigInt(len));
|
|
2185
|
-
};
|
|
2186
|
-
ws.onmessage = (event) => {
|
|
2187
|
-
const isBinary = event.data instanceof ArrayBuffer;
|
|
2188
|
-
const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
|
|
2189
|
-
const [ptr, len] = this.writeBytesToWasm(data);
|
|
2190
|
-
this._invoke(CallbackType_WebSocketMessage, wsId, BigInt(ptr), BigInt(len), BigInt(isBinary ? 1 : 0));
|
|
2191
|
-
};
|
|
2192
|
-
ws.onerror = (_event) => {
|
|
2193
|
-
const [ptr, len] = this._writeStringToWasm("WebSocket error");
|
|
2194
|
-
this._invoke(CallbackType_WebSocketError, wsId, BigInt(ptr), BigInt(len));
|
|
2195
|
-
};
|
|
2196
|
-
ws.onclose = (event) => {
|
|
2197
|
-
const reason = event.reason || "";
|
|
2198
|
-
const [ptr, len] = this._writeStringToWasm(reason);
|
|
2199
|
-
const c = BigInt(len) | BigInt(event.wasClean ? 1 : 0) << 32n;
|
|
2200
|
-
this._invoke(CallbackType_WebSocketClose, wsId, BigInt(event.code), BigInt(ptr), c);
|
|
2201
|
-
this.#websockets.delete(wsId);
|
|
2202
|
-
};
|
|
2203
|
-
this.#websockets.set(wsId, ws);
|
|
2204
|
-
} catch (error) {
|
|
2205
|
-
const msg = error instanceof Error ? error.message : "WebSocket connection failed";
|
|
2206
|
-
const [ptr, len] = this._writeStringToWasm(msg);
|
|
2207
|
-
this._invoke(CallbackType_WebSocketError, wsId, BigInt(ptr), BigInt(len));
|
|
1986
|
+
#view() {
|
|
1987
|
+
const buf = this.#memory.buffer;
|
|
1988
|
+
if (buf !== this.#memBuf) {
|
|
1989
|
+
this.#memBuf = buf;
|
|
1990
|
+
this.#memView = new Uint8Array(buf);
|
|
2208
1991
|
}
|
|
1992
|
+
return this.#memView;
|
|
2209
1993
|
}
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
const
|
|
2213
|
-
if (
|
|
2214
|
-
const
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
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;
|
|
2222
2026
|
}
|
|
2223
2027
|
}
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
const
|
|
2227
|
-
|
|
2228
|
-
const
|
|
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 = {};
|
|
2229
2034
|
try {
|
|
2230
|
-
|
|
2231
|
-
else ws.close(code);
|
|
2035
|
+
headers = JSON.parse(headersJson);
|
|
2232
2036
|
} catch {
|
|
2233
|
-
|
|
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
|
+
}
|
|
2234
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
|
+
});
|
|
2235
2058
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
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);
|
|
2245
2078
|
}
|
|
2246
|
-
this.#websockets.clear();
|
|
2247
2079
|
}
|
|
2248
2080
|
/**
|
|
2249
|
-
*
|
|
2250
|
-
*
|
|
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.
|
|
2251
2085
|
*/
|
|
2252
|
-
eventbridge(velementId, eventTypeId, eventRef) {
|
|
2253
|
-
const id = BigInt(velementId >>> 0);
|
|
2254
|
-
if (this.eventMaySuspend(velementId, eventTypeId)) {
|
|
2255
|
-
return invokeWasmExport(this.#eventbridgeAsync, id, eventTypeId, eventRef);
|
|
2256
|
-
}
|
|
2257
|
-
invokeWasmExport(this.#eventbridge, id, eventTypeId, eventRef);
|
|
2258
|
-
}
|
|
2259
|
-
/** Create the full browser import object for WASM instantiation (includes DOM + WebSocket). */
|
|
2260
2086
|
static createImportObject(bridgeRef) {
|
|
2261
2087
|
return {
|
|
2262
|
-
...jsz.importObject(),
|
|
2263
|
-
__zx_net: createFetchImports(() => {
|
|
2264
|
-
if (!jsz.memory) throw new Error("WASM memory is not ready");
|
|
2265
|
-
return jsz.memory;
|
|
2266
|
-
}),
|
|
2267
2088
|
__zx: {
|
|
2268
|
-
_log: (level, ptr, len) =>
|
|
2269
|
-
|
|
2270
|
-
bridgeRef[0]?.setEventHandlerMode(Number(vnodeId), eventTypeId, maySuspend !== 0);
|
|
2271
|
-
},
|
|
2272
|
-
_clearEventHandlerModes: (vnodeId) => {
|
|
2273
|
-
bridgeRef[0]?.clearEventHandlerModes(Number(vnodeId));
|
|
2089
|
+
_log: (level, ptr, len) => {
|
|
2090
|
+
bridgeRef[0]?.log(level, ptr, len);
|
|
2274
2091
|
},
|
|
2275
2092
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
2276
2093
|
bridgeRef[0]?.fetchAsync(
|
|
@@ -2294,188 +2111,330 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
2294
2111
|
},
|
|
2295
2112
|
_clearInterval: (callbackId) => {
|
|
2296
2113
|
bridgeRef[0]?.clearInterval(callbackId);
|
|
2297
|
-
},
|
|
2298
|
-
// WebSocket API
|
|
2299
|
-
_wsConnect: (wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) => {
|
|
2300
|
-
bridgeRef[0]?.wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen);
|
|
2301
|
-
},
|
|
2302
|
-
_wsSend: (wsId, dataPtr, dataLen, isBinary) => {
|
|
2303
|
-
bridgeRef[0]?.wsSend(wsId, dataPtr, dataLen, isBinary);
|
|
2304
|
-
},
|
|
2305
|
-
_wsClose: (wsId, code, reasonPtr, reasonLen) => {
|
|
2306
|
-
bridgeRef[0]?.wsClose(wsId, code, reasonPtr, reasonLen);
|
|
2307
|
-
},
|
|
2308
|
-
_flush: (ptr, len) => {
|
|
2309
|
-
flushDomCmds(ptr, len, {
|
|
2310
|
-
domNodes,
|
|
2311
|
-
cleanupDomNodes
|
|
2312
|
-
});
|
|
2313
|
-
},
|
|
2314
|
-
_getLocationHref: (bufPtr, bufLen) => {
|
|
2315
|
-
const bytes = textEncoder.encode(window.location.href);
|
|
2316
|
-
const len = Math.min(bytes.length, bufLen);
|
|
2317
|
-
writeBytes(bufPtr, bytes.subarray(0, len));
|
|
2318
|
-
return len;
|
|
2319
|
-
},
|
|
2320
|
-
_getFormData: (eventRef, outPtrAddr) => {
|
|
2321
|
-
const event = loadValueFromRef(eventRef);
|
|
2322
|
-
const el = event?.target;
|
|
2323
|
-
const form = el instanceof HTMLFormElement ? el : el?.closest?.("form") ?? null;
|
|
2324
|
-
if (!form) return 0;
|
|
2325
|
-
const entries = [];
|
|
2326
|
-
for (const [k, v] of new FormData(form).entries()) {
|
|
2327
|
-
entries.push(k, String(v));
|
|
2328
|
-
}
|
|
2329
|
-
const bytes = textEncoder.encode(JSON.stringify(entries));
|
|
2330
|
-
const [ptr, len] = bridgeRef[0].writeBytesToWasm(bytes);
|
|
2331
|
-
new DataView(jsz.memory.buffer).setUint32(outPtrAddr, ptr, true);
|
|
2332
|
-
return len;
|
|
2333
|
-
},
|
|
2334
|
-
_submitFormAction: (vnodeId, actionId) => {
|
|
2335
|
-
const form = domNodes.get(Number(vnodeId));
|
|
2336
|
-
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
2337
|
-
const formData = new FormData(form);
|
|
2338
|
-
fetch(window.location.href, {
|
|
2339
|
-
method: "POST",
|
|
2340
|
-
// `>>> 0` reinterprets the i32 from wasm as u32 (ids can exceed 2^31).
|
|
2341
|
-
headers: { "x-action": String(actionId >>> 0) },
|
|
2342
|
-
body: formData
|
|
2343
|
-
}).catch(() => {
|
|
2344
|
-
});
|
|
2345
|
-
},
|
|
2346
|
-
_submitFormActionAsync: (vnodeId, actionId, statesPtr, statesLen, fetchId) => {
|
|
2347
|
-
const form = domNodes.get(Number(vnodeId));
|
|
2348
|
-
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
2349
|
-
const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
|
|
2350
|
-
bridgeRef[0]?.submitFormActionAsync(form, actionId, statesJson, fetchId);
|
|
2351
2114
|
}
|
|
2352
2115
|
}
|
|
2353
2116
|
};
|
|
2354
2117
|
}
|
|
2355
2118
|
};
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
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
|
+
}
|
|
2371
2141
|
}
|
|
2372
|
-
|
|
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);
|
|
2373
2231
|
}
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
}
|
|
2377
|
-
for (let bits = highFreqBits & HIGH_FREQ_EVENT_BITS; bits !== 0; bits &= bits - 1) {
|
|
2378
|
-
maybeRemoveHighFreqListener(31 - Math.clz32(bits));
|
|
2379
|
-
}
|
|
2232
|
+
});
|
|
2233
|
+
return { client };
|
|
2380
2234
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
let eventRef;
|
|
2385
|
-
const pending = [];
|
|
2386
|
-
let target = event.target;
|
|
2387
|
-
while (target && target !== document.body) {
|
|
2388
|
-
const zxRef = target.__zx_ref;
|
|
2389
|
-
if (typeof zxRef === "number" && bridge.hasEventHandler(zxRef, eventTypeId)) {
|
|
2390
|
-
if (eventRef === void 0) eventRef = storeValueGetRef(event);
|
|
2391
|
-
const result = bridge.eventbridge(zxRef, eventTypeId, eventRef);
|
|
2392
|
-
if (result && typeof result.then === "function") {
|
|
2393
|
-
pending.push(result);
|
|
2394
|
-
}
|
|
2395
|
-
if (event.cancelBubble) break;
|
|
2396
|
-
}
|
|
2397
|
-
target = target.parentElement;
|
|
2398
|
-
}
|
|
2399
|
-
if (eventRef !== void 0) {
|
|
2400
|
-
const ref = eventRef;
|
|
2401
|
-
if (pending.length > 0) {
|
|
2402
|
-
Promise.all(pending).finally(() => releaseValueRef(ref));
|
|
2403
|
-
} else {
|
|
2404
|
-
releaseValueRef(ref);
|
|
2405
|
-
}
|
|
2235
|
+
function buildSysImports(jspi2, Suspending2) {
|
|
2236
|
+
return {
|
|
2237
|
+
sleep_ms: jspi2 ? new Suspending2(async (ms) => new Promise((r) => setTimeout(r, ms))) : (_ms) => {
|
|
2406
2238
|
}
|
|
2407
2239
|
};
|
|
2408
2240
|
}
|
|
2409
|
-
function
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
state.root.addEventListener(domType, listener, options);
|
|
2418
|
-
state.attached.set(eventTypeId, { listener, options });
|
|
2419
|
-
}
|
|
2420
|
-
function anyHandlerForType(eventTypeId) {
|
|
2421
|
-
const bit = 1 << eventTypeId;
|
|
2422
|
-
for (const mask of eventHandlersPresent.values()) {
|
|
2423
|
-
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();
|
|
2424
2249
|
}
|
|
2425
|
-
|
|
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
|
+
});
|
|
2426
2261
|
}
|
|
2427
|
-
function
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
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 });
|
|
2437
2363
|
}
|
|
2438
2364
|
|
|
2439
|
-
// src/platforms/cloudflare/
|
|
2440
|
-
|
|
2441
|
-
|
|
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 {
|
|
2442
2403
|
constructor(state, env) {
|
|
2443
|
-
/** All active connections in this room, keyed by their server-side WebSocket. */
|
|
2444
2404
|
this.connections = /* @__PURE__ */ new Map();
|
|
2445
|
-
this.
|
|
2405
|
+
this.state = state;
|
|
2446
2406
|
this.env = env;
|
|
2447
2407
|
}
|
|
2448
2408
|
async fetch(request) {
|
|
2449
|
-
const
|
|
2409
|
+
const isUpgrade = request.headers.get("upgrade")?.toLowerCase() === "websocket";
|
|
2410
|
+
const stdinData = !isUpgrade && request.body ? new Uint8Array(await request.arrayBuffer()) : void 0;
|
|
2450
2411
|
const { wasiImport, setMemory } = createWasiImports({ request, stdinData });
|
|
2451
2412
|
let wasmMemory = null;
|
|
2452
2413
|
const mem = () => wasmMemory;
|
|
2453
2414
|
const bridgeRef = [null];
|
|
2454
2415
|
const bridgeImports = ZxBridge.createImportObject(bridgeRef);
|
|
2455
|
-
const
|
|
2456
|
-
const
|
|
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
|
+
}
|
|
2457
2421
|
const decoder3 = new TextDecoder();
|
|
2458
|
-
let _resolveFirstSuspend;
|
|
2459
|
-
const firstSuspendPromise = new Promise((resolve) => {
|
|
2460
|
-
_resolveFirstSuspend = resolve;
|
|
2461
|
-
});
|
|
2462
|
-
let wasmExited = false;
|
|
2463
2422
|
const connState = {
|
|
2464
2423
|
upgraded: false,
|
|
2465
2424
|
server: null,
|
|
2466
2425
|
pendingWrites: [],
|
|
2467
2426
|
messageQueue: [],
|
|
2468
2427
|
recvResolve: null,
|
|
2469
|
-
_resolveFirstSuspend,
|
|
2470
2428
|
topics: /* @__PURE__ */ new Set(),
|
|
2471
2429
|
subscribe: (topic) => connState.topics.add(topic),
|
|
2472
2430
|
unsubscribe: (topic) => connState.topics.delete(topic),
|
|
2473
2431
|
publish: (topic, data) => {
|
|
2474
2432
|
let count = 0;
|
|
2475
|
-
|
|
2433
|
+
const text = textDecoder2.decode(data);
|
|
2434
|
+
for (const [sock, conn] of this.connections) {
|
|
2476
2435
|
if (conn.topics.has(topic)) {
|
|
2477
2436
|
try {
|
|
2478
|
-
|
|
2437
|
+
sock.send(text);
|
|
2479
2438
|
count++;
|
|
2480
2439
|
} catch {
|
|
2481
2440
|
}
|
|
@@ -2490,10 +2449,20 @@ function createWebSocketDO(module, options) {
|
|
|
2490
2449
|
isSubscribed: (topic) => connState.topics.has(topic)
|
|
2491
2450
|
};
|
|
2492
2451
|
const sysImports = {
|
|
2493
|
-
sleep_ms:
|
|
2494
|
-
|
|
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
|
|
2495
2465
|
};
|
|
2496
|
-
const wsImports = buildWsImports(jspi ? Suspending : null, mem, decoder3, connState);
|
|
2497
2466
|
const kvBindings = options?.kv?.(this.env);
|
|
2498
2467
|
const dbBindings = options?.db?.(this.env);
|
|
2499
2468
|
const allocRef = [null];
|
|
@@ -2501,23 +2470,20 @@ function createWebSocketDO(module, options) {
|
|
|
2501
2470
|
wasi_snapshot_preview1: wasiImport,
|
|
2502
2471
|
__zx_sys: sysImports,
|
|
2503
2472
|
__zx_ws: wsImports,
|
|
2473
|
+
__zx_http: buildHttpImports(mem, httpState),
|
|
2504
2474
|
__zx_net: createFetchImports(mem),
|
|
2505
2475
|
...options?.imports ? options.imports(mem) : {},
|
|
2506
2476
|
...bridgeImports
|
|
2507
2477
|
};
|
|
2508
2478
|
if (true) {
|
|
2509
2479
|
importObject.__zx_kv = createKVImports(
|
|
2510
|
-
kvBindings ?? { default:
|
|
2480
|
+
kvBindings ?? { default: { get: get4, put: put4, del: del4, list: list4 } },
|
|
2511
2481
|
mem,
|
|
2512
2482
|
allocRef
|
|
2513
2483
|
);
|
|
2514
2484
|
}
|
|
2515
2485
|
if (true) {
|
|
2516
|
-
importObject.__zx_db = createDbImports(
|
|
2517
|
-
dbBindings ?? {},
|
|
2518
|
-
mem,
|
|
2519
|
-
allocRef
|
|
2520
|
-
);
|
|
2486
|
+
importObject.__zx_db = createDbImports(dbBindings ?? {}, mem, allocRef);
|
|
2521
2487
|
}
|
|
2522
2488
|
const instance = new WebAssembly.Instance(module, importObject);
|
|
2523
2489
|
wasmMemory = instance.exports.memory;
|
|
@@ -2526,31 +2492,142 @@ function createWebSocketDO(module, options) {
|
|
|
2526
2492
|
bindWasmAlloc(allocRef, instance.exports);
|
|
2527
2493
|
const start = WebAssembly.promising(instance.exports._start);
|
|
2528
2494
|
const wasmPromise = start().catch((e) => {
|
|
2529
|
-
wasmExited = true;
|
|
2530
2495
|
if (e instanceof Error && e.message.startsWith("proc_exit")) return;
|
|
2531
|
-
console.error("[
|
|
2496
|
+
console.error("[StatefulFetch] WASM error:", e);
|
|
2532
2497
|
}).finally(() => {
|
|
2533
2498
|
if (connState.server) this.connections.delete(connState.server);
|
|
2534
|
-
|
|
2535
|
-
const res = connState.recvResolve;
|
|
2536
|
-
connState.recvResolve = null;
|
|
2537
|
-
res(null);
|
|
2538
|
-
}
|
|
2499
|
+
deliverToWasm(connState, null);
|
|
2539
2500
|
});
|
|
2540
|
-
|
|
2541
|
-
|
|
2501
|
+
if (!connState.upgraded) {
|
|
2502
|
+
await wasmPromise;
|
|
2542
2503
|
return new Response("WebSocket upgrade expected", { status: 426 });
|
|
2543
2504
|
}
|
|
2544
|
-
const
|
|
2505
|
+
const client = attachWebSocketPair(connState);
|
|
2545
2506
|
this.connections.set(connState.server, connState);
|
|
2546
|
-
this.
|
|
2507
|
+
this.state.waitUntil(wasmPromise);
|
|
2547
2508
|
return new Response(null, { status: 101, webSocket: client });
|
|
2548
2509
|
}
|
|
2549
2510
|
};
|
|
2550
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
|
+
}
|
|
2551
2622
|
export {
|
|
2552
2623
|
Ziex,
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
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
|
|
2556
2633
|
};
|