ziex 0.1.0-dev.1389 → 0.1.0-dev.1466

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +4 -1
  2. package/app.d.ts +6 -6
  3. package/build.zig.zon +1 -1
  4. package/index.js +490 -174
  5. package/package.json +7 -5
  6. package/{aws-lambda → platforms/aws-lambda}/index.js +1 -1
  7. package/platforms/cloudflare/app.d.ts +2 -0
  8. package/platforms/cloudflare/db.d.ts +6 -0
  9. package/{cloudflare → platforms/cloudflare}/do.d.ts +5 -5
  10. package/platforms/cloudflare/index.d.ts +4 -0
  11. package/{cloudflare → platforms/cloudflare}/index.js +1959 -1532
  12. package/platforms/cloudflare/kv.d.ts +5 -0
  13. package/platforms/cloudflare/worker.d.ts +3 -0
  14. package/{vercel → platforms/vercel}/index.js +1 -1
  15. package/runtime/db/extern.d.ts +38 -0
  16. package/runtime/db/sqlite.d.ts +7 -0
  17. package/runtime/db.d.ts +3 -0
  18. package/runtime/db.js +419 -0
  19. package/{fetch.d.ts → runtime/fetch.d.ts} +1 -1
  20. package/{runtime.d.ts → runtime/index.d.ts} +6 -15
  21. package/runtime/kv/extern.d.ts +11 -0
  22. package/runtime/kv/indexdb.d.ts +7 -0
  23. package/runtime/kv/localstorage.d.ts +6 -0
  24. package/runtime/kv/memory.d.ts +6 -0
  25. package/runtime/kv.d.ts +45 -0
  26. package/runtime/kv.js +543 -0
  27. package/wasm/constants.d.ts +33 -0
  28. package/wasm/core.d.ts +23 -33
  29. package/wasm/dom_cmd.d.ts +15 -0
  30. package/wasm/generated/event_bits.d.ts +2 -0
  31. package/wasm/generated/events.d.ts +1 -0
  32. package/wasm/generated/tag_indices.d.ts +2 -0
  33. package/wasm/generated/tags.d.ts +1 -0
  34. package/wasm/index.d.ts +15 -13
  35. package/wasm/index.js +911 -676
  36. package/wasm/init.dev.js +895 -674
  37. package/wasm/init.js +3 -3
  38. package/wasm/wasi.d.ts +1 -5
  39. package/browser/kv.d.ts +0 -13
  40. package/cloudflare/app.d.ts +0 -2
  41. package/cloudflare/db.d.ts +0 -2
  42. package/cloudflare/index.d.ts +0 -4
  43. package/cloudflare/kv.d.ts +0 -2
  44. package/cloudflare/worker.d.ts +0 -3
  45. package/db.d.ts +0 -22
  46. package/kv.d.ts +0 -42
  47. /package/{aws-lambda → platforms/aws-lambda}/index.d.ts +0 -0
  48. /package/{vercel → platforms/vercel}/index.d.ts +0 -0
  49. /package/{wasi.d.ts → runtime/wasi.d.ts} +0 -0
package/index.js CHANGED
@@ -1,9 +1,14 @@
1
+ // src/wasm/constants.ts
2
+ var CallbackType_FetchSuccess = 1;
3
+ var CallbackType_FetchError = 2;
4
+ var CallbackType_Timeout = 3;
5
+ var CallbackType_Interval = 4;
6
+
1
7
  // src/wasm/wasi.ts
2
8
  var decoder = new TextDecoder();
3
9
  var encoder = new TextEncoder();
4
10
  var ZxWasiBridge = class {
5
11
  #alloc;
6
- #fetchCompleteHandler;
7
12
  #memory;
8
13
  #cb;
9
14
  #intervals = /* @__PURE__ */ new Map();
@@ -13,7 +18,6 @@ var ZxWasiBridge = class {
13
18
  constructor(exports) {
14
19
  this.#memory = exports.memory;
15
20
  this.#alloc = exports.__zx_alloc;
16
- this.#fetchCompleteHandler = exports.__zx_fetch_complete;
17
21
  this.#cb = exports.__zx_cb;
18
22
  }
19
23
  #view() {
@@ -25,10 +29,21 @@ var ZxWasiBridge = class {
25
29
  return this.#memView;
26
30
  }
27
31
  #readString(ptr, len) {
28
- return decoder.decode(this.#view().subarray(ptr, ptr + len));
32
+ const start = ptr >>> 0;
33
+ const length = len >>> 0;
34
+ if (length === 0) return "";
35
+ const view = this.#view();
36
+ if (start + length > view.byteLength) return "";
37
+ return decoder.decode(view.subarray(start, start + length));
29
38
  }
30
39
  #writeBytes(ptr, data) {
31
- this.#view().set(data, ptr);
40
+ const start = ptr >>> 0;
41
+ const view = this.#view();
42
+ if (start + data.length > view.byteLength) return;
43
+ view.set(data, start);
44
+ }
45
+ #invoke(type, id, a = 0n, b = 0n, c = 0n) {
46
+ this.#cb?.(type, id, a, b, c);
32
47
  }
