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/runtime/kv.js ADDED
@@ -0,0 +1,543 @@
1
+ // src/runtime/kv/memory.ts
2
+ function createMemoryKV() {
3
+ const store = /* @__PURE__ */ new Map();
4
+ function read(key) {
5
+ const entry = store.get(key);
6
+ if (!entry) return null;
7
+ const expiresAt = entry[1];
8
+ if (expiresAt !== void 0 && Date.now() >= expiresAt) {
9
+ store.delete(key);
10
+ return null;
11
+ }
12
+ return entry[0];
13
+ }
14
+ function write(key, value, options) {
15
+ let expiresAt;
16
+ if (options?.expiration !== void 0) {
17
+ expiresAt = options.expiration * 1e3;
18
+ } else if (options?.expirationTtl !== void 0) {
19
+ expiresAt = Date.now() + options.expirationTtl * 1e3;
20
+ }
21
+ store.set(key, [value, expiresAt]);
22
+ }
23
+ return {
24
+ async get(key) {
25
+ return read(key);
26
+ },
27
+ async put(key, value, options) {
28
+ write(key, value, options);
29
+ },
30
+ async delete(key) {
31
+ store.delete(key);
32
+ },
33
+ async list(options) {
34
+ const keys = [...store.keys()].filter((k) => {
35
+ if (options?.prefix && !k.startsWith(options.prefix)) return false;
36
+ return read(k) !== null;
37
+ }).map((name) => ({ name }));
38
+ return { keys };
39
+ }
40
+ };
41
+ }
42
+
43
+ // src/runtime/kv/localstorage.ts
44
+ function getLocalStorage() {
45
+ if (typeof localStorage === "undefined") {
46
+ throw new Error("localStorage is not available in this environment");
47
+ }
48
+ return localStorage;
49
+ }
50
+ function createLocalStorageKV(options = {}) {
51
+ const storage = getLocalStorage();
52
+ const namespace = options.namespace ?? "default";
53
+ const storagePrefix = options.storagePrefix ?? "ziex-kv";
54
+ const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
55
+ const namespacePrefix = scopedKey("");
56
+ return {
57
+ getSync(key) {
58
+ return storage.getItem(scopedKey(key));
59
+ },
60
+ async get(key) {
61
+ return this.getSync(key);
62
+ },
63
+ putSync(key, value) {
64
+ storage.setItem(scopedKey(key), value);
65
+ },
66
+ async put(key, value) {
67
+ this.putSync(key, value);
68
+ },
69
+ deleteSync(key) {
70
+ storage.removeItem(scopedKey(key));
71
+ },
72
+ async delete(key) {
73
+ this.deleteSync(key);
74
+ },
75
+ listSync(options2) {
76
+ const prefix = namespacePrefix + (options2?.prefix ?? "");
77
+ const keys = [];
78
+ for (let i = 0; i < storage.length; i += 1) {
79
+ const key = storage.key(i);
80
+ if (!key || !key.startsWith(prefix)) continue;
81
+ keys.push({ name: key.slice(namespacePrefix.length) });
82
+ }
83
+ return { keys };
84
+ },
85
+ async list(options2) {
86
+ return this.listSync(options2);
87
+ }
88
+ };
89
+ }
90
+
91
+ // src/runtime/kv/indexdb.ts
92
+ function getIndexedDb() {
93
+ if (typeof indexedDB === "undefined") {
94
+ throw new Error("IndexedDB is not available in this environment");
95
+ }
96
+ return indexedDB;
97
+ }
98
+ function requestToPromise(request) {
99
+ return new Promise((resolve, reject) => {
100
+ request.onsuccess = () => resolve(request.result);
101
+ request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
102
+ });
103
+ }
104
+ function transactionToPromise(transaction) {
105
+ return new Promise((resolve, reject) => {
106
+ transaction.oncomplete = () => resolve();
107
+ transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
108
+ transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
109
+ });
110
+ }
111
+ function createIndexedDbKV(options = {}) {
112
+ const databaseName = options.databaseName ?? "ziex-kv";
113
+ const storeName = options.storeName ?? "kv";
114
+ const namespace = options.namespace ?? "default";
115
+ const dbPromise = new Promise((resolve, reject) => {
116
+ const request = getIndexedDb().open(databaseName, 1);
117
+ request.onupgradeneeded = () => {
118
+ const db = request.result;
119
+ if (!db.objectStoreNames.contains(storeName)) {
120
+ db.createObjectStore(storeName);
121
+ }
122
+ };
123
+ request.onsuccess = () => resolve(request.result);
124
+ request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
125
+ });
126
+ const scopedKey = (key) => `${namespace}:${key}`;
127
+ return {
128
+ async get(key) {
129
+ const db = await dbPromise;
130
+ const tx = db.transaction(storeName, "readonly");
131
+ const store = tx.objectStore(storeName);
132
+ const value = await requestToPromise(store.get(scopedKey(key)));
133
+ await transactionToPromise(tx);
134
+ return typeof value === "string" ? value : null;
135
+ },
136
+ async put(key, value) {
137
+ const db = await dbPromise;
138
+ const tx = db.transaction(storeName, "readwrite");
139
+ tx.objectStore(storeName).put(value, scopedKey(key));
140
+ await transactionToPromise(tx);
141
+ },
142
+ async delete(key) {
143
+ const db = await dbPromise;
144
+ const tx = db.transaction(storeName, "readwrite");
145
+ tx.objectStore(storeName).delete(scopedKey(key));
146
+ await transactionToPromise(tx);
147
+ },
148
+ async list(options2) {
149
+ const db = await dbPromise;
150
+ const tx = db.transaction(storeName, "readonly");
151
+ const store = tx.objectStore(storeName);
152
+ const keys = await requestToPromise(store.getAllKeys());
153
+ await transactionToPromise(tx);
154
+ const prefix = scopedKey(options2?.prefix ?? "");
155
+ return {
156
+ keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace.length + 1) }))
157
+ };
158
+ }
159
+ };
160
+ }
161
+
162
+ // ../../vendor/jsz/js/src/zigjs.ts
163
+ var NAN_PREFIX = 2146959360;
164
+ var predefined = {
165
+ "nan": 0,
166
+ "null": 1,
167
+ "true": 2,
168
+ "false": 3,
169
+ "undefined": 4,
170
+ "globalThis": 5,
171
+ "runtime": 6
172
+ };
173
+ var PREDEFINED_ID_MAX = 6;
174
+ var encoder = new TextEncoder();
175
+ var decoder = new TextDecoder("utf-8");
176
+ var ZigJS = class {
177
+ constructor() {
178
+ /**
179
+ * The values, indexed by ID (number). Duplicate values can be in this
180
+ * if they are loaded multiple times. That just acts as duplicate references.
181
+ * */
182
+ this.values = [NaN, null, true, false, void 0, globalThis, this];
183
+ /**
184
+ * When a value is removed from the values array, its ID is put
185
+ * in the pool so that we can use it next. This avoids fragmentation in
186
+ * our array keys.
187
+ * */
188
+ this.idPool = [];
189
+ }
190
+ /**
191
+ * Returns the import object that should be merged with your import
192
+ * object when instantiating your wasm instance. This injects the required
193
+ * functions into the wasm environment.
194
+ * */
195
+ importObject() {
196
+ return {
197
+ "zig-js": {
198
+ valueGet: this.valueGet.bind(this),
199
+ valueSet: this.valueSet.bind(this),
200
+ valueDeinit: this.valueDeinit.bind(this),
201
+ valueObjectCreate: this.valueObjectCreate.bind(this),
202
+ valueStringCreate: this.valueStringCreate.bind(this),
203
+ valueStringLen: this.valueStringLen.bind(this),
204
+ valueStringCopy: this.valueStringCopy.bind(this),
205
+ valueNew: this.valueNew.bind(this),
206
+ funcApply: this.funcApply.bind(this)
207
+ }
208
+ };
209
+ }
210
+ /**
211
+ * Get a value from the JS environment.
212
+ * */
213
+ valueGet(out, id, ptr, len) {
214
+ const val = this.loadValue(id);
215
+ if (val === null || val === void 0 || typeof val !== "object" && typeof val !== "function") {
216
+ this.storeValue(out, void 0);
217
+ return;
218
+ }
219
+ const str = this.loadString(ptr, len);
220
+ const result = Reflect.get(val, str);
221
+ this.storeValue(out, result);
222
+ }
223
+ /**
224
+ * Set a value on an object.
225
+ * */
226
+ valueSet(id, ptr, len, refAddr) {
227
+ const obj = this.loadValue(id);
228
+ const str = this.loadString(ptr, len);
229
+ const val = this.loadRef(refAddr);
230
+ Reflect.set(obj, str, val);
231
+ }
232
+ /**
233
+ * Dereference a value, allowing the JS environment to potentially GC it.
234
+ * */
235
+ valueDeinit(id) {
236
+ if (id > PREDEFINED_ID_MAX) {
237
+ this.values[id] = null;
238
+ this.idPool.push(id);
239
+ }
240
+ }
241
+ /**
242
+ * Create an empty object.
243
+ * */
244
+ valueObjectCreate(out) {
245
+ this.storeValue(out, new Object());
246
+ }
247
+ /**
248
+ * Creates a string on the JS side from a UTF-8 encoded string in wasm memory.
249
+ * */
250
+ valueStringCreate(out, ptr, len) {
251
+ const str = this.loadString(ptr, len);
252
+ this.storeValue(out, str);
253
+ }
254
+ /**
255
+ * Returns the length of the string given by id.
256
+ * */
257
+ valueStringLen(id) {
258
+ const val = this.loadValue(id);
259
+ const buf = encoder.encode(val);
260
+ return buf.byteLength;
261
+ }
262
+ /**
263
+ * Copy the string at id "id" into the shared memory at ptr.
264
+ * */
265
+ valueStringCopy(id, ptr, max) {
266
+ if (this.memory == null) return;
267
+ const dest = ptr >>> 0;
268
+ const cap = max >>> 0;
269
+ const val = this.loadValue(id);
270
+ if (typeof val !== "string") return;
271
+ const bytes = encoder.encode(val);
272
+ if (bytes.byteLength > cap || bytes.length === 0) return;
273
+ const buf = this.memory.buffer;
274
+ if (dest + bytes.length > buf.byteLength) return;
275
+ new Uint8Array(buf, dest, bytes.length).set(bytes);
276
+ }
277
+ /**
278
+ * Call a constructor given by id.
279
+ * */
280
+ valueNew(out, id, argsAddr, argsLen) {
281
+ const fn = this.loadValue(id);
282
+ const args = [];
283
+ const base = argsAddr >>> 0;
284
+ const count = argsLen >>> 0;
285
+ for (let i = 0; i < count; i++) {
286
+ args.push(this.loadRef(base + i * 8));
287
+ }
288
+ const result = Reflect.construct(fn, args);
289
+ this.storeValue(out, result);
290
+ }
291
+ /**
292
+ * Call a function given by id.
293
+ * */
294
+ funcApply(out, id, thisRefAddr, argsAddr, argsLen) {
295
+ const fn = this.loadValue(id);
296
+ const thisVal = this.loadRef(thisRefAddr >>> 0);
297
+ const args = [];
298
+ const base = argsAddr >>> 0;
299
+ const count = argsLen >>> 0;
300
+ for (let i = 0; i < count; i++) {
301
+ args.push(this.loadRef(base + i * 8));
302
+ }
303
+ if (typeof fn !== "function") {
304
+ this.storeValue(out, void 0);
305
+ return;
306
+ }
307
+ try {
308
+ const result = Reflect.apply(fn, thisVal, args);
309
+ this.storeValue(out, result);
310
+ } catch {
311
+ this.storeValue(out, void 0);
312
+ }
313
+ }
314
+ /**
315
+ * This can be used to load a value given by an ID. A WASM function
316
+ * might return a value as an ID. This can be used to retrieve it.
317
+ * */
318
+ loadValue(id) {
319
+ return this.values[id];
320
+ }
321
+ /**
322
+ * This removes the value from the values list and returns it. This
323
+ * will not remove predefined values but can still be used to retrieve
324
+ * them.
325
+ * */
326
+ deleteValue(id) {
327
+ const val = this.values[id];
328
+ this.valueDeinit(id);
329
+ return val;
330
+ }
331
+ loadRef(refAddr) {
332
+ if (this.memory == null) return;
333
+ const addr = refAddr >>> 0;
334
+ const view = new DataView(this.memory.buffer);
335
+ const floatVal = view.getFloat64(addr, true);
336
+ if (!isNaN(floatVal)) return floatVal;
337
+ const id = this.loadRefId(addr);
338
+ return this.values[id];
339
+ }
340
+ loadRefId(refAddr) {
341
+ if (this.memory == null) return 0;
342
+ return new DataView(this.memory.buffer).getUint32(refAddr >>> 0, true);
343
+ }
344
+ storeValue(out, val) {
345
+ if (this.memory == null) return;
346
+ const view = new DataView(this.memory.buffer);
347
+ out = out >>> 0;
348
+ if (typeof val === "number") {
349
+ if (isNaN(val)) {
350
+ view.setUint32(out, predefined.nan, true);
351
+ view.setUint32(out + 4, NAN_PREFIX, true);
352
+ } else {
353
+ view.setFloat64(out, val, true);
354
+ }
355
+ return;
356
+ }
357
+ if (val === null) {
358
+ view.setUint32(out, predefined.null, true);
359
+ view.setUint32(out + 4, NAN_PREFIX, true);
360
+ return;
361
+ }
362
+ if (val === void 0) {
363
+ view.setUint32(out, predefined.undefined, true);
364
+ view.setUint32(out + 4, NAN_PREFIX, true);
365
+ return;
366
+ }
367
+ if (typeof val === "boolean") {
368
+ view.setUint32(out, val ? predefined.true : predefined.false, true);
369
+ view.setUint32(out + 4, NAN_PREFIX, true);
370
+ return;
371
+ }
372
+ if (typeof val === "bigint") {
373
+ view.setFloat64(out, Number(val), true);
374
+ return;
375
+ }
376
+ let id = this.idPool.pop();
377
+ if (id === void 0) {
378
+ id = this.values.length;
379
+ }
380
+ this.values[id] = val;
381
+ let typeId = 0;
382
+ switch (typeof val) {
383
+ case "object":
384
+ typeId = 1;
385
+ break;
386
+ case "string":
387
+ typeId = 2;
388
+ break;
389
+ case "symbol":
390
+ typeId = 3;
391
+ break;
392
+ case "function":
393
+ typeId = 4;
394
+ break;
395
+ }
396
+ view.setUint32(out, Number(id), true);
397
+ view.setUint32(out + 4, NAN_PREFIX | typeId, true);
398
+ }
399
+ loadString(ptr, len) {
400
+ if (this.memory == null) return "";
401
+ const start = ptr >>> 0;
402
+ const length = Number(len) >>> 0;
403
+ const buf = this.memory.buffer;
404
+ if (length === 0 || start + length > buf.byteLength) return "";
405
+ const arr = new Uint8ClampedArray(buf, start, length);
406
+ const data = arr.slice();
407
+ return decoder.decode(data);
408
+ }
409
+ };
410
+
411
+ // src/wasm/core.ts
412
+ var jsz = new ZigJS();
413
+ var tempRefBuffer = new ArrayBuffer(8);
414
+ var tempRefView = new DataView(tempRefBuffer);
415
+ var textDecoder = new TextDecoder();
416
+ var textEncoder = new TextEncoder();
417
+ function writeBytesOut(getMemory, allocRef, outPtrAddr, data) {
418
+ if (data.length === 0) {
419
+ new DataView(getMemory().buffer).setUint32(outPtrAddr, 0, true);
420
+ return 0;
421
+ }
422
+ const alloc = allocRef[0];
423
+ if (!alloc) return -1;
424
+ const ptr = alloc(data.length) >>> 0;
425
+ if (!ptr) return -1;
426
+ const buffer = getMemory().buffer;
427
+ if (ptr + data.length > buffer.byteLength) return -1;
428
+ new Uint8Array(buffer, ptr, data.length).set(data);
429
+ new DataView(buffer).setUint32(outPtrAddr >>> 0, ptr, true);
430
+ return data.length;
431
+ }
432
+ function writeJsonOut(getMemory, allocRef, outPtrAddr, value) {
433
+ return writeBytesOut(getMemory, allocRef, outPtrAddr, textEncoder.encode(JSON.stringify(value)));
434
+ }
435
+
436
+ // src/runtime/kv/extern.ts
437
+ function putOptions(ttlSeconds) {
438
+ if (ttlSeconds < 60) return void 0;
439
+ return { expirationTtl: ttlSeconds };
440
+ }
441
+ function isSyncKVNamespace(binding) {
442
+ const candidate = binding;
443
+ return typeof candidate.getSync === "function" && typeof candidate.putSync === "function" && typeof candidate.deleteSync === "function" && typeof candidate.listSync === "function";
444
+ }
445
+ function createKVImports(bindings, getMemory, allocRef) {
446
+ const encoder2 = new TextEncoder();
447
+ const decoder2 = new TextDecoder();
448
+ function readStr(ptr, len) {
449
+ return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
450
+ }
451
+ function binding(ns) {
452
+ return bindings[ns] ?? bindings["default"] ?? null;
453
+ }
454
+ const Suspending = WebAssembly.Suspending;
455
+ if (typeof Suspending !== "function") {
456
+ let syncBinding2 = function(ns) {
457
+ const candidate = binding(ns);
458
+ return candidate && isSyncKVNamespace(candidate) ? candidate : null;
459
+ };
460
+ var syncBinding = syncBinding2;
461
+ return {
462
+ kv_get: (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
463
+ const b = syncBinding2(readStr(ns_ptr, ns_len));
464
+ if (!b) return -1;
465
+ const value = b.getSync(readStr(key_ptr, key_len));
466
+ if (value === null) return -1;
467
+ return writeBytesOut(getMemory, allocRef, out_ptr, encoder2.encode(value));
468
+ },
469
+ kv_put: (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
470
+ const b = syncBinding2(readStr(ns_ptr, ns_len));
471
+ if (!b) return 0;
472
+ b.putSync(readStr(key_ptr, key_len), readStr(val_ptr, val_len), putOptions(ttl_seconds));
473
+ return 0;
474
+ },
475
+ kv_delete: (ns_ptr, ns_len, key_ptr, key_len) => {
476
+ const b = syncBinding2(readStr(ns_ptr, ns_len));
477
+ if (!b) return 0;
478
+ b.deleteSync(readStr(key_ptr, key_len));
479
+ return 0;
480
+ },
481
+ kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
482
+ const b = syncBinding2(readStr(ns_ptr, ns_len));
483
+ if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
484
+ const prefix = readStr(pfx_ptr, pfx_len);
485
+ const result = b.listSync(prefix.length > 0 ? { prefix } : void 0);
486
+ return writeJsonOut(getMemory, allocRef, out_ptr, result.keys.map((k) => k.name));
487
+ }
488
+ };
489
+ }
490
+ return {
491
+ kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
492
+ const b = binding(readStr(ns_ptr, ns_len));
493
+ if (!b) return -1;
494
+ const value = await b.get(readStr(key_ptr, key_len));
495
+ if (value === null) return -1;
496
+ return writeBytesOut(getMemory, allocRef, out_ptr, encoder2.encode(value));
497
+ }),
498
+ kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
499
+ const b = binding(readStr(ns_ptr, ns_len));
500
+ if (!b) return -1;
501
+ await b.put(readStr(key_ptr, key_len), readStr(val_ptr, val_len), putOptions(ttl_seconds));
502
+ return 0;
503
+ }),
504
+ kv_delete: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len) => {
505
+ const b = binding(readStr(ns_ptr, ns_len));
506
+ if (!b) return -1;
507
+ await b.delete(readStr(key_ptr, key_len));
508
+ return 0;
509
+ }),
510
+ kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, out_ptr) => {
511
+ const b = binding(readStr(ns_ptr, ns_len));
512
+ if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
513
+ const prefix = readStr(prefix_ptr, prefix_len);
514
+ const result = await b.list(prefix.length > 0 ? { prefix } : void 0);
515
+ const names = result.keys.map((k) => k.name);
516
+ if (names.length === 0) {
517
+ new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
518
+ return 0;
519
+ }
520
+ return writeJsonOut(getMemory, allocRef, out_ptr, names);
521
+ })
522
+ };
523
+ }
524
+
525
+ // src/runtime/kv.ts
526
+ function hasJSPI() {
527
+ return typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
528
+ }
529
+ function createBrowserKVBindings(options = {}) {
530
+ const namespace = options.namespace ?? "default";
531
+ const isIndexedDb = hasJSPI() && !options.forceLocalStorage;
532
+ return {
533
+ [namespace]: isIndexedDb ? createIndexedDbKV(options) : createLocalStorageKV(options)
534
+ };
535
+ }
536
+ export {
537
+ createBrowserKVBindings,
538
+ createIndexedDbKV,
539
+ createKVImports,
540
+ createLocalStorageKV,
541
+ createMemoryKV,
542
+ hasJSPI
543
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Numeric wire constants for the WASM↔JS ABI.
3
+ *
4
+ * Kept in a path-import-free module so esbuild's const-inlining heuristic can
5
+ * fold these into call sites across the bundle (#1317 / #1981):
6
+ * only `null` / `undefined` / `true` / `false` / integers / short reals, at the
7
+ * top of a scope with no `import`/`export … from "…"`.
8
+ *
9
+ * Must stay in sync with Zig (`dom_cmd.zig`, `host.zig` / `__zx_cb` types).
10
+ */
11
+ export declare const DOM_CMD_HEADER_SIZE = 8;
12
+ export declare const DOM_CMD_RECORD_SIZE = 24;
13
+ export declare const DomOp_CreateElement = 1;
14
+ export declare const DomOp_CreateText = 2;
15
+ export declare const DomOp_HydrateInsert = 3;
16
+ export declare const DomOp_SetAttr = 4;
17
+ export declare const DomOp_SetProp = 5;
18
+ export declare const DomOp_RemoveAttr = 6;
19
+ export declare const DomOp_SetNodeValue = 7;
20
+ export declare const DomOp_SetInnerHtml = 8;
21
+ export declare const DomOp_AppendChild = 9;
22
+ export declare const DomOp_InsertBefore = 10;
23
+ export declare const DomOp_RemoveChild = 11;
24
+ export declare const DomOp_ReplaceChild = 12;
25
+ export declare const CallbackType_Event = 0;
26
+ export declare const CallbackType_FetchSuccess = 1;
27
+ export declare const CallbackType_FetchError = 2;
28
+ export declare const CallbackType_Timeout = 3;
29
+ export declare const CallbackType_Interval = 4;
30
+ export declare const CallbackType_WebSocketOpen = 5;
31
+ export declare const CallbackType_WebSocketMessage = 6;
32
+ export declare const CallbackType_WebSocketError = 7;
33
+ export declare const CallbackType_WebSocketClose = 8;
package/wasm/core.d.ts CHANGED
@@ -1,34 +1,25 @@
1
1
  import { ZigJS } from "../../../../vendor/jsz/js/src";
2
+ import { CallbackType_Event, CallbackType_FetchSuccess, CallbackType_FetchError, CallbackType_Timeout, CallbackType_Interval, CallbackType_WebSocketOpen, CallbackType_WebSocketMessage, CallbackType_WebSocketError, CallbackType_WebSocketClose } from "./constants";
3
+ export { CallbackType_Event, CallbackType_FetchSuccess, CallbackType_FetchError, CallbackType_Timeout, CallbackType_Interval, CallbackType_WebSocketOpen, CallbackType_WebSocketMessage, CallbackType_WebSocketError, CallbackType_WebSocketClose, } from "./constants";
4
+ export type CallbackTypeValue = typeof CallbackType_Event | typeof CallbackType_FetchSuccess | typeof CallbackType_FetchError | typeof CallbackType_Timeout | typeof CallbackType_Interval | typeof CallbackType_WebSocketOpen | typeof CallbackType_WebSocketMessage | typeof CallbackType_WebSocketError | typeof CallbackType_WebSocketClose;
5
+ /** Unified host→guest callback: (type, id, a, b, c). Extra args are msg-specific. */
6
+ export type CallbackHandler = (callbackType: number, id: bigint, a: bigint, b: bigint, c: bigint) => void;
2
7
  /**
3
8
  * Core WASM bridge - environment-agnostic (browser + edge).
4
- * Contains no references to browser globals (document, window, WebSocket, HTMLFormElement).
9
+ * No references to browser globals (document, window, WebSocket, HTMLFormElement).
5
10
  */
6
- export declare const CallbackType: {
7
- readonly Event: 0;
8
- readonly FetchSuccess: 1;
9
- readonly FetchError: 2;
10
- readonly Timeout: 3;
11
- readonly Interval: 4;
12
- readonly WebSocketOpen: 5;
13
- readonly WebSocketMessage: 6;
14
- readonly WebSocketError: 7;
15
- readonly WebSocketClose: 8;
16
- };
17
- export type CallbackTypeValue = typeof CallbackType[keyof typeof CallbackType];
18
- export type CallbackHandler = (callbackType: number, id: bigint, dataRef: bigint) => void;
19
- export type FetchCompleteHandler = (fetchId: bigint, statusCode: number, bodyPtr: number, bodyLen: number, isError: number) => void;
20
- export type WsOnOpenHandler = (wsId: bigint, protocolPtr: number, protocolLen: number) => void;
21
- export type WsOnMessageHandler = (wsId: bigint, dataPtr: number, dataLen: number, isBinary: number) => void;
22
- export type WsOnErrorHandler = (wsId: bigint, msgPtr: number, msgLen: number) => void;
23
- export type WsOnCloseHandler = (wsId: bigint, code: number, reasonPtr: number, reasonLen: number, wasClean: number) => void;
24
11
  export declare const jsz: ZigJS;
25
12
  /** Store a value using jsz.storeValue and get the 64-bit reference. */
26
13
  export declare function storeValueGetRef(val: any): bigint;
14
+ /** Resolve a NaN-boxed 64-bit reference back to the JS value. */
15
+ export declare function loadValueFromRef(ref: bigint): any;
16
+ /** Release a NaN-boxed jsz ref (no-op for numbers / predefined ids). */
17
+ export declare function releaseValueRef(ref: bigint): void;
27
18
  /** Shared encoder/decoder - avoids allocating new instances on every call. */
28
19
  export declare const textDecoder: TextDecoder;
29
20
  export declare const textEncoder: TextEncoder;
30
21
  export declare function getMemoryView(): Uint8Array;
31
- /** Read a string from WASM memory */
22
+ /** Read a string from WASM memory. Treats ptr/len as u32 (WASM i32 is signed in JS). */
32
23
  export declare function readString(ptr: number, len: number): string;
33
24
  /** Write bytes to WASM memory at a specific location */
34
25
  export declare function writeBytes(ptr: number, data: Uint8Array): void;
@@ -44,9 +35,11 @@ export declare class ZxBridgeCore {
44
35
  #private;
45
36
  protected readonly _alloc: (size: number) => number;
46
37
  constructor(exports: WebAssembly.Exports);
38
+ /** Invoke the unified callback handler */
39
+ protected _invoke(type: CallbackTypeValue, id: bigint, a?: bigint, b?: bigint, c?: bigint): void;
47
40
  /**
48
41
  * Async fetch with full options support.
49
- * Calls __zx_fetch_complete when done.
42
+ * Completes via `__zx_cb(fetch_success|fetch_error, ...)`.
50
43
  */
51
44
  fetchAsync(urlPtr: number, urlLen: number, methodPtr: number, methodLen: number, headersPtr: number, headersLen: number, bodyPtr: number, bodyLen: number, timeoutMs: number, fetchId: bigint): void;
52
45
  /** Notify WASM that a fetch completed. `body` is raw bytes on success, text on error. */
@@ -58,15 +51,9 @@ export declare class ZxBridgeCore {
58
51
  /** Clear an interval */
59
52
  clearInterval(callbackId: bigint): void;
60
53
  dispose(): void;
61
- /** Write a string to WASM memory, returning pointer and length */
62
- protected _writeStringToWasm(str: string): {
63
- ptr: number;
64
- len: number;
65
- };
66
- protected _writeBytesToWasm(data: Uint8Array): {
67
- ptr: number;
68
- len: number;
69
- };
54
+ /** Write a string to WASM memory, returning `[ptr, len]`. */
55
+ protected _writeStringToWasm(str: string): [number, number];
56
+ writeBytesToWasm(data: Uint8Array): [number, number];
70
57
  /** Log a message from WASM at the given level (0=error, 1=warn, 2=info, 3=debug) */
71
58
  static log(level: number, ptr: number, len: number): void;
72
59
  /**
@@ -75,7 +62,10 @@ export declare class ZxBridgeCore {
75
62
  * Use ZxBridge.createImportObject (from wasm/index.ts) in browser contexts
76
63
  * to additionally include DOM and WebSocket bindings.
77
64
  */
78
- static createImportObject(bridgeRef: {
79
- current: ZxBridgeCore | null;
80
- }): WebAssembly.Imports;
65
+ static createImportObject(bridgeRef: [ZxBridgeCore | null]): WebAssembly.Imports;
81
66
  }
67
+ /** Mutable slot for `__zx_alloc` - array so the slot name itself can minify. */
68
+ export type WasmAllocRef = [((size: number) => number) | null];
69
+ export declare function writeBytesOut(getMemory: () => WebAssembly.Memory, allocRef: WasmAllocRef, outPtrAddr: number, data: Uint8Array): number;
70
+ export declare function writeJsonOut(getMemory: () => WebAssembly.Memory, allocRef: WasmAllocRef, outPtrAddr: number, value: unknown): number;
71
+ export declare function bindWasmAlloc(allocRef: WasmAllocRef, exports: WebAssembly.Exports): void;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * DomCmd flush decoder — must match `src/runtime/client/dom_cmd.zig`.
3
+ *
4
+ * Buffer layout (little-endian):
5
+ * Header (8): u32 record_count, u32 flags (0 = absolute WASM ptr+len strings)
6
+ * Records (24 each): u8 op, u8 flags, u16 pad, u32 p0..p4
7
+ *
8
+ * String fields are absolute linear-memory pointers (same as the old per-op ABI).
9
+ */
10
+ export type DomFlushContext = {
11
+ domNodes: Map<number, Node>;
12
+ cleanupDomNodes: (node: Node) => void;
13
+ };
14
+ /** Apply a DomCmd buffer written at `ptr` with byte length `len`. */
15
+ export declare function flushDomCmds(ptr: number, len: number, ctx: DomFlushContext): void;
@@ -0,0 +1,2 @@
1
+ /** High-frequency event type bitmask -> `(bits & (1 << id)) !== 0`. */
2
+ export declare const HIGH_FREQ_EVENT_BITS = 3031040;
@@ -0,0 +1 @@
1
+ export declare const DELEGATED_EVENTS: readonly ['click', 'dblclick', 'input', 'change', 'submit', 'focusin', 'focusout', 'keydown', 'keyup', 'keypress', 'mouseenter', 'mouseleave', 'mousedown', 'mouseup', 'mousemove', 'touchstart', 'touchend', 'touchmove', 'scroll', 'wheel', 'pointerdown', 'pointermove', 'pointerup', 'pointercancel', 'pointerenter', 'pointerleave', 'lostpointercapture'];
@@ -0,0 +1,2 @@
1
+ export declare const SVG_TAG_START_INDEX = 140;
2
+ export declare const CUSTOM_TAG_INDEX = 199;