ziex 0.1.0-dev.1387 → 0.1.0-dev.1458

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