ziex 0.1.0-dev.785 → 0.1.0-dev.786

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/index.js CHANGED
@@ -13,7 +13,7 @@ var __export = (target, all) => {
13
13
  var zx = {
14
14
  name: "zx",
15
15
  version: "0.1.0-dev.785",
16
- jsglue_version: "0.1.0-dev.727",
16
+ jsglue_version: "0.1.0-dev.785",
17
17
  description: "ZX is a framework for building web applications with Zig.",
18
18
  repository: "https://github.com/ziex-dev/ziex",
19
19
  homepage: "https://ziex.dev",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziex",
3
- "version": "0.1.0-dev.785",
3
+ "version": "0.1.0-dev.786",
4
4
  "description": "ZX is a framework for building web applications with Zig.",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/wasm/index.d.ts CHANGED
@@ -61,11 +61,6 @@ export declare function init(options?: InitOptions): Promise<{
61
61
  source: WebAssembly.WebAssemblyInstantiatedSource;
62
62
  bridge: ZxBridge;
63
63
  }>;
64
- /** Initialize WASM with the ZX Bridge */
65
- export declare function edge(options?: InitOptions): Promise<{
66
- source: WebAssembly.WebAssemblyInstantiatedSource;
67
- bridge: ZxBridge;
68
- }>;
69
64
  declare global {
70
65
  interface HTMLElement {
71
66
  __zx_ref?: number;
package/wasm/index.js CHANGED
@@ -200,42 +200,54 @@ function storeValueGetRef(val) {
200
200
  jsz.memory = originalMemory;
201
201
  return tempRefView.getBigUint64(0, true);
202
202
  }
203
+ var textDecoder = new TextDecoder;
204
+ var textEncoder = new TextEncoder;
205
+ var memoryView = null;
206
+ var memoryBuffer = null;
207
+ function getMemoryView() {
208
+ const buf = jsz.memory.buffer;
209
+ if (buf !== memoryBuffer) {
210
+ memoryBuffer = buf;
211
+ memoryView = new Uint8Array(buf);
212
+ }
213
+ return memoryView;
214
+ }
215
+ var stringCache = new Map;
216
+ function stringCacheKey(ptr, len) {
217
+ return ptr * 65536 + len;
218
+ }
203
219
  function readString(ptr, len) {
204
- const memory = new Uint8Array(jsz.memory.buffer);
205
- return new TextDecoder().decode(memory.slice(ptr, ptr + len));
220
+ const key = stringCacheKey(ptr, len);
221
+ const cached = stringCache.get(key);
222
+ if (cached !== undefined)
223
+ return cached;
224
+ const str = textDecoder.decode(getMemoryView().subarray(ptr, ptr + len));
225
+ stringCache.set(key, str);
226
+ return str;
206
227
  }
207
228
  function writeBytes(ptr, data) {
208
- const memory = new Uint8Array(jsz.memory.buffer);
209
- memory.set(data, ptr);
229
+ getMemoryView().set(data, ptr);
210
230
  }
211
231
 
212
232
  class ZxBridge {
213
- #exports;
214
233
  #intervals = new Map;
215
234
  #websockets = new Map;
235
+ #alloc;
236
+ #handler;
237
+ #fetchCompleteHandler;
238
+ #wsOnOpenHandler;
239
+ #wsOnMessageHandler;
240
+ #wsOnErrorHandler;
241
+ #wsOnCloseHandler;
216
242
  constructor(exports) {
217
- this.#exports = exports;
218
- }
219
- get #alloc() {
220
- return this.#exports.__zx_alloc;
221
- }
222
- get #handler() {
223
- return this.#exports.__zx_cb;
224
- }
225
- get #fetchCompleteHandler() {
226
- return this.#exports.__zx_fetch_complete;
227
- }
228
- get #wsOnOpenHandler() {
229
- return this.#exports.__zx_ws_onopen;
230
- }
231
- get #wsOnMessageHandler() {
232
- return this.#exports.__zx_ws_onmessage;
233
- }
234
- get #wsOnErrorHandler() {
235
- return this.#exports.__zx_ws_onerror;
236
- }
237
- get #wsOnCloseHandler() {
238
- return this.#exports.__zx_ws_onclose;
243
+ this.#alloc = exports.__zx_alloc;
244
+ this.#handler = exports.__zx_cb;
245
+ this.#fetchCompleteHandler = exports.__zx_fetch_complete;
246
+ this.#wsOnOpenHandler = exports.__zx_ws_onopen;
247
+ this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
248
+ this.#wsOnErrorHandler = exports.__zx_ws_onerror;
249
+ this.#wsOnCloseHandler = exports.__zx_ws_onclose;
250
+ this.#eventbridge = exports.__zx_eventbridge;
239
251
  }
