ziex 0.1.0-dev.966 → 0.1.0-dev.987
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/browser/kv.d.ts +13 -0
- package/cloudflare/index.js +350 -110
- package/index.js +45 -8
- package/kv.d.ts +17 -2
- package/package.json +2 -2
- package/wasm/core.d.ts +2 -0
- package/wasm/index.d.ts +18 -0
- package/wasm/index.js +344 -23
- package/wasm/init.js +321 -23
package/wasm/init.js
CHANGED
|
@@ -217,6 +217,24 @@ function readString(ptr, len) {
|
|
|
217
217
|
function writeBytes(ptr, data) {
|
|
218
218
|
getMemoryView().set(data, ptr);
|
|
219
219
|
}
|
|
220
|
+
function wrapPromisingExport(fn) {
|
|
221
|
+
if (!fn)
|
|
222
|
+
return;
|
|
223
|
+
const promising = WebAssembly.promising;
|
|
224
|
+
if (typeof promising !== "function")
|
|
225
|
+
return fn;
|
|
226
|
+
return promising(fn);
|
|
227
|
+
}
|
|
228
|
+
function invokeWasmExport(fn, ...args) {
|
|
229
|
+
if (!fn)
|
|
230
|
+
return;
|
|
231
|
+
const result = fn(...args);
|
|
232
|
+
if (result && typeof result.then === "function") {
|
|
233
|
+
result.then(undefined, (error) => {
|
|
234
|
+
console.error(error);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
220
238
|
|
|
221
239
|
class ZxBridgeCore {
|
|
222
240
|
#intervals = new Map;
|
|
@@ -225,8 +243,12 @@ class ZxBridgeCore {
|
|
|
225
243
|
#fetchCompleteHandler;
|
|
226
244
|
constructor(exports) {
|
|
227
245
|
this._alloc = exports.__zx_alloc;
|
|
228
|
-
this.#handler = exports.__zx_cb;
|
|
229
|
-
|
|
246
|
+
this.#handler = wrapPromisingExport(exports.__zx_cb);
|
|
247
|
+
const fetchCompleteHandler = wrapPromisingExport(exports.__zx_fetch_complete);
|
|
248
|
+
if (!fetchCompleteHandler) {
|
|
249
|
+
throw new Error("__zx_fetch_complete not exported from WASM");
|
|
250
|
+
}
|
|
251
|
+
this.#fetchCompleteHandler = fetchCompleteHandler;
|
|
230
252
|
if (exports.memory)
|
|
231
253
|
jsz.memory = exports.memory;
|
|
232
254
|
}
|
|
@@ -237,7 +259,7 @@ class ZxBridgeCore {
|
|
|
237
259
|
return;
|
|
238
260
|
}
|
|
239
261
|
const dataRef = storeValueGetRef(data);
|
|
240
|
-
handler
|
|
262
|
+
invokeWasmExport(handler, type, id, dataRef);
|
|
241
263
|
}
|
|
242
264
|
fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) {
|
|
243
265
|
const url = readString(urlPtr, urlLen);
|
|
@@ -282,7 +304,7 @@ class ZxBridgeCore {
|
|
|
282
304
|
const encoded = textEncoder.encode(body);
|
|
283
305
|
const ptr = this._alloc(encoded.length);
|
|
284
306
|
writeBytes(ptr, encoded);
|
|
285
|
-
handler
|
|
307
|
+
invokeWasmExport(handler, fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
|
|
286
308
|
}
|
|
287
309
|
setTimeout(callbackId, delayMs) {
|
|
288
310
|
setTimeout(() => {
|
|
@@ -354,6 +376,230 @@ class ZxBridgeCore {
|
|
|
354
376
|
};
|
|
355
377
|
}
|
|
356
378
|
}
|
|
379
|
+
// src/kv.ts
|
|
380
|
+
function isSyncKVNamespace(binding) {
|
|
381
|
+
const candidate = binding;
|
|
382
|
+
return typeof candidate.getSync === "function" && typeof candidate.putSync === "function" && typeof candidate.deleteSync === "function" && typeof candidate.listSync === "function";
|
|
383
|
+
}
|
|
384
|
+
function createKVImports(bindings, getMemory) {
|
|
385
|
+
const encoder2 = new TextEncoder;
|
|
386
|
+
const decoder2 = new TextDecoder;
|
|
387
|
+
function readStr(ptr, len) {
|
|
388
|
+
return decoder2.decode(new Uint8Array(getMemory().buffer, ptr, len));
|
|
389
|
+
}
|
|
390
|
+
function writeBytes2(buf_ptr, buf_max, data) {
|
|
391
|
+
if (data.length > buf_max)
|
|
392
|
+
return -2;
|
|
393
|
+
new Uint8Array(getMemory().buffer, buf_ptr, data.length).set(data);
|
|
394
|
+
return data.length;
|
|
395
|
+
}
|
|
396
|
+
function binding(ns) {
|
|
397
|
+
return bindings[ns] ?? bindings["default"] ?? null;
|
|
398
|
+
}
|
|
399
|
+
const Suspending = WebAssembly.Suspending;
|
|
400
|
+
if (typeof Suspending !== "function") {
|
|
401
|
+
let syncBinding = function(ns) {
|
|
402
|
+
const candidate = binding(ns);
|
|
403
|
+
return candidate && isSyncKVNamespace(candidate) ? candidate : null;
|
|
404
|
+
};
|
|
405
|
+
return {
|
|
406
|
+
kv_get: (ns_ptr, ns_len, key_ptr, key_len, buf_ptr, buf_max) => {
|
|
407
|
+
const b = syncBinding(readStr(ns_ptr, ns_len));
|
|
408
|
+
if (!b)
|
|
409
|
+
return -1;
|
|
410
|
+
const value = b.getSync(readStr(key_ptr, key_len));
|
|
411
|
+
if (value === null)
|
|
412
|
+
return -1;
|
|
413
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode(value));
|
|
414
|
+
},
|
|
415
|
+
kv_put: (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len) => {
|
|
416
|
+
const b = syncBinding(readStr(ns_ptr, ns_len));
|
|
417
|
+
if (!b)
|
|
418
|
+
return 0;
|
|
419
|
+
b.putSync(readStr(key_ptr, key_len), readStr(val_ptr, val_len));
|
|
420
|
+
return 0;
|
|
421
|
+
},
|
|
422
|
+
kv_delete: (ns_ptr, ns_len, key_ptr, key_len) => {
|
|
423
|
+
const b = syncBinding(readStr(ns_ptr, ns_len));
|
|
424
|
+
if (!b)
|
|
425
|
+
return 0;
|
|
426
|
+
b.deleteSync(readStr(key_ptr, key_len));
|
|
427
|
+
return 0;
|
|
428
|
+
},
|
|
429
|
+
kv_list: (ns_ptr, ns_len, pfx_ptr, pfx_len, buf_ptr, buf_max) => {
|
|
430
|
+
const b = syncBinding(readStr(ns_ptr, ns_len));
|
|
431
|
+
if (!b)
|
|
432
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode("[]"));
|
|
433
|
+
const prefix = readStr(pfx_ptr, pfx_len);
|
|
434
|
+
const result = b.listSync(prefix.length > 0 ? { prefix } : undefined);
|
|
435
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode(JSON.stringify(result.keys.map((k) => k.name))));
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
kv_get: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, buf_ptr, buf_max) => {
|
|
441
|
+
const b = binding(readStr(ns_ptr, ns_len));
|
|
442
|
+
if (!b)
|
|
443
|
+
return -1;
|
|
444
|
+
const value = await b.get(readStr(key_ptr, key_len));
|
|
445
|
+
if (value === null)
|
|
446
|
+
return -1;
|
|
447
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode(value));
|
|
448
|
+
}),
|
|
449
|
+
kv_put: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len, val_ptr, val_len) => {
|
|
450
|
+
const b = binding(readStr(ns_ptr, ns_len));
|
|
451
|
+
if (!b)
|
|
452
|
+
return -1;
|
|
453
|
+
await b.put(readStr(key_ptr, key_len), readStr(val_ptr, val_len));
|
|
454
|
+
return 0;
|
|
455
|
+
}),
|
|
456
|
+
kv_delete: new Suspending(async (ns_ptr, ns_len, key_ptr, key_len) => {
|
|
457
|
+
const b = binding(readStr(ns_ptr, ns_len));
|
|
458
|
+
if (!b)
|
|
459
|
+
return -1;
|
|
460
|
+
await b.delete(readStr(key_ptr, key_len));
|
|
461
|
+
return 0;
|
|
462
|
+
}),
|
|
463
|
+
kv_list: new Suspending(async (ns_ptr, ns_len, prefix_ptr, prefix_len, buf_ptr, buf_max) => {
|
|
464
|
+
const b = binding(readStr(ns_ptr, ns_len));
|
|
465
|
+
if (!b)
|
|
466
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode("[]"));
|
|
467
|
+
const prefix = readStr(prefix_ptr, prefix_len);
|
|
468
|
+
const result = await b.list(prefix.length > 0 ? { prefix } : undefined);
|
|
469
|
+
return writeBytes2(buf_ptr, buf_max, encoder2.encode(JSON.stringify(result.keys.map((k) => k.name))));
|
|
470
|
+
})
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/browser/kv.ts
|
|
475
|
+
function getIndexedDb() {
|
|
476
|
+
if (typeof indexedDB === "undefined") {
|
|
477
|
+
throw new Error("IndexedDB is not available in this environment");
|
|
478
|
+
}
|
|
479
|
+
return indexedDB;
|
|
480
|
+
}
|
|
481
|
+
function requestToPromise(request) {
|
|
482
|
+
return new Promise((resolve, reject) => {
|
|
483
|
+
request.onsuccess = () => resolve(request.result);
|
|
484
|
+
request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
function transactionToPromise(transaction) {
|
|
488
|
+
return new Promise((resolve, reject) => {
|
|
489
|
+
transaction.oncomplete = () => resolve();
|
|
490
|
+
transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
|
|
491
|
+
transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB transaction failed"));
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
function createIndexedDbKV(options = {}) {
|
|
495
|
+
const databaseName = options.databaseName ?? "ziex-kv";
|
|
496
|
+
const storeName = options.storeName ?? "kv";
|
|
497
|
+
const namespace = options.namespace ?? "default";
|
|
498
|
+
const dbPromise = new Promise((resolve, reject) => {
|
|
499
|
+
const request = getIndexedDb().open(databaseName, 1);
|
|
500
|
+
request.onupgradeneeded = () => {
|
|
501
|
+
const db = request.result;
|
|
502
|
+
if (!db.objectStoreNames.contains(storeName)) {
|
|
503
|
+
db.createObjectStore(storeName);
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
request.onsuccess = () => resolve(request.result);
|
|
507
|
+
request.onerror = () => reject(request.error ?? new Error("Failed to open IndexedDB"));
|
|
508
|
+
});
|
|
509
|
+
const scopedKey = (key) => `${namespace}:${key}`;
|
|
510
|
+
return {
|
|
511
|
+
async get(key) {
|
|
512
|
+
const db = await dbPromise;
|
|
513
|
+
const tx = db.transaction(storeName, "readonly");
|
|
514
|
+
const store = tx.objectStore(storeName);
|
|
515
|
+
const value = await requestToPromise(store.get(scopedKey(key)));
|
|
516
|
+
await transactionToPromise(tx);
|
|
517
|
+
console.debug(`KV GET - Key: ${key}, Value: ${value}`);
|
|
518
|
+
return typeof value === "string" ? value : null;
|
|
519
|
+
},
|
|
520
|
+
async put(key, value) {
|
|
521
|
+
const db = await dbPromise;
|
|
522
|
+
const tx = db.transaction(storeName, "readwrite");
|
|
523
|
+
tx.objectStore(storeName).put(value, scopedKey(key));
|
|
524
|
+
await transactionToPromise(tx);
|
|
525
|
+
console.debug(`KV PUT - Key: ${key}, Value: ${value}`);
|
|
526
|
+
},
|
|
527
|
+
async delete(key) {
|
|
528
|
+
const db = await dbPromise;
|
|
529
|
+
const tx = db.transaction(storeName, "readwrite");
|
|
530
|
+
tx.objectStore(storeName).delete(scopedKey(key));
|
|
531
|
+
await transactionToPromise(tx);
|
|
532
|
+
},
|
|
533
|
+
async list(options2) {
|
|
534
|
+
const db = await dbPromise;
|
|
535
|
+
const tx = db.transaction(storeName, "readonly");
|
|
536
|
+
const store = tx.objectStore(storeName);
|
|
537
|
+
const keys = await requestToPromise(store.getAllKeys());
|
|
538
|
+
await transactionToPromise(tx);
|
|
539
|
+
const prefix = scopedKey(options2?.prefix ?? "");
|
|
540
|
+
return {
|
|
541
|
+
keys: keys.filter((key) => typeof key === "string" && key.startsWith(prefix)).map((key) => ({ name: key.slice(namespace.length + 1) }))
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function getLocalStorage() {
|
|
547
|
+
if (typeof localStorage === "undefined") {
|
|
548
|
+
throw new Error("localStorage is not available in this environment");
|
|
549
|
+
}
|
|
550
|
+
return localStorage;
|
|
551
|
+
}
|
|
552
|
+
function createLocalStorageKV(options = {}) {
|
|
553
|
+
const storage = getLocalStorage();
|
|
554
|
+
const namespace = options.namespace ?? "default";
|
|
555
|
+
const storagePrefix = options.storagePrefix ?? "ziex-kv";
|
|
556
|
+
const scopedKey = (key) => `${storagePrefix}:${namespace}:${key}`;
|
|
557
|
+
const namespacePrefix = scopedKey("");
|
|
558
|
+
return {
|
|
559
|
+
getSync(key) {
|
|
560
|
+
return storage.getItem(scopedKey(key));
|
|
561
|
+
},
|
|
562
|
+
async get(key) {
|
|
563
|
+
return this.getSync(key);
|
|
564
|
+
},
|
|
565
|
+
putSync(key, value) {
|
|
566
|
+
storage.setItem(scopedKey(key), value);
|
|
567
|
+
},
|
|
568
|
+
async put(key, value) {
|
|
569
|
+
this.putSync(key, value);
|
|
570
|
+
},
|
|
571
|
+
deleteSync(key) {
|
|
572
|
+
storage.removeItem(scopedKey(key));
|
|
573
|
+
},
|
|
574
|
+
async delete(key) {
|
|
575
|
+
this.deleteSync(key);
|
|
576
|
+
},
|
|
577
|
+
listSync(options2) {
|
|
578
|
+
const prefix = namespacePrefix + (options2?.prefix ?? "");
|
|
579
|
+
const keys = [];
|
|
580
|
+
for (let i = 0;i < storage.length; i += 1) {
|
|
581
|
+
const key = storage.key(i);
|
|
582
|
+
if (!key || !key.startsWith(prefix))
|
|
583
|
+
continue;
|
|
584
|
+
keys.push({ name: key.slice(namespacePrefix.length) });
|
|
585
|
+
}
|
|
586
|
+
return { keys };
|
|
587
|
+
},
|
|
588
|
+
async list(options2) {
|
|
589
|
+
return this.listSync(options2);
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function hasJSPI() {
|
|
594
|
+
return typeof WebAssembly.Suspending === "function" && typeof WebAssembly.promising === "function";
|
|
595
|
+
}
|
|
596
|
+
function createBrowserKVBindings(options = {}) {
|
|
597
|
+
const namespace = options.namespace ?? "default";
|
|
598
|
+
return {
|
|
599
|
+
[namespace]: hasJSPI() ? createIndexedDbKV(options) : createLocalStorageKV(options)
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
|
|
357
603
|
// src/wasm/index.ts
|
|
358
604
|
class ZxBridge extends ZxBridgeCore {
|
|
359
605
|
#websockets = new Map;
|
|
@@ -362,13 +608,30 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
362
608
|
#wsOnErrorHandler;
|
|
363
609
|
#wsOnCloseHandler;
|
|
364
610
|
#eventbridge;
|
|
611
|
+
#eventbridgeAsync;
|
|
365
612
|
constructor(exports) {
|
|
366
613
|
super(exports);
|
|
367
|
-
this.#wsOnOpenHandler = exports.__zx_ws_onopen;
|
|
368
|
-
this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
|
|
369
|
-
this.#wsOnErrorHandler = exports.__zx_ws_onerror;
|
|
370
|
-
this.#wsOnCloseHandler = exports.__zx_ws_onclose;
|
|
614
|
+
this.#wsOnOpenHandler = wrapPromisingExport(exports.__zx_ws_onopen);
|
|
615
|
+
this.#wsOnMessageHandler = wrapPromisingExport(exports.__zx_ws_onmessage);
|
|
616
|
+
this.#wsOnErrorHandler = wrapPromisingExport(exports.__zx_ws_onerror);
|
|
617
|
+
this.#wsOnCloseHandler = wrapPromisingExport(exports.__zx_ws_onclose);
|
|
371
618
|
this.#eventbridge = exports.__zx_eventbridge;
|
|
619
|
+
this.#eventbridgeAsync = wrapPromisingExport(exports.__zx_eventbridge_async ?? exports.__zx_eventbridge);
|
|
620
|
+
}
|
|
621
|
+
eventMaySuspend(velementId, eventTypeId) {
|
|
622
|
+
return !!((eventHandlerModes.get(velementId) ?? 0) & 1 << eventTypeId);
|
|
623
|
+
}
|
|
624
|
+
setEventHandlerMode(velementId, eventTypeId, maySuspend) {
|
|
625
|
+
const bit = 1 << eventTypeId;
|
|
626
|
+
const current = eventHandlerModes.get(velementId) ?? 0;
|
|
627
|
+
const next = maySuspend ? current | bit : current & ~bit;
|
|
628
|
+
if (next === 0)
|
|
629
|
+
eventHandlerModes.delete(velementId);
|
|
630
|
+
else
|
|
631
|
+
eventHandlerModes.set(velementId, next);
|
|
632
|
+
}
|
|
633
|
+
clearEventHandlerModes(velementId) {
|
|
634
|
+
eventHandlerModes.delete(velementId);
|
|
372
635
|
}
|
|
373
636
|
submitFormActionAsync(form, statesJson, fetchId) {
|
|
374
637
|
const formData = new FormData(form);
|
|
@@ -398,7 +661,7 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
398
661
|
return;
|
|
399
662
|
const protocol = ws.protocol || "";
|
|
400
663
|
const { ptr, len } = this._writeStringToWasm(protocol);
|
|
401
|
-
handler
|
|
664
|
+
invokeWasmExport(handler, wsId, ptr, len);
|
|
402
665
|
};
|
|
403
666
|
ws.onmessage = (event) => {
|
|
404
667
|
const handler = this.#wsOnMessageHandler;
|
|
@@ -407,14 +670,14 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
407
670
|
const isBinary = event.data instanceof ArrayBuffer;
|
|
408
671
|
const data = isBinary ? new Uint8Array(event.data) : textEncoder.encode(event.data);
|
|
409
672
|
const { ptr, len } = this._writeBytesToWasm(data);
|
|
410
|
-
handler
|
|
673
|
+
invokeWasmExport(handler, wsId, ptr, len, isBinary ? 1 : 0);
|
|
411
674
|
};
|
|
412
675
|
ws.onerror = (_event) => {
|
|
413
676
|
const handler = this.#wsOnErrorHandler;
|
|
414
677
|
if (!handler)
|
|
415
678
|
return;
|
|
416
679
|
const { ptr, len } = this._writeStringToWasm("WebSocket error");
|
|
417
|
-
handler
|
|
680
|
+
invokeWasmExport(handler, wsId, ptr, len);
|
|
418
681
|
};
|
|
419
682
|
ws.onclose = (event) => {
|
|
420
683
|
const handler = this.#wsOnCloseHandler;
|
|
@@ -422,7 +685,7 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
422
685
|
return;
|
|
423
686
|
const reason = event.reason || "";
|
|
424
687
|
const { ptr, len } = this._writeStringToWasm(reason);
|
|
425
|
-
handler
|
|
688
|
+
invokeWasmExport(handler, wsId, event.code, ptr, len, event.wasClean ? 1 : 0);
|
|
426
689
|
this.#websockets.delete(wsId);
|
|
427
690
|
};
|
|
428
691
|
this.#websockets.set(wsId, ws);
|
|
@@ -431,7 +694,7 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
431
694
|
if (handler) {
|
|
432
695
|
const msg = error instanceof Error ? error.message : "WebSocket connection failed";
|
|
433
696
|
const { ptr, len } = this._writeStringToWasm(msg);
|
|
434
|
-
handler
|
|
697
|
+
invokeWasmExport(handler, wsId, ptr, len);
|
|
435
698
|
}
|
|
436
699
|
}
|
|
437
700
|
}
|
|
@@ -462,6 +725,7 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
462
725
|
}
|
|
463
726
|
dispose() {
|
|
464
727
|
super.dispose();
|
|
728
|
+
eventHandlerModes.clear();
|
|
465
729
|
for (const ws of this.#websockets.values()) {
|
|
466
730
|
try {
|
|
467
731
|
ws.close();
|
|
@@ -470,16 +734,24 @@ class ZxBridge extends ZxBridgeCore {
|
|
|
470
734
|
this.#websockets.clear();
|
|
471
735
|
}
|
|
472
736
|
eventbridge(velementId, eventTypeId, event) {
|
|
473
|
-
if (!this.#eventbridge)
|
|
474
|
-
return;
|
|
475
737
|
const eventRef = storeValueGetRef(event);
|
|
476
|
-
this
|
|
738
|
+
if (this.eventMaySuspend(velementId, eventTypeId)) {
|
|
739
|
+
invokeWasmExport(this.#eventbridgeAsync, velementId, eventTypeId, eventRef);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
invokeWasmExport(this.#eventbridge, velementId, eventTypeId, eventRef);
|
|
477
743
|
}
|
|
478
744
|
static createImportObject(bridgeRef) {
|
|
479
745
|
return {
|
|
480
746
|
...jsz.importObject(),
|
|
481
747
|
__zx: {
|
|
482
748
|
_log: (level, ptr, len) => ZxBridgeCore.log(level, ptr, len),
|
|
749
|
+
_setEventHandlerMode: (vnodeId, eventTypeId, maySuspend) => {
|
|
750
|
+
bridgeRef.current?.setEventHandlerMode(vnodeId, eventTypeId, maySuspend !== 0);
|
|
751
|
+
},
|
|
752
|
+
_clearEventHandlerModes: (vnodeId) => {
|
|
753
|
+
bridgeRef.current?.clearEventHandlerModes(vnodeId);
|
|
754
|
+
},
|
|
483
755
|
_fetchAsync: (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId) => {
|
|
484
756
|
bridgeRef.current?.fetchAsync(urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, timeoutMs, fetchId);
|
|
485
757
|
},
|
|
@@ -848,6 +1120,7 @@ var EVENT_TYPE_MAP = {
|
|
|
848
1120
|
touchmove: 17,
|
|
849
1121
|
scroll: 18
|
|
850
1122
|
};
|
|
1123
|
+
var eventHandlerModes = new Map;
|
|
851
1124
|
function initEventDelegation(bridge, rootSelector = "body") {
|
|
852
1125
|
const root = document.querySelector(rootSelector);
|
|
853
1126
|
if (!root)
|
|
@@ -877,17 +1150,31 @@ function initEventDelegation(bridge, rootSelector = "body") {
|
|
|
877
1150
|
}
|
|
878
1151
|
var DEFAULT_URL = "/assets/_/main.wasm";
|
|
879
1152
|
var activeRuntime = null;
|
|
1153
|
+
function buildDevtoolsLocation() {
|
|
1154
|
+
return {
|
|
1155
|
+
href: window.location.href,
|
|
1156
|
+
origin: window.location.origin,
|
|
1157
|
+
host: window.location.host,
|
|
1158
|
+
pathname: window.location.pathname
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
880
1161
|
function normalizeOptions(options = {}) {
|
|
881
1162
|
return {
|
|
882
1163
|
url: options.url,
|
|
883
1164
|
eventDelegationRoot: options.eventDelegationRoot,
|
|
884
|
-
importObject: options.importObject
|
|
1165
|
+
importObject: options.importObject,
|
|
1166
|
+
kv: options.kv
|
|
885
1167
|
};
|
|
886
1168
|
}
|
|
887
1169
|
function registerDevReinit(options) {
|
|
888
1170
|
if (typeof window === "undefined")
|
|
889
1171
|
return;
|
|
890
|
-
|
|
1172
|
+
const reinit = () => init(options);
|
|
1173
|
+
window.__zx_dev_reinit = reinit;
|
|
1174
|
+
window.__ZIEX_DEVTOOLS_GLOBAL_HOOK__ = {
|
|
1175
|
+
location: buildDevtoolsLocation(),
|
|
1176
|
+
reinit
|
|
1177
|
+
};
|
|
891
1178
|
}
|
|
892
1179
|
async function init(options = {}) {
|
|
893
1180
|
const normalizedOptions = normalizeOptions(options);
|
|
@@ -897,17 +1184,28 @@ async function init(options = {}) {
|
|
|
897
1184
|
}
|
|
898
1185
|
const url = options.url ?? document.getElementById("__$wasmlink")?.href ?? DEFAULT_URL;
|
|
899
1186
|
const bridgeRef = { current: null };
|
|
900
|
-
|
|
1187
|
+
let wasmMemory = null;
|
|
1188
|
+
const kvBindings = options.kv ?? createBrowserKVBindings();
|
|
1189
|
+
const kvImportObject = {
|
|
1190
|
+
__zx_kv: createKVImports(kvBindings, () => {
|
|
1191
|
+
if (wasmMemory)
|
|
1192
|
+
return wasmMemory;
|
|
1193
|
+
if (jsz.memory)
|
|
1194
|
+
return jsz.memory;
|
|
1195
|
+
throw new Error("WASM memory is not ready");
|
|
1196
|
+
})
|
|
1197
|
+
};
|
|
1198
|
+
const importObject = Object.assign({}, ZxBridge.createImportObject(bridgeRef), kvImportObject, options.importObject);
|
|
901
1199
|
const source = await WebAssembly.instantiateStreaming(fetch(url), importObject);
|
|
902
1200
|
const { instance } = source;
|
|
903
|
-
|
|
1201
|
+
wasmMemory = instance.exports.memory;
|
|
1202
|
+
jsz.memory = wasmMemory;
|
|
904
1203
|
const bridge = new ZxBridge(instance.exports);
|
|
905
1204
|
bridgeRef.current = bridge;
|
|
906
1205
|
domNodes.clear();
|
|
907
1206
|
const disposeDelegation = initEventDelegation(bridge, options.eventDelegationRoot ?? "body");
|
|
908
|
-
const main = instance.exports.mainClient;
|
|
909
|
-
|
|
910
|
-
main();
|
|
1207
|
+
const main = wrapPromisingExport(instance.exports.mainClient);
|
|
1208
|
+
invokeWasmExport(main);
|
|
911
1209
|
activeRuntime = {
|
|
912
1210
|
options: normalizedOptions,
|
|
913
1211
|
dispose: () => {
|