33
48
  log(level, ptr, len) {
34
49
  const msg = decoder.decode(this.#view().subarray(ptr, ptr + len));
@@ -82,13 +97,14 @@ var ZxWasiBridge = class {
82
97
  const encoded = typeof body === "string" ? encoder.encode(body) : body;
83
98
  const ptr = this.#alloc(encoded.length);
84
99
  this.#writeBytes(ptr, encoded);
85
- this.#fetchCompleteHandler(fetchId, status, ptr, encoded.length, isError ? 1 : 0);
100
+ const type = isError ? CallbackType_FetchError : CallbackType_FetchSuccess;
101
+ this.#invoke(type, fetchId, BigInt(status), BigInt(ptr), BigInt(encoded.length));
86
102
  }
87
103
  setTimeout(callbackId, delayMs) {
88
- setTimeout(() => this.#cb?.(3, callbackId, 0n), delayMs);
104
+ setTimeout(() => this.#invoke(CallbackType_Timeout, callbackId), delayMs);
89
105
  }
90
106
  setInterval(callbackId, intervalMs) {
91
- const handle = setInterval(() => this.#cb?.(4, callbackId, 0n), intervalMs);
107
+ const handle = setInterval(() => this.#invoke(CallbackType_Interval, callbackId), intervalMs);
92
108
  this.#intervals.set(callbackId, handle);
93
109
  }
94
110
  clearInterval(callbackId) {
@@ -108,10 +124,10 @@ var ZxWasiBridge = class {
108
124
  return {
109
125
  __zx: {
110
126
  _log: (level, ptr, len) => {
111
- bridgeRef.current?.log(level, ptr, len);
127
+ bridgeRef[0]?.log(level, ptr, len);
112
128
  },
113
129
  _fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
114
- bridgeRef.current?.fetchAsync(
130
+ bridgeRef[0]?.fetchAsync(
115
131
  urlPtr,
116
132
  urlLen,
117
133
  methodPtr,
@@ -125,77 +141,376 @@ var ZxWasiBridge = class {
125
141
  );
126
142
  },
127
143
  _setTimeout: (callbackId, delayMs) => {
128
- bridgeRef.current?.setTimeout(callbackId, delayMs);
144
+ bridgeRef[0]?.setTimeout(callbackId, delayMs);
129
145
  },
130
146
  _setInterval: (callbackId, intervalMs) => {
131
- bridgeRef.current?.setInterval(callbackId, intervalMs);
147
+ bridgeRef[0]?.setInterval(callbackId, intervalMs);
132
148
  },
133
149
  _clearInterval: (callbackId) => {
134
- bridgeRef.current?.clearInterval(callbackId);
150
+ bridgeRef[0]?.clearInterval(callbackId);
135
151
  }
136
152
  }
137
153
  };
138
154
  }
139
155
  };
140
156
 
141
- // src/kv.ts
142
- function putOptions(ttlSeconds) {
143
- if (ttlSeconds < 60) return void 0;
144
- return { expirationTtl: ttlSeconds };
145
- }
146
- function createMemoryKV() {
147
- const store = /* @__PURE__ */ new Map();
148
- function read(key) {
149
- const entry = store.get(key);
150
- if (!entry) return null;
151
- if (entry.expiresAt !== void 0 && Date.now() >= entry.expiresAt) {
152
- store.delete(key);
153
- return null;
157
+ // src/runtime/fetch.ts
158
+ function createFetchImports(getMemory) {
159
+ const encoder3 = new TextEncoder();
160
+ const decoder3 = new TextDecoder();
161
+ function readStr(ptr, len) {
162
+ return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
163
+ }
164
+ function writeBytes(buf_ptr, buf_max, data) {
165
+ if (data.length > buf_max) return -2;
166
+ new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
167
+ return data.length;
168
+ }
169
+ function readBytes(ptr, len) {
170
+ return new Uint8Array(getMemory().buffer, ptr, len);
171
+ }
172
+ function parseHeaders(headersJson) {
173
+ let headers = {};
174
+ try {
175
+ headers = JSON.parse(headersJson);
176
+ } catch {
177
+ for (const line of headersJson.split("\n")) {
178
+ const colonIdx = line.indexOf(":");
179
+ if (colonIdx > 0) {
180
+ headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
181
+ }
182
+ }
154
183
  }
155
- return entry.value;
184
+ return headers;
156
185
  }
157
- function write(key, value, options) {
158
- let expiresAt;
159
- if (options?.expiration !== void 0) {
160
- expiresAt = options.expiration * 1e3;
161
- } else if (options?.expirationTtl !== void 0) {
162
- expiresAt = Date.now() + options.expirationTtl * 1e3;
186
+ 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) {
187
+ const url = readStr(url_ptr, url_len);
188
+ const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
189
+ const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
190
+ const body = body_len > 0 ? readBytes(body_ptr, body_len) : void 0;
191
+ const headers = parseHeaders(headersJson);
192
+ const controller = new AbortController();
193
+ const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
194
+ try {
195
+ const response = await fetch(url, {
196
+ method,
197
+ headers: Object.keys(headers).length > 0 ? headers : void 0,
198
+ body: method !== "GET" && method !== "HEAD" ? body : void 0,
199
+ signal: controller.signal
200
+ });
201
+ if (timeout) clearTimeout(timeout);
202
+ new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
203
+ const bytes = new Uint8Array(await response.arrayBuffer());
204
+ return writeBytes(buf_ptr, buf_max, bytes);
205
+ } catch (err) {
206
+ if (timeout) clearTimeout(timeout);
207
+ const msg = err instanceof Error ? err.message : String(err);
208
+ console.error(`wasm fetch failed: ${url} (${msg})`);
209
+ return -1;
163
210
  }
164
- store.set(key, { value, expiresAt });
211
+ }
212
+ const Suspending = WebAssembly.Suspending;
213
+ if (typeof Suspending !== "function") {
214
+ return {
215
+ 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
216
+ };
165
217
  }
166
218
  return {
167
- async get(key) {
168
- return read(key);
169
- },
170
- async put(key, value, options) {
171
- write(key, value, options);
172
- },
173
- async delete(key) {
174
- store.delete(key);
175
- },
176
- async list(options) {
177
- const keys = [...store.keys()].filter((k) => {
178
- if (options?.prefix && !k.startsWith(options.prefix)) return false;
179
- return read(k) !== null;
180
- }).map((name) => ({ name }));
181
- return { keys };
182
- }
219
+ fetch: new Suspending(doFetch)
183
220
  };
184
221
  }
222
+
223
+ // ../../vendor/jsz/js/src/zigjs.ts
224
+ var NAN_PREFIX = 2146959360;
225
+ var predefined = {
226
+ "nan": 0,
227
+ "null": 1,
228
+ "true": 2,
229
+ "false": 3,
230
+ "undefined": 4,
231
+ "globalThis": 5,
232
+ "runtime": 6
233
+ };
234
+ var PREDEFINED_ID_MAX = 6;
235
+ var encoder2 = new TextEncoder();
236
+ var decoder2 = new TextDecoder("utf-8");
237
+ var ZigJS = class {
238
+ constructor() {
239
+ /**
240
+ * The values, indexed by ID (number). Duplicate values can be in this
241
+ * if they are loaded multiple times. That just acts as duplicate references.
242
+ * */
243
+ this.values = [NaN, null, true, false, void 0, globalThis, this];
244
+ /**
245
+ * When a value is removed from the values array, its ID is put
246
+ * in the pool so that we can use it next. This avoids fragmentation in
247
+ * our array keys.
248
+ * */
249
+ this.idPool = [];
250
+ }
251
+ /**
252
+ * Returns the import object that should be merged with your import
253
+ * object when instantiating your wasm instance. This injects the required
254
+ * functions into the wasm environment.
255
+ * */
256
+ importObject() {
257
+ return {
258
+ "zig-js": {
259
+ valueGet: this.valueGet.bind(this),
260
+ valueSet: this.valueSet.bind(this),
261
+ valueDeinit: this.valueDeinit.bind(this),
262
+ valueObjectCreate: this.valueObjectCreate.bind(this),
263
+ valueStringCreate: this.valueStringCreate.bind(this),
264
+ valueStringLen: this.valueStringLen.bind(this),
265
+ valueStringCopy: this.valueStringCopy.bind(this),
266
+ valueNew: this.valueNew.bind(this),
267
+ funcApply: this.funcApply.bind(this)
268
+ }
269
+ };
270
+ }
271
+ /**
272
+ * Get a value from the JS environment.
273
+ * */
274
+ valueGet(out, id, ptr, len) {
275
+ const val = this.loadValue(id);
276
+ if (val === null || val === void 0 || typeof val !== "object" && typeof val !== "function") {
277
+ this.storeValue(out, void 0);
278
+ return;
279
+ }
280
+ const str = this.loadString(ptr, len);
281
+ const result = Reflect.get(val, str);
282
+ this.storeValue(out, result);
283
+ }
284
+ /**
285
+ * Set a value on an object.
286
+ * */
287
+ valueSet(id, ptr, len, refAddr) {
288
+ const obj = this.loadValue(id);
289
+ const str = this.loadString(ptr, len);
290
+ const val = this.loadRef(refAddr);
291
+ Reflect.set(obj, str, val);
292
+ }
293
+ /**
294
+ * Dereference a value, allowing the JS environment to potentially GC it.
295
+ * */
296
+ valueDeinit(id) {
297
+ if (id > PREDEFINED_ID_MAX) {
298
+ this.values[id] = null;
299
+ this.idPool.push(id);
300
+ }
301
+ }
302
+ /**
303
+ * Create an empty object.
304
+ * */
305
+ valueObjectCreate(out) {
306
+ this.storeValue(out, new Object());
307
+ }
308
+ /**
309
+ * Creates a string on the JS side from a UTF-8 encoded string in wasm memory.
310
+ * */
311
+ valueStringCreate(out, ptr, len) {
312
+ const str = this.loadString(ptr, len);
313
+ this.storeValue(out, str);
314
+ }
315
+ /**
316
+ * Returns the length of the string given by id.
317
+ * */
318
+ valueStringLen(id) {
319
+ const val = this.loadValue(id);
320
+ const buf = encoder2.encode(val);
321
+ return buf.byteLength;
322
+ }
323
+ /**
324
+ * Copy the string at id "id" into the shared memory at ptr.
325
+ * */
326
+ valueStringCopy(id, ptr, max) {
327
+ if (this.memory == null) return;
328
+ const dest = ptr >>> 0;
329
+ const cap = max >>> 0;
330
+ const val = this.loadValue(id);
331
+ if (typeof val !== "string") return;
332
+ const bytes = encoder2.encode(val);
333
+ if (bytes.byteLength > cap || bytes.length === 0) return;
334
+ const buf = this.memory.buffer;
335
+ if (dest + bytes.length > buf.byteLength) return;
336
+ new Uint8Array(buf, dest, bytes.length).set(bytes);
337
+ }
338
+ /**
339
+ * Call a constructor given by id.
340
+ * */
341
+ valueNew(out, id, argsAddr, argsLen) {
342
+ const fn = this.loadValue(id);
343
+ const args = [];
344
+ const base = argsAddr >>> 0;
345
+ const count = argsLen >>> 0;
346
+ for (let i = 0; i < count; i++) {
347
+ args.push(this.loadRef(base + i * 8));
348
+ }
349
+ const result = Reflect.construct(fn, args);
350
+ this.storeValue(out, result);
351
+ }
352
+ /**
353
+ * Call a function given by id.
354
+ * */
355
+ funcApply(out, id, thisRefAddr, argsAddr, argsLen) {
356
+ const fn = this.loadValue(id);
357
+ const thisVal = this.loadRef(thisRefAddr >>> 0);
358
+ const args = [];
359
+ const base = argsAddr >>> 0;
360
+ const count = argsLen >>> 0;
361
+ for (let i = 0; i < count; i++) {
362
+ args.push(this.loadRef(base + i * 8));
363
+ }
364
+ if (typeof fn !== "function") {
365
+ this.storeValue(out, void 0);
366
+ return;
367
+ }
368
+ try {
369
+ const result = Reflect.apply(fn, thisVal, args);
370
+ this.storeValue(out, result);
371
+ } catch {
372
+ this.storeValue(out, void 0);
373
+ }
374
+ }
375
+ /**
376
+ * This can be used to load a value given by an ID. A WASM function
377
+ * might return a value as an ID. This can be used to retrieve it.
378
+ * */
379
+ loadValue(id) {
380
+ return this.values[id];
381
+ }
382
+ /**
383
+ * This removes the value from the values list and returns it. This
384
+ * will not remove predefined values but can still be used to retrieve
385
+ * them.
386
+ * */
387
+ deleteValue(id) {
388
+ const val = this.values[id];
389
+ this.valueDeinit(id);
390
+ return val;
391
+ }
392
+ loadRef(refAddr) {
393
+ if (this.memory == null) return;
394
+ const addr = refAddr >>> 0;
395
+ const view = new DataView(this.memory.buffer);
396
+ const floatVal = view.getFloat64(addr, true);
397
+ if (!isNaN(floatVal)) return floatVal;
398
+ const id = this.loadRefId(addr);
399
+ return this.values[id];
400
+ }
401
+ loadRefId(refAddr) {
402
+ if (this.memory == null) return 0;
403
+ return new DataView(this.memory.buffer).getUint32(refAddr >>> 0, true);
404
+ }
405
+ storeValue(out, val) {
406
+ if (this.memory == null) return;
407
+ const view = new DataView(this.memory.buffer);
408
+ out = out >>> 0;
409
+ if (typeof val === "number") {
410
+ if (isNaN(val)) {
411
+ view.setUint32(out, predefined.nan, true);
412
+ view.setUint32(out + 4, NAN_PREFIX, true);
413
+ } else {
414
+ view.setFloat64(out, val, true);
415
+ }
416
+ return;
417
+ }
418
+ if (val === null) {
419
+ view.setUint32(out, predefined.null, true);
420
+ view.setUint32(out + 4, NAN_PREFIX, true);
421
+ return;
422
+ }
423
+ if (val === void 0) {
424
+ view.setUint32(out, predefined.undefined, true);
425
+ view.setUint32(out + 4, NAN_PREFIX, true);
426
+ return;
427
+ }
428
+ if (typeof val === "boolean") {
429
+ view.setUint32(out, val ? predefined.true : predefined.false, true);
430
+ view.setUint32(out + 4, NAN_PREFIX, true);
431
+ return;
432
+ }
433
+ if (typeof val === "bigint") {
434
+ view.setFloat64(out, Number(val), true);
435
+ return;
436
+ }
437
+ let id = this.idPool.pop();
438
+ if (id === void 0) {
439
+ id = this.values.length;
440
+ }
441
+ this.values[id] = val;
442
+ let typeId = 0;
443
+ switch (typeof val) {
444
+ case "object":
445
+ typeId = 1;
446
+ break;
447
+ case "string":
448
+ typeId = 2;
449
+ break;
450
+ case "symbol":
451
+ typeId = 3;
452
+ break;
453
+ case "function":
454
+ typeId = 4;
455
+ break;
456
+ }
457
+ view.setUint32(out, Number(id), true);
458
+ view.setUint32(out + 4, NAN_PREFIX | typeId, true);
459
+ }
460
+ loadString(ptr, len) {
461
+ if (this.memory == null) return "";
462
+ const start = ptr >>> 0;
463
+ const length = Number(len) >>> 0;
464
+ const buf = this.memory.buffer;
465
+ if (length === 0 || start + length > buf.byteLength) return "";
466
+ const arr = new Uint8ClampedArray(buf, start, length);
467
+ const data = arr.slice();
468
+ return decoder2.decode(data);
469
+ }
470
+ };
471
+
472
+ // src/wasm/core.ts
473
+ var jsz = new ZigJS();
474
+ var tempRefBuffer = new ArrayBuffer(8);
475
+ var tempRefView = new DataView(tempRefBuffer);
476
+ var textDecoder = new TextDecoder();
477
+ var textEncoder = new TextEncoder();
478
+ function writeBytesOut(getMemory, allocRef, outPtrAddr, data) {
479
+ if (data.length === 0) {
480
+ new DataView(getMemory().buffer).setUint32(outPtrAddr, 0, true);
481
+ return 0;
482
+ }
483
+ const alloc = allocRef[0];
484
+ if (!alloc) return -1;
485
+ const ptr = alloc(data.length) >>> 0;
486
+ if (!ptr) return -1;
487
+ const buffer = getMemory().buffer;
488
+ if (ptr + data.length > buffer.byteLength) return -1;
489
+ new Uint8Array(buffer, ptr, data.length).set(data);
490
+ new DataView(buffer).setUint32(outPtrAddr >>> 0, ptr, true);
491
+ return data.length;
492
+ }
493
+ function writeJsonOut(getMemory, allocRef, outPtrAddr, value) {
494
+ return writeBytesOut(getMemory, allocRef, outPtrAddr, textEncoder.encode(JSON.stringify(value)));
495
+ }
496
+ function bindWasmAlloc(allocRef, exports) {
497
+ allocRef[0] = exports.__zx_alloc;
498
+ }
499
+
500
+ // src/runtime/kv/extern.ts
501
+ function putOptions(ttlSeconds) {
502
+ if (ttlSeconds < 60) return void 0;
503
+ return { expirationTtl: ttlSeconds };
504
+ }
185
505
  function isSyncKVNamespace(binding) {
186
506
  const candidate = binding;
187
507
  return typeof candidate.getSync === "function" && typeof candidate.putSync === "function" && typeof candidate.deleteSync === "function" && typeof candidate.listSync === "function";
188
508
  }
189
- function createKVImports(bindings, getMemory) {
190
- const encoder2 = new TextEncoder();
191
- const decoder2 = new TextDecoder();
509
+ function createKVImports(bindings, getMemory, allocRef) {
510
+ const encoder3 = new TextEncoder();
511
+ const decoder3 = new TextDecoder();
192
512
  function readStr(ptr, len) {
193
- return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
194
- }
195
- function writeBytes(buf_ptr, buf_max, data) {
196
- if (data.length > buf_max) return -2;
197
- new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
198
- return data.length;
513
+ return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
199
514
  }
200
515
  function binding(ns) {
201
516
  return bindings[ns] ?? bindings["default"] ?? null;
@@ -208,12 +523,12 @@ function createKVImports(bindings, getMemory) {
208
523
  };
209
524
  var syncBinding = syncBinding2;
210
525
  return {
211
- kv_get: (ns_ptr, ns_len, key_ptr, key_len, buf_ptr, buf_max) => {
526
+ kv_get: (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
212
527
  const b = syncBinding2(readStr(ns_ptr, ns_len));
213
528
  if (!b) return -1;
214
529
  const value = b.getSync(readStr(key_ptr, key_len));
215
530
  if (value === null) return -1;
216
- return writeBytes(buf_ptr, buf_max, encoder2.encode(value));
531
+ return writeBytesOut(getMemory, allocRef, out_ptr, encoder3.encode(value));
217
532
  },
218
533
  kv_put: (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
219
534
  const b = syncBinding2(readStr(ns_ptr, ns_len));
@@ -227,22 +542,22 @@ function createKVImports(bindings, getMemory) {
227
542
  b.deleteSync(readStr(key_ptr, key_len));
228
543
  return 0;
229
544
  },
230
- kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, buf_ptr, buf_max) => {
545
+ kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
231
546
  const b = syncBinding2(readStr(ns_ptr, ns_len));
232
- if (!b) return writeBytes(buf_ptr, buf_max, encoder2.encode("[]"));
547
+ if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
233
548
  const prefix = readStr(pfx_ptr, pfx_len);
234
549
  const result = b.listSync(prefix.length > 0 ? { prefix } : void 0);
235
- return writeBytes(buf_ptr, buf_max, encoder2.encode(JSON.stringify(result.keys.map((k) => k.name))));
550
+ return writeJsonOut(getMemory, allocRef, out_ptr, result.keys.map((k) => k.name));
236
551
  }
237
552
  };
238
553
  }
239
554
  return {
240
- kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, buf_ptr, buf_max) => {
555
+ kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
241
556
  const b = binding(readStr(ns_ptr, ns_len));
242
557
  if (!b) return -1;
243
558
  const value = await b.get(readStr(key_ptr, key_len));
244
559
  if (value === null) return -1;
245
- return writeBytes(buf_ptr, buf_max, encoder2.encode(value));
560
+ return writeBytesOut(getMemory, allocRef, out_ptr, encoder3.encode(value));
246
561
  }),
247
562
  kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
248
563
  const b = binding(readStr(ns_ptr, ns_len));
@@ -256,90 +571,29 @@ function createKVImports(bindings, getMemory) {
256
571
  await b.delete(readStr(key_ptr, key_len));
257
572
  return 0;
258
573
  }),
259
- kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, buf_ptr, buf_max) => {
574
+ kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, out_ptr) => {
260
575
  const b = binding(readStr(ns_ptr, ns_len));
261
- if (!b) return writeBytes(buf_ptr, buf_max, encoder2.encode("[]"));
576
+ if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
262
577
  const prefix = readStr(prefix_ptr, prefix_len);
263
578
  const result = await b.list(prefix.length > 0 ? { prefix } : void 0);
264
- return writeBytes(buf_ptr, buf_max, encoder2.encode(JSON.stringify(result.keys.map((k) => k.name))));
265
- })
266
- };
267
- }
268
-
269
- // src/fetch.ts
270
- function createFetchImports(getMemory) {
271
- const encoder2 = new TextEncoder();
272
- const decoder2 = new TextDecoder();
273
- function readStr(ptr, len) {
274
- return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
275
- }
276
- function writeBytes(buf_ptr, buf_max, data) {
277
- if (data.length > buf_max) return -2;
278
- new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
279
- return data.length;
280
- }
281
- function readBytes(ptr, len) {
282
- return new Uint8Array(getMemory().buffer, ptr, len);
283
- }
284
- function parseHeaders(headersJson) {
285
- let headers = {};
286
- try {
287
- headers = JSON.parse(headersJson);
288
- } catch {
289
- for (const line of headersJson.split("\n")) {
290
- const colonIdx = line.indexOf(":");
291
- if (colonIdx > 0) {
292
- headers[line.slice(0, colonIdx)] = line.slice(colonIdx + 1);
293
- }
579
+ const names = result.keys.map((k) => k.name);
580
+ if (names.length === 0) {
581
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
582
+ return 0;
294
583
  }
295
- }
296
- return headers;
297
- }
298
- 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) {
299
- const url = readStr(url_ptr, url_len);
300
- const method = method_len > 0 ? readStr(method_ptr, method_len) : "GET";
301
- const headersJson = headers_len > 0 ? readStr(headers_ptr, headers_len) : "{}";
302
- const body = body_len > 0 ? readBytes(body_ptr, body_len) : void 0;
303
- const headers = parseHeaders(headersJson);
304
- const controller = new AbortController();
305
- const timeout = timeout_ms > 0 ? setTimeout(() => controller.abort(), timeout_ms) : null;
306
- try {
307
- const response = await fetch(url, {
308
- method,
309
- headers: Object.keys(headers).length > 0 ? headers : void 0,
310
- body: method !== "GET" && method !== "HEAD" ? body : void 0,
311
- signal: controller.signal
312
- });
313
- if (timeout) clearTimeout(timeout);
314
- new DataView(getMemory().buffer).setUint16(status_out, response.status, true);
315
- const bytes = new Uint8Array(await response.arrayBuffer());
316
- return writeBytes(buf_ptr, buf_max, bytes);
317
- } catch (err) {
318
- if (timeout) clearTimeout(timeout);
319
- const msg = err instanceof Error ? err.message : String(err);
320
- console.error(`wasm fetch failed: ${url} (${msg})`);
321
- return -1;
322
- }
323
- }
324
- const Suspending = WebAssembly.Suspending;
325
- if (typeof Suspending !== "function") {
326
- return {
327
- 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
328
- };
329
- }
330
- return {
331
- fetch: new Suspending(doFetch)
584
+ return writeJsonOut(getMemory, allocRef, out_ptr, names);
585
+ })
332
586
  };
333
587
  }
334
588
 
335
- // src/db.ts
589
+ // src/runtime/db/extern.ts
336
590
  function decodeBlob(base64) {
337
591
  const binary = atob(base64);
338
592
  const bytes = new Uint8Array(binary.length);
339
593
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
340
594
  return bytes;
341
595
  }
342
- function toD1Value(value) {
596
+ function toDbValue(value) {
343
597
  switch (value.kind) {
344
598
  case "null":
345
599
  return null;
@@ -360,9 +614,9 @@ function toPositionalBindings(json) {
360
614
  case "none":
361
615
  return [];
362
616
  case "positional":
363
- return json.values.map(toD1Value);
617
+ return json.values.map(toDbValue);
364
618
  case "named":
365
- throw new Error("Cloudflare D1 adapter does not support named bindings yet");
619
+ throw new Error("named SQL bindings are not supported yet");
366
620
  }
367
621
  }
368
622
  function toWireValue(value) {
@@ -397,17 +651,10 @@ function objectToWireRow(record) {
397
651
  function valuesToWireRows(rows) {
398
652
  return rows.map((row) => row.map((value) => toWireValue(value)));
399
653
  }
400
- function createD1Imports(bindings, getMemory) {
401
- const encoder2 = new TextEncoder();
402
- const decoder2 = new TextDecoder();
654
+ function createDbImports(bindings, getMemory, allocRef) {
655
+ const decoder3 = new TextDecoder();
403
656
  function readStr(ptr, len) {
404
- return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
405
- }
406
- function writeJson(buf_ptr, buf_max, value) {
407
- const data = encoder2.encode(JSON.stringify(value));
408
- if (data.length > buf_max) return -2;
409
- new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
410
- return data.length;
657
+ return decoder3.decode(new Uint8Array(getMemory().buffer, ptr, len));
411
658
  }
412
659
  function binding(ns) {
413
660
  return bindings[ns] ?? bindings["default"] ?? null;
@@ -423,46 +670,58 @@ function createD1Imports(bindings, getMemory) {
423
670
  if (typeof Suspending !== "function") {
424
671
  return {
425
672
  db_open: (_ns, _ns_len) => -1,
426
- db_run: (_a, _b, _c, _d, _e, _f, _g, _h) => -1,
427
- db_get: (_a, _b, _c, _d, _e, _f, _g, _h) => -1,
428
- db_all: (_a, _b, _c, _d, _e, _f, _g, _h) => -1,
429
- db_values: (_a, _b, _c, _d, _e, _f, _g, _h) => -1
673
+ db_run: (_a, _b, _c, _d, _e, _f, _g) => -1,
674
+ db_get: (_a, _b, _c, _d, _e, _f, _g) => -1,
675
+ db_all: (_a, _b, _c, _d, _e, _f, _g) => -1,
676
+ db_values: (_a, _b, _c, _d, _e, _f, _g) => -1
430
677
  };
431
678
  }
432
679
  return {
433
680
  db_open: (ns_ptr, ns_len) => binding(readStr(ns_ptr, ns_len)) ? 0 : -1,
434
- db_run: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, buf_ptr, buf_max) => {
681
+ db_run: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
435
682
  const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
436
683
  if (!stmt) return -1;
437
684
  const result = await stmt.run();
438
- return writeJson(buf_ptr, buf_max, {
685
+ return writeJsonOut(getMemory, allocRef, out_ptr, {
439
686
  last_insert_rowid: result.meta?.last_row_id ?? 0,
440
687
  changes: result.meta?.changes ?? 0
441
688
  });
442
689
  }),
443
- db_get: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, buf_ptr, buf_max) => {
690
+ db_get: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
444
691
  const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
445
692
  if (!stmt) return -1;
446
693
  const row = await stmt.first();
447
- if (!row) return 0;
448
- return writeJson(buf_ptr, buf_max, [objectToWireRow(row)]);
694
+ if (!row) {
695
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
696
+ return 0;
697
+ }
698
+ return writeJsonOut(getMemory, allocRef, out_ptr, [objectToWireRow(row)]);
449
699
  }),
450
- db_all: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, buf_ptr, buf_max) => {
700
+ db_all: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
451
701
  const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
452
702
  if (!stmt) return -1;
453
703
  const result = await stmt.all();
454
- return writeJson(buf_ptr, buf_max, (result.results ?? []).map(objectToWireRow));
704
+ const rows = (result.results ?? []).map(objectToWireRow);
705
+ if (rows.length === 0) {
706
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
707
+ return 0;
708
+ }
709
+ return writeJsonOut(getMemory, allocRef, out_ptr, rows);
455
710
  }),
456
- db_values: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, buf_ptr, buf_max) => {
711
+ db_values: new Suspending(async (ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len, out_ptr) => {
457
712
  const stmt = await statement(ns_ptr, ns_len, sql_ptr, sql_len, bindings_ptr, bindings_len);
458
713
  if (!stmt) return -1;
459
714
  const rows = await stmt.raw();
460
- return writeJson(buf_ptr, buf_max, valuesToWireRows(rows));
715
+ if (rows.length === 0) {
716
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
717
+ return 0;
718
+ }
719
+ return writeJsonOut(getMemory, allocRef, out_ptr, valuesToWireRows(rows));
461
720
  })
462
721
  };
463
722
  }
464
723
 
465
- // src/wasi.ts
724
+ // src/runtime/wasi.ts
466
725
  var ProcExit = class extends Error {
467
726
  constructor(code) {
468
727
  super(`proc_exit(${code})`);
@@ -474,7 +733,7 @@ function createWasiImports({
474
733
  stdinData,
475
734
  onStdout
476
735
  }) {
477
- const encoder2 = new TextEncoder();
736
+ const encoder3 = new TextEncoder();
478
737
  const url = new URL(request.url);
479
738
  const argStrings = [
480
739
  "wasm",
@@ -490,7 +749,7 @@ function createWasiImports({
490
749
  request.headers.forEach((value, name) => {
491
750
  if (value) argStrings.push("--header", `${name}:${value}`);
492
751
  });
493
- const encodedArgs = argStrings.map((a) => encoder2.encode(a + "\0"));
752
+ const encodedArgs = argStrings.map((a) => encoder3.encode(a + "\0"));
494
753
  const argBufSize = encodedArgs.reduce((s, a) => s + a.length, 0);
495
754
  let wasmMemory = null;
496
755
  const setMemory = (m2) => {
@@ -756,9 +1015,51 @@ function mergeUint8Arrays(arrays) {
756
1015
  return result;
757
1016
  }
758
1017
 
759
- // src/runtime.ts
760
- function buildWsImports(Suspending, mem, decoder2, ws) {
761
- const readStr = (ptr, len) => decoder2.decode(new Uint8Array(mem().buffer, ptr, len));
1018
+ // src/runtime/kv/memory.ts
1019
+ function createMemoryKV() {
1020
+ const store = /* @__PURE__ */ new Map();
1021
+ function read(key) {
1022
+ const entry = store.get(key);
1023
+ if (!entry) return null;
1024
+ const expiresAt = entry[1];
1025
+ if (expiresAt !== void 0 && Date.now() >= expiresAt) {
1026
+ store.delete(key);
1027
+ return null;
1028
+ }
1029
+ return entry[0];
1030
+ }
1031
+ function write(key, value, options) {
1032
+ let expiresAt;
1033
+ if (options?.expiration !== void 0) {
1034
+ expiresAt = options.expiration * 1e3;
1035
+ } else if (options?.expirationTtl !== void 0) {
1036
+ expiresAt = Date.now() + options.expirationTtl * 1e3;
1037
+ }
1038
+ store.set(key, [value, expiresAt]);
1039
+ }
1040
+ return {
1041
+ async get(key) {
1042
+ return read(key);
1043
+ },
1044
+ async put(key, value, options) {
1045
+ write(key, value, options);
1046
+ },
1047
+ async delete(key) {
1048
+ store.delete(key);
1049
+ },
1050
+ async list(options) {
1051
+ const keys = [...store.keys()].filter((k) => {
1052
+ if (options?.prefix && !k.startsWith(options.prefix)) return false;
1053
+ return read(k) !== null;
1054
+ }).map((name) => ({ name }));
1055
+ return { keys };
1056
+ }
1057
+ };
1058
+ }
1059
+
1060
+ // src/runtime/index.ts
1061
+ function buildWsImports(Suspending, mem, decoder3, ws) {
1062
+ const readStr = (ptr, len) => decoder3.decode(new Uint8Array(mem().buffer, ptr, len));
762
1063
  return {
763
1064
  ws_upgrade: () => {
764
1065
  ws.upgraded = true;
@@ -772,7 +1073,7 @@ function buildWsImports(Suspending, mem, decoder2, ws) {
772
1073
  }
773
1074
  },
774
1075
  ws_close: (code, reason_ptr, reason_len) => {
775
- ws.server?.close(code, decoder2.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
1076
+ ws.server?.close(code, decoder3.decode(new Uint8Array(mem().buffer, reason_ptr, reason_len)));
776
1077
  },
777
1078
  ws_recv: Suspending ? new Suspending(async (buf_ptr, buf_max) => {
778
1079
  if (ws._resolveFirstSuspend) {
@@ -908,7 +1209,8 @@ async function run({
908
1209
  });
909
1210
  let wasmMemory = null;
910
1211
  const mem = () => wasmMemory;
911
- const bridgeRef = { current: null };
1212
+ const bridgeRef = [null];
1213
+ const allocRef = [null];
912
1214
  const Suspending = WebAssembly.Suspending;
913
1215
  const jspi = typeof Suspending === "function";
914
1216
  const wsState = {
@@ -918,19 +1220,33 @@ async function run({
918
1220
  messageQueue: [],
919
1221
  recvResolve: null
920
1222
  };
921
- const instance = new WebAssembly.Instance(module, {
1223
+ const importObject = {
922
1224
  wasi_snapshot_preview1: { ...wasi?.wasiImport, ...wasiImport },
923
1225
  __zx_sys: buildSysImports(jspi, Suspending),
924
1226
  __zx_ws: buildWsImports(jspi ? Suspending : null, mem, new TextDecoder(), wsState),
925
- __zx_kv: createKVImports(kvBindings ?? { default: createMemoryKV() }, mem),
926
- __zx_db: createD1Imports(dbBindings ?? {}, mem),
927
1227
  __zx_net: createFetchImports(mem),
928
1228
  ...imports ? imports(mem) : {},
929
1229
  ...ZxWasiBridge.createImportObject(bridgeRef)
930
- });
1230
+ };
1231
+ if (true) {
1232
+ importObject.__zx_kv = createKVImports(
1233
+ kvBindings ?? { default: createMemoryKV() },
1234
+ mem,
1235
+ allocRef
1236
+ );
1237
+ }
1238
+ if (true) {
1239
+ importObject.__zx_db = createDbImports(
1240
+ dbBindings ?? {},
1241
+ mem,
1242
+ allocRef
1243
+ );
1244
+ }
1245
+ const instance = new WebAssembly.Instance(module, importObject);
931
1246
  wasmMemory = instance.exports.memory;
932
1247
  setMemory(wasmMemory);
933
- bridgeRef.current = new ZxWasiBridge(instance.exports);
1248
+ bridgeRef[0] = new ZxWasiBridge(instance.exports);
1249
+ bindWasmAlloc(allocRef, instance.exports);
934
1250
  const wasmPromise = executeWasm(instance, jspi, Suspending, wsState);
935
1251
  if (wsState.upgraded) {
936
1252
  const server = attachWebSocket(wsState);