240
252
  #invoke(type, id, data) {
241
253
  const handler = this.#handler;
@@ -286,7 +298,7 @@ class ZxBridge {
286
298
  }
287
299
  #notifyFetchComplete(fetchId, statusCode, body, isError) {
288
300
  const handler = this.#fetchCompleteHandler;
289
- const encoded = new TextEncoder().encode(body);
301
+ const encoded = textEncoder.encode(body);
290
302
  const ptr = this.#alloc(encoded.length);
291
303
  writeBytes(ptr, encoded);
292
304
  handler(fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
@@ -333,7 +345,7 @@ class ZxBridge {
333
345
  if (isBinary) {
334
346
  data = new Uint8Array(event.data);
335
347
  } else {
336
- data = new TextEncoder().encode(event.data);
348
+ data = textEncoder.encode(event.data);
337
349
  }
338
350
  const { ptr, len } = this.#writeBytesToWasm(data);
339
351
  handler(wsId, ptr, len, isBinary ? 1 : 0);
@@ -369,12 +381,11 @@ class ZxBridge {
369
381
  const ws = this.#websockets.get(wsId);
370
382
  if (!ws || ws.readyState !== WebSocket.OPEN)
371
383
  return;
372
- const memory = new Uint8Array(jsz.memory.buffer);
373
- const data = memory.slice(dataPtr, dataPtr + dataLen);
384
+ const memory = getMemoryView();
374
385
  if (isBinary) {
375
- ws.send(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength));
386
+ ws.send(memory.slice(dataPtr, dataPtr + dataLen));
376
387
  } else {
377
- ws.send(new TextDecoder().decode(data));
388
+ ws.send(textDecoder.decode(memory.subarray(dataPtr, dataPtr + dataLen)));
378
389
  }
379
390
  }
380
391
  wsClose(wsId, code, reasonPtr, reasonLen) {
@@ -393,7 +404,7 @@ class ZxBridge {
393
404
  }
394
405
  }
395
406
  #writeStringToWasm(str) {
396
- const encoded = new TextEncoder().encode(str);
407
+ const encoded = textEncoder.encode(str);
397
408
  return this.#writeBytesToWasm(encoded);
398
409
  }
399
410
  #writeBytesToWasm(data) {
@@ -401,11 +412,12 @@ class ZxBridge {
401
412
  writeBytes(ptr, data);
402
413
  return { ptr, len: data.length };
403
414
  }
415
+ #eventbridge;
404
416
  eventbridge(velementId, eventTypeId, event) {
417
+ if (!this.#eventbridge)
418
+ return;
405
419
  const eventRef = storeValueGetRef(event);
406
- const eventbridge = this.#exports.__zx_eventbridge;
407
- if (eventbridge)
408
- eventbridge(velementId, eventTypeId, eventRef);
420
+ this.#eventbridge(velementId, eventTypeId, eventRef);
409
421
  }
410
422
  static createImportObject(bridgeRef) {
411
423
  return {
@@ -432,15 +444,74 @@ class ZxBridge {
432
444
  _wsClose: (wsId, code, reasonPtr, reasonLen) => {
433
445
  bridgeRef.current?.wsClose(wsId, code, reasonPtr, reasonLen);
434
446
  },
435
- _ce: (id) => {
447
+ _ce: (id, vnodeId) => {
436
448
  const tagName = TAG_NAMES[id];
437
449
  const el = id >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
450
+ el.__zx_ref = Number(vnodeId);
451
+ domNodes.set(vnodeId, el);
438
452
  return storeValueGetRef(el);
453
+ },
454
+ _ct: (ptr, len, vnodeId) => {
455
+ const text = readString(ptr, len);
456
+ const node = document.createTextNode(text);
457
+ node.__zx_ref = Number(vnodeId);
458
+ domNodes.set(vnodeId, node);
459
+ return storeValueGetRef(node);
460
+ },
461
+ _sa: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
462
+ domNodes.get(vnodeId)?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
463
+ },
464
+ _ra: (vnodeId, namePtr, nameLen) => {
465
+ domNodes.get(vnodeId)?.removeAttribute(readString(namePtr, nameLen));
466
+ },
467
+ _snv: (vnodeId, ptr, len) => {
468
+ const node = domNodes.get(vnodeId);
469
+ if (node)
470
+ node.nodeValue = readString(ptr, len);
471
+ },
472
+ _ac: (parentId, childId) => {
473
+ const parent = domNodes.get(parentId);
474
+ const child = domNodes.get(childId);
475
+ if (parent && child)
476
+ parent.appendChild(child);
477
+ },
478
+ _ib: (parentId, childId, refId) => {
479
+ const parent = domNodes.get(parentId);
480
+ const child = domNodes.get(childId);
481
+ const ref = domNodes.get(refId) ?? null;
482
+ if (parent && child)
483
+ parent.insertBefore(child, ref);
484
+ },
485
+ _rc: (parentId, childId) => {
486
+ const parent = domNodes.get(parentId);
487
+ const child = domNodes.get(childId);
488
+ if (parent && child) {
489
+ parent.removeChild(child);
490
+ cleanupDomNodes(child);
491
+ }
492
+ },
493
+ _rpc: (parentId, newId, oldId) => {
494
+ const parent = domNodes.get(parentId);
495
+ const newChild = domNodes.get(newId);
496
+ const oldChild = domNodes.get(oldId);
497
+ if (parent && newChild && oldChild) {
498
+ parent.replaceChild(newChild, oldChild);
499
+ cleanupDomNodes(oldChild);
500
+ }
439
501
  }
440
502
  }
441
503
  };
442
504
  }
443
505
  }
