@opentui/core 0.4.5 → 0.5.1

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 (44) hide show
  1. package/README.md +4 -4
  2. package/Renderable.d.ts +3 -0
  3. package/audio.d.ts +202 -1
  4. package/buffer.d.ts +3 -0
  5. package/{chunk-bun-t2myhmwd.js → chunk-bun-83ry0rzt.js} +1212 -152
  6. package/chunk-bun-83ry0rzt.js.map +62 -0
  7. package/{chunk-bun-tkm837n2.js → chunk-bun-8fkgaxc6.js} +147 -37
  8. package/chunk-bun-8fkgaxc6.js.map +32 -0
  9. package/{chunk-node-51kpf0mz.js → chunk-node-0yw3x5m7.js} +147 -37
  10. package/chunk-node-0yw3x5m7.js.map +32 -0
  11. package/{chunk-node-q0cwyvm9.js → chunk-node-m23dbcww.js} +1212 -152
  12. package/chunk-node-m23dbcww.js.map +61 -0
  13. package/image.d.ts +105 -0
  14. package/index.bun.js +2137 -89
  15. package/index.bun.js.map +6 -4
  16. package/index.d.ts +1 -0
  17. package/index.node.js +2137 -89
  18. package/index.node.js.map +7 -3
  19. package/lib/env.d.ts +1 -0
  20. package/lib/stdin-parser.d.ts +5 -0
  21. package/node-assets.js +5 -2
  22. package/node-assets.js.map +3 -3
  23. package/package.json +10 -10
  24. package/parser.worker.js +5 -2
  25. package/parser.worker.js.map +3 -3
  26. package/platform/ffi.d.ts +2 -0
  27. package/renderables/Image.d.ts +44 -0
  28. package/renderables/index.d.ts +1 -0
  29. package/renderer.d.ts +14 -0
  30. package/testing.bun.js +4 -3
  31. package/testing.bun.js.map +3 -3
  32. package/testing.js +4 -3
  33. package/testing.js.map +3 -3
  34. package/tests/image-icc-allocation-child.d.ts +1 -0
  35. package/text-buffer-view.d.ts +2 -5
  36. package/types.d.ts +8 -0
  37. package/yoga.bun.js +1 -1
  38. package/yoga.js +1 -1
  39. package/zig-structs.d.ts +45 -24
  40. package/zig.d.ts +74 -7
  41. package/chunk-bun-t2myhmwd.js.map +0 -62
  42. package/chunk-bun-tkm837n2.js.map +0 -32
  43. package/chunk-node-51kpf0mz.js.map +0 -32
  44. package/chunk-node-q0cwyvm9.js.map +0 -61
@@ -229,6 +229,7 @@ function createUnsupportedBackend(cause) {
229
229
  };
230
230
  }
231
231
  var isBun = typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.bun === "string";
232
+ var usesBunFFI = isBun;
232
233
  var requireModule = createRequire(import.meta.url);
233
234
  var backend = loadBackend();
