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.
- package/README.md +4 -1
- package/app.d.ts +6 -6
- package/build.zig.zon +1 -1
- package/index.js +477 -169
- package/package.json +7 -5
- package/{aws-lambda → platforms/aws-lambda}/index.js +1 -1
- package/platforms/cloudflare/app.d.ts +2 -0
- package/platforms/cloudflare/db.d.ts +6 -0
- package/{cloudflare → platforms/cloudflare}/do.d.ts +5 -5
- package/platforms/cloudflare/index.d.ts +4 -0
- package/{cloudflare → platforms/cloudflare}/index.js +1666 -1293
- package/platforms/cloudflare/kv.d.ts +5 -0
- package/platforms/cloudflare/worker.d.ts +3 -0
- package/{vercel → platforms/vercel}/index.js +1 -1
- package/runtime/db/extern.d.ts +38 -0
- package/runtime/db/sqlite.d.ts +7 -0
- package/runtime/db.d.ts +3 -0
- package/runtime/db.js +419 -0
- package/{fetch.d.ts → runtime/fetch.d.ts} +1 -1
- package/{runtime.d.ts → runtime/index.d.ts} +6 -15
- package/runtime/kv/extern.d.ts +11 -0
- package/runtime/kv/indexdb.d.ts +7 -0
- package/runtime/kv/localstorage.d.ts +6 -0
- package/runtime/kv/memory.d.ts +6 -0
- package/runtime/kv.d.ts +44 -0
- package/runtime/kv.js +542 -0
- package/wasm/core.d.ts +29 -27
- package/wasm/index.d.ts +13 -12
- package/wasm/index.js +431 -240
- package/wasm/init.dev.js +407 -238
- package/wasm/init.js +3 -3
- package/wasm/wasi.d.ts +1 -5
- package/browser/kv.d.ts +0 -13
- package/cloudflare/app.d.ts +0 -2
- package/cloudflare/db.d.ts +0 -2
- package/cloudflare/index.d.ts +0 -4
- package/cloudflare/kv.d.ts +0 -2
- package/cloudflare/worker.d.ts +0 -3
- package/db.d.ts +0 -22
- package/kv.d.ts +0 -42
- /package/{aws-lambda → platforms/aws-lambda}/index.d.ts +0 -0
- /package/{vercel → platforms/vercel}/index.d.ts +0 -0
- /package/{wasi.d.ts → runtime/wasi.d.ts} +0 -0
package/wasm/init.dev.js
CHANGED
|
@@ -51,6 +51,10 @@ var ZigJS = class {
|
|
|
51
51
|
* */
|
|
52
52
|
valueGet(out, id, ptr, len) {
|
|
53
53
|
const val = this.loadValue(id);
|
|
54
|
+
if (val === null || val === void 0 || typeof val !== "object" && typeof val !== "function") {
|
|
55
|
+
this.storeValue(out, void 0);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
54
58
|
const str = this.loadString(ptr, len);
|
|
55
59
|
const result = Reflect.get(val, str);
|
|
56
60
|
this.storeValue(out, result);
|
|
@@ -99,11 +103,15 @@ var ZigJS = class {
|
|
|
99
103
|
* */
|
|
100
104
|
valueStringCopy(id, ptr, max) {
|
|
101
105
|
if (this.memory == null) return;
|
|
106
|
+
const dest = ptr >>> 0;
|
|
107
|
+
const cap = max >>> 0;
|
|
102
108
|
const val = this.loadValue(id);
|
|
109
|
+
if (typeof val !== "string") return;
|
|
103
110
|
const bytes = encoder.encode(val);
|
|
104
|
-
if (bytes.byteLength >
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
if (bytes.byteLength > cap || bytes.length === 0) return;
|
|
112
|
+
const buf = this.memory.buffer;
|
|
113
|
+
if (dest + bytes.length > buf.byteLength) return;
|
|
114
|
+
new Uint8Array(buf, dest, bytes.length).set(bytes);
|
|
107
115
|
}
|
|
108
116
|
/**
|
|
109
117
|
* Call a constructor given by id.
|
|
@@ -111,8 +119,10 @@ var ZigJS = class {
|
|
|
111
119
|
valueNew(out, id, argsAddr, argsLen) {
|
|
112
120
|
const fn = this.loadValue(id);
|
|
113
121
|
const args = [];
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
const base = argsAddr >>> 0;
|
|
123
|
+
const count = argsLen >>> 0;
|
|
124
|
+
for (let i = 0; i < count; i++) {
|
|
125
|
+
args.push(this.loadRef(base + i * 8));
|
|
116
126
|
}
|
|
117
127
|
const result = Reflect.construct(fn, args);
|
|
118
128
|
this.storeValue(out, result);
|
|
@@ -122,13 +132,23 @@ var ZigJS = class {
|
|
|
122
132
|
* */
|
|
123
133
|
funcApply(out, id, thisRefAddr, argsAddr, argsLen) {
|
|
124
134
|
const fn = this.loadValue(id);
|
|
125
|
-
const thisVal = this.loadRef(thisRefAddr);
|
|
135
|
+
const thisVal = this.loadRef(thisRefAddr >>> 0);
|
|
126
136
|
const args = [];
|
|
127
|
-
|
|
128
|
-
|
|
137
|
+
const base = argsAddr >>> 0;
|
|
138
|
+
const count = argsLen >>> 0;
|
|
139
|
+
for (let i = 0; i < count; i++) {
|
|
140
|
+
args.push(this.loadRef(base + i * 8));
|
|
141
|
+
}
|
|
142
|
+
if (typeof fn !== "function") {
|
|
143
|
+
this.storeValue(out, void 0);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const result = Reflect.apply(fn, thisVal, args);
|
|
148
|
+
this.storeValue(out, result);
|
|
149
|
+
} catch {
|
|
150
|
+
this.storeValue(out, void 0);
|
|
129
151
|
}
|
|
130
|
-
const result = Reflect.apply(fn, thisVal, args);
|
|
131
|
-
this.storeValue(out, result);
|
|
132
152
|
}
|
|
133
153
|
/**
|
|
134
154
|
* This can be used to load a value given by an ID. A WASM function
|
|
@@ -149,19 +169,21 @@ var ZigJS = class {
|
|
|
149
169
|
}
|
|
150
170
|
loadRef(refAddr) {
|
|
151
171
|
if (this.memory == null) return;
|
|
172
|
+
const addr = refAddr >>> 0;
|
|
152
173
|
const view = new DataView(this.memory.buffer);
|
|
153
|
-
const floatVal = view.getFloat64(
|
|
174
|
+
const floatVal = view.getFloat64(addr, true);
|
|
154
175
|
if (!isNaN(floatVal)) return floatVal;
|
|
155
|
-
const id = this.loadRefId(
|
|
176
|
+
const id = this.loadRefId(addr);
|
|
156
177
|
return this.values[id];
|
|
157
178
|
}
|
|
158
179
|
loadRefId(refAddr) {
|
|
159
180
|
if (this.memory == null) return 0;
|
|
160
|
-
return new DataView(this.memory.buffer).getUint32(refAddr, true);
|
|
181
|
+
return new DataView(this.memory.buffer).getUint32(refAddr >>> 0, true);
|
|
161
182
|
}
|
|
162
183
|
storeValue(out, val) {
|
|
163
184
|
if (this.memory == null) return;
|
|
164
185
|
const view = new DataView(this.memory.buffer);
|
|
186
|
+
out = out >>> 0;
|
|
165
187
|
if (typeof val === "number") {
|
|
166
188
|
if (isNaN(val)) {
|
|
167
189
|
view.setUint32(out, predefined.nan, true);
|
|
@@ -215,13 +237,17 @@ var ZigJS = class {
|
|
|
215
237
|
}
|
|
216
238
|
loadString(ptr, len) {
|
|
217
239
|
if (this.memory == null) return "";
|
|
218
|
-
const
|
|
240
|
+
const start = ptr >>> 0;
|
|
241
|
+
const length = Number(len) >>> 0;
|
|
242
|
+
const buf = this.memory.buffer;
|
|
243
|
+
if (length === 0 || start + length > buf.byteLength) return "";
|
|
244
|
+
const arr = new Uint8ClampedArray(buf, start, length);
|
|
219
245
|
const data = arr.slice();
|
|
220
246
|
return decoder.decode(data);
|
|
221
247
|
}
|
|
222
248
|
};
|
|
223
249
|
|
|
224
|
-
// src/fetch.ts
|
|
250
|
+
// src/runtime/fetch.ts
|
|
225
251
|
function createFetchImports(getMemory) {
|
|
226
252
|
const encoder2 = new TextEncoder();
|
|
227
253
|
const decoder2 = new TextDecoder();
|
|
@@ -288,17 +314,6 @@ function createFetchImports(getMemory) {
|
|
|
288
314
|
}
|
|
289
315
|
|
|
290
316
|
// src/wasm/core.ts
|
|
291
|
-
var CallbackType = {
|
|
292
|
-
Event: 0,
|
|
293
|
-
FetchSuccess: 1,
|
|
294
|
-
FetchError: 2,
|
|
295
|
-
Timeout: 3,
|
|
296
|
-
Interval: 4,
|
|
297
|
-
WebSocketOpen: 5,
|
|
298
|
-
WebSocketMessage: 6,
|
|
299
|
-
WebSocketError: 7,
|
|
300
|
-
WebSocketClose: 8
|
|
301
|
-
};
|
|
302
317
|
var jsz = new ZigJS();
|
|
303
318
|
var tempRefBuffer = new ArrayBuffer(8);
|
|
304
319
|
var tempRefView = new DataView(tempRefBuffer);
|
|
@@ -309,6 +324,20 @@ function storeValueGetRef(val) {
|
|
|
309
324
|
jsz.memory = originalMemory;
|
|
310
325
|
return tempRefView.getBigUint64(0, true);
|
|
311
326
|
}
|
|
327
|
+
function loadValueFromRef(ref) {
|
|
328
|
+
tempRefView.setBigUint64(0, ref, true);
|
|
329
|
+
const originalMemory = jsz.memory;
|
|
330
|
+
jsz.memory = { buffer: tempRefBuffer };
|
|
331
|
+
const val = jsz.loadRef(0);
|
|
332
|
+
jsz.memory = originalMemory;
|
|
333
|
+
return val;
|
|
334
|
+
}
|
|
335
|
+
function releaseValueRef(ref) {
|
|
336
|
+
tempRefView.setBigUint64(0, ref, true);
|
|
337
|
+
if (!Number.isNaN(tempRefView.getFloat64(0, true))) return;
|
|
338
|
+
const id = tempRefView.getUint32(0, true);
|
|
339
|
+
if (id > 6) jsz.deleteValue(id);
|
|
340
|
+
}
|
|
312
341
|
var textDecoder = new TextDecoder();
|
|
313
342
|
var textEncoder = new TextEncoder();
|
|
314
343
|
var memoryView = null;
|
|
@@ -321,20 +350,19 @@ function getMemoryView() {
|
|
|
321
350
|
}
|
|
322
351
|
return memoryView;
|
|
323
352
|
}
|
|
324
|
-
var stringCache = /* @__PURE__ */ new Map();
|
|
325
|
-
function stringCacheKey(ptr, len) {
|
|
326
|
-
return ptr * 65536 + len;
|
|
327
|
-
}
|
|
328
353
|
function readString(ptr, len) {
|
|
329
|
-
const
|
|
330
|
-
const
|
|
331
|
-
if (
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
return
|
|
354
|
+
const start = ptr >>> 0;
|
|
355
|
+
const length = len >>> 0;
|
|
356
|
+
if (length === 0) return "";
|
|
357
|
+
const view = getMemoryView();
|
|
358
|
+
if (start + length > view.byteLength) return "";
|
|
359
|
+
return textDecoder.decode(view.subarray(start, start + length));
|
|
335
360
|
}
|
|
336
361
|
function writeBytes(ptr, data) {
|
|
337
|
-
|
|
362
|
+
const start = ptr >>> 0;
|
|
363
|
+
const view = getMemoryView();
|
|
364
|
+
if (start + data.length > view.byteLength) return;
|
|
365
|
+
view.set(data, start);
|
|
338
366
|
}
|
|
339
367
|
function wrapPromisingExport(fn) {
|
|
340
368
|
if (!fn) return void 0;
|
|
@@ -418,20 +446,21 @@ var ZxBridgeCore = class _ZxBridgeCore {
|
|
|
418
446
|
_notifyFetchComplete(fetchId, statusCode, body, isError) {
|
|
419
447
|
const handler = this.#fetchCompleteHandler;
|
|
420
448
|
const encoded = typeof body === "string" ? textEncoder.encode(body) : body;
|
|
421
|
-
const ptr = this._alloc(encoded.length);
|
|
449
|
+
const ptr = this._alloc(encoded.length) >>> 0;
|
|
450
|
+
if (!ptr && encoded.length > 0) return;
|
|
422
451
|
writeBytes(ptr, encoded);
|
|
423
452
|
invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
|
|
424
453
|
}
|
|
425
454
|
/** Set a timeout and callback when it fires */
|
|
426
455
|
setTimeout(callbackId, delayMs) {
|
|
427
456
|
setTimeout(() => {
|
|
428
|
-
this.#invoke(
|
|
457
|
+
this.#invoke(3, callbackId, null);
|
|
429
458
|
}, delayMs);
|
|
430
459
|
}
|
|
431
460
|
/** Set an interval and callback each time it fires */
|
|
432
461
|
setInterval(callbackId, intervalMs) {
|
|
433
462
|
const handle = setInterval(() => {
|
|
434
|
-
this.#invoke(
|
|
463
|
+
this.#invoke(4, callbackId, null);
|
|
435
464
|
}, intervalMs);
|
|
436
465
|
this.#intervals.set(callbackId, handle);
|
|
437
466
|
}
|
|
@@ -449,18 +478,24 @@ var ZxBridgeCore = class _ZxBridgeCore {
|
|
|
449
478
|
}
|
|
450
479
|
this.#intervals.clear();
|
|
451
480
|
}
|
|
452
|
-
/** Write a string to WASM memory, returning
|
|
481
|
+
/** Write a string to WASM memory, returning `[ptr, len]`. */
|
|
453
482
|
_writeStringToWasm(str) {
|
|
454
|
-
return this.
|
|
483
|
+
return this.writeBytesToWasm(textEncoder.encode(str));
|
|
455
484
|
}
|
|
456
|
-
|
|
457
|
-
|
|
485
|
+
writeBytesToWasm(data) {
|
|
486
|
+
if (data.length === 0) return [0, 0];
|
|
487
|
+
const ptr = this._alloc(data.length) >>> 0;
|
|
488
|
+
if (!ptr) return [0, 0];
|
|
458
489
|
writeBytes(ptr, data);
|
|
459
|
-
return
|
|
490
|
+
return [ptr, data.length];
|
|
460
491
|
}
|
|
461
492
|
/** Log a message from WASM at the given level (0=error, 1=warn, 2=info, 3=debug) */
|
|
462
493
|
static log(level, ptr, len) {
|
|
463
|
-
const
|
|
494
|
+
const start = ptr >>> 0;
|
|
495
|
+
const length = len >>> 0;
|
|
496
|
+
const view = getMemoryView();
|
|
497
|
+
if (start + length > view.byteLength) return;
|
|
498
|
+
const msg = textDecoder.decode(view.subarray(start, start + length));
|
|
464
499
|
switch (level) {
|
|
465
500
|
case 0:
|
|
466
501
|
console.error(msg);
|
|
@@ -492,7 +527,7 @@ var ZxBridgeCore = class _ZxBridgeCore {
|
|
|
492
527
|
__zx: {
|
|
493
528
|
_log: (level, ptr, len) => _ZxBridgeCore.log(level, ptr, len),
|
|
494
529
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
495
|
-
bridgeRef
|
|
530
|
+
bridgeRef[0]?.fetchAsync(
|
|
496
531
|
urlPtr,
|
|
497
532
|
urlLen,
|
|
498
533
|
methodPtr,
|
|
@@ -506,20 +541,41 @@ var ZxBridgeCore = class _ZxBridgeCore {
|
|
|
506
541
|
);
|
|
507
542
|
},
|
|
508
543
|
_setTimeout: (callbackId, delayMs) => {
|
|
509
|
-
bridgeRef
|
|
544
|
+
bridgeRef[0]?.setTimeout(callbackId, delayMs);
|
|
510
545
|
},
|
|
511
546
|
_setInterval: (callbackId, intervalMs) => {
|
|
512
|
-
bridgeRef
|
|
547
|
+
bridgeRef[0]?.setInterval(callbackId, intervalMs);
|
|
513
548
|
},
|
|
514
549
|
_clearInterval: (callbackId) => {
|
|
515
|
-
bridgeRef
|
|
550
|
+
bridgeRef[0]?.clearInterval(callbackId);
|
|
516
551
|
}
|
|
517
552
|
}
|
|
518
553
|
};
|
|
519
554
|
}
|
|
520
555
|
};
|
|
556
|
+
function writeBytesOut(getMemory, allocRef, outPtrAddr, data) {
|
|
557
|
+
if (data.length === 0) {
|
|
558
|
+
new DataView(getMemory().buffer).setUint32(outPtrAddr, 0, true);
|
|
559
|
+
return 0;
|
|
560
|
+
}
|
|
561
|
+
const alloc = allocRef[0];
|
|
562
|
+
if (!alloc) return -1;
|
|
563
|
+
const ptr = alloc(data.length) >>> 0;
|
|
564
|
+
if (!ptr) return -1;
|
|
565
|
+
const buffer = getMemory().buffer;
|
|
566
|
+
if (ptr + data.length > buffer.byteLength) return -1;
|
|
567
|
+
new Uint8Array(buffer, ptr, data.length).set(data);
|
|
568
|
+
new DataView(buffer).setUint32(outPtrAddr >>> 0, ptr, true);
|
|
569
|
+
return data.length;
|
|
570
|
+
}
|
|
571
|
+
function writeJsonOut(getMemory, allocRef, outPtrAddr, value) {
|
|
572
|
+
return writeBytesOut(getMemory, allocRef, outPtrAddr, textEncoder.encode(JSON.stringify(value)));
|
|
573
|
+
}
|
|
574
|
+
function bindWasmAlloc(allocRef, exports) {
|
|
575
|
+
allocRef[0] = exports.__zx_alloc;
|
|
576
|
+
}
|
|
521
577
|
|
|
522
|
-
// src/kv.ts
|
|
578
|
+
// src/runtime/kv/extern.ts
|
|
523
579
|
function putOptions(ttlSeconds) {
|
|
524
580
|
if (ttlSeconds < 60) return void 0;
|
|
525
581
|
return { expirationTtl: ttlSeconds };
|
|
@@ -528,17 +584,12 @@ function isSyncKVNamespace(binding) {
|
|
|
528
584
|
const candidate = binding;
|
|
529
585
|
return typeof candidate.getSync === "function" && typeof candidate.putSync === "function" && typeof candidate.deleteSync === "function" && typeof candidate.listSync === "function";
|
|
530
586
|
}
|
|
531
|
-
function createKVImports(bindings, getMemory) {
|
|
587
|
+
function createKVImports(bindings, getMemory, allocRef) {
|
|
532
588
|
const encoder2 = new TextEncoder();
|
|
533
589
|
const decoder2 = new TextDecoder();
|
|
534
590
|
function readStr(ptr, len) {
|
|
535
591
|
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
536
592
|
}
|
|
537
|
-
function writeBytes2(buf_ptr, buf_max, data) {
|
|
538
|
-
if (data.length > buf_max) return -2;
|
|
539
|
-
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
540
|
-
return data.length;
|
|
541
|
-
}
|
|
542
593
|
function binding(ns) {
|
|
543
594
|
return bindings[ns] ?? bindings["default"] ?? null;
|
|
544
595
|
}
|
|
@@ -550,12 +601,12 @@ function createKVImports(bindings, getMemory) {
|
|
|
550
601
|
};
|
|
551
602
|
var syncBinding = syncBinding2;
|
|
552
603
|
return {
|
|
553
|
-
kv_get: (ns_ptr, ns_len, key_ptr, key_len,
|
|
604
|
+
kv_get: (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
|
|
554
605
|
const b = syncBinding2(readStr(ns_ptr, ns_len));
|
|
555
606
|
if (!b) return -1;
|
|
556
607
|
const value = b.getSync(readStr(key_ptr, key_len));
|
|
557
608
|
if (value === null) return -1;
|
|
558
|
-
return
|
|
609
|
+
return writeBytesOut(getMemory, allocRef, out_ptr, encoder2.encode(value));
|
|
559
610
|
},
|
|
560
611
|
kv_put: (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
|
|
561
612
|
const b = syncBinding2(readStr(ns_ptr, ns_len));
|
|
@@ -569,22 +620,22 @@ function createKVImports(bindings, getMemory) {
|
|
|
569
620
|
b.deleteSync(readStr(key_ptr, key_len));
|
|
570
621
|
return 0;
|
|
571
622
|
},
|
|
572
|
-
kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len,
|
|
623
|
+
kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, out_ptr) => {
|
|
573
624
|
const b = syncBinding2(readStr(ns_ptr, ns_len));
|
|
574
|
-
if (!b) return
|
|
625
|
+
if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
|
|
575
626
|
const prefix = readStr(pfx_ptr, pfx_len);
|
|
576
627
|
const result = b.listSync(prefix.length > 0 ? { prefix } : void 0);
|
|
577
|
-
return
|
|
628
|
+
return writeJsonOut(getMemory, allocRef, out_ptr, result.keys.map((k) => k.name));
|
|
578
629
|
}
|
|
579
630
|
};
|
|
580
631
|
}
|
|
581
632
|
return {
|
|
582
|
-
kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len,
|
|
633
|
+
kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, out_ptr) => {
|
|
583
634
|
const b = binding(readStr(ns_ptr, ns_len));
|
|
584
635
|
if (!b) return -1;
|
|
585
636
|
const value = await b.get(readStr(key_ptr, key_len));
|
|
586
637
|
if (value === null) return -1;
|
|
587
|
-
return
|
|
638
|
+
return writeBytesOut(getMemory, allocRef, out_ptr, encoder2.encode(value));
|
|
588
639
|
}),
|
|
589
640
|
kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len, ttl_seconds) => {
|
|
590
641
|
const b = binding(readStr(ns_ptr, ns_len));
|
|
@@ -598,17 +649,70 @@ function createKVImports(bindings, getMemory) {
|
|
|
598
649
|
await b.delete(readStr(key_ptr, key_len));
|
|
599
650
|
return 0;
|
|
600
651
|
}),
|
|
601
|
-
kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len,
|
|
652
|
+
kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, out_ptr) => {
|
|
602
653
|
const b = binding(readStr(ns_ptr, ns_len));
|
|
603
|
-
if (!b) return
|
|
654
|
+
if (!b) return writeJsonOut(getMemory, allocRef, out_ptr, []);
|
|
604
655
|
const prefix = readStr(prefix_ptr, prefix_len);
|
|
605
656
|
const result = await b.list(prefix.length > 0 ? { prefix } : void 0);
|
|
606
|
-
|
|
657
|
+
const names = result.keys.map((k) => k.name);
|
|
658
|
+
if (names.length === 0) {
|
|
659
|
+
new DataView(getMemory().buffer).setUint32(out_ptr, 0, true);
|
|
660
|
+
return 0;
|
|
661
|
+
}
|
|
662
|
+
return writeJsonOut(getMemory, allocRef, out_ptr, names);
|
|
607
663
|
})
|
|
608
664
|
};
|
|
609
665
|
}
|
|
610
666
|
|
|
611
|
-
// src/
|
|
667
|
+
// src/runtime/kv/localstorage.ts
|
|
668
|
+
function getLocalStorage() {
|
|
669
|
+
if (typeof localStorage === "undefined") {
|
|
670
|
+
throw new Error("localStorage is not available in this environment");
|
|
671
|
+
}
|
|
672
|
+
return localStorage;
|
|
673
|
+
}
|
|
674
|
+
function createLocalStorageKV(options = {}) {
|
|
675
|
+
const storage = getLocalStorage();
|
|
676
|
+
const namespace = options.namespace ?? "default";
|
|
677
|
+
const storagePrefix = options.storagePrefix ?? "ziex-kv";
|
|
678
|
+
const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
|
|
679
|
+
const namespacePrefix = scopedKey("");
|
|
680
|
+
return {
|
|
681
|
+
getSync(key) {
|
|
682
|
+
return storage.getItem(scopedKey(key));
|
|
683
|
+
},
|
|
684
|
+
async get(key) {
|
|
685
|
+
return this.getSync(key);
|
|
686
|
+
},
|
|
687
|
+
putSync(key, value) {
|
|
688
|
+
storage.setItem(scopedKey(key), value);
|
|
689
|
+
},
|
|
690
|
+
async put(key, value) {
|
|
691
|
+
this.putSync(key, value);
|
|
692
|
+
},
|
|
693
|
+
deleteSync(key) {
|
|
694
|
+
storage.removeItem(scopedKey(key));
|
|
695
|
+
},
|
|
696
|
+
async delete(key) {
|
|
697
|
+
this.deleteSync(key);
|
|
698
|
+
},
|
|
699
|
+
listSync(options2) {
|
|
700
|
+
const prefix = namespacePrefix + (options2?.prefix ?? "");
|
|
701
|
+
const keys = [];
|
|
702
|
+
for (let i = 0; i < storage.length; i += 1) {
|
|
703
|
+
const key = storage.key(i);
|
|
704
|
+
if (!key || !key.startsWith(prefix)) continue;
|
|
705
|
+
keys.push({ name: key.slice(namespacePrefix.length) });
|
|
706
|
+
}
|
|
707
|
+
return { keys };
|
|
708
|
+
},
|
|
709
|
+
async list(options2) {
|
|
710
|
+
return this.listSync(options2);
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// src/runtime/kv/indexdb.ts
|
|
612
716
|
function getIndexedDb() {
|
|
613
717
|
if (typeof indexedDB === "undefined") {
|
|
614
718
|
throw new Error("IndexedDB is not available in this environment");
|
|
@@ -651,7 +755,6 @@ function createIndexedDbKV(options = {}) {
|
|
|
651
755
|
const store = tx.objectStore(storeName);
|
|
652
756
|
const value = await requestToPromise(store.get(scopedKey(key)));
|
|
653
757
|
await transactionToPromise(tx);
|
|
654
|
-
console.debug(`KV GET - Key: ${key}, Value: ${value}`);
|
|
655
758
|
return typeof value === "string" ? value : null;
|
|
656
759
|
},
|
|
657
760
|
async put(key, value) {
|
|
@@ -659,7 +762,6 @@ function createIndexedDbKV(options = {}) {
|
|
|
659
762
|
const tx = db.transaction(storeName, "readwrite");
|
|
660
763
|
tx.objectStore(storeName).put(value, scopedKey(key));
|
|
661
764
|
await transactionToPromise(tx);
|
|
662
|
-
console.debug(`KV PUT - Key: ${key}, Value: ${value}`);
|
|
663
765
|
},
|
|
664
766
|
async delete(key) {
|
|
665
767
|
const db = await dbPromise;
|
|
@@ -680,52 +782,8 @@ function createIndexedDbKV(options = {}) {
|
|
|
680
782
|
}
|
|
681
783
|
};
|
|
682
784
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
throw new Error("localStorage is not available in this environment");
|
|
686
|
-
}
|
|
687
|
-
return localStorage;
|
|
688
|
-
}
|
|
689
|
-
function createLocalStorageKV(options = {}) {
|
|
690
|
-
const storage = getLocalStorage();
|
|
691
|
-
const namespace = options.namespace ?? "default";
|
|
692
|
-
const storagePrefix = options.storagePrefix ?? "ziex-kv";
|
|
693
|
-
const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
|
|
694
|
-
const namespacePrefix = scopedKey("");
|
|
695
|
-
return {
|
|
696
|
-
getSync(key) {
|
|
697
|
-
return storage.getItem(scopedKey(key));
|
|
698
|
-
},
|
|
699
|
-
async get(key) {
|
|
700
|
-
return this.getSync(key);
|
|
701
|
-
},
|
|
702
|
-
putSync(key, value) {
|
|
703
|
-
storage.setItem(scopedKey(key), value);
|
|
704
|
-
},
|
|
705
|
-
async put(key, value) {
|
|
706
|
-
this.putSync(key, value);
|
|
707
|
-
},
|
|
708
|
-
deleteSync(key) {
|
|
709
|
-
storage.removeItem(scopedKey(key));
|
|
710
|
-
},
|
|
711
|
-
async delete(key) {
|
|
712
|
-
this.deleteSync(key);
|
|
713
|
-
},
|
|
714
|
-
listSync(options2) {
|
|
715
|
-
const prefix = namespacePrefix + (options2?.prefix ?? "");
|
|
716
|
-
const keys = [];
|
|
717
|
-
for (let i = 0; i < storage.length; i += 1) {
|
|
718
|
-
const key = storage.key(i);
|
|
719
|
-
if (!key || !key.startsWith(prefix)) continue;
|
|
720
|
-
keys.push({ name: key.slice(namespacePrefix.length) });
|
|
721
|
-
}
|
|
722
|
-
return { keys };
|
|
723
|
-
},
|
|
724
|
-
async list(options2) {
|
|
725
|
-
return this.listSync(options2);
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
}
|
|
785
|
+
|
|
786
|
+
// src/runtime/kv.ts
|
|
729
787
|
function hasJSPI() {
|
|
730
788
|
return typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
|
|
731
789
|
}
|
|
@@ -756,18 +814,29 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
756
814
|
exports.__zx_eventbridge_async ?? exports.__zx_eventbridge
|
|
757
815
|
);
|
|
758
816
|
}
|
|
817
|
+
hasEventHandler(velementId, eventTypeId) {
|
|
818
|
+
return !!((eventHandlersPresent.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
819
|
+
}
|
|
759
820
|
eventMaySuspend(velementId, eventTypeId) {
|
|
760
|
-
return !!((
|
|
821
|
+
return !!((eventHandlersSuspend.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
761
822
|
}
|
|
762
823
|
setEventHandlerMode(velementId, eventTypeId, maySuspend) {
|
|
763
824
|
const bit = 1 << eventTypeId;
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
825
|
+
const present = (eventHandlersPresent.get(velementId) ?? 0) | bit;
|
|
826
|
+
eventHandlersPresent.set(velementId, present);
|
|
827
|
+
const suspendBits = eventHandlersSuspend.get(velementId) ?? 0;
|
|
828
|
+
const nextSuspend = maySuspend ? suspendBits | bit : suspendBits & ~bit;
|
|
829
|
+
if (nextSuspend === 0) eventHandlersSuspend.delete(velementId);
|
|
830
|
+
else eventHandlersSuspend.set(velementId, nextSuspend);
|
|
831
|
+
ensureDelegatedListener(eventTypeId);
|
|
768
832
|
}
|
|
769
833
|
clearEventHandlerModes(velementId) {
|
|
770
|
-
|
|
834
|
+
const present = eventHandlersPresent.get(velementId) ?? 0;
|
|
835
|
+
eventHandlersPresent.delete(velementId);
|
|
836
|
+
eventHandlersSuspend.delete(velementId);
|
|
837
|
+
for (const eventTypeId of HIGH_FREQ_EVENT_IDS) {
|
|
838
|
+
if (present & 1 << eventTypeId) maybeRemoveHighFreqListener(eventTypeId);
|
|
839
|
+
}
|
|
771
840
|
}
|
|
772
841
|
/** Submit a form action with bound-state round-trip. */
|
|
773
842
|
submitFormActionAsync(form, actionId, statesJson, fetchId) {
|
|
@@ -801,7 +870,7 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
801
870
|
const handler = this.#wsOnOpenHandler;
|
|
802
871
|
if (!handler) return;
|
|
803
872
|
const protocol = ws.protocol || "";
|
|
804
|
-
const
|
|
873
|
+
const [ptr, len] = this._writeStringToWasm(protocol);
|
|
805
874
|
invokeWasmExport(handler, wsId, ptr, len);
|
|
806
875
|
};
|
|
807
876
|
ws.onmessage = (event) => {
|
|
@@ -809,20 +878,20 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
809
878
|
if (!handler) return;
|
|
810
879
|
const isBinary = event.data instanceof ArrayBuffer;
|
|
811
880
|
const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
|
|
812
|
-
const
|
|
881
|
+
const [ptr, len] = this.writeBytesToWasm(data);
|
|
813
882
|
invokeWasmExport(handler, wsId, ptr, len, isBinary ? 1 : 0);
|
|
814
883
|
};
|
|
815
884
|
ws.onerror = (_event) => {
|
|
816
885
|
const handler = this.#wsOnErrorHandler;
|
|
817
886
|
if (!handler) return;
|
|
818
|
-
const
|
|
887
|
+
const [ptr, len] = this._writeStringToWasm("WebSocket error");
|
|
819
888
|
invokeWasmExport(handler, wsId, ptr, len);
|
|
820
889
|
};
|
|
821
890
|
ws.onclose = (event) => {
|
|
822
891
|
const handler = this.#wsOnCloseHandler;
|
|
823
892
|
if (!handler) return;
|
|
824
893
|
const reason = event.reason || "";
|
|
825
|
-
const
|
|
894
|
+
const [ptr, len] = this._writeStringToWasm(reason);
|
|
826
895
|
invokeWasmExport(handler, wsId, event.code, ptr, len, event.wasClean ? 1 : 0);
|
|
827
896
|
this.#websockets.delete(wsId);
|
|
828
897
|
};
|
|
@@ -831,7 +900,7 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
831
900
|
const handler = this.#wsOnErrorHandler;
|
|
832
901
|
if (handler) {
|
|
833
902
|
const msg = error instanceof Error ? error.message : "WebSocket connection failed";
|
|
834
|
-
const
|
|
903
|
+
const [ptr, len] = this._writeStringToWasm(msg);
|
|
835
904
|
invokeWasmExport(handler, wsId, ptr, len);
|
|
836
905
|
}
|
|
837
906
|
}
|
|
@@ -841,10 +910,13 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
841
910
|
const ws = this.#websockets.get(wsId);
|
|
842
911
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
843
912
|
const memory = getMemoryView();
|
|
913
|
+
const start = dataPtr >>> 0;
|
|
914
|
+
const length = dataLen >>> 0;
|
|
915
|
+
if (start + length > memory.byteLength) return;
|
|
844
916
|
if (isBinary) {
|
|
845
|
-
ws.send(memory.slice(
|
|
917
|
+
ws.send(memory.slice(start, start + length));
|
|
846
918
|
} else {
|
|
847
|
-
ws.send(textDecoder.decode(memory.subarray(
|
|
919
|
+
ws.send(textDecoder.decode(memory.subarray(start, start + length)));
|
|
848
920
|
}
|
|
849
921
|
}
|
|
850
922
|
/** Close WebSocket connection */
|
|
@@ -861,7 +933,8 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
861
933
|
}
|
|
862
934
|
dispose() {
|
|
863
935
|
super.dispose();
|
|
864
|
-
|
|
936
|
+
eventHandlersPresent.clear();
|
|
937
|
+
eventHandlersSuspend.clear();
|
|
865
938
|
for (const ws of this.#websockets.values()) {
|
|
866
939
|
try {
|
|
867
940
|
ws.close();
|
|
@@ -870,14 +943,16 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
870
943
|
}
|
|
871
944
|
this.#websockets.clear();
|
|
872
945
|
}
|
|
873
|
-
/**
|
|
874
|
-
|
|
875
|
-
|
|
946
|
+
/**
|
|
947
|
+
* Dispatch to WASM for one vnode. Caller owns `eventRef` lifetime
|
|
948
|
+
* (store once per bubble, release after sync/async work completes).
|
|
949
|
+
*/
|
|
950
|
+
eventbridge(velementId, eventTypeId, eventRef) {
|
|
951
|
+
const id = BigInt(velementId >>> 0);
|
|
876
952
|
if (this.eventMaySuspend(velementId, eventTypeId)) {
|
|
877
|
-
invokeWasmExport(this.#eventbridgeAsync,
|
|
878
|
-
return;
|
|
953
|
+
return invokeWasmExport(this.#eventbridgeAsync, id, eventTypeId, eventRef);
|
|
879
954
|
}
|
|
880
|
-
invokeWasmExport(this.#eventbridge,
|
|
955
|
+
invokeWasmExport(this.#eventbridge, id, eventTypeId, eventRef);
|
|
881
956
|
}
|
|
882
957
|
/** Create the full browser import object for WASM instantiation (includes DOM + WebSocket). */
|
|
883
958
|
static createImportObject(bridgeRef) {
|
|
@@ -890,13 +965,13 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
890
965
|
__zx: {
|
|
891
966
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
892
967
|
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
|
893
|
-
bridgeRef
|
|
968
|
+
bridgeRef[0]?.setEventHandlerMode(Number(vnodeId), eventTypeId, maySuspend !== 0);
|
|
894
969
|
},
|
|
895
970
|
_clearEventHandlerModes: (vnodeId) => {
|
|
896
|
-
bridgeRef
|
|
971
|
+
bridgeRef[0]?.clearEventHandlerModes(Number(vnodeId));
|
|
897
972
|
},
|
|
898
973
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
899
|
-
bridgeRef
|
|
974
|
+
bridgeRef[0]?.fetchAsync(
|
|
900
975
|
urlPtr,
|
|
901
976
|
urlLen,
|
|
902
977
|
methodPtr,
|
|
@@ -910,43 +985,49 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
910
985
|
);
|
|
911
986
|
},
|
|
912
987
|
_setTimeout: (callbackId, delayMs) => {
|
|
913
|
-
bridgeRef
|
|
988
|
+
bridgeRef[0]?.setTimeout(callbackId, delayMs);
|
|
914
989
|
},
|
|
915
990
|
_setInterval: (callbackId, intervalMs) => {
|
|
916
|
-
bridgeRef
|
|
991
|
+
bridgeRef[0]?.setInterval(callbackId, intervalMs);
|
|
917
992
|
},
|
|
918
993
|
_clearInterval: (callbackId) => {
|
|
919
|
-
bridgeRef
|
|
994
|
+
bridgeRef[0]?.clearInterval(callbackId);
|
|
920
995
|
},
|
|
921
996
|
// WebSocket API
|
|
922
997
|
_wsConnect: (wsId, urlPtr, urlLen, protocolsPtr, protocolsLen) => {
|
|
923
|
-
bridgeRef
|
|
998
|
+
bridgeRef[0]?.wsConnect(wsId, urlPtr, urlLen, protocolsPtr, protocolsLen);
|
|
924
999
|
},
|
|
925
1000
|
_wsSend: (wsId, dataPtr, dataLen, isBinary) => {
|
|
926
|
-
bridgeRef
|
|
1001
|
+
bridgeRef[0]?.wsSend(wsId, dataPtr, dataLen, isBinary);
|
|
927
1002
|
},
|
|
928
1003
|
_wsClose: (wsId, code, reasonPtr, reasonLen) => {
|
|
929
|
-
bridgeRef
|
|
1004
|
+
bridgeRef[0]?.wsClose(wsId, code, reasonPtr, reasonLen);
|
|
930
1005
|
},
|
|
931
1006
|
_ce: (id, vnodeId) => {
|
|
1007
|
+
const nid = Number(vnodeId);
|
|
932
1008
|
const tagName = TAG_NAMES[id];
|
|
933
1009
|
const el = id >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
|
|
934
|
-
el.__zx_ref =
|
|
935
|
-
domNodes.set(
|
|
936
|
-
return storeValueGetRef(el);
|
|
1010
|
+
el.__zx_ref = nid;
|
|
1011
|
+
domNodes.set(nid, el);
|
|
937
1012
|
},
|
|
938
1013
|
_ct: (ptr, len, vnodeId) => {
|
|
939
|
-
const
|
|
940
|
-
const node = document.createTextNode(
|
|
941
|
-
node.__zx_ref =
|
|
942
|
-
domNodes.set(
|
|
943
|
-
|
|
1014
|
+
const nid = Number(vnodeId);
|
|
1015
|
+
const node = document.createTextNode(readString(ptr, len));
|
|
1016
|
+
node.__zx_ref = nid;
|
|
1017
|
+
domNodes.set(nid, node);
|
|
1018
|
+
},
|
|
1019
|
+
/** Insert vnode before a jsz-held end comment (hydration). */
|
|
1020
|
+
_ih: (vnodeId, endCommentRef) => {
|
|
1021
|
+
const child = domNodes.get(Number(vnodeId));
|
|
1022
|
+
const end = loadValueFromRef(endCommentRef);
|
|
1023
|
+
if (!child || !end?.parentNode) return;
|
|
1024
|
+
end.parentNode.insertBefore(child, end);
|
|
944
1025
|
},
|
|
945
1026
|
_sa: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
|
|
946
|
-
domNodes.get(vnodeId)?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
|
|
1027
|
+
domNodes.get(Number(vnodeId))?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
|
|
947
1028
|
},
|
|
948
1029
|
_sp: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
|
|
949
|
-
const el = domNodes.get(vnodeId);
|
|
1030
|
+
const el = domNodes.get(Number(vnodeId));
|
|
950
1031
|
if (el) {
|
|
951
1032
|
const name = readString(namePtr, nameLen);
|
|
952
1033
|
const val = readString(valPtr, valLen);
|
|
@@ -958,39 +1039,39 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
958
1039
|
}
|
|
959
1040
|
},
|
|
960
1041
|
_ra: (vnodeId, namePtr, nameLen) => {
|
|
961
|
-
domNodes.get(vnodeId)?.removeAttribute(readString(namePtr, nameLen));
|
|
1042
|
+
domNodes.get(Number(vnodeId))?.removeAttribute(readString(namePtr, nameLen));
|
|
962
1043
|
},
|
|
963
1044
|
_snv: (vnodeId, ptr, len) => {
|
|
964
|
-
const node = domNodes.get(vnodeId);
|
|
1045
|
+
const node = domNodes.get(Number(vnodeId));
|
|
965
1046
|
if (node) node.nodeValue = readString(ptr, len);
|
|
966
1047
|
},
|
|
967
1048
|
_srh: (vnodeId, ptr, len) => {
|
|
968
|
-
const el = domNodes.get(vnodeId);
|
|
1049
|
+
const el = domNodes.get(Number(vnodeId));
|
|
969
1050
|
if (el) el.innerHTML = readString(ptr, len);
|
|
970
1051
|
},
|
|
971
1052
|
_ac: (parentId, childId) => {
|
|
972
|
-
const parent = domNodes.get(parentId);
|
|
973
|
-
const child = domNodes.get(childId);
|
|
1053
|
+
const parent = domNodes.get(Number(parentId));
|
|
1054
|
+
const child = domNodes.get(Number(childId));
|
|
974
1055
|
if (parent && child) parent.appendChild(child);
|
|
975
1056
|
},
|
|
976
1057
|
_ib: (parentId, childId, refId) => {
|
|
977
|
-
const parent = domNodes.get(parentId);
|
|
978
|
-
const child = domNodes.get(childId);
|
|
979
|
-
const ref = domNodes.get(refId) ?? null;
|
|
1058
|
+
const parent = domNodes.get(Number(parentId));
|
|
1059
|
+
const child = domNodes.get(Number(childId));
|
|
1060
|
+
const ref = domNodes.get(Number(refId)) ?? null;
|
|
980
1061
|
if (parent && child) parent.insertBefore(child, ref);
|
|
981
1062
|
},
|
|
982
1063
|
_rc: (parentId, childId) => {
|
|
983
|
-
const parent = domNodes.get(parentId);
|
|
984
|
-
const child = domNodes.get(childId);
|
|
1064
|
+
const parent = domNodes.get(Number(parentId));
|
|
1065
|
+
const child = domNodes.get(Number(childId));
|
|
985
1066
|
if (parent && child) {
|
|
986
1067
|
parent.removeChild(child);
|
|
987
1068
|
cleanupDomNodes(child);
|
|
988
1069
|
}
|
|
989
1070
|
},
|
|
990
1071
|
_rpc: (parentId, newId, oldId) => {
|
|
991
|
-
const parent = domNodes.get(parentId);
|
|
992
|
-
const newChild = domNodes.get(newId);
|
|
993
|
-
const oldChild = domNodes.get(oldId);
|
|
1072
|
+
const parent = domNodes.get(Number(parentId));
|
|
1073
|
+
const newChild = domNodes.get(Number(newId));
|
|
1074
|
+
const oldChild = domNodes.get(Number(oldId));
|
|
994
1075
|
if (parent && newChild && oldChild) {
|
|
995
1076
|
parent.replaceChild(newChild, oldChild);
|
|
996
1077
|
cleanupDomNodes(oldChild);
|
|
@@ -1002,18 +1083,22 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
1002
1083
|
writeBytes(bufPtr, bytes.subarray(0, len));
|
|
1003
1084
|
return len;
|
|
1004
1085
|
},
|
|
1005
|
-
_getFormData: (
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1010
|
-
const
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1086
|
+
_getFormData: (eventRef, outPtrAddr) => {
|
|
1087
|
+
const event = loadValueFromRef(eventRef);
|
|
1088
|
+
const el = event?.target;
|
|
1089
|
+
const form = el instanceof HTMLFormElement ? el : el?.closest?.("form") ?? null;
|
|
1090
|
+
if (!form) return 0;
|
|
1091
|
+
const entries = [];
|
|
1092
|
+
for (const [k, v] of new FormData(form).entries()) {
|
|
1093
|
+
entries.push(k, String(v));
|
|
1094
|
+
}
|
|
1095
|
+
const bytes = textEncoder.encode(JSON.stringify(entries));
|
|
1096
|
+
const [ptr, len] = bridgeRef[0].writeBytesToWasm(bytes);
|
|
1097
|
+
new DataView(jsz.memory.buffer).setUint32(outPtrAddr, ptr, true);
|
|
1013
1098
|
return len;
|
|
1014
1099
|
},
|
|
1015
1100
|
_submitFormAction: (vnodeId, actionId) => {
|
|
1016
|
-
const form = domNodes.get(vnodeId);
|
|
1101
|
+
const form = domNodes.get(Number(vnodeId));
|
|
1017
1102
|
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
1018
1103
|
const formData = new FormData(form);
|
|
1019
1104
|
fetch(window.location.href, {
|
|
@@ -1025,21 +1110,39 @@ var ZxBridge = class extends ZxBridgeCore {
|
|
|
1025
1110
|
});
|
|
1026
1111
|
},
|
|
1027
1112
|
_submitFormActionAsync: (vnodeId, actionId, statesPtr, statesLen, fetchId) => {
|
|
1028
|
-
const form = domNodes.get(vnodeId);
|
|
1113
|
+
const form = domNodes.get(Number(vnodeId));
|
|
1029
1114
|
if (!form || !(form instanceof HTMLFormElement)) return;
|
|
1030
1115
|
const statesJson = statesLen > 0 ? readString(statesPtr, statesLen) : "[]";
|
|
1031
|
-
bridgeRef
|
|
1116
|
+
bridgeRef[0]?.submitFormActionAsync(form, actionId, statesJson, fetchId);
|
|
1032
1117
|
}
|
|
1033
1118
|
}
|
|
1034
1119
|
};
|
|
1035
1120
|
}
|
|
1036
1121
|
};
|
|
1037
1122
|
var domNodes = /* @__PURE__ */ new Map();
|
|
1123
|
+
var eventHandlersPresent = /* @__PURE__ */ new Map();
|
|
1124
|
+
var eventHandlersSuspend = /* @__PURE__ */ new Map();
|
|
1038
1125
|
function cleanupDomNodes(node) {
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1126
|
+
const stack = [node];
|
|
1127
|
+
let highFreqBits = 0;
|
|
1128
|
+
while (stack.length > 0) {
|
|
1129
|
+
const n = stack.pop();
|
|
1130
|
+
const ref = n.__zx_ref;
|
|
1131
|
+
if (typeof ref === "number") {
|
|
1132
|
+
const present = eventHandlersPresent.get(ref);
|
|
1133
|
+
if (present !== void 0) {
|
|
1134
|
+
highFreqBits |= present;
|
|
1135
|
+
eventHandlersPresent.delete(ref);
|
|
1136
|
+
eventHandlersSuspend.delete(ref);
|
|
1137
|
+
}
|
|
1138
|
+
domNodes.delete(ref);
|
|
1139
|
+
}
|
|
1140
|
+
const children = n.childNodes;
|
|
1141
|
+
for (let i = 0; i < children.length; i++) stack.push(children[i]);
|
|
1142
|
+
}
|
|
1143
|
+
for (const eventTypeId of HIGH_FREQ_EVENT_IDS) {
|
|
1144
|
+
if (highFreqBits & 1 << eventTypeId) maybeRemoveHighFreqListener(eventTypeId);
|
|
1145
|
+
}
|
|
1043
1146
|
}
|
|
1044
1147
|
var SVG_TAG_START_INDEX = 140;
|
|
1045
1148
|
var TAG_NAMES = [
|
|
@@ -1245,54 +1348,115 @@ var TAG_NAMES = [
|
|
|
1245
1348
|
"view"
|
|
1246
1349
|
];
|
|
1247
1350
|
var DELEGATED_EVENTS = [
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
// focus/blur do not bubble
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1351
|
+
"click",
|
|
1352
|
+
"dblclick",
|
|
1353
|
+
"input",
|
|
1354
|
+
"change",
|
|
1355
|
+
"submit",
|
|
1356
|
+
// focus/blur do not bubble - listen to focusin/focusout instead.
|
|
1357
|
+
"focusin",
|
|
1358
|
+
"focusout",
|
|
1359
|
+
"keydown",
|
|
1360
|
+
"keyup",
|
|
1361
|
+
"keypress",
|
|
1362
|
+
"mouseenter",
|
|
1363
|
+
"mouseleave",
|
|
1364
|
+
"mousedown",
|
|
1365
|
+
"mouseup",
|
|
1366
|
+
"mousemove",
|
|
1367
|
+
"touchstart",
|
|
1368
|
+
"touchend",
|
|
1369
|
+
"touchmove",
|
|
1370
|
+
"scroll",
|
|
1371
|
+
"wheel",
|
|
1372
|
+
"pointerdown",
|
|
1373
|
+
"pointermove",
|
|
1374
|
+
"pointerup",
|
|
1375
|
+
"pointercancel"
|
|
1268
1376
|
];
|
|
1269
|
-
var
|
|
1377
|
+
var HIGH_FREQ_EVENT_IDS = new Set([
|
|
1378
|
+
DELEGATED_EVENTS.indexOf("mousemove"),
|
|
1379
|
+
DELEGATED_EVENTS.indexOf("pointermove"),
|
|
1380
|
+
DELEGATED_EVENTS.indexOf("wheel"),
|
|
1381
|
+
DELEGATED_EVENTS.indexOf("scroll"),
|
|
1382
|
+
DELEGATED_EVENTS.indexOf("touchmove")
|
|
1383
|
+
].filter((id) => id >= 0));
|
|
1384
|
+
var delegationState = null;
|
|
1385
|
+
function makeDelegatedListener(bridge, eventTypeId) {
|
|
1386
|
+
return (event) => {
|
|
1387
|
+
let eventRef;
|
|
1388
|
+
const pending = [];
|
|
1389
|
+
let target = event.target;
|
|
1390
|
+
while (target && target !== document.body) {
|
|
1391
|
+
const zxRef = target.__zx_ref;
|
|
1392
|
+
if (typeof zxRef === "number" && bridge.hasEventHandler(zxRef, eventTypeId)) {
|
|
1393
|
+
if (eventRef === void 0) eventRef = storeValueGetRef(event);
|
|
1394
|
+
const result = bridge.eventbridge(zxRef, eventTypeId, eventRef);
|
|
1395
|
+
if (result && typeof result.then === "function") {
|
|
1396
|
+
pending.push(result);
|
|
1397
|
+
}
|
|
1398
|
+
if (event.cancelBubble) break;
|
|
1399
|
+
}
|
|
1400
|
+
target = target.parentElement;
|
|
1401
|
+
}
|
|
1402
|
+
if (eventRef !== void 0) {
|
|
1403
|
+
const ref = eventRef;
|
|
1404
|
+
if (pending.length > 0) {
|
|
1405
|
+
Promise.all(pending).finally(() => releaseValueRef(ref));
|
|
1406
|
+
} else {
|
|
1407
|
+
releaseValueRef(ref);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
function ensureDelegatedListener(eventTypeId) {
|
|
1413
|
+
const state = delegationState;
|
|
1414
|
+
if (!state || state.attached.has(eventTypeId)) return;
|
|
1415
|
+
const domType = DELEGATED_EVENTS[eventTypeId];
|
|
1416
|
+
if (!domType) return;
|
|
1417
|
+
const passive = domType.startsWith("touch") || domType === "scroll";
|
|
1418
|
+
const options = { passive };
|
|
1419
|
+
const listener = makeDelegatedListener(state.bridge, eventTypeId);
|
|
1420
|
+
state.root.addEventListener(domType, listener, options);
|
|
1421
|
+
state.attached.set(eventTypeId, { listener, options });
|
|
1422
|
+
}
|
|
1423
|
+
function anyHandlerForType(eventTypeId) {
|
|
1424
|
+
const bit = 1 << eventTypeId;
|
|
1425
|
+
for (const mask of eventHandlersPresent.values()) {
|
|
1426
|
+
if (mask & bit) return true;
|
|
1427
|
+
}
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
function maybeRemoveHighFreqListener(eventTypeId) {
|
|
1431
|
+
if (!HIGH_FREQ_EVENT_IDS.has(eventTypeId)) return;
|
|
1432
|
+
if (anyHandlerForType(eventTypeId)) return;
|
|
1433
|
+
const state = delegationState;
|
|
1434
|
+
if (!state) return;
|
|
1435
|
+
const entry = state.attached.get(eventTypeId);
|
|
1436
|
+
if (!entry) return;
|
|
1437
|
+
const domType = DELEGATED_EVENTS[eventTypeId];
|
|
1438
|
+
state.root.removeEventListener(domType, entry.listener, entry.options);
|
|
1439
|
+
state.attached.delete(eventTypeId);
|
|
1440
|
+
}
|
|
1270
1441
|
function initEventDelegation(bridge, rootSelector = "body") {
|
|
1271
1442
|
const root = document.querySelector(rootSelector);
|
|
1272
1443
|
if (!root) return () => {
|
|
1273
1444
|
};
|
|
1274
|
-
|
|
1275
|
-
for (
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
while (target && target !== document.body) {
|
|
1279
|
-
const zxRef = target.__zx_ref;
|
|
1280
|
-
if (zxRef !== void 0) {
|
|
1281
|
-
bridge.eventbridge(BigInt(zxRef), delegatedEvent.eventTypeId, event);
|
|
1282
|
-
if (event.cancelBubble) break;
|
|
1283
|
-
}
|
|
1284
|
-
target = target.parentElement;
|
|
1285
|
-
}
|
|
1286
|
-
};
|
|
1287
|
-
const options = { passive: delegatedEvent.domType.startsWith("touch") || delegatedEvent.domType === "scroll" };
|
|
1288
|
-
root.addEventListener(delegatedEvent.domType, listener, options);
|
|
1289
|
-
removers.push(() => root.removeEventListener(delegatedEvent.domType, listener, options));
|
|
1445
|
+
delegationState = { root, bridge, attached: /* @__PURE__ */ new Map() };
|
|
1446
|
+
for (let eventTypeId = 0; eventTypeId < DELEGATED_EVENTS.length; eventTypeId++) {
|
|
1447
|
+
if (HIGH_FREQ_EVENT_IDS.has(eventTypeId)) continue;
|
|
1448
|
+
ensureDelegatedListener(eventTypeId);
|
|
1290
1449
|
}
|
|
1291
1450
|
return () => {
|
|
1292
|
-
|
|
1451
|
+
if (!delegationState) return;
|
|
1452
|
+
for (const [eventTypeId, entry] of delegationState.attached) {
|
|
1453
|
+
const domType = DELEGATED_EVENTS[eventTypeId];
|
|
1454
|
+
delegationState.root.removeEventListener(domType, entry.listener, entry.options);
|
|
1455
|
+
}
|
|
1456
|
+
delegationState.attached.clear();
|
|
1457
|
+
delegationState = null;
|
|
1293
1458
|
};
|
|
1294
1459
|
}
|
|
1295
|
-
var DEFAULT_URL = "/assets/_/main.wasm";
|
|
1296
1460
|
var activeRuntime = null;
|
|
1297
1461
|
function buildDevtoolsLocation() {
|
|
1298
1462
|
return {
|
|
@@ -1325,29 +1489,34 @@ async function init(options = {}) {
|
|
|
1325
1489
|
activeRuntime.dispose();
|
|
1326
1490
|
activeRuntime = null;
|
|
1327
1491
|
}
|
|
1328
|
-
const url = options.url ?? document.getElementById("__$wasmlink")?.href
|
|
1329
|
-
|
|
1492
|
+
const url = options.url ?? document.getElementById("__$wasmlink")?.href;
|
|
1493
|
+
if (!url) throw new Error("WASM URL is not set");
|
|
1494
|
+
const bridgeRef = [null];
|
|
1330
1495
|
let wasmMemory = null;
|
|
1331
|
-
const
|
|
1332
|
-
const
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1496
|
+
const allocRef = [null];
|
|
1497
|
+
const getMemory = () => {
|
|
1498
|
+
if (wasmMemory) return wasmMemory;
|
|
1499
|
+
if (jsz.memory) return jsz.memory;
|
|
1500
|
+
throw new Error("WASM memory is not ready");
|
|
1501
|
+
};
|
|
1502
|
+
const importObject = {
|
|
1503
|
+
...ZxBridge.createImportObject(bridgeRef),
|
|
1504
|
+
...options.importObject
|
|
1338
1505
|
};
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1506
|
+
if (true) {
|
|
1507
|
+
importObject.__zx_kv = createKVImports(
|
|
1508
|
+
options.kv ?? createBrowserKVBindings(),
|
|
1509
|
+
getMemory,
|
|
1510
|
+
allocRef
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1345
1513
|
const source = await WebAssembly.instantiateStreaming(fetch(url), importObject);
|
|
1346
1514
|
const { instance } = source;
|
|
1347
1515
|
wasmMemory = instance.exports.memory;
|
|
1348
1516
|
jsz.memory = wasmMemory;
|
|
1517
|
+
bindWasmAlloc(allocRef, instance.exports);
|
|
1349
1518
|
const bridge = new ZxBridge(instance.exports);
|
|
1350
|
-
bridgeRef
|
|
1519
|
+
bridgeRef[0] = bridge;
|
|
1351
1520
|
domNodes.clear();
|
|
1352
1521
|
const disposeDelegation = initEventDelegation(bridge, options.eventDelegationRoot ?? "body");
|
|
1353
1522
|
const main = wrapPromisingExport(instance.exports.mainClient);
|