506
+ var domNodes = new Map;
507
+ function cleanupDomNodes(node) {
508
+ const ref = node.__zx_ref;
509
+ if (ref !== undefined)
510
+ domNodes.delete(BigInt(ref));
511
+ const children = node.childNodes;
512
+ for (let i = 0;i < children.length; i++)
513
+ cleanupDomNodes(children[i]);
514
+ }
444
515
  var SVG_TAG_START_INDEX = 140;
445
516
  var TAG_NAMES = [
446
517
  "aside",
@@ -696,7 +767,8 @@ function initEventDelegation(bridge, rootSelector = "body") {
696
767
  const zxRef = target.__zx_ref;
697
768
  if (zxRef !== undefined) {
698
769
  bridge.eventbridge(BigInt(zxRef), EVENT_TYPE_MAP[eventType] ?? 0, event);
699
- break;
770
+ if (event.cancelBubble)
771
+ break;
700
772
  }
701
773
  target = target.parentElement;
702
774
  }
@@ -719,27 +791,11 @@ async function init(options = {}) {
719
791
  main();
720
792
  return { source, bridge };
721
793
  }
722
- async function edge(options = {}) {
723
- const url = options.url ?? DEFAULT_URL;
724
- const bridgeRef = { current: null };
725
- const importObject = Object.assign({}, ZxBridge.createImportObject(bridgeRef), options.importObject);
726
- const source = await WebAssembly.instantiateStreaming(fetch(url), importObject);
727
- const { instance } = source;
728
- jsz.memory = instance.exports.memory;
729
- const bridge = new ZxBridge(instance.exports);
730
- bridgeRef.current = bridge;
731
- initEventDelegation(bridge, options.eventDelegationRoot ?? "body");
732
- const main = instance.exports.main;
733
- if (typeof main === "function")
734
- main();
735
- return { source, bridge };
736
- }
737
794
  export {
738
795
  storeValueGetRef,
739
796
  jsz,
740
797
  initEventDelegation,
741
798
  init,
742
- edge,
743
799
  ZxBridge,
744
800
  CallbackType
745
801
  };
package/wasm/init.js CHANGED
@@ -189,42 +189,54 @@ function storeValueGetRef(val) {
189
189
  jsz.memory = originalMemory;
190
190
  return tempRefView.getBigUint64(0, true);
191
191
  }
192
+ var textDecoder = new TextDecoder;
193
+ var textEncoder = new TextEncoder;
194
+ var memoryView = null;
195
+ var memoryBuffer = null;
196
+ function getMemoryView() {
197
+ const buf = jsz.memory.buffer;
198
+ if (buf !== memoryBuffer) {
199
+ memoryBuffer = buf;
200
+ memoryView = new Uint8Array(buf);
201
+ }
202
+ return memoryView;
203
+ }
204
+ var stringCache = new Map;
205
+ function stringCacheKey(ptr, len) {
206
+ return ptr * 65536 + len;
207
+ }
192
208
  function readString(ptr, len) {
193
- const memory = new Uint8Array(jsz.memory.buffer);
194
- return new TextDecoder().decode(memory.slice(ptr, ptr + len));
209
+ const key = stringCacheKey(ptr, len);
210
+ const cached = stringCache.get(key);
211
+ if (cached !== undefined)
212
+ return cached;
213
+ const str = textDecoder.decode(getMemoryView().subarray(ptr, ptr + len));
214
+ stringCache.set(key, str);
215
+ return str;
195
216
  }
196
217
  function writeBytes(ptr, data) {
197
- const memory = new Uint8Array(jsz.memory.buffer);
198
- memory.set(data, ptr);
218
+ getMemoryView().set(data, ptr);
199
219
  }
200
220
 
201
221
  class ZxBridge {
202
- #exports;
203
222
  #intervals = new Map;
204
223
  #websockets = new Map;
224
+ #alloc;
225
+ #handler;
226
+ #fetchCompleteHandler;
227
+ #wsOnOpenHandler;
228
+ #wsOnMessageHandler;
229
+ #wsOnErrorHandler;
230
+ #wsOnCloseHandler;
205
231
  constructor(exports) {
206
- this.#exports = exports;
207
- }
208
- get #alloc() {
209
- return this.#exports.__zx_alloc;
210
- }
211
- get #handler() {
212
- return this.#exports.__zx_cb;
213
- }
214
- get #fetchCompleteHandler() {
215
- return this.#exports.__zx_fetch_complete;
216
- }
217
- get #wsOnOpenHandler() {
218
- return this.#exports.__zx_ws_onopen;
219
- }
220
- get #wsOnMessageHandler() {
221
- return this.#exports.__zx_ws_onmessage;
222
- }
223
- get #wsOnErrorHandler() {
224
- return this.#exports.__zx_ws_onerror;
225
- }
226
- get #wsOnCloseHandler() {
227
- return this.#exports.__zx_ws_onclose;
232
+ this.#alloc = exports.__zx_alloc;
233
+ this.#handler = exports.__zx_cb;
234
+ this.#fetchCompleteHandler = exports.__zx_fetch_complete;
235
+ this.#wsOnOpenHandler = exports.__zx_ws_onopen;
236
+ this.#wsOnMessageHandler = exports.__zx_ws_onmessage;
237
+ this.#wsOnErrorHandler = exports.__zx_ws_onerror;
238
+ this.#wsOnCloseHandler = exports.__zx_ws_onclose;
239
+ this.#eventbridge = exports.__zx_eventbridge;
228
240
  }