234
235
  function loadBackend() {
@@ -254,6 +255,11 @@ function toPointer(value) {
254
255
  function ffiBool(value) {
255
256
  return value ? 1 : 0;
256
257
  }
258
+ function trimNodeFFIOutputBytes(buffer, length) {
259
+ if (length === buffer.byteLength)
260
+ return buffer;
261
+ return new Uint8Array(buffer.buffer.transferToFixedLength(length));
262
+ }
257
263
  function toSafeNumberPointer(pointer) {
258
264
  if (pointer < 0n) {
259
265
  throw new Error(POINTER_NEGATIVE);
@@ -419,6 +425,34 @@ function wrapNodeSymbol(fn, definition) {
419
425
  if (pointerArgIndexes.length === 0) {
420
426
  return fn;
421
427
  }
428
+ if (definition.args?.length === 7 && pointerArgIndexes.length >= 2) {
429
+ return wrapNodeSymbol7(fn, pointerArgIndexes);
430
+ }
431
+ if (definition.args?.length === 8) {
432
+ return wrapNodeSymbol8(fn, pointerArgIndexes);
433
+ }
434
+ const pointerArgs = new Set(pointerArgIndexes);
435
+ const normalize = (value, index) => pointerArgs.has(index) ? toNodePointerArgumentFast(value) : value;
436
+ switch (definition.args?.length) {
437
+ case 1:
438
+ return function(arg0) {
439
+ if (arguments.length !== 1)
440
+ return Reflect.apply(fn, undefined, arguments);
441
+ return fn(normalize(arg0, 0));
442
+ };
443
+ case 2:
444
+ return function(arg0, arg1) {
445
+ if (arguments.length !== 2)
446
+ return Reflect.apply(fn, undefined, arguments);
447
+ return fn(normalize(arg0, 0), normalize(arg1, 1));
448
+ };
449
+ case 3:
450
+ return function(arg0, arg1, arg2) {
451
+ if (arguments.length !== 3)
452
+ return Reflect.apply(fn, undefined, arguments);
453
+ return fn(normalize(arg0, 0), normalize(arg1, 1), normalize(arg2, 2));
454
+ };
455
+ }
422
456
  return (...args) => {
423
457
  const normalizedArgs = args.slice();
424
458
  for (const index of pointerArgIndexes) {
@@ -427,6 +461,49 @@ function wrapNodeSymbol(fn, definition) {
427
461
  return fn(...normalizedArgs);
428
462
  };
429
463
  }
464
+ function wrapNodeSymbol7(fn, pointerArgIndexes) {
465
+ const pointer0 = pointerArgIndexes.includes(0);
466
+ const pointer1 = pointerArgIndexes.includes(1);
467
+ const pointer2 = pointerArgIndexes.includes(2);
468
+ const pointer3 = pointerArgIndexes.includes(3);
469
+ const pointer4 = pointerArgIndexes.includes(4);
470
+ const pointer5 = pointerArgIndexes.includes(5);
471
+ const pointer6 = pointerArgIndexes.includes(6);
472
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
473
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
474
+ if (arguments.length !== 7)
475
+ return Reflect.apply(fn, undefined, arguments);
476
+ return fn(normalize(arg0, pointer0), normalize(arg1, pointer1), normalize(arg2, pointer2), normalize(arg3, pointer3), normalize(arg4, pointer4), normalize(arg5, pointer5), normalize(arg6, pointer6));
477
+ };
478
+ }
479
+ function wrapNodeSymbol8(fn, pointerArgIndexes) {
480
+ const pointer0 = pointerArgIndexes.includes(0);
481
+ const pointer1 = pointerArgIndexes.includes(1);
482
+ const pointer2 = pointerArgIndexes.includes(2);
483
+ const pointer3 = pointerArgIndexes.includes(3);
484
+ const pointer4 = pointerArgIndexes.includes(4);
485
+ const pointer5 = pointerArgIndexes.includes(5);
486
+ const pointer6 = pointerArgIndexes.includes(6);
487
+ const pointer7 = pointerArgIndexes.includes(7);
488
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
489
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
490
+ if (arguments.length !== 8)
491
+ return Reflect.apply(fn, undefined, arguments);
492
+ return fn(normalize(arg0, pointer0), normalize(arg1, pointer1), normalize(arg2, pointer2), normalize(arg3, pointer3), normalize(arg4, pointer4), normalize(arg5, pointer5), normalize(arg6, pointer6), normalize(arg7, pointer7));
493
+ };
494
+ }
495
+ function toNodePointerArgumentFast(value) {
496
+ if (typeof value === "bigint") {
497
+ return value >= 0n ? value : toNodePointerArgument(value);
498
+ }
499
+ if (ArrayBuffer.isView(value) && value.byteLength > 0 && value.buffer instanceof ArrayBuffer) {
500
+ return value;
501
+ }
502
+ if (value instanceof ArrayBuffer && value.byteLength > 0) {
503
+ return value;
504
+ }
505
+ return toNodePointerArgument(value);
506
+ }
430
507
  function isNodePointerArgumentType(type) {
431
508
  return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback;
432
509
  }
@@ -693,7 +770,7 @@ var envRegistry = singleton("env-registry", () => ({}));
693
770
  function registerEnvVar(config) {
694
771
  const existing = envRegistry[config.name];
695
772
  if (existing) {
696
- if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
773
+ if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default || existing.required !== config.required) {
697
774
  throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
698
775
  }
699
776
  return;
@@ -709,6 +786,9 @@ function parseEnvValue(config) {
709
786
  if (envValue === undefined && config.default !== undefined) {
710
787
  return config.default;
711
788
  }
789
+ if (envValue === undefined && config.required === false) {
790
+ return;
791
+ }
712
792
  if (envValue === undefined) {
713
793
  throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
714
794
  }
@@ -778,6 +858,9 @@ No environment variables registered.
778
858
  if (config.default !== undefined) {
779
859
  const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
780
860
  markdown += `**Default:** \`${defaultValue}\`
861
+ `;
862
+ } else if (config.required === false) {
863
+ markdown += `**Default:** *unset*
781
864
  `;
782
865
  } else {
783
866
  markdown += `**Default:** *Required*
@@ -809,6 +892,9 @@ No environment variables registered.
809
892
  if (config.default !== undefined) {
810
893
  const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
811
894
  output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
895
+ `;
896
+ } else if (config.required === false) {
897
+ output += `\x1B[32mDefault:\x1B[0m \x1B[35munset\x1B[0m
812
898
  `;
813
899
  } else {
814
900
  output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
@@ -909,7 +995,11 @@ async function resolveBundledFilePath(key, loadBundledFile, fallbackPath, metaUr
909
995
  }
910
996
  return await loadBundledFilePath(loadBundledFile, metaUrl, options.loadBundledFileFallback ?? false) ?? path;
911
997
  }
912
- return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl);
998
+ const loaded = (await loadBundledFile()).default;
999
+ if (typeof loaded !== "string") {
1000
+ return resolveFallbackFilePath(fallbackPath, metaUrl);
1001
+ }
1002
+ return normalizeLoadedFilePath(loaded, metaUrl);
913
1003
  }
914
1004
  function resolveFallbackFilePath(fallbackPath, metaUrl) {
915
1005
  const path = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath;
@@ -6356,6 +6446,31 @@ function canStillBeStartupCursorCprPrefix(state) {
6356
6446
  function canStillBePixelResolution(state) {
6357
6447
  return state.firstParamValue === 4 && state.semicolons === 2;
6358
6448
  }
6449
+ function canStillBePixelResolutionPrefix(bytes) {
6450
+ const fixedPrefix = [ESC, 91, 52, 59];
6451
+ const fixedLength = Math.min(bytes.length, fixedPrefix.length);
6452
+ for (let index2 = 0;index2 < fixedLength; index2 += 1) {
6453
+ if (bytes[index2] !== fixedPrefix[index2])
6454
+ return false;
6455
+ }
6456
+ if (bytes.length <= fixedPrefix.length)
6457
+ return bytes.length > 0;
6458
+ let index = fixedPrefix.length;
6459
+ const heightStart = index;
6460
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6461
+ index += 1;
6462
+ if (index === bytes.length)
6463
+ return index > heightStart;
6464
+ if (index === heightStart || bytes[index] !== 59)
6465
+ return false;
6466
+ index += 1;
6467
+ const widthStart = index;
6468
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6469
+ index += 1;
6470
+ if (index === bytes.length)
6471
+ return true;
6472
+ return index > widthStart && bytes[index] === 116;
6473
+ }
6359
6474
  function canDeferParametricCsi(state, context) {
6360
6475
  return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
6361
6476
  }
@@ -6478,6 +6593,8 @@ class StdinParser {
6478
6593
  timeoutId = null;
6479
6594
  destroyed = false;
6480
6595
  pendingSinceMs = null;
6596
+ pendingTimeoutPaused = false;
6597
+ suspendedPixelResolutionPrefixLength = 0;
6481
6598
  forceFlush = false;
6482
6599
  justFlushedEsc = false;
6483
6600
  state = { tag: "ground" };
@@ -6506,6 +6623,12 @@ class StdinParser {
6506
6623
  updateProtocolContext(patch) {
6507
6624
  this.ensureAlive();
6508
6625
  this.protocolContext = { ...this.protocolContext, ...patch };
6626
+ if (!this.protocolContext.pixelResolutionQueryActive && this.suspendedPixelResolutionPrefixLength > 0) {
6627
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6628
+ this.state = { tag: "ground" };
6629
+ this.consumePrefix(prefixLength);
6630
+ this.scanPending();
6631
+ }
6509
6632
  this.reconcileDeferredStateWithProtocolContext();
6510
6633
  this.reconcileTimeoutState();
6511
6634
  }
@@ -6580,6 +6703,11 @@ class StdinParser {
6580
6703
  const appendEnd = immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length;
6581
6704
  this.pending.append(remainder.subarray(0, appendEnd));
6582
6705
  remainder = remainder.subarray(appendEnd);
6706
+ if (this.suspendedPixelResolutionPrefixLength > 0 && this.protocolContext.pixelResolutionQueryActive && !canStillBePixelResolutionPrefix(this.pending.view())) {
6707
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6708
+ this.state = { tag: "ground" };
6709
+ this.consumePrefix(prefixLength);
6710
+ }
6583
6711
  this.scanPending();
6584
6712
  if (this.paste && this.pending.length > 0) {
6585
6713
  remainder = this.consumePasteBytes(this.takePendingBytes());
@@ -6636,6 +6764,23 @@ class StdinParser {
6636
6764
  this.clearTimeout();
6637
6765
  this.resetState();
6638
6766
  }
6767
+ hasPendingPixelResolutionResponse() {
6768
+ if (!this.protocolContext.pixelResolutionQueryActive || this.pending.length === 0)
6769
+ return false;
6770
+ return canStillBePixelResolutionPrefix(this.pending.view());
6771
+ }
6772
+ pausePendingTimeout() {
6773
+ this.ensureAlive();
6774
+ this.pendingTimeoutPaused = true;
6775
+ this.suspendedPixelResolutionPrefixLength = this.pending.length;
6776
+ this.clearTimeout();
6777
+ }
6778
+ resumePendingTimeout() {
6779
+ this.ensureAlive();
6780
+ if (this.pending.length === 0)
6781
+ this.pendingTimeoutPaused = false;
6782
+ this.reconcileTimeoutState();
6783
+ }
6639
6784
  resetMouseState() {
6640
6785
  this.ensureAlive();
6641
6786
  this.mouseParser.reset();
@@ -7463,6 +7608,8 @@ class StdinParser {
7463
7608
  }
7464
7609
  consumePrefix(endExclusive) {
7465
7610
  this.pending.consume(endExclusive);
7611
+ this.pendingTimeoutPaused = false;
7612
+ this.suspendedPixelResolutionPrefixLength = 0;
7466
7613
  this.cursor = 0;
7467
7614
  this.unitStart = 0;
7468
7615
  this.pendingSinceMs = null;
@@ -7485,6 +7632,8 @@ class StdinParser {
7485
7632
  this.cursor = 0;
7486
7633
  this.unitStart = 0;
7487
7634
  this.pendingSinceMs = null;
7635
+ this.pendingTimeoutPaused = false;
7636
+ this.suspendedPixelResolutionPrefixLength = 0;
7488
7637
  this.forceFlush = false;
7489
7638
  this.state = { tag: "ground" };
7490
7639
  }
@@ -7541,6 +7690,10 @@ class StdinParser {
7541
7690
  if (!this.armTimeouts) {
7542
7691
  return;
7543
7692
  }
7693
+ if (this.pendingTimeoutPaused) {
7694
+ this.clearTimeout();
7695
+ return;
7696
+ }
7544
7697
  if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7545
7698
  this.clearTimeout();
7546
7699
  return;
@@ -7570,6 +7723,8 @@ class StdinParser {
7570
7723
  this.pending.reset(INITIAL_PENDING_CAPACITY);
7571
7724
  this.events.length = 0;
7572
7725
  this.pendingSinceMs = null;
7726
+ this.pendingTimeoutPaused = false;
7727
+ this.suspendedPixelResolutionPrefixLength = 0;
7573
7728
  this.forceFlush = false;
7574
7729
  this.justFlushedEsc = false;
7575
7730
  this.state = { tag: "ground" };
@@ -10448,6 +10603,11 @@ function detectLinks(chunks, context) {
10448
10603
  return chunks;
10449
10604
  }
10450
10605
  // src/buffer.ts
10606
+ function requireInteger(value, name, min, max) {
10607
+ if (!Number.isSafeInteger(value) || value < min || value > max) {
10608
+ throw new RangeError(`${name} must be an integer from ${min} to ${max}`);
10609
+ }
10610
+ }
10451
10611
  function packDrawOptions(border2, shouldFill, titleAlignment, bottomTitleAlignment) {
10452
10612
  let packed = 0;
10453
10613
  if (border2 === true) {
@@ -10686,6 +10846,23 @@ class OptimizedBuffer {
10686
10846
  this.guard();
10687
10847
  this.lib.bufferDrawSuperSampleBuffer(this.bufferPtr, x, y, toPointer(pixelDataPtr), pixelDataLength, format, alignedBytesPerRow);
10688
10848
  }
10849
+ drawImage(image, x, y, width, height, pixelWidth = 0, pixelHeight = 0, sourceX = 0, sourceY = 0, sourceWidth = image.width, sourceHeight = image.height, protocol = "auto") {
10850
+ this.guard();
10851
+ requireInteger(x, "x", -2147483648, 2147483647);
10852
+ requireInteger(y, "y", -2147483648, 2147483647);
10853
+ requireInteger(width, "width", 1, 2147483647);
10854
+ requireInteger(height, "height", 1, 2147483647);
10855
+ requireInteger(pixelWidth, "pixelWidth", 0, 2147483647);
10856
+ requireInteger(pixelHeight, "pixelHeight", 0, 2147483647);
10857
+ requireInteger(sourceX, "sourceX", 0, 4294967295);
10858
+ requireInteger(sourceY, "sourceY", 0, 4294967295);
10859
+ requireInteger(sourceWidth, "sourceWidth", 1, 4294967295);
10860
+ requireInteger(sourceHeight, "sourceHeight", 1, 4294967295);
10861
+ if (x + width > 2147483647 || y + height > 2147483647) {
10862
+ throw new RangeError("image destination coordinates and dimensions exceed i32 bounds");
10863
+ }
10864
+ return this.lib.bufferDrawImage(this.bufferPtr, image.ptr, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol);
10865
+ }
10689
10866
  drawPackedBuffer(dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
10690
10867
  this.guard();
10691
10868
  this.lib.bufferDrawPackedBuffer(this.bufferPtr, toPointer(dataPtr), dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
@@ -10955,8 +11132,8 @@ class TextBuffer {
10955
11132
  }
10956
11133
  }
10957
11134
 
10958
- // ../../node_modules/.bun/bun-ffi-structs@0.2.4+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
10959
- var FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).";
11135
+ // ../../node_modules/.bun/bun-ffi-structs@0.3.1+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
11136
+ var FFI_LOAD_ERROR = "bun-ffi-structs pointer operations require Bun or Node.js 26.1+ with node:ffi enabled (--experimental-ffi).";
10960
11137
  var backend2 = await loadBackend2();
10961
11138
  function unavailable2(cause) {
10962
11139
  throw new Error(FFI_LOAD_ERROR, {
@@ -10998,7 +11175,8 @@ function createNodeBackend2(nodeFfi) {
10998
11175
  return {
10999
11176
  ptr(value) {
11000
11177
  if (ArrayBuffer.isView(value)) {
11001
- return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset);
11178
+ const pointer = nodeFfi.getRawPointer(value.buffer);
11179
+ return value.byteOffset === 0 ? pointer : pointer + BigInt(value.byteOffset);
11002
11180
  }
11003
11181
  if (value instanceof ArrayBuffer) {
11004
11182
  return nodeFfi.getRawPointer(value);
@@ -11061,6 +11239,30 @@ var typeGetters = {
11061
11239
  function isObjectPointerDef(type) {
11062
11240
  return typeof type === "object" && type !== null && type.__type === "objectPointer";
11063
11241
  }
11242
+ function allocStruct(structDef, options) {
11243
+ const buffer = new ArrayBuffer(structDef.size);
11244
+ const view = new DataView(buffer);
11245
+ const result = { buffer, view };
11246
+ if (options?.lengths) {
11247
+ const subBuffers = {};
11248
+ for (const [arrayFieldName, length] of Object.entries(options.lengths)) {
11249
+ const arrayMeta = structDef.arrayFields.get(arrayFieldName);
11250
+ if (!arrayMeta) {
11251
+ throw new Error(`Field '${arrayFieldName}' is not an array field with a lengthOf field`);
11252
+ }
11253
+ const subBuffer = new ArrayBuffer(length * arrayMeta.elementSize);
11254
+ subBuffers[arrayFieldName] = subBuffer;
11255
+ const pointer = length > 0 ? ptr2(subBuffer) : null;
11256
+ pointerPacker(view, arrayMeta.arrayOffset, pointer);
11257
+ retainPointerTarget(buffer, subBuffer);
11258
+ arrayMeta.lengthPack(view, arrayMeta.lengthOffset, length);
11259
+ }
11260
+ if (Object.keys(subBuffers).length > 0) {
11261
+ result.subBuffers = subBuffers;
11262
+ }
11263
+ }
11264
+ return result;
11265
+ }
11064
11266
  function alignOffset(offset, align) {
11065
11267
  return offset + (align - 1) & ~(align - 1);
11066
11268
  }
@@ -11084,9 +11286,48 @@ function defineEnum(mapping, base = "u32") {
11084
11286
  function isEnum(type) {
11085
11287
  return typeof type === "object" && type.__type === "enum";
11086
11288
  }
11289
+ function hasPlainPrimitiveRuntimeOptions(options) {
11290
+ return options.optional === true || options.unpackTransform !== undefined || options.packTransform !== undefined || options.lengthOf !== undefined || options.default !== undefined || options.validate !== undefined;
11291
+ }
11087
11292
  function isStruct(type) {
11088
11293
  return typeof type === "object" && type.__type === "struct";
11089
11294
  }
11295
+ var structInternals = new WeakMap;
11296
+ var freshPackBuffers = new WeakSet;
11297
+ function packInlineStruct(internals, view, baseOffset, obj, options) {
11298
+ let mappedObj = internals.options?.mapValue ? internals.options.mapValue(obj) : obj;
11299
+ if (internals.materializeArrayIterables)
11300
+ mappedObj = internals.materializeArrayIterables(mappedObj);
11301
+ for (const field of internals.layout) {
11302
+ const value = mappedObj[field.name] ?? field.default;
11303
+ if (!field.optional && value === undefined) {
11304
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11305
+ }
11306
+ if (field.validate) {
11307
+ for (const validateFn of field.validate) {
11308
+ validateFn(value, field.name, {
11309
+ hints: options?.validationHints,
11310
+ input: mappedObj
11311
+ });
11312
+ }
11313
+ }
11314
+ field.pack(view, baseOffset + field.offset, value, mappedObj, options);
11315
+ }
11316
+ }
11317
+ function unpackInlineStruct(internals, view, baseOffset) {
11318
+ const result = internals.options?.default ? { ...internals.options.default } : {};
11319
+ for (const field of internals.layout) {
11320
+ if (!field.unpack)
11321
+ continue;
11322
+ try {
11323
+ result[field.name] = field.unpack(view, baseOffset + field.offset);
11324
+ } catch (error) {
11325
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
11326
+ throw error;
11327
+ }
11328
+ }
11329
+ return internals.options?.reduceValue ? internals.options.reduceValue(result) : result;
11330
+ }
11090
11331
  function primitivePackers(type) {
11091
11332
  let pack;
11092
11333
  let unpack;
@@ -11136,23 +11377,254 @@ function primitivePackers(type) {
11136
11377
  unpack = (view, off) => view.getFloat64(off, true);
11137
11378
  break;
11138
11379
  case "pointer":
11139
- pack = (view, off, val) => {
11140
- pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11141
- };
11142
- unpack = (view, off) => {
11143
- if (pointerSize === 8) {
11144
- const value = view.getBigUint64(off, true);
11145
- return isBun2 ? Number(value) : value;
11146
- }
11147
- return view.getUint32(off, true);
11148
- };
11380
+ if (pointerSize === 8 && isBun2) {
11381
+ pack = (view, off, val) => {
11382
+ if (!val) {
11383
+ view.setUint32(off, 0, true);
11384
+ view.setUint32(off + 4, 0, true);
11385
+ } else if (typeof val === "number" && Number.isInteger(val)) {
11386
+ view.setUint32(off, val, true);
11387
+ view.setUint32(off + 4, Math.floor(val / 4294967296), true);
11388
+ } else {
11389
+ view.setBigUint64(off, BigInt(val), true);
11390
+ }
11391
+ };
11392
+ unpack = (view, off) => view.getUint32(off, true) + view.getUint32(off + 4, true) * 4294967296;
11393
+ } else {
11394
+ pack = (view, off, val) => {
11395
+ pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11396
+ };
11397
+ unpack = (view, off) => {
11398
+ if (pointerSize === 8) {
11399
+ const value = view.getBigUint64(off, true);
11400
+ return isBun2 ? Number(value) : value;
11401
+ }
11402
+ return view.getUint32(off, true);
11403
+ };
11404
+ }
11149
11405
  break;
11150
11406
  default:
11151
11407
  fatalError(`Unsupported primitive type: ${type}`);
11152
11408
  }
11153
11409
  return { pack, unpack };
11154
11410
  }
11411
+ function primitiveSetterSource(type, offset, value) {
11412
+ const target = `baseOffset + ${offset}`;
11413
+ switch (type) {
11414
+ case "u8":
11415
+ return `view.setUint8(${target}, ${value})`;
11416
+ case "bool_u8":
11417
+ return `view.setUint8(${target}, ${value} ? 1 : 0)`;
11418
+ case "bool_u32":
11419
+ return `view.setUint32(${target}, ${value} ? 1 : 0, true)`;
11420
+ case "u16":
11421
+ return `view.setUint16(${target}, ${value}, true)`;
11422
+ case "i16":
11423
+ return `view.setInt16(${target}, ${value}, true)`;
11424
+ case "u32":
11425
+ return `view.setUint32(${target}, ${value}, true)`;
11426
+ case "i32":
11427
+ return `view.setInt32(${target}, ${value}, true)`;
11428
+ case "i64":
11429
+ return `view.setBigInt64(${target}, BigInt(${value}), true)`;
11430
+ case "u64":
11431
+ return `view.setBigUint64(${target}, BigInt(${value}), true)`;
11432
+ case "f32":
11433
+ return `view.setFloat32(${target}, ${value}, true)`;
11434
+ case "f64":
11435
+ return `view.setFloat64(${target}, ${value}, true)`;
11436
+ }
11437
+ }
11438
+ function primitiveGetterSource(type, offset) {
11439
+ const target = `baseOffset + ${offset}`;
11440
+ switch (type) {
11441
+ case "u8":
11442
+ return `view.getUint8(${target})`;
11443
+ case "bool_u8":
11444
+ return `Boolean(view.getUint8(${target}))`;
11445
+ case "bool_u32":
11446
+ return `Boolean(view.getUint32(${target}, true))`;
11447
+ case "u16":
11448
+ return `view.getUint16(${target}, true)`;
11449
+ case "i16":
11450
+ return `view.getInt16(${target}, true)`;
11451
+ case "u32":
11452
+ return `view.getUint32(${target}, true)`;
11453
+ case "i32":
11454
+ return `view.getInt32(${target}, true)`;
11455
+ case "i64":
11456
+ return `view.getBigInt64(${target}, true)`;
11457
+ case "u64":
11458
+ return `view.getBigUint64(${target}, true)`;
11459
+ case "f32":
11460
+ return `view.getFloat32(${target}, true)`;
11461
+ case "f64":
11462
+ return `view.getFloat64(${target}, true)`;
11463
+ case "pointer":
11464
+ if (pointerSize === 8 && isBun2) {
11465
+ return `view.getUint32(${target}, true) + view.getUint32(${target} + 4, true) * 0x100000000`;
11466
+ }
11467
+ return pointerSize === 8 ? `view.getBigUint64(${target}, true)` : `view.getUint32(${target}, true)`;
11468
+ }
11469
+ }
11470
+ function compilePlainPrimitivePackList(fields, totalSize) {
11471
+ const writes = fields.map((field, index) => {
11472
+ const value = `value${index}`;
11473
+ const missing = `Packing non-optional field '${field.name}' at index `;
11474
+ return `
11475
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11476
+ if (${value} === undefined) fatalError(${JSON.stringify(missing)} + index + ${JSON.stringify(" but value is undefined (and no default provided)")})
11477
+ ${primitiveSetterSource(field.type, field.offset, value)}
11478
+ `;
11479
+ }).join(`
11480
+ `);
11481
+ return new Function("fatalError", `return function packPlainPrimitiveList(objects) {
11482
+ const buffer = new ArrayBuffer(${totalSize} * objects.length)
11483
+ const view = new DataView(buffer)
11484
+ for (let index = 0, baseOffset = 0; index < objects.length; index++, baseOffset += ${totalSize}) {
11485
+ const obj = objects[index]
11486
+ ${writes}
11487
+ }
11488
+ return buffer
11489
+ }`)(fatalError);
11490
+ }
11491
+ function compilePlainPrimitivePack(fields, totalSize) {
11492
+ const writes = fields.map((field, index) => {
11493
+ const value = `value${index}`;
11494
+ return `
11495
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11496
+ if (${value} === undefined) fatalError(${JSON.stringify(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`)})
11497
+ ${primitiveSetterSource(field.type, field.offset, value)}
11498
+ `;
11499
+ }).join(`
11500
+ `);
11501
+ return new Function("fatalError", `return function packPlainPrimitive(obj) {
11502
+ const buffer = new ArrayBuffer(${totalSize})
11503
+ const view = new DataView(buffer)
11504
+ let baseOffset = 0
11505
+ ${writes}
11506
+ return buffer
11507
+ }`)(fatalError);
11508
+ }
11509
+ function compilePlainPrimitivePackInto(fields) {
11510
+ const writes = fields.map((field, index) => {
11511
+ const value = `value${index}`;
11512
+ return `
11513
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11514
+ if (${value} === undefined) {
11515
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11516
+ }
11517
+ ${primitiveSetterSource(field.type, field.offset, value)}
11518
+ `;
11519
+ }).join(`
11520
+ `);
11521
+ return new Function(`return function packPlainPrimitiveInto(obj, view, baseOffset) {
11522
+ ${writes}
11523
+ }`)();
11524
+ }
11525
+ function compilePlainPrimitivePackListInto(fields, totalSize) {
11526
+ const writes = fields.map((field, index) => {
11527
+ const value = `value${index}`;
11528
+ return `
11529
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11530
+ if (${value} === undefined) {
11531
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11532
+ }
11533
+ ${primitiveSetterSource(field.type, field.offset, value)}
11534
+ `;
11535
+ }).join(`
11536
+ `);
11537
+ return new Function(`return function packPlainPrimitiveListInto(objects, view, initialOffset) {
11538
+ for (let index = 0, baseOffset = initialOffset; index < objects.length; index++, baseOffset += ${totalSize}) {
11539
+ const obj = objects[index]
11540
+ ${writes}
11541
+ }
11542
+ }`)();
11543
+ }
11544
+ function compilePlainPrimitiveUnpackList(fields, totalSize) {
11545
+ const reads = fields.map((field, index) => `
11546
+ let value${index}
11547
+ try {
11548
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11549
+ } catch (error) {
11550
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11551
+ throw error
11552
+ }
11553
+ `).join(`
11554
+ `);
11555
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11556
+ return new Function(`return function unpackPlainPrimitiveList(view, count) {
11557
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11558
+ const results = preallocated ? new Array(count) : []
11559
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11560
+ ${reads}
11561
+ const value = { ${properties} }
11562
+ if (preallocated) results[index] = value
11563
+ else results.push(value)
11564
+ }
11565
+ return results
11566
+ }`)();
11567
+ }
11568
+ function compileReducedPrimitiveUnpackList(fields, totalSize, options) {
11569
+ const reads = fields.map((field, index) => `
11570
+ let value${index}
11571
+ try {
11572
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11573
+ } catch (error) {
11574
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11575
+ throw error
11576
+ }
11577
+ `).join(`
11578
+ `);
11579
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11580
+ return new Function("options", `return function unpackReducedPrimitiveList(view, count) {
11581
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11582
+ const results = preallocated ? new Array(count) : []
11583
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11584
+ ${reads}
11585
+ const raw = { ${properties} }
11586
+ const value = options.reduceValue ? options.reduceValue(raw) : raw
11587
+ if (preallocated) results[index] = value
11588
+ else results.push(value)
11589
+ }
11590
+ return results
11591
+ }`)(options);
11592
+ }
11593
+ function compilePlainPrimitiveUnpack(fields) {
11594
+ const reads = fields.map((field, index) => `
11595
+ let value${index}
11596
+ try {
11597
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11598
+ } catch (error) {
11599
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11600
+ throw error
11601
+ }
11602
+ `).join(`
11603
+ `);
11604
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11605
+ return new Function(`return function unpackPlainPrimitive(view) {
11606
+ let baseOffset = 0
11607
+ ${reads}
11608
+ return { ${properties} }
11609
+ }`)();
11610
+ }
11611
+ function compilePlainPrimitiveUnpackInto(fields) {
11612
+ const reads = fields.map((field) => `
11613
+ try {
11614
+ target[${JSON.stringify(field.name)}] = ${primitiveGetterSource(field.type, field.offset)}
11615
+ } catch (error) {
11616
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11617
+ throw error
11618
+ }
11619
+ `).join(`
11620
+ `);
11621
+ return new Function(`return function unpackPlainPrimitiveInto(view, target, baseOffset) {
11622
+ ${reads}
11623
+ return target
11624
+ }`)();
11625
+ }
11155
11626
  var { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers("pointer");
11627
+ var foreignMemoryPointerUnpacker = pointerSize === 8 && isBun2 ? (view, off) => Number(view.getBigUint64(off, true)) : pointerUnpacker;
11156
11628
  var retainedPointerTargets = new WeakMap;
11157
11629
  function retainPointerTarget(owner, target) {
11158
11630
  const retained = retainedPointerTargets.get(owner);
@@ -11163,9 +11635,8 @@ function retainPointerTarget(owner, target) {
11163
11635
  }
11164
11636
  }
11165
11637
  function retainIfPointerTargets(owner, target) {
11166
- if (retainedPointerTargets.has(target)) {
11638
+ if (retainedPointerTargets.has(target))
11167
11639
  retainPointerTarget(owner, target);
11168
- }
11169
11640
  }
11170
11641
  function isNullPointer(pointer) {
11171
11642
  return pointer == null || pointer === 0 || pointer === 0n;
@@ -11173,6 +11644,9 @@ function isNullPointer(pointer) {
11173
11644
  function toItemCount(length) {
11174
11645
  return typeof length === "bigint" ? Number(length) : length;
11175
11646
  }
11647
+ var arrayPreallocationThreshold = 256;
11648
+ var plainPrimitiveSpecializationThreshold = 256;
11649
+ var maxArrayLength = 4294967295;
11176
11650
  function packObjectArray(val) {
11177
11651
  const buffer = new ArrayBuffer(val.length * pointerSize);
11178
11652
  const bufferView = new DataView(buffer);
@@ -11188,10 +11662,15 @@ var decoder = new TextDecoder;
11188
11662
  function defineStruct(fields, structDefOptions) {
11189
11663
  let offset = 0;
11190
11664
  let maxAlign = 1;
11665
+ let hasDirectInlinePack = false;
11666
+ let directInlineUnpackSafe = !structDefOptions?.default && !structDefOptions?.reduceValue;
11667
+ let plainPrimitiveFields = structDefOptions?.mapValue || structDefOptions?.default || structDefOptions?.reduceValue ? null : [];
11668
+ let primitiveDecodeFields = structDefOptions?.reduceValue && !structDefOptions.default ? [] : null;
11191
11669
  const layout = [];
11192
11670
  const lengthOfFields = {};
11193
11671
  const lengthOfRequested = [];
11194
11672
  const arrayFieldsMetadata = {};
11673
+ const arrayElementSizes = {};
11195
11674
  for (const [name, typeOrStruct, options = {}] of fields) {
11196
11675
  if (options.condition && !options.condition()) {
11197
11676
  continue;
@@ -11201,6 +11680,7 @@ function defineStruct(fields, structDefOptions) {
11201
11680
  let unpack;
11202
11681
  let needsLengthOf = false;
11203
11682
  let lengthOfDef = null;
11683
+ let plainPrimitiveType = null;
11204
11684
  if (isPrimitiveType(typeOrStruct)) {
11205
11685
  size = typeSizes[typeOrStruct];
11206
11686
  align = typeAlignments[typeOrStruct];
@@ -11219,7 +11699,14 @@ function defineStruct(fields, structDefOptions) {
11219
11699
  pointerPacker(view, off, val);
11220
11700
  };
11221
11701
  }
11702
+ if (plainPrimitiveFields) {
11703
+ if (typeOrStruct === "pointer" || hasPlainPrimitiveRuntimeOptions(options))
11704
+ plainPrimitiveFields = null;
11705
+ else
11706
+ plainPrimitiveType = typeOrStruct;
11707
+ }
11222
11708
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") {
11709
+ plainPrimitiveFields = null;
11223
11710
  size = pointerSize;
11224
11711
  align = pointerSize;
11225
11712
  pack = (view, off, val) => {
@@ -11237,6 +11724,7 @@ function defineStruct(fields, structDefOptions) {
11237
11724
  return ptrVal;
11238
11725
  };
11239
11726
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "char*") {
11727
+ plainPrimitiveFields = null;
11240
11728
  size = pointerSize;
11241
11729
  align = pointerSize;
11242
11730
  pack = (view, off, val) => {
@@ -11255,6 +11743,8 @@ function defineStruct(fields, structDefOptions) {
11255
11743
  };
11256
11744
  needsLengthOf = true;
11257
11745
  } else if (isEnum(typeOrStruct)) {
11746
+ plainPrimitiveFields = null;
11747
+ directInlineUnpackSafe = false;
11258
11748
  const base = typeOrStruct.type;
11259
11749
  size = typeSizes[base];
11260
11750
  align = typeAlignments[base];
@@ -11268,7 +11758,9 @@ function defineStruct(fields, structDefOptions) {
11268
11758
  return typeOrStruct.from(raw);
11269
11759
  };
11270
11760
  } else if (isStruct(typeOrStruct)) {
11761
+ plainPrimitiveFields = null;
11271
11762
  if (options.asPointer === true) {
11763
+ directInlineUnpackSafe = false;
11272
11764
  size = pointerSize;
11273
11765
  align = pointerSize;
11274
11766
  pack = (view, off, val, obj, options2) => {
@@ -11286,19 +11778,33 @@ function defineStruct(fields, structDefOptions) {
11286
11778
  } else {
11287
11779
  size = typeOrStruct.size;
11288
11780
  align = typeOrStruct.align;
11289
- pack = (view, off, val, obj, options2) => {
11290
- const nestedBuf = typeOrStruct.pack(val, options2);
11781
+ const internals = structInternals.get(typeOrStruct);
11782
+ directInlineUnpackSafe &&= !!internals?.directInlineUnpackSafe;
11783
+ hasDirectInlinePack ||= !!internals && !options.optional;
11784
+ pack = (view, off, val, obj, packOptions) => {
11785
+ const publicPack = typeOrStruct.pack;
11786
+ if (internals && freshPackBuffers.has(view.buffer) && publicPack === internals.publicPack) {
11787
+ packInlineStruct(internals, view, off, val, packOptions);
11788
+ return;
11789
+ }
11790
+ const nestedBuf = Reflect.apply(publicPack, typeOrStruct, [val, packOptions]);
11291
11791
  const nestedView = new Uint8Array(nestedBuf);
11292
- const dView = new Uint8Array(view.buffer);
11792
+ const dView = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
11293
11793
  dView.set(nestedView, off);
11294
11794
  retainIfPointerTargets(view.buffer, nestedBuf);
11295
11795
  };
11296
11796
  unpack = (view, off) => {
11297
- const slice = view.buffer.slice(off, off + size);
11797
+ const publicUnpack = Object.getOwnPropertyDescriptor(typeOrStruct, "unpack")?.value;
11798
+ if (internals?.directInlineUnpackSafe && publicUnpack === internals.publicUnpack && !(view.buffer instanceof SharedArrayBuffer)) {
11799
+ return unpackInlineStruct(internals, view, off);
11800
+ }
11801
+ const start = view.byteOffset + off;
11802
+ const slice = view.buffer.slice(start, start + size);
11298
11803
  return typeOrStruct.unpack(slice);
11299
11804
  };
11300
11805
  }
11301
11806
  } else if (isObjectPointerDef(typeOrStruct)) {
11807
+ plainPrimitiveFields = null;
11302
11808
  size = pointerSize;
11303
11809
  align = pointerSize;
11304
11810
  pack = (view, off, value) => {
@@ -11314,12 +11820,15 @@ function defineStruct(fields, structDefOptions) {
11314
11820
  return pointerUnpacker(view, off);
11315
11821
  };
11316
11822
  } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) {
11823
+ plainPrimitiveFields = null;
11317
11824
  const [def] = typeOrStruct;
11318
11825
  size = pointerSize;
11319
11826
  align = pointerSize;
11320
11827
  let arrayElementSize;
11321
11828
  if (isEnum(def)) {
11829
+ directInlineUnpackSafe = false;
11322
11830
  arrayElementSize = typeSizes[def.type];
11831
+ const { pack: enumPack } = primitivePackers(def.type);
11323
11832
  pack = (view, off, val, obj) => {
11324
11833
  if (!val || val.length === 0) {
11325
11834
  pointerPacker(view, off, null);
@@ -11329,7 +11838,7 @@ function defineStruct(fields, structDefOptions) {
11329
11838
  const bufferView = new DataView(buffer);
11330
11839
  for (let i = 0;i < val.length; i++) {
11331
11840
  const num = def.to(val[i]);
11332
- bufferView.setUint32(i * arrayElementSize, num, true);
11841
+ enumPack(bufferView, i * arrayElementSize, num);
11333
11842
  }
11334
11843
  pointerPacker(view, off, ptr2(buffer));
11335
11844
  retainPointerTarget(view.buffer, buffer);
@@ -11338,7 +11847,9 @@ function defineStruct(fields, structDefOptions) {
11338
11847
  needsLengthOf = true;
11339
11848
  lengthOfDef = def;
11340
11849
  } else if (isStruct(def)) {
11850
+ directInlineUnpackSafe = false;
11341
11851
  arrayElementSize = def.size;
11852
+ const defInternals = structInternals.get(def);
11342
11853
  pack = (view, off, val, obj, options2) => {
11343
11854
  if (!val || val.length === 0) {
11344
11855
  pointerPacker(view, off, null);
@@ -11346,8 +11857,19 @@ function defineStruct(fields, structDefOptions) {
11346
11857
  }
11347
11858
  const buffer = new ArrayBuffer(val.length * arrayElementSize);
11348
11859
  const bufferView = new DataView(buffer);
11349
- for (let i = 0;i < val.length; i++) {
11350
- def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11860
+ if (defInternals?.hasDirectInlinePack) {
11861
+ freshPackBuffers.add(buffer);
11862
+ try {
11863
+ for (let i = 0;i < val.length; i++) {
11864
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11865
+ }
11866
+ } finally {
11867
+ freshPackBuffers.delete(buffer);
11868
+ }
11869
+ } else {
11870
+ for (let i = 0;i < val.length; i++) {
11871
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11872
+ }
11351
11873
  }
11352
11874
  pointerPacker(view, off, ptr2(buffer));
11353
11875
  retainPointerTarget(view.buffer, buffer);
@@ -11375,6 +11897,7 @@ function defineStruct(fields, structDefOptions) {
11375
11897
  needsLengthOf = true;
11376
11898
  lengthOfDef = def;
11377
11899
  } else if (isObjectPointerDef(def)) {
11900
+ directInlineUnpackSafe = false;
11378
11901
  arrayElementSize = pointerSize;
11379
11902
  pack = (view, off, val) => {
11380
11903
  if (!val || val.length === 0) {
@@ -11391,21 +11914,23 @@ function defineStruct(fields, structDefOptions) {
11391
11914
  } else {
11392
11915
  throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`);
11393
11916
  }
11394
- const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name);
11395
- if (lengthOfField && isPrimitiveType(lengthOfField.type)) {
11396
- const { pack: lengthPack } = primitivePackers(lengthOfField.type);
11397
- arrayFieldsMetadata[name] = {
11398
- elementSize: arrayElementSize,
11399
- arrayOffset: offset,
11400
- lengthOffset: lengthOfField.offset,
11401
- lengthPack
11402
- };
11403
- }
11917
+ arrayElementSizes[name] = arrayElementSize;
11404
11918
  } else {
11405
11919
  throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`);
11406
11920
  }
11407
11921
  offset = alignOffset(offset, align);
11922
+ if (plainPrimitiveFields && plainPrimitiveType) {
11923
+ plainPrimitiveFields.push({ name, offset, type: plainPrimitiveType });
11924
+ }
11925
+ if (primitiveDecodeFields) {
11926
+ if (isPrimitiveType(typeOrStruct) && !options.unpackTransform) {
11927
+ primitiveDecodeFields.push({ name, offset, type: typeOrStruct });
11928
+ } else {
11929
+ primitiveDecodeFields = null;
11930
+ }
11931
+ }
11408
11932
  if (options.unpackTransform) {
11933
+ directInlineUnpackSafe = false;
11409
11934
  const originalUnpack = unpack;
11410
11935
  unpack = (view, off) => options.unpackTransform(originalUnpack(view, off));
11411
11936
  }
@@ -11454,6 +11979,7 @@ function defineStruct(fields, structDefOptions) {
11454
11979
  default: options.default,
11455
11980
  pack,
11456
11981
  unpack,
11982
+ unpackTransform: options.unpackTransform,
11457
11983
  type: typeOrStruct,
11458
11984
  lengthOf: options.lengthOf
11459
11985
  };
@@ -11470,6 +11996,19 @@ function defineStruct(fields, structDefOptions) {
11470
11996
  offset += size;
11471
11997
  maxAlign = Math.max(maxAlign, align);
11472
11998
  }
11999
+ for (const [arrayName, lengthOfField] of Object.entries(lengthOfFields)) {
12000
+ const arrayField = layout.find((field) => field.name === arrayName);
12001
+ const elementSize = arrayElementSizes[arrayName];
12002
+ if (!arrayField || elementSize === undefined || !isPrimitiveType(lengthOfField.type))
12003
+ continue;
12004
+ const { pack: lengthPack } = primitivePackers(lengthOfField.type);
12005
+ arrayFieldsMetadata[arrayName] = {
12006
+ elementSize,
12007
+ arrayOffset: arrayField.offset,
12008
+ lengthOffset: lengthOfField.offset,
12009
+ lengthPack
12010
+ };
12011
+ }
11473
12012
  for (const { requester, def } of lengthOfRequested) {
11474
12013
  const lengthOfField = lengthOfFields[requester.name];
11475
12014
  if (!lengthOfField) {
@@ -11481,7 +12020,7 @@ function defineStruct(fields, structDefOptions) {
11481
12020
  if (def === "char*") {
11482
12021
  const relativeOffset = lengthOfField.offset - requester.offset;
11483
12022
  requester.unpack = (view, off) => {
11484
- const ptrAddress = pointerUnpacker(view, off);
12023
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11485
12024
  const length = lengthOfField.unpack(view, off + relativeOffset);
11486
12025
  if (isNullPointer(ptrAddress)) {
11487
12026
  return null;
@@ -11498,10 +12037,9 @@ function defineStruct(fields, structDefOptions) {
11498
12037
  const { unpack: primitiveUnpack } = primitivePackers(def);
11499
12038
  const relativeOffset = lengthOfField.offset - requester.offset;
11500
12039
  requester.unpack = (view, off) => {
11501
- const result = [];
11502
12040
  const length = lengthOfField.unpack(view, off + relativeOffset);
11503
12041
  const itemCount = toItemCount(length);
11504
- const ptrAddress = pointerUnpacker(view, off);
12042
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11505
12043
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11506
12044
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11507
12045
  }
@@ -11510,19 +12048,26 @@ function defineStruct(fields, structDefOptions) {
11510
12048
  }
11511
12049
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11512
12050
  const bufferView = new DataView(buffer);
11513
- for (let i = 0;i < itemCount; i++) {
11514
- result.push(primitiveUnpack(bufferView, i * elemSize));
12051
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12052
+ const result2 = new Array(itemCount);
12053
+ for (let i = 0;i < itemCount; i++) {
12054
+ result2[i] = primitiveUnpack(bufferView, i * elemSize);
12055
+ }
12056
+ return result2;
11515
12057
  }
12058
+ const result = [];
12059
+ for (let i = 0;i < itemCount; i++)
12060
+ result.push(primitiveUnpack(bufferView, i * elemSize));
11516
12061
  return result;
11517
12062
  };
11518
12063
  } else {
11519
- const elemSize = def.type === "u32" ? 4 : 8;
12064
+ const elemSize = typeSizes[def.type];
12065
+ const { unpack: enumUnpack } = primitivePackers(def.type);
11520
12066
  const relativeOffset = lengthOfField.offset - requester.offset;
11521
12067
  requester.unpack = (view, off) => {
11522
- const result = [];
11523
12068
  const length = lengthOfField.unpack(view, off + relativeOffset);
11524
12069
  const itemCount = toItemCount(length);
11525
- const ptrAddress = pointerUnpacker(view, off);
12070
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11526
12071
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11527
12072
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11528
12073
  }
@@ -11531,12 +12076,23 @@ function defineStruct(fields, structDefOptions) {
11531
12076
  }
11532
12077
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11533
12078
  const bufferView = new DataView(buffer);
11534
- for (let i = 0;i < itemCount; i++) {
11535
- result.push(def.from(bufferView.getUint32(i * elemSize, true)));
12079
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12080
+ const result2 = new Array(itemCount);
12081
+ for (let i = 0;i < itemCount; i++) {
12082
+ result2[i] = def.from(enumUnpack(bufferView, i * elemSize));
12083
+ }
12084
+ return result2;
11536
12085
  }
12086
+ const result = [];
12087
+ for (let i = 0;i < itemCount; i++)
12088
+ result.push(def.from(enumUnpack(bufferView, i * elemSize)));
11537
12089
  return result;
11538
12090
  };
11539
12091
  }
12092
+ if (requester.unpackTransform) {
12093
+ const originalUnpack = requester.unpack;
12094
+ requester.unpack = (view, off) => requester.unpackTransform(originalUnpack(view, off));
12095
+ }
11540
12096
  }
11541
12097
  const totalSize = alignOffset(offset, maxAlign);
11542
12098
  const description = layout.map((f) => ({
@@ -11550,7 +12106,87 @@ function defineStruct(fields, structDefOptions) {
11550
12106
  }));
11551
12107
  const layoutByName = new Map(description.map((f) => [f.name, f]));
11552
12108
  const arrayFields = new Map(Object.entries(arrayFieldsMetadata));
11553
- return {
12109
+ const iterableArrayFields = layout.filter((field) => Array.isArray(field.type));
12110
+ if (plainPrimitiveFields?.length !== layout.length || plainPrimitiveFields.length === 0)
12111
+ plainPrimitiveFields = null;
12112
+ const supportsPackListInto = !!plainPrimitiveFields;
12113
+ if (primitiveDecodeFields?.length !== layout.length || primitiveDecodeFields.length === 0) {
12114
+ primitiveDecodeFields = null;
12115
+ }
12116
+ let plainPrimitivePackList;
12117
+ let plainPrimitiveUnpackList;
12118
+ let reducedPrimitiveUnpackList;
12119
+ let plainPrimitivePack;
12120
+ let plainPrimitivePackInto;
12121
+ let plainPrimitivePackListInto;
12122
+ let plainPrimitiveUnpack;
12123
+ let plainPrimitiveUnpackInto;
12124
+ let plainPrimitivePackListItems = 0;
12125
+ let plainPrimitivePackListIntoItems = 0;
12126
+ let plainPrimitiveUnpackListItems = 0;
12127
+ let reducedPrimitiveUnpackListItems = 0;
12128
+ let plainPrimitivePackCalls = 0;
12129
+ let plainPrimitivePackIntoCalls = 0;
12130
+ let plainPrimitiveUnpackCalls = 0;
12131
+ let plainPrimitiveUnpackIntoCalls = 0;
12132
+ const compilePlainPrimitive = (compile) => {
12133
+ try {
12134
+ return compile();
12135
+ } catch (error) {
12136
+ if (!(error instanceof EvalError))
12137
+ throw error;
12138
+ plainPrimitiveFields = null;
12139
+ primitiveDecodeFields = null;
12140
+ return;
12141
+ }
12142
+ };
12143
+ const validateDecodeRange = (view, decodeOffset) => {
12144
+ if (!Number.isSafeInteger(decodeOffset) || decodeOffset < 0) {
12145
+ throw new RangeError(`Decode offset must be a non-negative safe integer, got ${decodeOffset}`);
12146
+ }
12147
+ if (decodeOffset > view.byteLength - totalSize) {
12148
+ throw new RangeError(`DataView range (${view.byteLength} bytes) is too small for a struct at offset ${decodeOffset}`);
12149
+ }
12150
+ };
12151
+ const decodeFieldsInto = (target, view, baseOffset) => {
12152
+ if (structDefOptions?.default)
12153
+ Object.assign(target, structDefOptions.default);
12154
+ for (const field of layout) {
12155
+ if (!field.unpack)
12156
+ continue;
12157
+ try {
12158
+ target[field.name] = field.unpack(view, baseOffset + field.offset);
12159
+ } catch (error) {
12160
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
12161
+ throw error;
12162
+ }
12163
+ }
12164
+ };
12165
+ const unpackInto = (view, target, decodeOffset = 0) => {
12166
+ validateDecodeRange(view, decodeOffset);
12167
+ if (plainPrimitiveFields && (plainPrimitiveUnpackInto || ++plainPrimitiveUnpackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12168
+ plainPrimitiveUnpackInto ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackInto(plainPrimitiveFields));
12169
+ if (plainPrimitiveUnpackInto)
12170
+ return plainPrimitiveUnpackInto(view, target, decodeOffset);
12171
+ }
12172
+ decodeFieldsInto(target, view, decodeOffset);
12173
+ return target;
12174
+ };
12175
+ const materializeArrayIterables = iterableArrayFields.length === 0 ? null : (obj) => {
12176
+ let normalized = obj;
12177
+ for (const field of iterableArrayFields) {
12178
+ const value = obj[field.name];
12179
+ if (value == null || Array.isArray(value) || ArrayBuffer.isView(value))
12180
+ continue;
12181
+ if (typeof value[Symbol.iterator] !== "function")
12182
+ continue;
12183
+ if (normalized === obj)
12184
+ normalized = { ...obj };
12185
+ normalized[field.name] = Array.from(value);
12186
+ }
12187
+ return normalized;
12188
+ };
12189
+ const definition = {
11554
12190
  __type: "struct",
11555
12191
  size: totalSize,
11556
12192
  align: maxAlign,
@@ -11558,34 +12194,57 @@ function defineStruct(fields, structDefOptions) {
11558
12194
  layoutByName,
11559
12195
  arrayFields,
11560
12196
  pack(obj, options) {
12197
+ if (plainPrimitiveFields && (plainPrimitivePack || ++plainPrimitivePackCalls >= plainPrimitiveSpecializationThreshold)) {
12198
+ plainPrimitivePack ??= compilePlainPrimitive(() => compilePlainPrimitivePack(plainPrimitiveFields, totalSize));
12199
+ if (plainPrimitivePack)
12200
+ return plainPrimitivePack(obj);
12201
+ }
11561
12202
  const buf = new ArrayBuffer(totalSize);
11562
12203
  const view = new DataView(buf);
11563
12204
  let mappedObj = obj;
11564
12205
  if (structDefOptions?.mapValue) {
11565
12206
  mappedObj = structDefOptions.mapValue(obj);
11566
12207
  }
11567
- for (const field of layout) {
11568
- const value = mappedObj[field.name] ?? field.default;
11569
- if (!field.optional && value === undefined) {
11570
- fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11571
- }
11572
- if (field.validate) {
11573
- for (const validateFn of field.validate) {
11574
- validateFn(value, field.name, {
11575
- hints: options?.validationHints,
11576
- input: mappedObj
11577
- });
12208
+ if (materializeArrayIterables)
12209
+ mappedObj = materializeArrayIterables(mappedObj);
12210
+ if (hasDirectInlinePack)
12211
+ freshPackBuffers.add(buf);
12212
+ try {
12213
+ for (const field of layout) {
12214
+ const value = mappedObj[field.name] ?? field.default;
12215
+ if (!field.optional && value === undefined) {
12216
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11578
12217
  }
12218
+ if (field.validate) {
12219
+ for (const validateFn of field.validate) {
12220
+ validateFn(value, field.name, {
12221
+ hints: options?.validationHints,
12222
+ input: mappedObj
12223
+ });
12224
+ }
12225
+ }
12226
+ field.pack(view, field.offset, value, mappedObj, options);
11579
12227
  }
11580
- field.pack(view, field.offset, value, mappedObj, options);
12228
+ } finally {
12229
+ if (hasDirectInlinePack)
12230
+ freshPackBuffers.delete(buf);
11581
12231
  }
11582
12232
  return view.buffer;
11583
12233
  },
11584
12234
  packInto(obj, view, offset2, options) {
12235
+ if (plainPrimitiveFields && (plainPrimitivePackInto || ++plainPrimitivePackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12236
+ plainPrimitivePackInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackInto(plainPrimitiveFields));
12237
+ if (plainPrimitivePackInto) {
12238
+ plainPrimitivePackInto(obj, view, offset2);
12239
+ return;
12240
+ }
12241
+ }
11585
12242
  let mappedObj = obj;
11586
12243
  if (structDefOptions?.mapValue) {
11587
12244
  mappedObj = structDefOptions.mapValue(obj);
11588
12245
  }
12246
+ if (materializeArrayIterables)
12247
+ mappedObj = materializeArrayIterables(mappedObj);
11589
12248
  for (const field of layout) {
11590
12249
  const value = mappedObj[field.name] ?? field.default;
11591
12250
  if (!field.optional && value === undefined) {
@@ -11607,6 +12266,11 @@ function defineStruct(fields, structDefOptions) {
11607
12266
  fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`);
11608
12267
  }
11609
12268
  const view = new DataView(buf);
12269
+ if (plainPrimitiveFields && (plainPrimitiveUnpack || ++plainPrimitiveUnpackCalls >= plainPrimitiveSpecializationThreshold)) {
12270
+ plainPrimitiveUnpack ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpack(plainPrimitiveFields));
12271
+ if (plainPrimitiveUnpack)
12272
+ return plainPrimitiveUnpack(view);
12273
+ }
11610
12274
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
11611
12275
  for (const field of layout) {
11612
12276
  if (!field.unpack) {
@@ -11628,31 +12292,67 @@ function defineStruct(fields, structDefOptions) {
11628
12292
  if (objects.length === 0) {
11629
12293
  return new ArrayBuffer(0);
11630
12294
  }
12295
+ if (plainPrimitiveFields) {
12296
+ plainPrimitivePackListItems += objects.length;
12297
+ if (plainPrimitivePackList || objects.length > 1 && plainPrimitivePackListItems >= plainPrimitiveSpecializationThreshold) {
12298
+ plainPrimitivePackList ??= compilePlainPrimitive(() => compilePlainPrimitivePackList(plainPrimitiveFields, totalSize));
12299
+ if (plainPrimitivePackList)
12300
+ return plainPrimitivePackList(objects);
12301
+ }
12302
+ }
11631
12303
  const buffer = new ArrayBuffer(totalSize * objects.length);
11632
12304
  const view = new DataView(buffer);
11633
- for (let i = 0;i < objects.length; i++) {
11634
- let mappedObj = objects[i];
11635
- if (structDefOptions?.mapValue) {
11636
- mappedObj = structDefOptions.mapValue(objects[i]);
11637
- }
11638
- for (const field of layout) {
11639
- const value = mappedObj[field.name] ?? field.default;
11640
- if (!field.optional && value === undefined) {
11641
- fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
12305
+ if (hasDirectInlinePack)
12306
+ freshPackBuffers.add(buffer);
12307
+ try {
12308
+ for (let i = 0;i < objects.length; i++) {
12309
+ let mappedObj = objects[i];
12310
+ if (structDefOptions?.mapValue) {
12311
+ mappedObj = structDefOptions.mapValue(objects[i]);
11642
12312
  }
11643
- if (field.validate) {
11644
- for (const validateFn of field.validate) {
11645
- validateFn(value, field.name, {
11646
- hints: options?.validationHints,
11647
- input: mappedObj
11648
- });
12313
+ if (materializeArrayIterables)
12314
+ mappedObj = materializeArrayIterables(mappedObj);
12315
+ for (const field of layout) {
12316
+ const value = mappedObj[field.name] ?? field.default;
12317
+ if (!field.optional && value === undefined) {
12318
+ fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
11649
12319
  }
12320
+ if (field.validate) {
12321
+ for (const validateFn of field.validate) {
12322
+ validateFn(value, field.name, {
12323
+ hints: options?.validationHints,
12324
+ input: mappedObj
12325
+ });
12326
+ }
12327
+ }
12328
+ field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11650
12329
  }
11651
- field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11652
12330
  }
12331
+ } finally {
12332
+ if (hasDirectInlinePack)
12333
+ freshPackBuffers.delete(buffer);
11653
12334
  }
11654
12335
  return buffer;
11655
12336
  },
12337
+ packListInto(objects, view, offset2, options) {
12338
+ if (objects.length === 0)
12339
+ return;
12340
+ if (!supportsPackListInto)
12341
+ throw new Error("packListInto only supports required primitive fields");
12342
+ if (plainPrimitiveFields) {
12343
+ plainPrimitivePackListIntoItems += objects.length;
12344
+ if (plainPrimitivePackListInto || objects.length > 1 && plainPrimitivePackListIntoItems >= plainPrimitiveSpecializationThreshold) {
12345
+ plainPrimitivePackListInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackListInto(plainPrimitiveFields, totalSize));
12346
+ if (plainPrimitivePackListInto) {
12347
+ plainPrimitivePackListInto(objects, view, offset2);
12348
+ return;
12349
+ }
12350
+ }
12351
+ }
12352
+ for (let index = 0;index < objects.length; index += 1) {
12353
+ definition.packInto(objects[index], view, offset2 + index * totalSize, options);
12354
+ }
12355
+ },
11656
12356
  unpackList(buf, count) {
11657
12357
  if (count === 0) {
11658
12358
  return [];
@@ -11662,7 +12362,24 @@ function defineStruct(fields, structDefOptions) {
11662
12362
  fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`);
11663
12363
  }
11664
12364
  const view = new DataView(buf);
11665
- const results = [];
12365
+ if (plainPrimitiveFields && Number.isSafeInteger(count) && count > 1) {
12366
+ plainPrimitiveUnpackListItems += count;
12367
+ if (plainPrimitiveUnpackList || plainPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12368
+ plainPrimitiveUnpackList ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackList(plainPrimitiveFields, totalSize));
12369
+ if (plainPrimitiveUnpackList)
12370
+ return plainPrimitiveUnpackList(view, count);
12371
+ }
12372
+ }
12373
+ if (!plainPrimitiveFields && primitiveDecodeFields && Number.isSafeInteger(count) && count > 1) {
12374
+ reducedPrimitiveUnpackListItems += count;
12375
+ if (reducedPrimitiveUnpackList || reducedPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12376
+ reducedPrimitiveUnpackList ??= compilePlainPrimitive(() => compileReducedPrimitiveUnpackList(primitiveDecodeFields, totalSize, structDefOptions));
12377
+ if (reducedPrimitiveUnpackList)
12378
+ return reducedPrimitiveUnpackList(view, count);
12379
+ }
12380
+ }
12381
+ const preallocated = Number.isSafeInteger(count) && count >= arrayPreallocationThreshold && count <= maxArrayLength;
12382
+ const results = preallocated ? new Array(count) : [];
11666
12383
  for (let i = 0;i < count; i++) {
11667
12384
  const offset2 = i * totalSize;
11668
12385
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
@@ -11678,9 +12395,16 @@ function defineStruct(fields, structDefOptions) {
11678
12395
  }
11679
12396
  }
11680
12397
  if (structDefOptions?.reduceValue) {
11681
- results.push(structDefOptions.reduceValue(result));
12398
+ const value = structDefOptions.reduceValue(result);
12399
+ if (preallocated)
12400
+ results[i] = value;
12401
+ else
12402
+ results.push(value);
11682
12403
  } else {
11683
- results.push(result);
12404
+ if (preallocated)
12405
+ results[i] = result;
12406
+ else
12407
+ results.push(result);
11684
12408
  }
11685
12409
  }
11686
12410
  return results;
@@ -11689,6 +12413,18 @@ function defineStruct(fields, structDefOptions) {
11689
12413
  return description;
11690
12414
  }
11691
12415
  };
12416
+ if (!structDefOptions?.reduceValue)
12417
+ Object.assign(definition, { unpackInto });
12418
+ structInternals.set(definition, {
12419
+ layout,
12420
+ options: structDefOptions,
12421
+ publicPack: definition.pack,
12422
+ publicUnpack: definition.unpack,
12423
+ hasDirectInlinePack,
12424
+ directInlineUnpackSafe,
12425
+ materializeArrayIterables
12426
+ });
12427
+ return definition;
11692
12428
  }
11693
12429
 
11694
12430
  // src/zig-structs.ts
@@ -11759,6 +12495,7 @@ var VisualCursorStruct = defineStruct([
11759
12495
  var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
11760
12496
  var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8");
11761
12497
  var Osc52SupportEnum = defineEnum({ unknown: 0, supported: 1, unsupported: 2 }, "u8");
12498
+ var ImageProtocolEnum = defineEnum({ auto: 0, kitty: 1, sixel: 2, blocks: 3 }, "u8");
11762
12499
  var TerminalCapabilitiesStruct = defineStruct([
11763
12500
  ["kitty_keyboard", "bool_u8"],
11764
12501
  ["kitty_graphics", "bool_u8"],
@@ -11779,6 +12516,7 @@ var TerminalCapabilitiesStruct = defineStruct([
11779
12516
  ["explicit_cursor_positioning", "bool_u8"],
11780
12517
  ["remote", "bool_u8"],
11781
12518
  ["multiplexer", TerminalMultiplexerEnum],
12519
+ ["image_protocol", ImageProtocolEnum],
11782
12520
  ["term_name", "char*"],
11783
12521
  ["term_name_len", "u64", { lengthOf: "term_name" }],
11784
12522
  ["term_version", "char*"],
@@ -11790,6 +12528,29 @@ var EncodedCharStruct = defineStruct([
11790
12528
  ["width", "u8"],
11791
12529
  ["char", "u32"]
11792
12530
  ]);
12531
+ var NativeImageInfoStruct = defineStruct([
12532
+ ["width", "u32"],
12533
+ ["height", "u32"],
12534
+ ["sourceWidth", "u32"],
12535
+ ["sourceHeight", "u32"],
12536
+ ["format", "u32"],
12537
+ ["colorStatus", "u32"],
12538
+ ["orientation", "u32"],
12539
+ ["hasAlpha", "u32"]
12540
+ ]);
12541
+ var ImageDrawOptionsStruct = defineStruct([
12542
+ ["x", "i32"],
12543
+ ["y", "i32"],
12544
+ ["width", "u32"],
12545
+ ["height", "u32"],
12546
+ ["pixelWidth", "u32"],
12547
+ ["pixelHeight", "u32"],
12548
+ ["sourceX", "u32"],
12549
+ ["sourceY", "u32"],
12550
+ ["sourceWidth", "u32"],
12551
+ ["sourceHeight", "u32"],
12552
+ ["protocol", "u32"]
12553
+ ]);
11793
12554
  var LineInfoStruct = defineStruct([
11794
12555
  ["startCols", ["u32"]],
11795
12556
  ["startColsLen", "u32", { lengthOf: "startCols" }],
@@ -11972,6 +12733,15 @@ var AudioStreamStatsStruct = defineStruct([
11972
12733
  ["errorCode", "i32"],
11973
12734
  ["readyGeneration", "u32"]
11974
12735
  ]);
12736
+ var AudioCaptureStatsStruct = defineStruct([
12737
+ ["framesReceived", "u64"],
12738
+ ["framesRead", "u64"],
12739
+ ["framesDropped", "u64"],
12740
+ ["sampleRate", "u32"],
12741
+ ["channels", "u32"],
12742
+ ["bufferedFrames", "u32"],
12743
+ ["capacityFrames", "u32"]
12744
+ ]);
11975
12745
  var AudioStatsStruct = defineStruct([
11976
12746
  ["soundsLoaded", "u32"],
11977
12747
  ["voicesActive", "u32"],
@@ -12018,27 +12788,33 @@ registerEnvVar({
12018
12788
  });
12019
12789
  registerEnvVar({
12020
12790
  name: "OPENTUI_FORCE_WCWIDTH",
12021
- description: "Use wcwidth for character width calculations",
12022
- type: "boolean",
12023
- default: false
12791
+ description: "Use wcwidth for character width calculations when the variable is present",
12792
+ type: "string",
12793
+ required: false
12024
12794
  });
12025
12795
  registerEnvVar({
12026
12796
  name: "OPENTUI_FORCE_UNICODE",
12027
- description: "Force Mode 2026 Unicode support in terminal capabilities",
12028
- type: "boolean",
12029
- default: false
12797
+ description: "Force Mode 2026 Unicode support when the variable is present",
12798
+ type: "string",
12799
+ required: false
12030
12800
  });
12031
12801
  registerEnvVar({
12032
12802
  name: "OPENTUI_GRAPHICS",
12033
- description: "Enable Kitty graphics protocol detection",
12034
- type: "boolean",
12035
- default: true
12803
+ description: "Control Kitty and Sixel graphics detection with the exact value true, 1, false, or 0",
12804
+ type: "string",
12805
+ required: false
12806
+ });
12807
+ registerEnvVar({
12808
+ name: "OPENTUI_IMAGE_PROTOCOL",
12809
+ description: "Override image rendering protocol: auto, kitty, sixel, or blocks",
12810
+ type: "string",
12811
+ default: "auto"
12036
12812
  });
12037
12813
  registerEnvVar({
12038
12814
  name: "OPENTUI_FORCE_NOZWJ",
12039
- description: "Use no_zwj width method (Unicode without ZWJ joining)",
12040
- type: "boolean",
12041
- default: false
12815
+ description: "Use no_zwj width mode when the variable is present",
12816
+ type: "string",
12817
+ required: false
12042
12818
  });
12043
12819
  var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 };
12044
12820
  var CURSOR_ID_TO_STYLE = ["block", "line", "underline", "default"];
@@ -12355,6 +13131,10 @@ function getOpenTUILib(libPath) {
12355
13131
  args: ["u32", "u32", "u32", "ptr", "u32", "u8", "u32"],
12356
13132
  returns: "void"
12357
13133
  },
13134
+ bufferDrawImage: {
13135
+ args: ["u32", "u32", "ptr"],
13136
+ returns: "u8"
13137
+ },
12358
13138
  bufferDrawPackedBuffer: {
12359
13139
  args: ["u32", "ptr", "u32", "u32", "u32", "u32", "u32"],
12360
13140
  returns: "void"
@@ -13055,6 +13835,23 @@ function getOpenTUILib(libPath) {
13055
13835
  args: ["u32"],
13056
13836
  returns: "u32"
13057
13837
  },
13838
+ imageInfo: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13839
+ imageRetainIccCache: { args: [], returns: "void" },
13840
+ imageReleaseIccCache: { args: [], returns: "void" },
13841
+ imageTestFailIccProfileCopyAllocationOnce: { args: [], returns: "void" },
13842
+ imageDecode: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13843
+ imageCreateFromRgba: { args: ["ptr", "u64", "u32", "u32", "u32", "ptr"], returns: "u32" },
13844
+ imageDestroy: { args: ["u32"], returns: "void" },
13845
+ imageGetInfo: { args: ["u32", "ptr"], returns: "u32" },
13846
+ imageMaterialize: { args: ["u32"], returns: "u32" },
13847
+ imageGetPixelsPtr: { args: ["u32"], returns: "ptr" },
13848
+ imageClone: { args: ["u32", "ptr"], returns: "u32" },
13849
+ imageCopyPixels: { args: ["u32", "ptr", "u64", "u32", "u8"], returns: "u32" },
13850
+ imageResize: { args: ["u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13851
+ imageExtract: { args: ["u32", "u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13852
+ imageExtend: { args: ["u32", "u32", "u32", "u32", "u32", "ptr", "ptr"], returns: "u32" },
13853
+ imageTransform: { args: ["u32", "u32", "ptr"], returns: "u32" },
13854
+ imageComposite: { args: ["u32", "u32", "i32", "i32", "u32", "u8", "ptr"], returns: "u32" },
13058
13855
  getTerminalCapabilities: {
13059
13856
  args: ["u32", "ptr"],
13060
13857
  returns: "void"
@@ -13307,6 +14104,50 @@ function getOpenTUILib(libPath) {
13307
14104
  args: ["u32"],
13308
14105
  returns: "void"
13309
14106
  },
14107
+ audioRefreshCaptureDevices: {
14108
+ args: ["u32"],
14109
+ returns: "i32"
14110
+ },
14111
+ audioGetCaptureDeviceCount: {
14112
+ args: ["u32"],
14113
+ returns: "u32"
14114
+ },
14115
+ audioGetCaptureDeviceName: {
14116
+ args: ["u32", "u32", "ptr", "u32"],
14117
+ returns: "u32"
14118
+ },
14119
+ audioIsCaptureDeviceDefault: {
14120
+ args: ["u32", "u32"],
14121
+ returns: "bool"
14122
+ },
14123
+ audioSelectCaptureDevice: {
14124
+ args: ["u32", "u32"],
14125
+ returns: "i32"
14126
+ },
14127
+ audioClearCaptureDeviceSelection: {
14128
+ args: ["u32"],
14129
+ returns: "void"
14130
+ },
14131
+ audioStartCapture: {
14132
+ args: ["u32", "ptr", "u32", "u32"],
14133
+ returns: "i32"
14134
+ },
14135
+ audioStopCapture: {
14136
+ args: ["u32"],
14137
+ returns: "i32"
14138
+ },
14139
+ audioIsCaptureRunning: {
14140
+ args: ["u32"],
14141
+ returns: "bool"
14142
+ },
14143
+ audioReadCapture: {
14144
+ args: ["u32", "ptr", "u32", "u32", "ptr"],
14145
+ returns: "i32"
14146
+ },
14147
+ audioGetCaptureStats: {
14148
+ args: ["u32", "ptr"],
14149
+ returns: "i32"
14150
+ },
13310
14151
  audioStart: {
13311
14152
  args: ["u32", "ptr"],
13312
14153
  returns: "i32"
@@ -13609,6 +14450,47 @@ var NativeMeasureTargetKind = {
13609
14450
 
13610
14451
  class FFIRenderLib {
13611
14452
  opentui;
14453
+ iccCacheClient = false;
14454
+ yogaLayout = new Float32Array(6);
14455
+ yogaLayoutPtr = ptr(this.yogaLayout);
14456
+ ffiStructStorage = {
14457
+ logicalCursor: {
14458
+ ...allocStruct(LogicalCursorStruct),
14459
+ result: { row: 0, col: 0, offset: 0 }
14460
+ },
14461
+ visualCursor: {
14462
+ ...allocStruct(VisualCursorStruct),
14463
+ result: {
14464
+ visualRow: 0,
14465
+ visualCol: 0,
14466
+ logicalRow: 0,
14467
+ logicalCol: 0,
14468
+ offset: 0
14469
+ }
14470
+ },
14471
+ measureResult: {
14472
+ ...allocStruct(MeasureResultStruct),
14473
+ result: { lineCount: 0, widthColsMax: 0 }
14474
+ },
14475
+ audioStreamStats: {
14476
+ ...allocStruct(AudioStreamStatsStruct),
14477
+ result: {
14478
+ bytesReceived: 0n,
14479
+ framesDecoded: 0n,
14480
+ framesPlayed: 0n,
14481
+ state: 0,
14482
+ sampleRate: 0,
14483
+ channels: 0,
14484
+ bufferedFrames: 0,
14485
+ capacityFrames: 0,
14486
+ underruns: 0,
14487
+ errorCode: 0,
14488
+ readyGeneration: 0
14489
+ }
14490
+ },
14491
+ imageDrawOptions: allocStruct(ImageDrawOptionsStruct),
14492
+ gridDrawOptions: allocStruct(GridDrawOptionsStruct)
14493
+ };
13612
14494
  encoder = new TextEncoder;
13613
14495
  decoder = new TextDecoder;
13614
14496
  logCallbackWrapper = null;
@@ -13635,6 +14517,8 @@ class FFIRenderLib {
13635
14517
  }
13636
14518
  constructor(libPath) {
13637
14519
  this.opentui = getOpenTUILib(libPath);
14520
+ this.imageRetainIccCache();
14521
+ this.iccCacheClient = true;
13638
14522
  try {
13639
14523
  this.setupLogging();
13640
14524
  this.setupEventBus();
@@ -13698,12 +14582,19 @@ class FFIRenderLib {
13698
14582
  this.setLogCallback(null);
13699
14583
  } finally {
13700
14584
  try {
13701
- this.opentui.close();
14585
+ if (this.iccCacheClient) {
14586
+ this.iccCacheClient = false;
14587
+ this.imageReleaseIccCache();
14588
+ }
13702
14589
  } finally {
13703
- this.eventCallbackWrapper = null;
13704
- this.logCallbackWrapper = null;
13705
- this.nativeSpanFeedCallbackWrapper = null;
13706
- this.nativeSpanFeedHandlers.clear();
14590
+ try {
14591
+ this.opentui.close();
14592
+ } finally {
14593
+ this.eventCallbackWrapper = null;
14594
+ this.logCallbackWrapper = null;
14595
+ this.nativeSpanFeedCallbackWrapper = null;
14596
+ this.nativeSpanFeedHandlers.clear();
14597
+ }
13707
14598
  }
13708
14599
  }
13709
14600
  }
@@ -13935,6 +14826,24 @@ class FFIRenderLib {
13935
14826
  const formatId = format === "bgra8unorm" ? 0 : 1;
13936
14827
  this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
13937
14828
  }
14829
+ bufferDrawImage(buffer, image, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol) {
14830
+ const protocolId = { auto: 0, kitty: 1, sixel: 2, blocks: 3 }[protocol];
14831
+ const storage = this.ffiStructStorage.imageDrawOptions;
14832
+ ImageDrawOptionsStruct.packInto({
14833
+ x,
14834
+ y,
14835
+ width,
14836
+ height,
14837
+ pixelWidth,
14838
+ pixelHeight,
14839
+ sourceX,
14840
+ sourceY,
14841
+ sourceWidth,
14842
+ sourceHeight,
14843
+ protocol: protocolId
14844
+ }, storage.view, 0);
14845
+ return Boolean(this.opentui.symbols.bufferDrawImage(buffer, image, storage.buffer));
14846
+ }
13938
14847
  bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
13939
14848
  this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
13940
14849
  }
@@ -13945,11 +14854,8 @@ class FFIRenderLib {
13945
14854
  this.opentui.symbols.bufferDrawGrayscaleBufferSupersampled(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, optionalRgbaPtr(fg2), optionalRgbaPtr(bg2));
13946
14855
  }
13947
14856
  bufferDrawGrid(buffer, borderChars, borderFg, borderBg, columnOffsets, columnCount, rowOffsets, rowCount, options) {
13948
- const optionsBuffer = GridDrawOptionsStruct.pack({
13949
- drawInner: options.drawInner,
13950
- drawOuter: options.drawOuter
13951
- });
13952
- this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, ptr(optionsBuffer));
14857
+ GridDrawOptionsStruct.packInto({ drawInner: options.drawInner, drawOuter: options.drawOuter }, this.ffiStructStorage.gridDrawOptions.view, 0);
14858
+ this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, this.ffiStructStorage.gridDrawOptions.buffer);
13953
14859
  }
13954
14860
  bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, titleColor, title, bottomTitle) {
13955
14861
  const titleBytes = title ? this.encoder.encode(title) : null;
@@ -14097,11 +15003,11 @@ class FFIRenderLib {
14097
15003
  this.opentui.symbols.dumpHitGrid(renderer);
14098
15004
  }
14099
15005
  dumpBuffers(renderer, timestamp) {
14100
- const ts = timestamp ?? Date.now();
15006
+ const ts = BigInt(timestamp ?? Date.now());
14101
15007
  this.opentui.symbols.dumpBuffers(renderer, ts);
14102
15008
  }
14103
15009
  dumpOutputBuffer(renderer, timestamp) {
14104
- const ts = timestamp ?? Date.now();
15010
+ const ts = BigInt(timestamp ?? Date.now());
14105
15011
  this.opentui.symbols.dumpOutputBuffer(renderer, ts);
14106
15012
  }
14107
15013
  restoreTerminalModes(renderer) {
@@ -14255,8 +15161,8 @@ class FFIRenderLib {
14255
15161
  return this.opentui.symbols.yogaNodeGetAlwaysFormsContainingBlock(node);
14256
15162
  }
14257
15163
  yogaNodeGetComputedLayout(node) {
14258
- const layout = new Float32Array(6);
14259
- this.opentui.symbols.yogaNodeGetComputedLayout(node, ptr(layout));
15164
+ const layout = this.yogaLayout;
15165
+ this.opentui.symbols.yogaNodeGetComputedLayout(node, this.yogaLayoutPtr);
14260
15166
  return {
14261
15167
  left: layout[0],
14262
15168
  top: layout[1],
@@ -14437,7 +15343,7 @@ class FFIRenderLib {
14437
15343
  if (len === 0) {
14438
15344
  return null;
14439
15345
  }
14440
- return outBuffer.slice(0, len);
15346
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14441
15347
  }
14442
15348
  createTextBufferView(textBuffer) {
14443
15349
  const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer);
@@ -14574,14 +15480,12 @@ class FFIRenderLib {
14574
15480
  this.opentui.symbols.textBufferViewSetTruncate(view, ffiBool(truncate));
14575
15481
  }
14576
15482
  textBufferViewMeasureForDimensions(view, width, height) {
14577
- const resultBuffer = new ArrayBuffer(MeasureResultStruct.size);
14578
- const resultPtr = ptr(new Uint8Array(resultBuffer));
14579
- const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, resultPtr);
14580
- if (!success) {
15483
+ const storage = this.ffiStructStorage.measureResult;
15484
+ const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, storage.buffer);
15485
+ if (!success)
14581
15486
  return null;
14582
- }
14583
- const result = MeasureResultStruct.unpack(resultBuffer);
14584
- return result;
15487
+ const result = MeasureResultStruct.unpackInto(storage.view, storage.result);
15488
+ return { lineCount: result.lineCount, widthColsMax: result.widthColsMax };
14585
15489
  }
14586
15490
  textBufferAddHighlightByCharRange(buffer, highlight) {
14587
15491
  const packedHighlight = HighlightStruct.pack(highlight);
@@ -14807,9 +15711,10 @@ class FFIRenderLib {
14807
15711
  this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset);
14808
15712
  }
14809
15713
  editBufferGetCursorPosition(buffer) {
14810
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14811
- this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr(cursorBuffer));
14812
- return LogicalCursorStruct.unpack(cursorBuffer);
15714
+ const storage = this.ffiStructStorage.logicalCursor;
15715
+ this.opentui.symbols.editBufferGetCursorPosition(buffer, storage.buffer);
15716
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15717
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14813
15718
  }
14814
15719
  editBufferGetId(buffer) {
14815
15720
  return this.opentui.symbols.editBufferGetId(buffer);
@@ -14853,26 +15758,30 @@ class FFIRenderLib {
14853
15758
  this.opentui.symbols.editBufferClear(buffer);
14854
15759
  }
14855
15760
  editBufferGetNextWordBoundary(buffer) {
14856
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14857
- this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr(cursorBuffer));
14858
- return LogicalCursorStruct.unpack(cursorBuffer);
15761
+ const storage = this.ffiStructStorage.logicalCursor;
15762
+ this.opentui.symbols.editBufferGetNextWordBoundary(buffer, storage.buffer);
15763
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15764
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14859
15765
  }
14860
15766
  editBufferGetPrevWordBoundary(buffer) {
14861
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14862
- this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr(cursorBuffer));
14863
- return LogicalCursorStruct.unpack(cursorBuffer);
15767
+ const storage = this.ffiStructStorage.logicalCursor;
15768
+ this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, storage.buffer);
15769
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15770
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14864
15771
  }
14865
15772
  editBufferGetEOL(buffer) {
14866
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14867
- this.opentui.symbols.editBufferGetEOL(buffer, ptr(cursorBuffer));
14868
- return LogicalCursorStruct.unpack(cursorBuffer);
15773
+ const storage = this.ffiStructStorage.logicalCursor;
15774
+ this.opentui.symbols.editBufferGetEOL(buffer, storage.buffer);
15775
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15776
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14869
15777
  }
14870
15778
  editBufferOffsetToPosition(buffer, offset) {
14871
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14872
- const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, ptr(cursorBuffer));
15779
+ const storage = this.ffiStructStorage.logicalCursor;
15780
+ const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, storage.buffer);
14873
15781
  if (!success)
14874
15782
  return null;
14875
- return LogicalCursorStruct.unpack(cursorBuffer);
15783
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15784
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14876
15785
  }
14877
15786
  editBufferPositionToOffset(buffer, row, col) {
14878
15787
  return this.opentui.symbols.editBufferPositionToOffset(buffer, row, col);
@@ -14894,7 +15803,7 @@ class FFIRenderLib {
14894
15803
  const len = actualLen;
14895
15804
  if (len === 0)
14896
15805
  return null;
14897
- return outBuffer.slice(0, len);
15806
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14898
15807
  }
14899
15808
  editorViewSetSelection(view, start, end, bgColor, fgColor) {
14900
15809
  const bg2 = optionalRgbaPtr(bgColor);
@@ -14954,9 +15863,10 @@ class FFIRenderLib {
14954
15863
  return outBuffer.slice(0, len);
14955
15864
  }
14956
15865
  editorViewGetVisualCursor(view) {
14957
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14958
- this.opentui.symbols.editorViewGetVisualCursor(view, ptr(cursorBuffer));
14959
- return VisualCursorStruct.unpack(cursorBuffer);
15866
+ const storage = this.ffiStructStorage.visualCursor;
15867
+ this.opentui.symbols.editorViewGetVisualCursor(view, storage.buffer);
15868
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15869
+ return { ...cursor };
14960
15870
  }
14961
15871
  editorViewMoveUpVisual(view) {
14962
15872
  this.opentui.symbols.editorViewMoveUpVisual(view);
@@ -14971,29 +15881,34 @@ class FFIRenderLib {
14971
15881
  this.opentui.symbols.editorViewSetCursorByOffset(view, offset);
14972
15882
  }
14973
15883
  editorViewGetNextWordBoundary(view) {
14974
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14975
- this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr(cursorBuffer));
14976
- return VisualCursorStruct.unpack(cursorBuffer);
15884
+ const storage = this.ffiStructStorage.visualCursor;
15885
+ this.opentui.symbols.editorViewGetNextWordBoundary(view, storage.buffer);
15886
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15887
+ return { ...cursor };
14977
15888
  }
14978
15889
  editorViewGetPrevWordBoundary(view) {
14979
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14980
- this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr(cursorBuffer));
14981
- return VisualCursorStruct.unpack(cursorBuffer);
15890
+ const storage = this.ffiStructStorage.visualCursor;
15891
+ this.opentui.symbols.editorViewGetPrevWordBoundary(view, storage.buffer);
15892
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15893
+ return { ...cursor };
14982
15894
  }
14983
15895
  editorViewGetEOL(view) {
14984
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14985
- this.opentui.symbols.editorViewGetEOL(view, ptr(cursorBuffer));
14986
- return VisualCursorStruct.unpack(cursorBuffer);
15896
+ const storage = this.ffiStructStorage.visualCursor;
15897
+ this.opentui.symbols.editorViewGetEOL(view, storage.buffer);
15898
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15899
+ return { ...cursor };
14987
15900
  }
14988
15901
  editorViewGetVisualSOL(view) {
14989
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14990
- this.opentui.symbols.editorViewGetVisualSOL(view, ptr(cursorBuffer));
14991
- return VisualCursorStruct.unpack(cursorBuffer);
15902
+ const storage = this.ffiStructStorage.visualCursor;
15903
+ this.opentui.symbols.editorViewGetVisualSOL(view, storage.buffer);
15904
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15905
+ return { ...cursor };
14992
15906
  }
14993
15907
  editorViewGetVisualEOL(view) {
14994
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14995
- this.opentui.symbols.editorViewGetVisualEOL(view, ptr(cursorBuffer));
14996
- return VisualCursorStruct.unpack(cursorBuffer);
15908
+ const storage = this.ffiStructStorage.visualCursor;
15909
+ this.opentui.symbols.editorViewGetVisualEOL(view, storage.buffer);
15910
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15911
+ return { ...cursor };
14997
15912
  }
14998
15913
  bufferPushScissorRect(buffer, x, y, width, height) {
14999
15914
  this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height);
@@ -15041,6 +15956,7 @@ class FFIRenderLib {
15041
15956
  explicit_cursor_positioning: caps.explicit_cursor_positioning,
15042
15957
  remote: caps.remote,
15043
15958
  multiplexer: caps.multiplexer,
15959
+ image_protocol: caps.image_protocol,
15044
15960
  terminal: {
15045
15961
  name: caps.term_name ?? "",
15046
15962
  version: caps.term_version ?? "",
@@ -15108,6 +16024,76 @@ class FFIRenderLib {
15108
16024
  audioClearPlaybackDeviceSelection(engine) {
15109
16025
  this.opentui.symbols.audioClearPlaybackDeviceSelection(engine);
15110
16026
  }
16027
+ audioRefreshCaptureDevices(engine) {
16028
+ return this.opentui.symbols.audioRefreshCaptureDevices(engine);
16029
+ }
16030
+ audioGetCaptureDeviceCount(engine) {
16031
+ return this.opentui.symbols.audioGetCaptureDeviceCount(engine);
16032
+ }
16033
+ audioGetCaptureDeviceName(engine, index) {
16034
+ const outBuffer = new Uint8Array(512);
16035
+ const bytesWritten = toNumber(this.opentui.symbols.audioGetCaptureDeviceName(engine, index, outBuffer, outBuffer.length));
16036
+ const safeBytesWritten = Math.max(0, Math.min(outBuffer.length, bytesWritten));
16037
+ return this.decoder.decode(outBuffer.subarray(0, safeBytesWritten));
16038
+ }
16039
+ audioIsCaptureDeviceDefault(engine, index) {
16040
+ return Boolean(this.opentui.symbols.audioIsCaptureDeviceDefault(engine, index));
16041
+ }
16042
+ audioSelectCaptureDevice(engine, index) {
16043
+ return this.opentui.symbols.audioSelectCaptureDevice(engine, index);
16044
+ }
16045
+ audioClearCaptureDeviceSelection(engine) {
16046
+ this.opentui.symbols.audioClearCaptureDeviceSelection(engine);
16047
+ }
16048
+ audioStartCapture(engine, options, channels, capacityFrames) {
16049
+ let optionsBuffer;
16050
+ try {
16051
+ const noFixedSizedCallback = options?.noFixedSizedCallback;
16052
+ optionsBuffer = AudioStartOptionsStruct.pack(options ?? {});
16053
+ if (noFixedSizedCallback === undefined) {
16054
+ const field = AudioStartOptionsStruct.layoutByName.get("noFixedSizedCallback");
16055
+ if (!field)
16056
+ return -1;
16057
+ new DataView(optionsBuffer).setUint8(field.offset, 1);
16058
+ }
16059
+ } catch {
16060
+ return -1;
16061
+ }
16062
+ return this.opentui.symbols.audioStartCapture(engine, optionsBuffer, channels, capacityFrames);
16063
+ }
16064
+ audioStopCapture(engine) {
16065
+ return this.opentui.symbols.audioStopCapture(engine);
16066
+ }
16067
+ audioIsCaptureRunning(engine) {
16068
+ return Boolean(this.opentui.symbols.audioIsCaptureRunning(engine));
16069
+ }
16070
+ audioReadCapture(engine, outBuffer, frameCount) {
16071
+ const outFramesReadBuffer = new ArrayBuffer(4);
16072
+ const sampleCapacity = toSafeFFIU32Length(outBuffer.length, "Audio capture output sample capacity");
16073
+ const status = this.opentui.symbols.audioReadCapture(engine, outBuffer, sampleCapacity, frameCount, outFramesReadBuffer);
16074
+ if (status !== 0)
16075
+ return { status, framesRead: 0 };
16076
+ return { status, framesRead: new Uint32Array(outFramesReadBuffer)[0] ?? 0 };
16077
+ }
16078
+ audioGetCaptureStats(engine) {
16079
+ const statsBuffer = new ArrayBuffer(AudioCaptureStatsStruct.size);
16080
+ const status = this.opentui.symbols.audioGetCaptureStats(engine, statsBuffer);
16081
+ if (status !== 0)
16082
+ return { status, stats: null };
16083
+ const stats = AudioCaptureStatsStruct.unpack(statsBuffer);
16084
+ return {
16085
+ status,
16086
+ stats: {
16087
+ framesReceived: typeof stats.framesReceived === "bigint" ? stats.framesReceived : BigInt(stats.framesReceived),
16088
+ framesRead: typeof stats.framesRead === "bigint" ? stats.framesRead : BigInt(stats.framesRead),
16089
+ framesDropped: typeof stats.framesDropped === "bigint" ? stats.framesDropped : BigInt(stats.framesDropped),
16090
+ sampleRate: stats.sampleRate,
16091
+ channels: stats.channels,
16092
+ bufferedFrames: stats.bufferedFrames,
16093
+ capacityFrames: stats.capacityFrames
16094
+ }
16095
+ };
16096
+ }
15111
16097
  audioStart(engine, options) {
15112
16098
  let optionsBuffer;
15113
16099
  try {
@@ -15156,18 +16142,20 @@ class FFIRenderLib {
15156
16142
  return this.opentui.symbols.audioSetStreamGroup(engine, streamId, groupId);
15157
16143
  }
15158
16144
  audioGetStreamStats(engine, streamId) {
15159
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15160
- const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, outBuffer);
16145
+ const storage = this.ffiStructStorage.audioStreamStats;
16146
+ const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, storage.buffer);
15161
16147
  if (status !== 0)
15162
16148
  return null;
15163
- return AudioStreamStatsStruct.unpack(outBuffer);
16149
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16150
+ return { ...stats };
15164
16151
  }
15165
16152
  audioCloseStream(engine, streamId, reason) {
15166
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15167
- const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, outBuffer);
16153
+ const storage = this.ffiStructStorage.audioStreamStats;
16154
+ const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, storage.buffer);
15168
16155
  if (status !== 0)
15169
16156
  return { status, stats: null };
15170
- return { status, stats: AudioStreamStatsStruct.unpack(outBuffer) };
16157
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16158
+ return { status, stats: { ...stats } };
15171
16159
  }
15172
16160
  audioLoad(engine, data) {
15173
16161
  const outBuffer = new ArrayBuffer(4);
@@ -15341,6 +16329,78 @@ class FFIRenderLib {
15341
16329
  syntaxStyleGetStyleCount(style) {
15342
16330
  return this.opentui.symbols.syntaxStyleGetStyleCount(style);
15343
16331
  }
16332
+ imageHandleResult(status, output) {
16333
+ return { status, handle: status === 0 && output[0] !== 0 ? output[0] : null };
16334
+ }
16335
+ imageInfo(data) {
16336
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16337
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16338
+ const status = this.opentui.symbols.imageInfo(data.byteLength === 0 ? null : data, length, output);
16339
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16340
+ }
16341
+ imageDecode(data) {
16342
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16343
+ const output = new Uint32Array(1);
16344
+ return this.imageHandleResult(this.opentui.symbols.imageDecode(data.byteLength === 0 ? null : data, length, output), output);
16345
+ }
16346
+ imageCreateFromRgba(pixels, width, height, stride) {
16347
+ const output = new Uint32Array(1);
16348
+ const status = this.opentui.symbols.imageCreateFromRgba(pixels.byteLength === 0 ? null : pixels, BigInt(pixels.byteLength), width, height, stride, output);
16349
+ return this.imageHandleResult(status, output);
16350
+ }
16351
+ imageDestroy(image) {
16352
+ this.opentui.symbols.imageDestroy(image);
16353
+ }
16354
+ imageRetainIccCache() {
16355
+ this.opentui.symbols.imageRetainIccCache();
16356
+ }
16357
+ imageReleaseIccCache() {
16358
+ this.opentui.symbols.imageReleaseIccCache();
16359
+ }
16360
+ imageTestFailIccProfileCopyAllocationOnce() {
16361
+ this.opentui.symbols.imageTestFailIccProfileCopyAllocationOnce();
16362
+ }
16363
+ imageGetInfo(image) {
16364
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16365
+ const status = this.opentui.symbols.imageGetInfo(image, output);
16366
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16367
+ }
16368
+ imageGetPixelsPtr(image) {
16369
+ const pointer = this.opentui.symbols.imageGetPixelsPtr(image);
16370
+ return pointer === null || pointer === 0 || pointer === 0n ? null : pointer;
16371
+ }
16372
+ imageMaterialize(image) {
16373
+ return this.opentui.symbols.imageMaterialize(image);
16374
+ }
16375
+ imageClone(image) {
16376
+ const output = new Uint32Array(1);
16377
+ return this.imageHandleResult(this.opentui.symbols.imageClone(image, output), output);
16378
+ }
16379
+ imageCopyPixels(image, destination, stride, bgra) {
16380
+ return this.opentui.symbols.imageCopyPixels(image, destination.byteLength === 0 ? null : destination, BigInt(destination.byteLength), stride, bgra ? 1 : 0);
16381
+ }
16382
+ imageResize(image, width, height, filter) {
16383
+ const output = new Uint32Array(1);
16384
+ return this.imageHandleResult(this.opentui.symbols.imageResize(image, width, height, filter, output), output);
16385
+ }
16386
+ imageExtract(image, left, top, width, height) {
16387
+ const output = new Uint32Array(1);
16388
+ return this.imageHandleResult(this.opentui.symbols.imageExtract(image, left, top, width, height, output), output);
16389
+ }
16390
+ imageExtend(image, top, right, bottom, left, background) {
16391
+ if (!(background instanceof Uint8Array) || background.byteLength !== 4)
16392
+ return { status: 7, handle: null };
16393
+ const output = new Uint32Array(1);
16394
+ return this.imageHandleResult(this.opentui.symbols.imageExtend(image, top, right, bottom, left, background, output), output);
16395
+ }
16396
+ imageTransform(image, operation) {
16397
+ const output = new Uint32Array(1);
16398
+ return this.imageHandleResult(this.opentui.symbols.imageTransform(image, operation, output), output);
16399
+ }
16400
+ imageComposite(base, overlay, left, top, blend, opacity) {
16401
+ const output = new Uint32Array(1);
16402
+ return this.imageHandleResult(this.opentui.symbols.imageComposite(base, overlay, left, top, blend, opacity, output), output);
16403
+ }
15344
16404
  editorViewSetPlaceholderStyledText(view, chunks) {
15345
16405
  const nonEmptyChunks = chunks.filter((c) => c.text.length > 0);
15346
16406
  if (nonEmptyChunks.length === 0) {
@@ -16357,5 +17417,5 @@ var yoga_default = Yoga;
16357
17417
 
16358
17418
  export { toArrayBuffer, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, sleep, stringWidth2 as stringWidth, resolveBundledFilePath, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, getTreeSitterClient, destroyTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, ClipboardTarget, Clipboard, detectLinks, OptimizedBuffer, TextBuffer, SpanInfoStruct, NativeAudioStreamFormat, NativeAudioStreamState, NativeAudioStreamStateNames, NativeAudioStreamCloseReason, NativeAudioStreamState2 as NativeAudioStreamState1, NativeAudioStreamCloseReason2 as NativeAudioStreamCloseReason1, NativeAudioStreamFormat2 as NativeAudioStreamFormat1, LogLevel2 as LogLevel, NativeMeasureTargetKind, setRenderLibPath, resolveRenderLib, Align, BoxSizing, Dimension, Direction, Display, Edge, Errata, ExperimentalFeature, FlexDirection, Gutter, Justify, LogLevel as LogLevel1, MeasureMode, NodeType, Overflow, PositionType, Unit, Wrap, ALIGN_AUTO, ALIGN_FLEX_START, ALIGN_CENTER, ALIGN_FLEX_END, ALIGN_STRETCH, ALIGN_BASELINE, ALIGN_SPACE_BETWEEN, ALIGN_SPACE_AROUND, ALIGN_SPACE_EVENLY, BOX_SIZING_BORDER_BOX, BOX_SIZING_CONTENT_BOX, DIMENSION_WIDTH, DIMENSION_HEIGHT, DIRECTION_INHERIT, DIRECTION_LTR, DIRECTION_RTL, DISPLAY_FLEX, DISPLAY_NONE, DISPLAY_CONTENTS, EDGE_LEFT, EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_START, EDGE_END, EDGE_HORIZONTAL, EDGE_VERTICAL, EDGE_ALL, ERRATA_NONE, ERRATA_STRETCH_FLEX_BASIS, ERRATA_ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING, ERRATA_ABSOLUTE_PERCENT_AGAINST_INNER_SIZE, ERRATA_ALL, ERRATA_CLASSIC, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS, FLEX_DIRECTION_COLUMN, FLEX_DIRECTION_COLUMN_REVERSE, FLEX_DIRECTION_ROW, FLEX_DIRECTION_ROW_REVERSE, GUTTER_COLUMN, GUTTER_ROW, GUTTER_ALL, JUSTIFY_FLEX_START, JUSTIFY_CENTER, JUSTIFY_FLEX_END, JUSTIFY_SPACE_BETWEEN, JUSTIFY_SPACE_AROUND, JUSTIFY_SPACE_EVENLY, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, LOG_LEVEL_FATAL, MEASURE_MODE_UNDEFINED, MEASURE_MODE_EXACTLY, MEASURE_MODE_AT_MOST, NODE_TYPE_DEFAULT, NODE_TYPE_TEXT, OVERFLOW_VISIBLE, OVERFLOW_HIDDEN, OVERFLOW_SCROLL, POSITION_TYPE_STATIC, POSITION_TYPE_RELATIVE, POSITION_TYPE_ABSOLUTE, UNIT_UNDEFINED, UNIT_POINT, UNIT_PERCENT, UNIT_AUTO, WRAP_NO_WRAP, WRAP_WRAP, WRAP_WRAP_REVERSE, Config, Node, exports_yoga, yoga_default };
16359
17419
 
16360
- //# debugId=F036A274BA18217764756E2164756E21
16361
- //# sourceMappingURL=chunk-node-q0cwyvm9.js.map
17420
+ //# debugId=4DE83B5000E1E53964756E2164756E21
17421
+ //# sourceMappingURL=chunk-node-m23dbcww.js.map