229
241
  #invoke(type, id, data) {
230
242
  const handler = this.#handler;
@@ -275,7 +287,7 @@ class ZxBridge {
275
287
  }
276
288
  #notifyFetchComplete(fetchId, statusCode, body, isError) {
277
289
  const handler = this.#fetchCompleteHandler;
278
- const encoded = new TextEncoder().encode(body);
290
+ const encoded = textEncoder.encode(body);
279
291
  const ptr = this.#alloc(encoded.length);
280
292
  writeBytes(ptr, encoded);
281
293
  handler(fetchId, statusCode, ptr, encoded.length, isError ? 1 : 0);
@@ -322,7 +334,7 @@ class ZxBridge {
322
334
  if (isBinary) {
323
335
  data = new Uint8Array(event.data);
324
336
  } else {
325
- data = new TextEncoder().encode(event.data);
337
+ data = textEncoder.encode(event.data);
326
338
  }
327
339
  const { ptr, len } = this.#writeBytesToWasm(data);
328
340
  handler(wsId, ptr, len, isBinary ? 1 : 0);
@@ -358,12 +370,11 @@ class ZxBridge {
358
370
  const ws = this.#websockets.get(wsId);
359
371
  if (!ws || ws.readyState !== WebSocket.OPEN)
360
372
  return;
361
- const memory = new Uint8Array(jsz.memory.buffer);
362
- const data = memory.slice(dataPtr, dataPtr + dataLen);
373
+ const memory = getMemoryView();
363
374
  if (isBinary) {
364
- ws.send(data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength));
375
+ ws.send(memory.slice(dataPtr, dataPtr + dataLen));
365
376
  } else {
366
- ws.send(new TextDecoder().decode(data));
377
+ ws.send(textDecoder.decode(memory.subarray(dataPtr, dataPtr + dataLen)));
367
378
  }
368
379
  }
369
380
  wsClose(wsId, code, reasonPtr, reasonLen) {
@@ -382,7 +393,7 @@ class ZxBridge {
382
393
  }
383
394
  }
384
395
  #writeStringToWasm(str) {
385
- const encoded = new TextEncoder().encode(str);
396
+ const encoded = textEncoder.encode(str);
386
397
  return this.#writeBytesToWasm(encoded);
387
398
  }
388
399
  #writeBytesToWasm(data) {
@@ -390,11 +401,12 @@ class ZxBridge {
390
401
  writeBytes(ptr, data);
391
402
  return { ptr, len: data.length };
392
403
  }
404
+ #eventbridge;
393
405
  eventbridge(velementId, eventTypeId, event) {
406
+ if (!this.#eventbridge)
407
+ return;
394
408
  const eventRef = storeValueGetRef(event);
395
- const eventbridge = this.#exports.__zx_eventbridge;
396
- if (eventbridge)
397
- eventbridge(velementId, eventTypeId, eventRef);
409
+ this.#eventbridge(velementId, eventTypeId, eventRef);
398
410
  }
399
411
  static createImportObject(bridgeRef) {
400
412
  return {
@@ -421,15 +433,74 @@ class ZxBridge {
421
433
  _wsClose: (wsId, code, reasonPtr, reasonLen) => {
422
434
  bridgeRef.current?.wsClose(wsId, code, reasonPtr, reasonLen);
423
435
  },
424
- _ce: (id) => {
436
+ _ce: (id, vnodeId) => {
425
437
  const tagName = TAG_NAMES[id];
426
438
  const el = id >= SVG_TAG_START_INDEX ? document.createElementNS("http://www.w3.org/2000/svg", tagName) : document.createElement(tagName);
439
+ el.__zx_ref = Number(vnodeId);
440
+ domNodes.set(vnodeId, el);
427
441
  return storeValueGetRef(el);
442
+ },
443
+ _ct: (ptr, len, vnodeId) => {
444
+ const text = readString(ptr, len);
445
+ const node = document.createTextNode(text);
446
+ node.__zx_ref = Number(vnodeId);
447
+ domNodes.set(vnodeId, node);
448
+ return storeValueGetRef(node);
449
+ },
450
+ _sa: (vnodeId, namePtr, nameLen, valPtr, valLen) => {
451
+ domNodes.get(vnodeId)?.setAttribute(readString(namePtr, nameLen), readString(valPtr, valLen));
452
+ },
453
+ _ra: (vnodeId, namePtr, nameLen) => {
454
+ domNodes.get(vnodeId)?.removeAttribute(readString(namePtr, nameLen));
455
+ },
456
+ _snv: (vnodeId, ptr, len) => {
457
+ const node = domNodes.get(vnodeId);
458
+ if (node)
459
+ node.nodeValue = readString(ptr, len);
460
+ },
461
+ _ac: (parentId, childId) => {
462
+ const parent = domNodes.get(parentId);
463
+ const child = domNodes.get(childId);
464
+ if (parent && child)
465
+ parent.appendChild(child);
466
+ },
467
+ _ib: (parentId, childId, refId) => {
468
+ const parent = domNodes.get(parentId);
469
+ const child = domNodes.get(childId);
470
+ const ref = domNodes.get(refId) ?? null;
471
+ if (parent && child)
472
+ parent.insertBefore(child, ref);
473
+ },
474
+ _rc: (parentId, childId) => {
475
+ const parent = domNodes.get(parentId);
476
+ const child = domNodes.get(childId);
477
+ if (parent && child) {
478
+ parent.removeChild(child);
479
+ cleanupDomNodes(child);
480
+ }
481
+ },
482
+ _rpc: (parentId, newId, oldId) => {
483
+ const parent = domNodes.get(parentId);
484
+ const newChild = domNodes.get(newId);
485
+ const oldChild = domNodes.get(oldId);
486
+ if (parent && newChild && oldChild) {
487
+ parent.replaceChild(newChild, oldChild);
488
+ cleanupDomNodes(oldChild);
489
+ }
428
490
  }
429
491
  }
430
492
  };
431
493
  }
432
494
  }
495
+ var domNodes = new Map;
496
+ function cleanupDomNodes(node) {
497
+ const ref = node.__zx_ref;
498
+ if (ref !== undefined)
499
+ domNodes.delete(BigInt(ref));
500
+ const children = node.childNodes;
501
+ for (let i = 0;i < children.length; i++)
502
+ cleanupDomNodes(children[i]);
503
+ }
433
504
  var SVG_TAG_START_INDEX = 140;
434
505
  var TAG_NAMES = [
435
506
  "aside",
@@ -685,7 +756,8 @@ function initEventDelegation(bridge, rootSelector = "body") {
685
756
  const zxRef = target.__zx_ref;
686
757
  if (zxRef !== undefined) {
687
758
  bridge.eventbridge(BigInt(zxRef), EVENT_TYPE_MAP[eventType] ?? 0, event);
688
- break;
759
+ if (event.cancelBubble)
760
+ break;
689
761
  }
690
762
  target = target.parentElement;
691
763
  }