@opentui/core 0.4.5 → 0.5.0

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 (43) 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-ctxxvhwz.js} +1181 -147
  6. package/chunk-bun-ctxxvhwz.js.map +62 -0
  7. package/{chunk-bun-tkm837n2.js → chunk-bun-v3e63tzw.js} +147 -37
  8. package/chunk-bun-v3e63tzw.js.map +32 -0
  9. package/{chunk-node-51kpf0mz.js → chunk-node-1j69hr31.js} +147 -37
  10. package/chunk-node-1j69hr31.js.map +32 -0
  11. package/{chunk-node-q0cwyvm9.js → chunk-node-savhj5rp.js} +1181 -147
  12. package/chunk-node-savhj5rp.js.map +61 -0
  13. package/image.d.ts +105 -0
  14. package/index.bun.js +2131 -89
  15. package/index.bun.js.map +6 -4
  16. package/index.d.ts +1 -0
  17. package/index.node.js +2131 -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/text-buffer-view.d.ts +2 -5
  35. package/types.d.ts +8 -0
  36. package/yoga.bun.js +1 -1
  37. package/yoga.js +1 -1
  38. package/zig-structs.d.ts +45 -24
  39. package/zig.d.ts +70 -7
  40. package/chunk-bun-t2myhmwd.js.map +0 -62
  41. package/chunk-bun-tkm837n2.js.map +0 -32
  42. package/chunk-node-51kpf0mz.js.map +0 -32
  43. package/chunk-node-q0cwyvm9.js.map +0 -61
@@ -194,6 +194,7 @@ function createUnsupportedBackend(cause) {
194
194
  };
195
195
  }
196
196
  var isBun = typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.bun === "string";
197
+ var usesBunFFI = isBun;
197
198
  var requireModule = createRequire(import.meta.url);
198
199
  var backend = loadBackend();
199
200
  function loadBackend() {
@@ -219,6 +220,11 @@ function toPointer(value) {
219
220
  function ffiBool(value) {
220
221
  return value ? 1 : 0;
221
222
  }
223
+ function trimNodeFFIOutputBytes(buffer, length) {
224
+ if (length === buffer.byteLength)
225
+ return buffer;
226
+ return new Uint8Array(buffer.buffer.transferToFixedLength(length));
227
+ }
222
228
  function toSafeNumberPointer(pointer) {
223
229
  if (pointer < 0n) {
224
230
  throw new Error(POINTER_NEGATIVE);
@@ -384,6 +390,34 @@ function wrapNodeSymbol(fn, definition) {
384
390
  if (pointerArgIndexes.length === 0) {
385
391
  return fn;
386
392
  }
393
+ if (definition.args?.length === 7 && pointerArgIndexes.length >= 2) {
394
+ return wrapNodeSymbol7(fn, pointerArgIndexes);
395
+ }
396
+ if (definition.args?.length === 8) {
397
+ return wrapNodeSymbol8(fn, pointerArgIndexes);
398
+ }
399
+ const pointerArgs = new Set(pointerArgIndexes);
400
+ const normalize = (value, index) => pointerArgs.has(index) ? toNodePointerArgumentFast(value) : value;
401
+ switch (definition.args?.length) {
402
+ case 1:
403
+ return function(arg0) {
404
+ if (arguments.length !== 1)
405
+ return Reflect.apply(fn, undefined, arguments);
406
+ return fn(normalize(arg0, 0));
407
+ };
408
+ case 2:
409
+ return function(arg0, arg1) {
410
+ if (arguments.length !== 2)
411
+ return Reflect.apply(fn, undefined, arguments);
412
+ return fn(normalize(arg0, 0), normalize(arg1, 1));
413
+ };
414
+ case 3:
415
+ return function(arg0, arg1, arg2) {
416
+ if (arguments.length !== 3)
417
+ return Reflect.apply(fn, undefined, arguments);
418
+ return fn(normalize(arg0, 0), normalize(arg1, 1), normalize(arg2, 2));
419
+ };
420
+ }
387
421
  return (...args) => {
388
422
  const normalizedArgs = args.slice();
389
423
  for (const index of pointerArgIndexes) {
@@ -392,6 +426,49 @@ function wrapNodeSymbol(fn, definition) {
392
426
  return fn(...normalizedArgs);
393
427
  };
394
428
  }
429
+ function wrapNodeSymbol7(fn, pointerArgIndexes) {
430
+ const pointer0 = pointerArgIndexes.includes(0);
431
+ const pointer1 = pointerArgIndexes.includes(1);
432
+ const pointer2 = pointerArgIndexes.includes(2);
433
+ const pointer3 = pointerArgIndexes.includes(3);
434
+ const pointer4 = pointerArgIndexes.includes(4);
435
+ const pointer5 = pointerArgIndexes.includes(5);
436
+ const pointer6 = pointerArgIndexes.includes(6);
437
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
438
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
439
+ if (arguments.length !== 7)
440
+ return Reflect.apply(fn, undefined, arguments);
441
+ return fn(normalize(arg0, pointer0), normalize(arg1, pointer1), normalize(arg2, pointer2), normalize(arg3, pointer3), normalize(arg4, pointer4), normalize(arg5, pointer5), normalize(arg6, pointer6));
442
+ };
443
+ }
444
+ function wrapNodeSymbol8(fn, pointerArgIndexes) {
445
+ const pointer0 = pointerArgIndexes.includes(0);
446
+ const pointer1 = pointerArgIndexes.includes(1);
447
+ const pointer2 = pointerArgIndexes.includes(2);
448
+ const pointer3 = pointerArgIndexes.includes(3);
449
+ const pointer4 = pointerArgIndexes.includes(4);
450
+ const pointer5 = pointerArgIndexes.includes(5);
451
+ const pointer6 = pointerArgIndexes.includes(6);
452
+ const pointer7 = pointerArgIndexes.includes(7);
453
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
454
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
455
+ if (arguments.length !== 8)
456
+ return Reflect.apply(fn, undefined, arguments);
457
+ 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));
458
+ };
459
+ }
460
+ function toNodePointerArgumentFast(value) {
461
+ if (typeof value === "bigint") {
462
+ return value >= 0n ? value : toNodePointerArgument(value);
463
+ }
464
+ if (ArrayBuffer.isView(value) && value.byteLength > 0 && value.buffer instanceof ArrayBuffer) {
465
+ return value;
466
+ }
467
+ if (value instanceof ArrayBuffer && value.byteLength > 0) {
468
+ return value;
469
+ }
470
+ return toNodePointerArgument(value);
471
+ }
395
472
  function isNodePointerArgumentType(type) {
396
473
  return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback;
397
474
  }
@@ -662,7 +739,7 @@ var envRegistry = singleton("env-registry", () => ({}));
662
739
  function registerEnvVar(config) {
663
740
  const existing = envRegistry[config.name];
664
741
  if (existing) {
665
- if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
742
+ if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default || existing.required !== config.required) {
666
743
  throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
667
744
  }
668
745
  return;
@@ -678,6 +755,9 @@ function parseEnvValue(config) {
678
755
  if (envValue === undefined && config.default !== undefined) {
679
756
  return config.default;
680
757
  }
758
+ if (envValue === undefined && config.required === false) {
759
+ return;
760
+ }
681
761
  if (envValue === undefined) {
682
762
  throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
683
763
  }
@@ -747,6 +827,9 @@ No environment variables registered.
747
827
  if (config.default !== undefined) {
748
828
  const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
749
829
  markdown += `**Default:** \`${defaultValue}\`
830
+ `;
831
+ } else if (config.required === false) {
832
+ markdown += `**Default:** *unset*
750
833
  `;
751
834
  } else {
752
835
  markdown += `**Default:** *Required*
@@ -778,6 +861,9 @@ No environment variables registered.
778
861
  if (config.default !== undefined) {
779
862
  const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
780
863
  output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
864
+ `;
865
+ } else if (config.required === false) {
866
+ output += `\x1B[32mDefault:\x1B[0m \x1B[35munset\x1B[0m
781
867
  `;
782
868
  } else {
783
869
  output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
@@ -878,7 +964,11 @@ async function resolveBundledFilePath(key, loadBundledFile, fallbackPath, metaUr
878
964
  }
879
965
  return await loadBundledFilePath(loadBundledFile, metaUrl, options.loadBundledFileFallback ?? false) ?? path;
880
966
  }
881
- return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl);
967
+ const loaded = (await loadBundledFile()).default;
968
+ if (typeof loaded !== "string") {
969
+ return resolveFallbackFilePath(fallbackPath, metaUrl);
970
+ }
971
+ return normalizeLoadedFilePath(loaded, metaUrl);
882
972
  }
883
973
  function resolveFallbackFilePath(fallbackPath, metaUrl) {
884
974
  const path = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath;
@@ -6325,6 +6415,31 @@ function canStillBeStartupCursorCprPrefix(state) {
6325
6415
  function canStillBePixelResolution(state) {
6326
6416
  return state.firstParamValue === 4 && state.semicolons === 2;
6327
6417
  }
6418
+ function canStillBePixelResolutionPrefix(bytes) {
6419
+ const fixedPrefix = [ESC, 91, 52, 59];
6420
+ const fixedLength = Math.min(bytes.length, fixedPrefix.length);
6421
+ for (let index2 = 0;index2 < fixedLength; index2 += 1) {
6422
+ if (bytes[index2] !== fixedPrefix[index2])
6423
+ return false;
6424
+ }
6425
+ if (bytes.length <= fixedPrefix.length)
6426
+ return bytes.length > 0;
6427
+ let index = fixedPrefix.length;
6428
+ const heightStart = index;
6429
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6430
+ index += 1;
6431
+ if (index === bytes.length)
6432
+ return index > heightStart;
6433
+ if (index === heightStart || bytes[index] !== 59)
6434
+ return false;
6435
+ index += 1;
6436
+ const widthStart = index;
6437
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6438
+ index += 1;
6439
+ if (index === bytes.length)
6440
+ return true;
6441
+ return index > widthStart && bytes[index] === 116;
6442
+ }
6328
6443
  function canDeferParametricCsi(state, context) {
6329
6444
  return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
6330
6445
  }
@@ -6447,6 +6562,8 @@ class StdinParser {
6447
6562
  timeoutId = null;
6448
6563
  destroyed = false;
6449
6564
  pendingSinceMs = null;
6565
+ pendingTimeoutPaused = false;
6566
+ suspendedPixelResolutionPrefixLength = 0;
6450
6567
  forceFlush = false;
6451
6568
  justFlushedEsc = false;
6452
6569
  state = { tag: "ground" };
@@ -6475,6 +6592,12 @@ class StdinParser {
6475
6592
  updateProtocolContext(patch) {
6476
6593
  this.ensureAlive();
6477
6594
  this.protocolContext = { ...this.protocolContext, ...patch };
6595
+ if (!this.protocolContext.pixelResolutionQueryActive && this.suspendedPixelResolutionPrefixLength > 0) {
6596
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6597
+ this.state = { tag: "ground" };
6598
+ this.consumePrefix(prefixLength);
6599
+ this.scanPending();
6600
+ }
6478
6601
  this.reconcileDeferredStateWithProtocolContext();
6479
6602
  this.reconcileTimeoutState();
6480
6603
  }
@@ -6549,6 +6672,11 @@ class StdinParser {
6549
6672
  const appendEnd = immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length;
6550
6673
  this.pending.append(remainder.subarray(0, appendEnd));
6551
6674
  remainder = remainder.subarray(appendEnd);
6675
+ if (this.suspendedPixelResolutionPrefixLength > 0 && this.protocolContext.pixelResolutionQueryActive && !canStillBePixelResolutionPrefix(this.pending.view())) {
6676
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6677
+ this.state = { tag: "ground" };
6678
+ this.consumePrefix(prefixLength);
6679
+ }
6552
6680
  this.scanPending();
6553
6681
  if (this.paste && this.pending.length > 0) {
6554
6682
  remainder = this.consumePasteBytes(this.takePendingBytes());
@@ -6605,6 +6733,23 @@ class StdinParser {
6605
6733
  this.clearTimeout();
6606
6734
  this.resetState();
6607
6735
  }
6736
+ hasPendingPixelResolutionResponse() {
6737
+ if (!this.protocolContext.pixelResolutionQueryActive || this.pending.length === 0)
6738
+ return false;
6739
+ return canStillBePixelResolutionPrefix(this.pending.view());
6740
+ }
6741
+ pausePendingTimeout() {
6742
+ this.ensureAlive();
6743
+ this.pendingTimeoutPaused = true;
6744
+ this.suspendedPixelResolutionPrefixLength = this.pending.length;
6745
+ this.clearTimeout();
6746
+ }
6747
+ resumePendingTimeout() {
6748
+ this.ensureAlive();
6749
+ if (this.pending.length === 0)
6750
+ this.pendingTimeoutPaused = false;
6751
+ this.reconcileTimeoutState();
6752
+ }
6608
6753
  resetMouseState() {
6609
6754
  this.ensureAlive();
6610
6755
  this.mouseParser.reset();
@@ -7432,6 +7577,8 @@ class StdinParser {
7432
7577
  }
7433
7578
  consumePrefix(endExclusive) {
7434
7579
  this.pending.consume(endExclusive);
7580
+ this.pendingTimeoutPaused = false;
7581
+ this.suspendedPixelResolutionPrefixLength = 0;
7435
7582
  this.cursor = 0;
7436
7583
  this.unitStart = 0;
7437
7584
  this.pendingSinceMs = null;
@@ -7454,6 +7601,8 @@ class StdinParser {
7454
7601
  this.cursor = 0;
7455
7602
  this.unitStart = 0;
7456
7603
  this.pendingSinceMs = null;
7604
+ this.pendingTimeoutPaused = false;
7605
+ this.suspendedPixelResolutionPrefixLength = 0;
7457
7606
  this.forceFlush = false;
7458
7607
  this.state = { tag: "ground" };
7459
7608
  }
@@ -7510,6 +7659,10 @@ class StdinParser {
7510
7659
  if (!this.armTimeouts) {
7511
7660
  return;
7512
7661
  }
7662
+ if (this.pendingTimeoutPaused) {
7663
+ this.clearTimeout();
7664
+ return;
7665
+ }
7513
7666
  if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7514
7667
  this.clearTimeout();
7515
7668
  return;
@@ -7539,6 +7692,8 @@ class StdinParser {
7539
7692
  this.pending.reset(INITIAL_PENDING_CAPACITY);
7540
7693
  this.events.length = 0;
7541
7694
  this.pendingSinceMs = null;
7695
+ this.pendingTimeoutPaused = false;
7696
+ this.suspendedPixelResolutionPrefixLength = 0;
7542
7697
  this.forceFlush = false;
7543
7698
  this.justFlushedEsc = false;
7544
7699
  this.state = { tag: "ground" };
@@ -10469,6 +10624,11 @@ function detectLinks(chunks, context) {
10469
10624
  return chunks;
10470
10625
  }
10471
10626
  // src/buffer.ts
10627
+ function requireInteger(value, name, min, max) {
10628
+ if (!Number.isSafeInteger(value) || value < min || value > max) {
10629
+ throw new RangeError(`${name} must be an integer from ${min} to ${max}`);
10630
+ }
10631
+ }
10472
10632
  function packDrawOptions(border2, shouldFill, titleAlignment, bottomTitleAlignment) {
10473
10633
  let packed = 0;
10474
10634
  if (border2 === true) {
@@ -10707,6 +10867,23 @@ class OptimizedBuffer {
10707
10867
  this.guard();
10708
10868
  this.lib.bufferDrawSuperSampleBuffer(this.bufferPtr, x, y, toPointer(pixelDataPtr), pixelDataLength, format, alignedBytesPerRow);
10709
10869
  }
10870
+ drawImage(image, x, y, width, height, pixelWidth = 0, pixelHeight = 0, sourceX = 0, sourceY = 0, sourceWidth = image.width, sourceHeight = image.height, protocol = "auto") {
10871
+ this.guard();
10872
+ requireInteger(x, "x", -2147483648, 2147483647);
10873
+ requireInteger(y, "y", -2147483648, 2147483647);
10874
+ requireInteger(width, "width", 1, 2147483647);
10875
+ requireInteger(height, "height", 1, 2147483647);
10876
+ requireInteger(pixelWidth, "pixelWidth", 0, 2147483647);
10877
+ requireInteger(pixelHeight, "pixelHeight", 0, 2147483647);
10878
+ requireInteger(sourceX, "sourceX", 0, 4294967295);
10879
+ requireInteger(sourceY, "sourceY", 0, 4294967295);
10880
+ requireInteger(sourceWidth, "sourceWidth", 1, 4294967295);
10881
+ requireInteger(sourceHeight, "sourceHeight", 1, 4294967295);
10882
+ if (x + width > 2147483647 || y + height > 2147483647) {
10883
+ throw new RangeError("image destination coordinates and dimensions exceed i32 bounds");
10884
+ }
10885
+ return this.lib.bufferDrawImage(this.bufferPtr, image.ptr, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol);
10886
+ }
10710
10887
  drawPackedBuffer(dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
10711
10888
  this.guard();
10712
10889
  this.lib.bufferDrawPackedBuffer(this.bufferPtr, toPointer(dataPtr), dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
@@ -10976,8 +11153,8 @@ class TextBuffer {
10976
11153
  }
10977
11154
  }
10978
11155
 
10979
- // ../../node_modules/.bun/bun-ffi-structs@0.2.4+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
10980
- var FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).";
11156
+ // ../../node_modules/.bun/bun-ffi-structs@0.3.1+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
11157
+ var FFI_LOAD_ERROR = "bun-ffi-structs pointer operations require Bun or Node.js 26.1+ with node:ffi enabled (--experimental-ffi).";
10981
11158
  var backend2 = await loadBackend2();
10982
11159
  function unavailable2(cause) {
10983
11160
  throw new Error(FFI_LOAD_ERROR, {
@@ -11019,7 +11196,8 @@ function createNodeBackend2(nodeFfi) {
11019
11196
  return {
11020
11197
  ptr(value) {
11021
11198
  if (ArrayBuffer.isView(value)) {
11022
- return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset);
11199
+ const pointer = nodeFfi.getRawPointer(value.buffer);
11200
+ return value.byteOffset === 0 ? pointer : pointer + BigInt(value.byteOffset);
11023
11201
  }
11024
11202
  if (value instanceof ArrayBuffer) {
11025
11203
  return nodeFfi.getRawPointer(value);
@@ -11082,6 +11260,30 @@ var typeGetters = {
11082
11260
  function isObjectPointerDef(type) {
11083
11261
  return typeof type === "object" && type !== null && type.__type === "objectPointer";
11084
11262
  }
11263
+ function allocStruct(structDef, options) {
11264
+ const buffer = new ArrayBuffer(structDef.size);
11265
+ const view = new DataView(buffer);
11266
+ const result = { buffer, view };
11267
+ if (options?.lengths) {
11268
+ const subBuffers = {};
11269
+ for (const [arrayFieldName, length] of Object.entries(options.lengths)) {
11270
+ const arrayMeta = structDef.arrayFields.get(arrayFieldName);
11271
+ if (!arrayMeta) {
11272
+ throw new Error(`Field '${arrayFieldName}' is not an array field with a lengthOf field`);
11273
+ }
11274
+ const subBuffer = new ArrayBuffer(length * arrayMeta.elementSize);
11275
+ subBuffers[arrayFieldName] = subBuffer;
11276
+ const pointer = length > 0 ? ptr2(subBuffer) : null;
11277
+ pointerPacker(view, arrayMeta.arrayOffset, pointer);
11278
+ retainPointerTarget(buffer, subBuffer);
11279
+ arrayMeta.lengthPack(view, arrayMeta.lengthOffset, length);
11280
+ }
11281
+ if (Object.keys(subBuffers).length > 0) {
11282
+ result.subBuffers = subBuffers;
11283
+ }
11284
+ }
11285
+ return result;
11286
+ }
11085
11287
  function alignOffset(offset, align) {
11086
11288
  return offset + (align - 1) & ~(align - 1);
11087
11289
  }
@@ -11105,9 +11307,48 @@ function defineEnum(mapping, base = "u32") {
11105
11307
  function isEnum(type) {
11106
11308
  return typeof type === "object" && type.__type === "enum";
11107
11309
  }
11310
+ function hasPlainPrimitiveRuntimeOptions(options) {
11311
+ return options.optional === true || options.unpackTransform !== undefined || options.packTransform !== undefined || options.lengthOf !== undefined || options.default !== undefined || options.validate !== undefined;
11312
+ }
11108
11313
  function isStruct(type) {
11109
11314
  return typeof type === "object" && type.__type === "struct";
11110
11315
  }
11316
+ var structInternals = new WeakMap;
11317
+ var freshPackBuffers = new WeakSet;
11318
+ function packInlineStruct(internals, view, baseOffset, obj, options) {
11319
+ let mappedObj = internals.options?.mapValue ? internals.options.mapValue(obj) : obj;
11320
+ if (internals.materializeArrayIterables)
11321
+ mappedObj = internals.materializeArrayIterables(mappedObj);
11322
+ for (const field of internals.layout) {
11323
+ const value = mappedObj[field.name] ?? field.default;
11324
+ if (!field.optional && value === undefined) {
11325
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11326
+ }
11327
+ if (field.validate) {
11328
+ for (const validateFn of field.validate) {
11329
+ validateFn(value, field.name, {
11330
+ hints: options?.validationHints,
11331
+ input: mappedObj
11332
+ });
11333
+ }
11334
+ }
11335
+ field.pack(view, baseOffset + field.offset, value, mappedObj, options);
11336
+ }
11337
+ }
11338
+ function unpackInlineStruct(internals, view, baseOffset) {
11339
+ const result = internals.options?.default ? { ...internals.options.default } : {};
11340
+ for (const field of internals.layout) {
11341
+ if (!field.unpack)
11342
+ continue;
11343
+ try {
11344
+ result[field.name] = field.unpack(view, baseOffset + field.offset);
11345
+ } catch (error) {
11346
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
11347
+ throw error;
11348
+ }
11349
+ }
11350
+ return internals.options?.reduceValue ? internals.options.reduceValue(result) : result;
11351
+ }
11111
11352
  function primitivePackers(type) {
11112
11353
  let pack;
11113
11354
  let unpack;
@@ -11157,23 +11398,254 @@ function primitivePackers(type) {
11157
11398
  unpack = (view, off) => view.getFloat64(off, true);
11158
11399
  break;
11159
11400
  case "pointer":
11160
- pack = (view, off, val) => {
11161
- pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11162
- };
11163
- unpack = (view, off) => {
11164
- if (pointerSize === 8) {
11165
- const value = view.getBigUint64(off, true);
11166
- return isBun2 ? Number(value) : value;
11167
- }
11168
- return view.getUint32(off, true);
11169
- };
11401
+ if (pointerSize === 8 && isBun2) {
11402
+ pack = (view, off, val) => {
11403
+ if (!val) {
11404
+ view.setUint32(off, 0, true);
11405
+ view.setUint32(off + 4, 0, true);
11406
+ } else if (typeof val === "number" && Number.isInteger(val)) {
11407
+ view.setUint32(off, val, true);
11408
+ view.setUint32(off + 4, Math.floor(val / 4294967296), true);
11409
+ } else {
11410
+ view.setBigUint64(off, BigInt(val), true);
11411
+ }
11412
+ };
11413
+ unpack = (view, off) => view.getUint32(off, true) + view.getUint32(off + 4, true) * 4294967296;
11414
+ } else {
11415
+ pack = (view, off, val) => {
11416
+ pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11417
+ };
11418
+ unpack = (view, off) => {
11419
+ if (pointerSize === 8) {
11420
+ const value = view.getBigUint64(off, true);
11421
+ return isBun2 ? Number(value) : value;
11422
+ }
11423
+ return view.getUint32(off, true);
11424
+ };
11425
+ }
11170
11426
  break;
11171
11427
  default:
11172
11428
  fatalError(`Unsupported primitive type: ${type}`);
11173
11429
  }
11174
11430
  return { pack, unpack };
11175
11431
  }
11432
+ function primitiveSetterSource(type, offset, value) {
11433
+ const target = `baseOffset + ${offset}`;
11434
+ switch (type) {
11435
+ case "u8":
11436
+ return `view.setUint8(${target}, ${value})`;
11437
+ case "bool_u8":
11438
+ return `view.setUint8(${target}, ${value} ? 1 : 0)`;
11439
+ case "bool_u32":
11440
+ return `view.setUint32(${target}, ${value} ? 1 : 0, true)`;
11441
+ case "u16":
11442
+ return `view.setUint16(${target}, ${value}, true)`;
11443
+ case "i16":
11444
+ return `view.setInt16(${target}, ${value}, true)`;
11445
+ case "u32":
11446
+ return `view.setUint32(${target}, ${value}, true)`;
11447
+ case "i32":
11448
+ return `view.setInt32(${target}, ${value}, true)`;
11449
+ case "i64":
11450
+ return `view.setBigInt64(${target}, BigInt(${value}), true)`;
11451
+ case "u64":
11452
+ return `view.setBigUint64(${target}, BigInt(${value}), true)`;
11453
+ case "f32":
11454
+ return `view.setFloat32(${target}, ${value}, true)`;
11455
+ case "f64":
11456
+ return `view.setFloat64(${target}, ${value}, true)`;
11457
+ }
11458
+ }
11459
+ function primitiveGetterSource(type, offset) {
11460
+ const target = `baseOffset + ${offset}`;
11461
+ switch (type) {
11462
+ case "u8":
11463
+ return `view.getUint8(${target})`;
11464
+ case "bool_u8":
11465
+ return `Boolean(view.getUint8(${target}))`;
11466
+ case "bool_u32":
11467
+ return `Boolean(view.getUint32(${target}, true))`;
11468
+ case "u16":
11469
+ return `view.getUint16(${target}, true)`;
11470
+ case "i16":
11471
+ return `view.getInt16(${target}, true)`;
11472
+ case "u32":
11473
+ return `view.getUint32(${target}, true)`;
11474
+ case "i32":
11475
+ return `view.getInt32(${target}, true)`;
11476
+ case "i64":
11477
+ return `view.getBigInt64(${target}, true)`;
11478
+ case "u64":
11479
+ return `view.getBigUint64(${target}, true)`;
11480
+ case "f32":
11481
+ return `view.getFloat32(${target}, true)`;
11482
+ case "f64":
11483
+ return `view.getFloat64(${target}, true)`;
11484
+ case "pointer":
11485
+ if (pointerSize === 8 && isBun2) {
11486
+ return `view.getUint32(${target}, true) + view.getUint32(${target} + 4, true) * 0x100000000`;
11487
+ }
11488
+ return pointerSize === 8 ? `view.getBigUint64(${target}, true)` : `view.getUint32(${target}, true)`;
11489
+ }
11490
+ }
11491
+ function compilePlainPrimitivePackList(fields, totalSize) {
11492
+ const writes = fields.map((field, index) => {
11493
+ const value = `value${index}`;
11494
+ const missing = `Packing non-optional field '${field.name}' at index `;
11495
+ return `
11496
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11497
+ if (${value} === undefined) fatalError(${JSON.stringify(missing)} + index + ${JSON.stringify(" but value is undefined (and no default provided)")})
11498
+ ${primitiveSetterSource(field.type, field.offset, value)}
11499
+ `;
11500
+ }).join(`
11501
+ `);
11502
+ return new Function("fatalError", `return function packPlainPrimitiveList(objects) {
11503
+ const buffer = new ArrayBuffer(${totalSize} * objects.length)
11504
+ const view = new DataView(buffer)
11505
+ for (let index = 0, baseOffset = 0; index < objects.length; index++, baseOffset += ${totalSize}) {
11506
+ const obj = objects[index]
11507
+ ${writes}
11508
+ }
11509
+ return buffer
11510
+ }`)(fatalError);
11511
+ }
11512
+ function compilePlainPrimitivePack(fields, totalSize) {
11513
+ const writes = fields.map((field, index) => {
11514
+ const value = `value${index}`;
11515
+ return `
11516
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11517
+ if (${value} === undefined) fatalError(${JSON.stringify(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`)})
11518
+ ${primitiveSetterSource(field.type, field.offset, value)}
11519
+ `;
11520
+ }).join(`
11521
+ `);
11522
+ return new Function("fatalError", `return function packPlainPrimitive(obj) {
11523
+ const buffer = new ArrayBuffer(${totalSize})
11524
+ const view = new DataView(buffer)
11525
+ let baseOffset = 0
11526
+ ${writes}
11527
+ return buffer
11528
+ }`)(fatalError);
11529
+ }
11530
+ function compilePlainPrimitivePackInto(fields) {
11531
+ const writes = fields.map((field, index) => {
11532
+ const value = `value${index}`;
11533
+ return `
11534
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11535
+ if (${value} === undefined) {
11536
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11537
+ }
11538
+ ${primitiveSetterSource(field.type, field.offset, value)}
11539
+ `;
11540
+ }).join(`
11541
+ `);
11542
+ return new Function(`return function packPlainPrimitiveInto(obj, view, baseOffset) {
11543
+ ${writes}
11544
+ }`)();
11545
+ }
11546
+ function compilePlainPrimitivePackListInto(fields, totalSize) {
11547
+ const writes = fields.map((field, index) => {
11548
+ const value = `value${index}`;
11549
+ return `
11550
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11551
+ if (${value} === undefined) {
11552
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11553
+ }
11554
+ ${primitiveSetterSource(field.type, field.offset, value)}
11555
+ `;
11556
+ }).join(`
11557
+ `);
11558
+ return new Function(`return function packPlainPrimitiveListInto(objects, view, initialOffset) {
11559
+ for (let index = 0, baseOffset = initialOffset; index < objects.length; index++, baseOffset += ${totalSize}) {
11560
+ const obj = objects[index]
11561
+ ${writes}
11562
+ }
11563
+ }`)();
11564
+ }
11565
+ function compilePlainPrimitiveUnpackList(fields, totalSize) {
11566
+ const reads = fields.map((field, index) => `
11567
+ let value${index}
11568
+ try {
11569
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11570
+ } catch (error) {
11571
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11572
+ throw error
11573
+ }
11574
+ `).join(`
11575
+ `);
11576
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11577
+ return new Function(`return function unpackPlainPrimitiveList(view, count) {
11578
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11579
+ const results = preallocated ? new Array(count) : []
11580
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11581
+ ${reads}
11582
+ const value = { ${properties} }
11583
+ if (preallocated) results[index] = value
11584
+ else results.push(value)
11585
+ }
11586
+ return results
11587
+ }`)();
11588
+ }
11589
+ function compileReducedPrimitiveUnpackList(fields, totalSize, options) {
11590
+ const reads = fields.map((field, index) => `
11591
+ let value${index}
11592
+ try {
11593
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11594
+ } catch (error) {
11595
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11596
+ throw error
11597
+ }
11598
+ `).join(`
11599
+ `);
11600
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11601
+ return new Function("options", `return function unpackReducedPrimitiveList(view, count) {
11602
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11603
+ const results = preallocated ? new Array(count) : []
11604
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11605
+ ${reads}
11606
+ const raw = { ${properties} }
11607
+ const value = options.reduceValue ? options.reduceValue(raw) : raw
11608
+ if (preallocated) results[index] = value
11609
+ else results.push(value)
11610
+ }
11611
+ return results
11612
+ }`)(options);
11613
+ }
11614
+ function compilePlainPrimitiveUnpack(fields) {
11615
+ const reads = fields.map((field, index) => `
11616
+ let value${index}
11617
+ try {
11618
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11619
+ } catch (error) {
11620
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11621
+ throw error
11622
+ }
11623
+ `).join(`
11624
+ `);
11625
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11626
+ return new Function(`return function unpackPlainPrimitive(view) {
11627
+ let baseOffset = 0
11628
+ ${reads}
11629
+ return { ${properties} }
11630
+ }`)();
11631
+ }
11632
+ function compilePlainPrimitiveUnpackInto(fields) {
11633
+ const reads = fields.map((field) => `
11634
+ try {
11635
+ target[${JSON.stringify(field.name)}] = ${primitiveGetterSource(field.type, field.offset)}
11636
+ } catch (error) {
11637
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11638
+ throw error
11639
+ }
11640
+ `).join(`
11641
+ `);
11642
+ return new Function(`return function unpackPlainPrimitiveInto(view, target, baseOffset) {
11643
+ ${reads}
11644
+ return target
11645
+ }`)();
11646
+ }
11176
11647
  var { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers("pointer");
11648
+ var foreignMemoryPointerUnpacker = pointerSize === 8 && isBun2 ? (view, off) => Number(view.getBigUint64(off, true)) : pointerUnpacker;
11177
11649
  var retainedPointerTargets = new WeakMap;
11178
11650
  function retainPointerTarget(owner, target) {
11179
11651
  const retained = retainedPointerTargets.get(owner);
@@ -11184,9 +11656,8 @@ function retainPointerTarget(owner, target) {
11184
11656
  }
11185
11657
  }
11186
11658
  function retainIfPointerTargets(owner, target) {
11187
- if (retainedPointerTargets.has(target)) {
11659
+ if (retainedPointerTargets.has(target))
11188
11660
  retainPointerTarget(owner, target);
11189
- }
11190
11661
  }
11191
11662
  function isNullPointer(pointer) {
11192
11663
  return pointer == null || pointer === 0 || pointer === 0n;
@@ -11194,6 +11665,9 @@ function isNullPointer(pointer) {
11194
11665
  function toItemCount(length) {
11195
11666
  return typeof length === "bigint" ? Number(length) : length;
11196
11667
  }
11668
+ var arrayPreallocationThreshold = 256;
11669
+ var plainPrimitiveSpecializationThreshold = 256;
11670
+ var maxArrayLength = 4294967295;
11197
11671
  function packObjectArray(val) {
11198
11672
  const buffer = new ArrayBuffer(val.length * pointerSize);
11199
11673
  const bufferView = new DataView(buffer);
@@ -11209,10 +11683,15 @@ var decoder = new TextDecoder;
11209
11683
  function defineStruct(fields, structDefOptions) {
11210
11684
  let offset = 0;
11211
11685
  let maxAlign = 1;
11686
+ let hasDirectInlinePack = false;
11687
+ let directInlineUnpackSafe = !structDefOptions?.default && !structDefOptions?.reduceValue;
11688
+ let plainPrimitiveFields = structDefOptions?.mapValue || structDefOptions?.default || structDefOptions?.reduceValue ? null : [];
11689
+ let primitiveDecodeFields = structDefOptions?.reduceValue && !structDefOptions.default ? [] : null;
11212
11690
  const layout = [];
11213
11691
  const lengthOfFields = {};
11214
11692
  const lengthOfRequested = [];
11215
11693
  const arrayFieldsMetadata = {};
11694
+ const arrayElementSizes = {};
11216
11695
  for (const [name, typeOrStruct, options = {}] of fields) {
11217
11696
  if (options.condition && !options.condition()) {
11218
11697
  continue;
@@ -11222,6 +11701,7 @@ function defineStruct(fields, structDefOptions) {
11222
11701
  let unpack;
11223
11702
  let needsLengthOf = false;
11224
11703
  let lengthOfDef = null;
11704
+ let plainPrimitiveType = null;
11225
11705
  if (isPrimitiveType(typeOrStruct)) {
11226
11706
  size = typeSizes[typeOrStruct];
11227
11707
  align = typeAlignments[typeOrStruct];
@@ -11240,7 +11720,14 @@ function defineStruct(fields, structDefOptions) {
11240
11720
  pointerPacker(view, off, val);
11241
11721
  };
11242
11722
  }
11723
+ if (plainPrimitiveFields) {
11724
+ if (typeOrStruct === "pointer" || hasPlainPrimitiveRuntimeOptions(options))
11725
+ plainPrimitiveFields = null;
11726
+ else
11727
+ plainPrimitiveType = typeOrStruct;
11728
+ }
11243
11729
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") {
11730
+ plainPrimitiveFields = null;
11244
11731
  size = pointerSize;
11245
11732
  align = pointerSize;
11246
11733
  pack = (view, off, val) => {
@@ -11258,6 +11745,7 @@ function defineStruct(fields, structDefOptions) {
11258
11745
  return ptrVal;
11259
11746
  };
11260
11747
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "char*") {
11748
+ plainPrimitiveFields = null;
11261
11749
  size = pointerSize;
11262
11750
  align = pointerSize;
11263
11751
  pack = (view, off, val) => {
@@ -11276,6 +11764,8 @@ function defineStruct(fields, structDefOptions) {
11276
11764
  };
11277
11765
  needsLengthOf = true;
11278
11766
  } else if (isEnum(typeOrStruct)) {
11767
+ plainPrimitiveFields = null;
11768
+ directInlineUnpackSafe = false;
11279
11769
  const base = typeOrStruct.type;
11280
11770
  size = typeSizes[base];
11281
11771
  align = typeAlignments[base];
@@ -11289,7 +11779,9 @@ function defineStruct(fields, structDefOptions) {
11289
11779
  return typeOrStruct.from(raw);
11290
11780
  };
11291
11781
  } else if (isStruct(typeOrStruct)) {
11782
+ plainPrimitiveFields = null;
11292
11783
  if (options.asPointer === true) {
11784
+ directInlineUnpackSafe = false;
11293
11785
  size = pointerSize;
11294
11786
  align = pointerSize;
11295
11787
  pack = (view, off, val, obj, options2) => {
@@ -11307,19 +11799,33 @@ function defineStruct(fields, structDefOptions) {
11307
11799
  } else {
11308
11800
  size = typeOrStruct.size;
11309
11801
  align = typeOrStruct.align;
11310
- pack = (view, off, val, obj, options2) => {
11311
- const nestedBuf = typeOrStruct.pack(val, options2);
11802
+ const internals = structInternals.get(typeOrStruct);
11803
+ directInlineUnpackSafe &&= !!internals?.directInlineUnpackSafe;
11804
+ hasDirectInlinePack ||= !!internals && !options.optional;
11805
+ pack = (view, off, val, obj, packOptions) => {
11806
+ const publicPack = typeOrStruct.pack;
11807
+ if (internals && freshPackBuffers.has(view.buffer) && publicPack === internals.publicPack) {
11808
+ packInlineStruct(internals, view, off, val, packOptions);
11809
+ return;
11810
+ }
11811
+ const nestedBuf = Reflect.apply(publicPack, typeOrStruct, [val, packOptions]);
11312
11812
  const nestedView = new Uint8Array(nestedBuf);
11313
- const dView = new Uint8Array(view.buffer);
11813
+ const dView = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
11314
11814
  dView.set(nestedView, off);
11315
11815
  retainIfPointerTargets(view.buffer, nestedBuf);
11316
11816
  };
11317
11817
  unpack = (view, off) => {
11318
- const slice = view.buffer.slice(off, off + size);
11818
+ const publicUnpack = Object.getOwnPropertyDescriptor(typeOrStruct, "unpack")?.value;
11819
+ if (internals?.directInlineUnpackSafe && publicUnpack === internals.publicUnpack && !(view.buffer instanceof SharedArrayBuffer)) {
11820
+ return unpackInlineStruct(internals, view, off);
11821
+ }
11822
+ const start = view.byteOffset + off;
11823
+ const slice = view.buffer.slice(start, start + size);
11319
11824
  return typeOrStruct.unpack(slice);
11320
11825
  };
11321
11826
  }
11322
11827
  } else if (isObjectPointerDef(typeOrStruct)) {
11828
+ plainPrimitiveFields = null;
11323
11829
  size = pointerSize;
11324
11830
  align = pointerSize;
11325
11831
  pack = (view, off, value) => {
@@ -11335,12 +11841,15 @@ function defineStruct(fields, structDefOptions) {
11335
11841
  return pointerUnpacker(view, off);
11336
11842
  };
11337
11843
  } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) {
11844
+ plainPrimitiveFields = null;
11338
11845
  const [def] = typeOrStruct;
11339
11846
  size = pointerSize;
11340
11847
  align = pointerSize;
11341
11848
  let arrayElementSize;
11342
11849
  if (isEnum(def)) {
11850
+ directInlineUnpackSafe = false;
11343
11851
  arrayElementSize = typeSizes[def.type];
11852
+ const { pack: enumPack } = primitivePackers(def.type);
11344
11853
  pack = (view, off, val, obj) => {
11345
11854
  if (!val || val.length === 0) {
11346
11855
  pointerPacker(view, off, null);
@@ -11350,7 +11859,7 @@ function defineStruct(fields, structDefOptions) {
11350
11859
  const bufferView = new DataView(buffer);
11351
11860
  for (let i = 0;i < val.length; i++) {
11352
11861
  const num = def.to(val[i]);
11353
- bufferView.setUint32(i * arrayElementSize, num, true);
11862
+ enumPack(bufferView, i * arrayElementSize, num);
11354
11863
  }
11355
11864
  pointerPacker(view, off, ptr2(buffer));
11356
11865
  retainPointerTarget(view.buffer, buffer);
@@ -11359,7 +11868,9 @@ function defineStruct(fields, structDefOptions) {
11359
11868
  needsLengthOf = true;
11360
11869
  lengthOfDef = def;
11361
11870
  } else if (isStruct(def)) {
11871
+ directInlineUnpackSafe = false;
11362
11872
  arrayElementSize = def.size;
11873
+ const defInternals = structInternals.get(def);
11363
11874
  pack = (view, off, val, obj, options2) => {
11364
11875
  if (!val || val.length === 0) {
11365
11876
  pointerPacker(view, off, null);
@@ -11367,8 +11878,19 @@ function defineStruct(fields, structDefOptions) {
11367
11878
  }
11368
11879
  const buffer = new ArrayBuffer(val.length * arrayElementSize);
11369
11880
  const bufferView = new DataView(buffer);
11370
- for (let i = 0;i < val.length; i++) {
11371
- def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11881
+ if (defInternals?.hasDirectInlinePack) {
11882
+ freshPackBuffers.add(buffer);
11883
+ try {
11884
+ for (let i = 0;i < val.length; i++) {
11885
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11886
+ }
11887
+ } finally {
11888
+ freshPackBuffers.delete(buffer);
11889
+ }
11890
+ } else {
11891
+ for (let i = 0;i < val.length; i++) {
11892
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11893
+ }
11372
11894
  }
11373
11895
  pointerPacker(view, off, ptr2(buffer));
11374
11896
  retainPointerTarget(view.buffer, buffer);
@@ -11396,6 +11918,7 @@ function defineStruct(fields, structDefOptions) {
11396
11918
  needsLengthOf = true;
11397
11919
  lengthOfDef = def;
11398
11920
  } else if (isObjectPointerDef(def)) {
11921
+ directInlineUnpackSafe = false;
11399
11922
  arrayElementSize = pointerSize;
11400
11923
  pack = (view, off, val) => {
11401
11924
  if (!val || val.length === 0) {
@@ -11412,21 +11935,23 @@ function defineStruct(fields, structDefOptions) {
11412
11935
  } else {
11413
11936
  throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`);
11414
11937
  }
11415
- const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name);
11416
- if (lengthOfField && isPrimitiveType(lengthOfField.type)) {
11417
- const { pack: lengthPack } = primitivePackers(lengthOfField.type);
11418
- arrayFieldsMetadata[name] = {
11419
- elementSize: arrayElementSize,
11420
- arrayOffset: offset,
11421
- lengthOffset: lengthOfField.offset,
11422
- lengthPack
11423
- };
11424
- }
11938
+ arrayElementSizes[name] = arrayElementSize;
11425
11939
  } else {
11426
11940
  throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`);
11427
11941
  }
11428
11942
  offset = alignOffset(offset, align);
11943
+ if (plainPrimitiveFields && plainPrimitiveType) {
11944
+ plainPrimitiveFields.push({ name, offset, type: plainPrimitiveType });
11945
+ }
11946
+ if (primitiveDecodeFields) {
11947
+ if (isPrimitiveType(typeOrStruct) && !options.unpackTransform) {
11948
+ primitiveDecodeFields.push({ name, offset, type: typeOrStruct });
11949
+ } else {
11950
+ primitiveDecodeFields = null;
11951
+ }
11952
+ }
11429
11953
  if (options.unpackTransform) {
11954
+ directInlineUnpackSafe = false;
11430
11955
  const originalUnpack = unpack;
11431
11956
  unpack = (view, off) => options.unpackTransform(originalUnpack(view, off));
11432
11957
  }
@@ -11475,6 +12000,7 @@ function defineStruct(fields, structDefOptions) {
11475
12000
  default: options.default,
11476
12001
  pack,
11477
12002
  unpack,
12003
+ unpackTransform: options.unpackTransform,
11478
12004
  type: typeOrStruct,
11479
12005
  lengthOf: options.lengthOf
11480
12006
  };
@@ -11491,6 +12017,19 @@ function defineStruct(fields, structDefOptions) {
11491
12017
  offset += size;
11492
12018
  maxAlign = Math.max(maxAlign, align);
11493
12019
  }
12020
+ for (const [arrayName, lengthOfField] of Object.entries(lengthOfFields)) {
12021
+ const arrayField = layout.find((field) => field.name === arrayName);
12022
+ const elementSize = arrayElementSizes[arrayName];
12023
+ if (!arrayField || elementSize === undefined || !isPrimitiveType(lengthOfField.type))
12024
+ continue;
12025
+ const { pack: lengthPack } = primitivePackers(lengthOfField.type);
12026
+ arrayFieldsMetadata[arrayName] = {
12027
+ elementSize,
12028
+ arrayOffset: arrayField.offset,
12029
+ lengthOffset: lengthOfField.offset,
12030
+ lengthPack
12031
+ };
12032
+ }
11494
12033
  for (const { requester, def } of lengthOfRequested) {
11495
12034
  const lengthOfField = lengthOfFields[requester.name];
11496
12035
  if (!lengthOfField) {
@@ -11502,7 +12041,7 @@ function defineStruct(fields, structDefOptions) {
11502
12041
  if (def === "char*") {
11503
12042
  const relativeOffset = lengthOfField.offset - requester.offset;
11504
12043
  requester.unpack = (view, off) => {
11505
- const ptrAddress = pointerUnpacker(view, off);
12044
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11506
12045
  const length = lengthOfField.unpack(view, off + relativeOffset);
11507
12046
  if (isNullPointer(ptrAddress)) {
11508
12047
  return null;
@@ -11519,10 +12058,9 @@ function defineStruct(fields, structDefOptions) {
11519
12058
  const { unpack: primitiveUnpack } = primitivePackers(def);
11520
12059
  const relativeOffset = lengthOfField.offset - requester.offset;
11521
12060
  requester.unpack = (view, off) => {
11522
- const result = [];
11523
12061
  const length = lengthOfField.unpack(view, off + relativeOffset);
11524
12062
  const itemCount = toItemCount(length);
11525
- const ptrAddress = pointerUnpacker(view, off);
12063
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11526
12064
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11527
12065
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11528
12066
  }
@@ -11531,19 +12069,26 @@ function defineStruct(fields, structDefOptions) {
11531
12069
  }
11532
12070
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11533
12071
  const bufferView = new DataView(buffer);
11534
- for (let i = 0;i < itemCount; i++) {
11535
- result.push(primitiveUnpack(bufferView, i * elemSize));
12072
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12073
+ const result2 = new Array(itemCount);
12074
+ for (let i = 0;i < itemCount; i++) {
12075
+ result2[i] = primitiveUnpack(bufferView, i * elemSize);
12076
+ }
12077
+ return result2;
11536
12078
  }
12079
+ const result = [];
12080
+ for (let i = 0;i < itemCount; i++)
12081
+ result.push(primitiveUnpack(bufferView, i * elemSize));
11537
12082
  return result;
11538
12083
  };
11539
12084
  } else {
11540
- const elemSize = def.type === "u32" ? 4 : 8;
12085
+ const elemSize = typeSizes[def.type];
12086
+ const { unpack: enumUnpack } = primitivePackers(def.type);
11541
12087
  const relativeOffset = lengthOfField.offset - requester.offset;
11542
12088
  requester.unpack = (view, off) => {
11543
- const result = [];
11544
12089
  const length = lengthOfField.unpack(view, off + relativeOffset);
11545
12090
  const itemCount = toItemCount(length);
11546
- const ptrAddress = pointerUnpacker(view, off);
12091
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11547
12092
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11548
12093
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11549
12094
  }
@@ -11552,12 +12097,23 @@ function defineStruct(fields, structDefOptions) {
11552
12097
  }
11553
12098
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11554
12099
  const bufferView = new DataView(buffer);
11555
- for (let i = 0;i < itemCount; i++) {
11556
- result.push(def.from(bufferView.getUint32(i * elemSize, true)));
12100
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12101
+ const result2 = new Array(itemCount);
12102
+ for (let i = 0;i < itemCount; i++) {
12103
+ result2[i] = def.from(enumUnpack(bufferView, i * elemSize));
12104
+ }
12105
+ return result2;
11557
12106
  }
12107
+ const result = [];
12108
+ for (let i = 0;i < itemCount; i++)
12109
+ result.push(def.from(enumUnpack(bufferView, i * elemSize)));
11558
12110
  return result;
11559
12111
  };
11560
12112
  }
12113
+ if (requester.unpackTransform) {
12114
+ const originalUnpack = requester.unpack;
12115
+ requester.unpack = (view, off) => requester.unpackTransform(originalUnpack(view, off));
12116
+ }
11561
12117
  }
11562
12118
  const totalSize = alignOffset(offset, maxAlign);
11563
12119
  const description = layout.map((f) => ({
@@ -11571,7 +12127,87 @@ function defineStruct(fields, structDefOptions) {
11571
12127
  }));
11572
12128
  const layoutByName = new Map(description.map((f) => [f.name, f]));
11573
12129
  const arrayFields = new Map(Object.entries(arrayFieldsMetadata));
11574
- return {
12130
+ const iterableArrayFields = layout.filter((field) => Array.isArray(field.type));
12131
+ if (plainPrimitiveFields?.length !== layout.length || plainPrimitiveFields.length === 0)
12132
+ plainPrimitiveFields = null;
12133
+ const supportsPackListInto = !!plainPrimitiveFields;
12134
+ if (primitiveDecodeFields?.length !== layout.length || primitiveDecodeFields.length === 0) {
12135
+ primitiveDecodeFields = null;
12136
+ }
12137
+ let plainPrimitivePackList;
12138
+ let plainPrimitiveUnpackList;
12139
+ let reducedPrimitiveUnpackList;
12140
+ let plainPrimitivePack;
12141
+ let plainPrimitivePackInto;
12142
+ let plainPrimitivePackListInto;
12143
+ let plainPrimitiveUnpack;
12144
+ let plainPrimitiveUnpackInto;
12145
+ let plainPrimitivePackListItems = 0;
12146
+ let plainPrimitivePackListIntoItems = 0;
12147
+ let plainPrimitiveUnpackListItems = 0;
12148
+ let reducedPrimitiveUnpackListItems = 0;
12149
+ let plainPrimitivePackCalls = 0;
12150
+ let plainPrimitivePackIntoCalls = 0;
12151
+ let plainPrimitiveUnpackCalls = 0;
12152
+ let plainPrimitiveUnpackIntoCalls = 0;
12153
+ const compilePlainPrimitive = (compile) => {
12154
+ try {
12155
+ return compile();
12156
+ } catch (error) {
12157
+ if (!(error instanceof EvalError))
12158
+ throw error;
12159
+ plainPrimitiveFields = null;
12160
+ primitiveDecodeFields = null;
12161
+ return;
12162
+ }
12163
+ };
12164
+ const validateDecodeRange = (view, decodeOffset) => {
12165
+ if (!Number.isSafeInteger(decodeOffset) || decodeOffset < 0) {
12166
+ throw new RangeError(`Decode offset must be a non-negative safe integer, got ${decodeOffset}`);
12167
+ }
12168
+ if (decodeOffset > view.byteLength - totalSize) {
12169
+ throw new RangeError(`DataView range (${view.byteLength} bytes) is too small for a struct at offset ${decodeOffset}`);
12170
+ }
12171
+ };
12172
+ const decodeFieldsInto = (target, view, baseOffset) => {
12173
+ if (structDefOptions?.default)
12174
+ Object.assign(target, structDefOptions.default);
12175
+ for (const field of layout) {
12176
+ if (!field.unpack)
12177
+ continue;
12178
+ try {
12179
+ target[field.name] = field.unpack(view, baseOffset + field.offset);
12180
+ } catch (error) {
12181
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
12182
+ throw error;
12183
+ }
12184
+ }
12185
+ };
12186
+ const unpackInto = (view, target, decodeOffset = 0) => {
12187
+ validateDecodeRange(view, decodeOffset);
12188
+ if (plainPrimitiveFields && (plainPrimitiveUnpackInto || ++plainPrimitiveUnpackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12189
+ plainPrimitiveUnpackInto ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackInto(plainPrimitiveFields));
12190
+ if (plainPrimitiveUnpackInto)
12191
+ return plainPrimitiveUnpackInto(view, target, decodeOffset);
12192
+ }
12193
+ decodeFieldsInto(target, view, decodeOffset);
12194
+ return target;
12195
+ };
12196
+ const materializeArrayIterables = iterableArrayFields.length === 0 ? null : (obj) => {
12197
+ let normalized = obj;
12198
+ for (const field of iterableArrayFields) {
12199
+ const value = obj[field.name];
12200
+ if (value == null || Array.isArray(value) || ArrayBuffer.isView(value))
12201
+ continue;
12202
+ if (typeof value[Symbol.iterator] !== "function")
12203
+ continue;
12204
+ if (normalized === obj)
12205
+ normalized = { ...obj };
12206
+ normalized[field.name] = Array.from(value);
12207
+ }
12208
+ return normalized;
12209
+ };
12210
+ const definition = {
11575
12211
  __type: "struct",
11576
12212
  size: totalSize,
11577
12213
  align: maxAlign,
@@ -11579,34 +12215,57 @@ function defineStruct(fields, structDefOptions) {
11579
12215
  layoutByName,
11580
12216
  arrayFields,
11581
12217
  pack(obj, options) {
12218
+ if (plainPrimitiveFields && (plainPrimitivePack || ++plainPrimitivePackCalls >= plainPrimitiveSpecializationThreshold)) {
12219
+ plainPrimitivePack ??= compilePlainPrimitive(() => compilePlainPrimitivePack(plainPrimitiveFields, totalSize));
12220
+ if (plainPrimitivePack)
12221
+ return plainPrimitivePack(obj);
12222
+ }
11582
12223
  const buf = new ArrayBuffer(totalSize);
11583
12224
  const view = new DataView(buf);
11584
12225
  let mappedObj = obj;
11585
12226
  if (structDefOptions?.mapValue) {
11586
12227
  mappedObj = structDefOptions.mapValue(obj);
11587
12228
  }
11588
- for (const field of layout) {
11589
- const value = mappedObj[field.name] ?? field.default;
11590
- if (!field.optional && value === undefined) {
11591
- fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11592
- }
11593
- if (field.validate) {
11594
- for (const validateFn of field.validate) {
11595
- validateFn(value, field.name, {
11596
- hints: options?.validationHints,
11597
- input: mappedObj
11598
- });
12229
+ if (materializeArrayIterables)
12230
+ mappedObj = materializeArrayIterables(mappedObj);
12231
+ if (hasDirectInlinePack)
12232
+ freshPackBuffers.add(buf);
12233
+ try {
12234
+ for (const field of layout) {
12235
+ const value = mappedObj[field.name] ?? field.default;
12236
+ if (!field.optional && value === undefined) {
12237
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11599
12238
  }
12239
+ if (field.validate) {
12240
+ for (const validateFn of field.validate) {
12241
+ validateFn(value, field.name, {
12242
+ hints: options?.validationHints,
12243
+ input: mappedObj
12244
+ });
12245
+ }
12246
+ }
12247
+ field.pack(view, field.offset, value, mappedObj, options);
11600
12248
  }
11601
- field.pack(view, field.offset, value, mappedObj, options);
12249
+ } finally {
12250
+ if (hasDirectInlinePack)
12251
+ freshPackBuffers.delete(buf);
11602
12252
  }
11603
12253
  return view.buffer;
11604
12254
  },
11605
12255
  packInto(obj, view, offset2, options) {
12256
+ if (plainPrimitiveFields && (plainPrimitivePackInto || ++plainPrimitivePackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12257
+ plainPrimitivePackInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackInto(plainPrimitiveFields));
12258
+ if (plainPrimitivePackInto) {
12259
+ plainPrimitivePackInto(obj, view, offset2);
12260
+ return;
12261
+ }
12262
+ }
11606
12263
  let mappedObj = obj;
11607
12264
  if (structDefOptions?.mapValue) {
11608
12265
  mappedObj = structDefOptions.mapValue(obj);
11609
12266
  }
12267
+ if (materializeArrayIterables)
12268
+ mappedObj = materializeArrayIterables(mappedObj);
11610
12269
  for (const field of layout) {
11611
12270
  const value = mappedObj[field.name] ?? field.default;
11612
12271
  if (!field.optional && value === undefined) {
@@ -11628,6 +12287,11 @@ function defineStruct(fields, structDefOptions) {
11628
12287
  fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`);
11629
12288
  }
11630
12289
  const view = new DataView(buf);
12290
+ if (plainPrimitiveFields && (plainPrimitiveUnpack || ++plainPrimitiveUnpackCalls >= plainPrimitiveSpecializationThreshold)) {
12291
+ plainPrimitiveUnpack ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpack(plainPrimitiveFields));
12292
+ if (plainPrimitiveUnpack)
12293
+ return plainPrimitiveUnpack(view);
12294
+ }
11631
12295
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
11632
12296
  for (const field of layout) {
11633
12297
  if (!field.unpack) {
@@ -11649,31 +12313,67 @@ function defineStruct(fields, structDefOptions) {
11649
12313
  if (objects.length === 0) {
11650
12314
  return new ArrayBuffer(0);
11651
12315
  }
12316
+ if (plainPrimitiveFields) {
12317
+ plainPrimitivePackListItems += objects.length;
12318
+ if (plainPrimitivePackList || objects.length > 1 && plainPrimitivePackListItems >= plainPrimitiveSpecializationThreshold) {
12319
+ plainPrimitivePackList ??= compilePlainPrimitive(() => compilePlainPrimitivePackList(plainPrimitiveFields, totalSize));
12320
+ if (plainPrimitivePackList)
12321
+ return plainPrimitivePackList(objects);
12322
+ }
12323
+ }
11652
12324
  const buffer = new ArrayBuffer(totalSize * objects.length);
11653
12325
  const view = new DataView(buffer);
11654
- for (let i = 0;i < objects.length; i++) {
11655
- let mappedObj = objects[i];
11656
- if (structDefOptions?.mapValue) {
11657
- mappedObj = structDefOptions.mapValue(objects[i]);
11658
- }
11659
- for (const field of layout) {
11660
- const value = mappedObj[field.name] ?? field.default;
11661
- if (!field.optional && value === undefined) {
11662
- fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
12326
+ if (hasDirectInlinePack)
12327
+ freshPackBuffers.add(buffer);
12328
+ try {
12329
+ for (let i = 0;i < objects.length; i++) {
12330
+ let mappedObj = objects[i];
12331
+ if (structDefOptions?.mapValue) {
12332
+ mappedObj = structDefOptions.mapValue(objects[i]);
11663
12333
  }
11664
- if (field.validate) {
11665
- for (const validateFn of field.validate) {
11666
- validateFn(value, field.name, {
11667
- hints: options?.validationHints,
11668
- input: mappedObj
11669
- });
12334
+ if (materializeArrayIterables)
12335
+ mappedObj = materializeArrayIterables(mappedObj);
12336
+ for (const field of layout) {
12337
+ const value = mappedObj[field.name] ?? field.default;
12338
+ if (!field.optional && value === undefined) {
12339
+ fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
12340
+ }
12341
+ if (field.validate) {
12342
+ for (const validateFn of field.validate) {
12343
+ validateFn(value, field.name, {
12344
+ hints: options?.validationHints,
12345
+ input: mappedObj
12346
+ });
12347
+ }
11670
12348
  }
12349
+ field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11671
12350
  }
11672
- field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11673
12351
  }
12352
+ } finally {
12353
+ if (hasDirectInlinePack)
12354
+ freshPackBuffers.delete(buffer);
11674
12355
  }
11675
12356
  return buffer;
11676
12357
  },
12358
+ packListInto(objects, view, offset2, options) {
12359
+ if (objects.length === 0)
12360
+ return;
12361
+ if (!supportsPackListInto)
12362
+ throw new Error("packListInto only supports required primitive fields");
12363
+ if (plainPrimitiveFields) {
12364
+ plainPrimitivePackListIntoItems += objects.length;
12365
+ if (plainPrimitivePackListInto || objects.length > 1 && plainPrimitivePackListIntoItems >= plainPrimitiveSpecializationThreshold) {
12366
+ plainPrimitivePackListInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackListInto(plainPrimitiveFields, totalSize));
12367
+ if (plainPrimitivePackListInto) {
12368
+ plainPrimitivePackListInto(objects, view, offset2);
12369
+ return;
12370
+ }
12371
+ }
12372
+ }
12373
+ for (let index = 0;index < objects.length; index += 1) {
12374
+ definition.packInto(objects[index], view, offset2 + index * totalSize, options);
12375
+ }
12376
+ },
11677
12377
  unpackList(buf, count) {
11678
12378
  if (count === 0) {
11679
12379
  return [];
@@ -11683,7 +12383,24 @@ function defineStruct(fields, structDefOptions) {
11683
12383
  fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`);
11684
12384
  }
11685
12385
  const view = new DataView(buf);
11686
- const results = [];
12386
+ if (plainPrimitiveFields && Number.isSafeInteger(count) && count > 1) {
12387
+ plainPrimitiveUnpackListItems += count;
12388
+ if (plainPrimitiveUnpackList || plainPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12389
+ plainPrimitiveUnpackList ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackList(plainPrimitiveFields, totalSize));
12390
+ if (plainPrimitiveUnpackList)
12391
+ return plainPrimitiveUnpackList(view, count);
12392
+ }
12393
+ }
12394
+ if (!plainPrimitiveFields && primitiveDecodeFields && Number.isSafeInteger(count) && count > 1) {
12395
+ reducedPrimitiveUnpackListItems += count;
12396
+ if (reducedPrimitiveUnpackList || reducedPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12397
+ reducedPrimitiveUnpackList ??= compilePlainPrimitive(() => compileReducedPrimitiveUnpackList(primitiveDecodeFields, totalSize, structDefOptions));
12398
+ if (reducedPrimitiveUnpackList)
12399
+ return reducedPrimitiveUnpackList(view, count);
12400
+ }
12401
+ }
12402
+ const preallocated = Number.isSafeInteger(count) && count >= arrayPreallocationThreshold && count <= maxArrayLength;
12403
+ const results = preallocated ? new Array(count) : [];
11687
12404
  for (let i = 0;i < count; i++) {
11688
12405
  const offset2 = i * totalSize;
11689
12406
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
@@ -11699,9 +12416,16 @@ function defineStruct(fields, structDefOptions) {
11699
12416
  }
11700
12417
  }
11701
12418
  if (structDefOptions?.reduceValue) {
11702
- results.push(structDefOptions.reduceValue(result));
12419
+ const value = structDefOptions.reduceValue(result);
12420
+ if (preallocated)
12421
+ results[i] = value;
12422
+ else
12423
+ results.push(value);
11703
12424
  } else {
11704
- results.push(result);
12425
+ if (preallocated)
12426
+ results[i] = result;
12427
+ else
12428
+ results.push(result);
11705
12429
  }
11706
12430
  }
11707
12431
  return results;
@@ -11710,6 +12434,18 @@ function defineStruct(fields, structDefOptions) {
11710
12434
  return description;
11711
12435
  }
11712
12436
  };
12437
+ if (!structDefOptions?.reduceValue)
12438
+ Object.assign(definition, { unpackInto });
12439
+ structInternals.set(definition, {
12440
+ layout,
12441
+ options: structDefOptions,
12442
+ publicPack: definition.pack,
12443
+ publicUnpack: definition.unpack,
12444
+ hasDirectInlinePack,
12445
+ directInlineUnpackSafe,
12446
+ materializeArrayIterables
12447
+ });
12448
+ return definition;
11713
12449
  }
11714
12450
 
11715
12451
  // src/zig-structs.ts
@@ -11780,6 +12516,7 @@ var VisualCursorStruct = defineStruct([
11780
12516
  var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
11781
12517
  var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8");
11782
12518
  var Osc52SupportEnum = defineEnum({ unknown: 0, supported: 1, unsupported: 2 }, "u8");
12519
+ var ImageProtocolEnum = defineEnum({ auto: 0, kitty: 1, sixel: 2, blocks: 3 }, "u8");
11783
12520
  var TerminalCapabilitiesStruct = defineStruct([
11784
12521
  ["kitty_keyboard", "bool_u8"],
11785
12522
  ["kitty_graphics", "bool_u8"],
@@ -11800,6 +12537,7 @@ var TerminalCapabilitiesStruct = defineStruct([
11800
12537
  ["explicit_cursor_positioning", "bool_u8"],
11801
12538
  ["remote", "bool_u8"],
11802
12539
  ["multiplexer", TerminalMultiplexerEnum],
12540
+ ["image_protocol", ImageProtocolEnum],
11803
12541
  ["term_name", "char*"],
11804
12542
  ["term_name_len", "u64", { lengthOf: "term_name" }],
11805
12543
  ["term_version", "char*"],
@@ -11811,6 +12549,29 @@ var EncodedCharStruct = defineStruct([
11811
12549
  ["width", "u8"],
11812
12550
  ["char", "u32"]
11813
12551
  ]);
12552
+ var NativeImageInfoStruct = defineStruct([
12553
+ ["width", "u32"],
12554
+ ["height", "u32"],
12555
+ ["sourceWidth", "u32"],
12556
+ ["sourceHeight", "u32"],
12557
+ ["format", "u32"],
12558
+ ["colorStatus", "u32"],
12559
+ ["orientation", "u32"],
12560
+ ["hasAlpha", "u32"]
12561
+ ]);
12562
+ var ImageDrawOptionsStruct = defineStruct([
12563
+ ["x", "i32"],
12564
+ ["y", "i32"],
12565
+ ["width", "u32"],
12566
+ ["height", "u32"],
12567
+ ["pixelWidth", "u32"],
12568
+ ["pixelHeight", "u32"],
12569
+ ["sourceX", "u32"],
12570
+ ["sourceY", "u32"],
12571
+ ["sourceWidth", "u32"],
12572
+ ["sourceHeight", "u32"],
12573
+ ["protocol", "u32"]
12574
+ ]);
11814
12575
  var LineInfoStruct = defineStruct([
11815
12576
  ["startCols", ["u32"]],
11816
12577
  ["startColsLen", "u32", { lengthOf: "startCols" }],
@@ -11993,6 +12754,15 @@ var AudioStreamStatsStruct = defineStruct([
11993
12754
  ["errorCode", "i32"],
11994
12755
  ["readyGeneration", "u32"]
11995
12756
  ]);
12757
+ var AudioCaptureStatsStruct = defineStruct([
12758
+ ["framesReceived", "u64"],
12759
+ ["framesRead", "u64"],
12760
+ ["framesDropped", "u64"],
12761
+ ["sampleRate", "u32"],
12762
+ ["channels", "u32"],
12763
+ ["bufferedFrames", "u32"],
12764
+ ["capacityFrames", "u32"]
12765
+ ]);
11996
12766
  var AudioStatsStruct = defineStruct([
11997
12767
  ["soundsLoaded", "u32"],
11998
12768
  ["voicesActive", "u32"],
@@ -12039,27 +12809,33 @@ registerEnvVar({
12039
12809
  });
12040
12810
  registerEnvVar({
12041
12811
  name: "OPENTUI_FORCE_WCWIDTH",
12042
- description: "Use wcwidth for character width calculations",
12043
- type: "boolean",
12044
- default: false
12812
+ description: "Use wcwidth for character width calculations when the variable is present",
12813
+ type: "string",
12814
+ required: false
12045
12815
  });
12046
12816
  registerEnvVar({
12047
12817
  name: "OPENTUI_FORCE_UNICODE",
12048
- description: "Force Mode 2026 Unicode support in terminal capabilities",
12049
- type: "boolean",
12050
- default: false
12818
+ description: "Force Mode 2026 Unicode support when the variable is present",
12819
+ type: "string",
12820
+ required: false
12051
12821
  });
12052
12822
  registerEnvVar({
12053
12823
  name: "OPENTUI_GRAPHICS",
12054
- description: "Enable Kitty graphics protocol detection",
12055
- type: "boolean",
12056
- default: true
12824
+ description: "Control Kitty and Sixel graphics detection with the exact value true, 1, false, or 0",
12825
+ type: "string",
12826
+ required: false
12827
+ });
12828
+ registerEnvVar({
12829
+ name: "OPENTUI_IMAGE_PROTOCOL",
12830
+ description: "Override image rendering protocol: auto, kitty, sixel, or blocks",
12831
+ type: "string",
12832
+ default: "auto"
12057
12833
  });
12058
12834
  registerEnvVar({
12059
12835
  name: "OPENTUI_FORCE_NOZWJ",
12060
- description: "Use no_zwj width method (Unicode without ZWJ joining)",
12061
- type: "boolean",
12062
- default: false
12836
+ description: "Use no_zwj width mode when the variable is present",
12837
+ type: "string",
12838
+ required: false
12063
12839
  });
12064
12840
  var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 };
12065
12841
  var CURSOR_ID_TO_STYLE = ["block", "line", "underline", "default"];
@@ -12376,6 +13152,10 @@ function getOpenTUILib(libPath) {
12376
13152
  args: ["u32", "u32", "u32", "ptr", "u32", "u8", "u32"],
12377
13153
  returns: "void"
12378
13154
  },
13155
+ bufferDrawImage: {
13156
+ args: ["u32", "u32", "ptr"],
13157
+ returns: "u8"
13158
+ },
12379
13159
  bufferDrawPackedBuffer: {
12380
13160
  args: ["u32", "ptr", "u32", "u32", "u32", "u32", "u32"],
12381
13161
  returns: "void"
@@ -13076,6 +13856,19 @@ function getOpenTUILib(libPath) {
13076
13856
  args: ["u32"],
13077
13857
  returns: "u32"
13078
13858
  },
13859
+ imageInfo: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13860
+ imageDecode: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13861
+ imageCreateFromRgba: { args: ["ptr", "u64", "u32", "u32", "u32", "ptr"], returns: "u32" },
13862
+ imageDestroy: { args: ["u32"], returns: "void" },
13863
+ imageGetInfo: { args: ["u32", "ptr"], returns: "u32" },
13864
+ imageGetPixelsPtr: { args: ["u32"], returns: "ptr" },
13865
+ imageClone: { args: ["u32", "ptr"], returns: "u32" },
13866
+ imageCopyPixels: { args: ["u32", "ptr", "u64", "u32", "u8"], returns: "u32" },
13867
+ imageResize: { args: ["u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13868
+ imageExtract: { args: ["u32", "u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13869
+ imageExtend: { args: ["u32", "u32", "u32", "u32", "u32", "ptr", "ptr"], returns: "u32" },
13870
+ imageTransform: { args: ["u32", "u32", "ptr"], returns: "u32" },
13871
+ imageComposite: { args: ["u32", "u32", "i32", "i32", "u32", "u8", "ptr"], returns: "u32" },
13079
13872
  getTerminalCapabilities: {
13080
13873
  args: ["u32", "ptr"],
13081
13874
  returns: "void"
@@ -13328,6 +14121,50 @@ function getOpenTUILib(libPath) {
13328
14121
  args: ["u32"],
13329
14122
  returns: "void"
13330
14123
  },
14124
+ audioRefreshCaptureDevices: {
14125
+ args: ["u32"],
14126
+ returns: "i32"
14127
+ },
14128
+ audioGetCaptureDeviceCount: {
14129
+ args: ["u32"],
14130
+ returns: "u32"
14131
+ },
14132
+ audioGetCaptureDeviceName: {
14133
+ args: ["u32", "u32", "ptr", "u32"],
14134
+ returns: "u32"
14135
+ },
14136
+ audioIsCaptureDeviceDefault: {
14137
+ args: ["u32", "u32"],
14138
+ returns: "bool"
14139
+ },
14140
+ audioSelectCaptureDevice: {
14141
+ args: ["u32", "u32"],
14142
+ returns: "i32"
14143
+ },
14144
+ audioClearCaptureDeviceSelection: {
14145
+ args: ["u32"],
14146
+ returns: "void"
14147
+ },
14148
+ audioStartCapture: {
14149
+ args: ["u32", "ptr", "u32", "u32"],
14150
+ returns: "i32"
14151
+ },
14152
+ audioStopCapture: {
14153
+ args: ["u32"],
14154
+ returns: "i32"
14155
+ },
14156
+ audioIsCaptureRunning: {
14157
+ args: ["u32"],
14158
+ returns: "bool"
14159
+ },
14160
+ audioReadCapture: {
14161
+ args: ["u32", "ptr", "u32", "u32", "ptr"],
14162
+ returns: "i32"
14163
+ },
14164
+ audioGetCaptureStats: {
14165
+ args: ["u32", "ptr"],
14166
+ returns: "i32"
14167
+ },
13331
14168
  audioStart: {
13332
14169
  args: ["u32", "ptr"],
13333
14170
  returns: "i32"
@@ -13630,6 +14467,46 @@ var NativeMeasureTargetKind = {
13630
14467
 
13631
14468
  class FFIRenderLib {
13632
14469
  opentui;
14470
+ yogaLayout = new Float32Array(6);
14471
+ yogaLayoutPtr = ptr(this.yogaLayout);
14472
+ ffiStructStorage = {
14473
+ logicalCursor: {
14474
+ ...allocStruct(LogicalCursorStruct),
14475
+ result: { row: 0, col: 0, offset: 0 }
14476
+ },
14477
+ visualCursor: {
14478
+ ...allocStruct(VisualCursorStruct),
14479
+ result: {
14480
+ visualRow: 0,
14481
+ visualCol: 0,
14482
+ logicalRow: 0,
14483
+ logicalCol: 0,
14484
+ offset: 0
14485
+ }
14486
+ },
14487
+ measureResult: {
14488
+ ...allocStruct(MeasureResultStruct),
14489
+ result: { lineCount: 0, widthColsMax: 0 }
14490
+ },
14491
+ audioStreamStats: {
14492
+ ...allocStruct(AudioStreamStatsStruct),
14493
+ result: {
14494
+ bytesReceived: 0n,
14495
+ framesDecoded: 0n,
14496
+ framesPlayed: 0n,
14497
+ state: 0,
14498
+ sampleRate: 0,
14499
+ channels: 0,
14500
+ bufferedFrames: 0,
14501
+ capacityFrames: 0,
14502
+ underruns: 0,
14503
+ errorCode: 0,
14504
+ readyGeneration: 0
14505
+ }
14506
+ },
14507
+ imageDrawOptions: allocStruct(ImageDrawOptionsStruct),
14508
+ gridDrawOptions: allocStruct(GridDrawOptionsStruct)
14509
+ };
13633
14510
  encoder = new TextEncoder;
13634
14511
  decoder = new TextDecoder;
13635
14512
  logCallbackWrapper = null;
@@ -13956,6 +14833,24 @@ class FFIRenderLib {
13956
14833
  const formatId = format === "bgra8unorm" ? 0 : 1;
13957
14834
  this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
13958
14835
  }
14836
+ bufferDrawImage(buffer, image, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol) {
14837
+ const protocolId = { auto: 0, kitty: 1, sixel: 2, blocks: 3 }[protocol];
14838
+ const storage = this.ffiStructStorage.imageDrawOptions;
14839
+ ImageDrawOptionsStruct.packInto({
14840
+ x,
14841
+ y,
14842
+ width,
14843
+ height,
14844
+ pixelWidth,
14845
+ pixelHeight,
14846
+ sourceX,
14847
+ sourceY,
14848
+ sourceWidth,
14849
+ sourceHeight,
14850
+ protocol: protocolId
14851
+ }, storage.view, 0);
14852
+ return Boolean(this.opentui.symbols.bufferDrawImage(buffer, image, storage.buffer));
14853
+ }
13959
14854
  bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
13960
14855
  this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
13961
14856
  }
@@ -13966,11 +14861,8 @@ class FFIRenderLib {
13966
14861
  this.opentui.symbols.bufferDrawGrayscaleBufferSupersampled(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, optionalRgbaPtr(fg2), optionalRgbaPtr(bg2));
13967
14862
  }
13968
14863
  bufferDrawGrid(buffer, borderChars, borderFg, borderBg, columnOffsets, columnCount, rowOffsets, rowCount, options) {
13969
- const optionsBuffer = GridDrawOptionsStruct.pack({
13970
- drawInner: options.drawInner,
13971
- drawOuter: options.drawOuter
13972
- });
13973
- this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, ptr(optionsBuffer));
14864
+ GridDrawOptionsStruct.packInto({ drawInner: options.drawInner, drawOuter: options.drawOuter }, this.ffiStructStorage.gridDrawOptions.view, 0);
14865
+ this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, this.ffiStructStorage.gridDrawOptions.buffer);
13974
14866
  }
13975
14867
  bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, titleColor, title, bottomTitle) {
13976
14868
  const titleBytes = title ? this.encoder.encode(title) : null;
@@ -14118,11 +15010,11 @@ class FFIRenderLib {
14118
15010
  this.opentui.symbols.dumpHitGrid(renderer);
14119
15011
  }
14120
15012
  dumpBuffers(renderer, timestamp) {
14121
- const ts = timestamp ?? Date.now();
15013
+ const ts = BigInt(timestamp ?? Date.now());
14122
15014
  this.opentui.symbols.dumpBuffers(renderer, ts);
14123
15015
  }
14124
15016
  dumpOutputBuffer(renderer, timestamp) {
14125
- const ts = timestamp ?? Date.now();
15017
+ const ts = BigInt(timestamp ?? Date.now());
14126
15018
  this.opentui.symbols.dumpOutputBuffer(renderer, ts);
14127
15019
  }
14128
15020
  restoreTerminalModes(renderer) {
@@ -14276,8 +15168,8 @@ class FFIRenderLib {
14276
15168
  return this.opentui.symbols.yogaNodeGetAlwaysFormsContainingBlock(node);
14277
15169
  }
14278
15170
  yogaNodeGetComputedLayout(node) {
14279
- const layout = new Float32Array(6);
14280
- this.opentui.symbols.yogaNodeGetComputedLayout(node, ptr(layout));
15171
+ const layout = this.yogaLayout;
15172
+ this.opentui.symbols.yogaNodeGetComputedLayout(node, this.yogaLayoutPtr);
14281
15173
  return {
14282
15174
  left: layout[0],
14283
15175
  top: layout[1],
@@ -14458,7 +15350,7 @@ class FFIRenderLib {
14458
15350
  if (len === 0) {
14459
15351
  return null;
14460
15352
  }
14461
- return outBuffer.slice(0, len);
15353
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14462
15354
  }
14463
15355
  createTextBufferView(textBuffer) {
14464
15356
  const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer);
@@ -14595,14 +15487,12 @@ class FFIRenderLib {
14595
15487
  this.opentui.symbols.textBufferViewSetTruncate(view, ffiBool(truncate));
14596
15488
  }
14597
15489
  textBufferViewMeasureForDimensions(view, width, height) {
14598
- const resultBuffer = new ArrayBuffer(MeasureResultStruct.size);
14599
- const resultPtr = ptr(new Uint8Array(resultBuffer));
14600
- const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, resultPtr);
14601
- if (!success) {
15490
+ const storage = this.ffiStructStorage.measureResult;
15491
+ const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, storage.buffer);
15492
+ if (!success)
14602
15493
  return null;
14603
- }
14604
- const result = MeasureResultStruct.unpack(resultBuffer);
14605
- return result;
15494
+ const result = MeasureResultStruct.unpackInto(storage.view, storage.result);
15495
+ return { lineCount: result.lineCount, widthColsMax: result.widthColsMax };
14606
15496
  }
14607
15497
  textBufferAddHighlightByCharRange(buffer, highlight) {
14608
15498
  const packedHighlight = HighlightStruct.pack(highlight);
@@ -14828,9 +15718,10 @@ class FFIRenderLib {
14828
15718
  this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset);
14829
15719
  }
14830
15720
  editBufferGetCursorPosition(buffer) {
14831
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14832
- this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr(cursorBuffer));
14833
- return LogicalCursorStruct.unpack(cursorBuffer);
15721
+ const storage = this.ffiStructStorage.logicalCursor;
15722
+ this.opentui.symbols.editBufferGetCursorPosition(buffer, storage.buffer);
15723
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15724
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14834
15725
  }
14835
15726
  editBufferGetId(buffer) {
14836
15727
  return this.opentui.symbols.editBufferGetId(buffer);
@@ -14874,26 +15765,30 @@ class FFIRenderLib {
14874
15765
  this.opentui.symbols.editBufferClear(buffer);
14875
15766
  }
14876
15767
  editBufferGetNextWordBoundary(buffer) {
14877
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14878
- this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr(cursorBuffer));
14879
- return LogicalCursorStruct.unpack(cursorBuffer);
15768
+ const storage = this.ffiStructStorage.logicalCursor;
15769
+ this.opentui.symbols.editBufferGetNextWordBoundary(buffer, storage.buffer);
15770
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15771
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14880
15772
  }
14881
15773
  editBufferGetPrevWordBoundary(buffer) {
14882
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14883
- this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr(cursorBuffer));
14884
- return LogicalCursorStruct.unpack(cursorBuffer);
15774
+ const storage = this.ffiStructStorage.logicalCursor;
15775
+ this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, storage.buffer);
15776
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15777
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14885
15778
  }
14886
15779
  editBufferGetEOL(buffer) {
14887
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14888
- this.opentui.symbols.editBufferGetEOL(buffer, ptr(cursorBuffer));
14889
- return LogicalCursorStruct.unpack(cursorBuffer);
15780
+ const storage = this.ffiStructStorage.logicalCursor;
15781
+ this.opentui.symbols.editBufferGetEOL(buffer, storage.buffer);
15782
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15783
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14890
15784
  }
14891
15785
  editBufferOffsetToPosition(buffer, offset) {
14892
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14893
- const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, ptr(cursorBuffer));
15786
+ const storage = this.ffiStructStorage.logicalCursor;
15787
+ const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, storage.buffer);
14894
15788
  if (!success)
14895
15789
  return null;
14896
- return LogicalCursorStruct.unpack(cursorBuffer);
15790
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15791
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14897
15792
  }
14898
15793
  editBufferPositionToOffset(buffer, row, col) {
14899
15794
  return this.opentui.symbols.editBufferPositionToOffset(buffer, row, col);
@@ -14915,7 +15810,7 @@ class FFIRenderLib {
14915
15810
  const len = actualLen;
14916
15811
  if (len === 0)
14917
15812
  return null;
14918
- return outBuffer.slice(0, len);
15813
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14919
15814
  }
14920
15815
  editorViewSetSelection(view, start, end, bgColor, fgColor) {
14921
15816
  const bg2 = optionalRgbaPtr(bgColor);
@@ -14975,9 +15870,10 @@ class FFIRenderLib {
14975
15870
  return outBuffer.slice(0, len);
14976
15871
  }
14977
15872
  editorViewGetVisualCursor(view) {
14978
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14979
- this.opentui.symbols.editorViewGetVisualCursor(view, ptr(cursorBuffer));
14980
- return VisualCursorStruct.unpack(cursorBuffer);
15873
+ const storage = this.ffiStructStorage.visualCursor;
15874
+ this.opentui.symbols.editorViewGetVisualCursor(view, storage.buffer);
15875
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15876
+ return { ...cursor };
14981
15877
  }
14982
15878
  editorViewMoveUpVisual(view) {
14983
15879
  this.opentui.symbols.editorViewMoveUpVisual(view);
@@ -14992,29 +15888,34 @@ class FFIRenderLib {
14992
15888
  this.opentui.symbols.editorViewSetCursorByOffset(view, offset);
14993
15889
  }
14994
15890
  editorViewGetNextWordBoundary(view) {
14995
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14996
- this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr(cursorBuffer));
14997
- return VisualCursorStruct.unpack(cursorBuffer);
15891
+ const storage = this.ffiStructStorage.visualCursor;
15892
+ this.opentui.symbols.editorViewGetNextWordBoundary(view, storage.buffer);
15893
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15894
+ return { ...cursor };
14998
15895
  }
14999
15896
  editorViewGetPrevWordBoundary(view) {
15000
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
15001
- this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr(cursorBuffer));
15002
- return VisualCursorStruct.unpack(cursorBuffer);
15897
+ const storage = this.ffiStructStorage.visualCursor;
15898
+ this.opentui.symbols.editorViewGetPrevWordBoundary(view, storage.buffer);
15899
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15900
+ return { ...cursor };
15003
15901
  }
15004
15902
  editorViewGetEOL(view) {
15005
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
15006
- this.opentui.symbols.editorViewGetEOL(view, ptr(cursorBuffer));
15007
- return VisualCursorStruct.unpack(cursorBuffer);
15903
+ const storage = this.ffiStructStorage.visualCursor;
15904
+ this.opentui.symbols.editorViewGetEOL(view, storage.buffer);
15905
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15906
+ return { ...cursor };
15008
15907
  }
15009
15908
  editorViewGetVisualSOL(view) {
15010
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
15011
- this.opentui.symbols.editorViewGetVisualSOL(view, ptr(cursorBuffer));
15012
- return VisualCursorStruct.unpack(cursorBuffer);
15909
+ const storage = this.ffiStructStorage.visualCursor;
15910
+ this.opentui.symbols.editorViewGetVisualSOL(view, storage.buffer);
15911
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15912
+ return { ...cursor };
15013
15913
  }
15014
15914
  editorViewGetVisualEOL(view) {
15015
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
15016
- this.opentui.symbols.editorViewGetVisualEOL(view, ptr(cursorBuffer));
15017
- return VisualCursorStruct.unpack(cursorBuffer);
15915
+ const storage = this.ffiStructStorage.visualCursor;
15916
+ this.opentui.symbols.editorViewGetVisualEOL(view, storage.buffer);
15917
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15918
+ return { ...cursor };
15018
15919
  }
15019
15920
  bufferPushScissorRect(buffer, x, y, width, height) {
15020
15921
  this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height);
@@ -15062,6 +15963,7 @@ class FFIRenderLib {
15062
15963
  explicit_cursor_positioning: caps.explicit_cursor_positioning,
15063
15964
  remote: caps.remote,
15064
15965
  multiplexer: caps.multiplexer,
15966
+ image_protocol: caps.image_protocol,
15065
15967
  terminal: {
15066
15968
  name: caps.term_name ?? "",
15067
15969
  version: caps.term_version ?? "",
@@ -15129,6 +16031,76 @@ class FFIRenderLib {
15129
16031
  audioClearPlaybackDeviceSelection(engine) {
15130
16032
  this.opentui.symbols.audioClearPlaybackDeviceSelection(engine);
15131
16033
  }
16034
+ audioRefreshCaptureDevices(engine) {
16035
+ return this.opentui.symbols.audioRefreshCaptureDevices(engine);
16036
+ }
16037
+ audioGetCaptureDeviceCount(engine) {
16038
+ return this.opentui.symbols.audioGetCaptureDeviceCount(engine);
16039
+ }
16040
+ audioGetCaptureDeviceName(engine, index) {
16041
+ const outBuffer = new Uint8Array(512);
16042
+ const bytesWritten = toNumber(this.opentui.symbols.audioGetCaptureDeviceName(engine, index, outBuffer, outBuffer.length));
16043
+ const safeBytesWritten = Math.max(0, Math.min(outBuffer.length, bytesWritten));
16044
+ return this.decoder.decode(outBuffer.subarray(0, safeBytesWritten));
16045
+ }
16046
+ audioIsCaptureDeviceDefault(engine, index) {
16047
+ return Boolean(this.opentui.symbols.audioIsCaptureDeviceDefault(engine, index));
16048
+ }
16049
+ audioSelectCaptureDevice(engine, index) {
16050
+ return this.opentui.symbols.audioSelectCaptureDevice(engine, index);
16051
+ }
16052
+ audioClearCaptureDeviceSelection(engine) {
16053
+ this.opentui.symbols.audioClearCaptureDeviceSelection(engine);
16054
+ }
16055
+ audioStartCapture(engine, options, channels, capacityFrames) {
16056
+ let optionsBuffer;
16057
+ try {
16058
+ const noFixedSizedCallback = options?.noFixedSizedCallback;
16059
+ optionsBuffer = AudioStartOptionsStruct.pack(options ?? {});
16060
+ if (noFixedSizedCallback === undefined) {
16061
+ const field = AudioStartOptionsStruct.layoutByName.get("noFixedSizedCallback");
16062
+ if (!field)
16063
+ return -1;
16064
+ new DataView(optionsBuffer).setUint8(field.offset, 1);
16065
+ }
16066
+ } catch {
16067
+ return -1;
16068
+ }
16069
+ return this.opentui.symbols.audioStartCapture(engine, optionsBuffer, channels, capacityFrames);
16070
+ }
16071
+ audioStopCapture(engine) {
16072
+ return this.opentui.symbols.audioStopCapture(engine);
16073
+ }
16074
+ audioIsCaptureRunning(engine) {
16075
+ return Boolean(this.opentui.symbols.audioIsCaptureRunning(engine));
16076
+ }
16077
+ audioReadCapture(engine, outBuffer, frameCount) {
16078
+ const outFramesReadBuffer = new ArrayBuffer(4);
16079
+ const sampleCapacity = toSafeFFIU32Length(outBuffer.length, "Audio capture output sample capacity");
16080
+ const status = this.opentui.symbols.audioReadCapture(engine, outBuffer, sampleCapacity, frameCount, outFramesReadBuffer);
16081
+ if (status !== 0)
16082
+ return { status, framesRead: 0 };
16083
+ return { status, framesRead: new Uint32Array(outFramesReadBuffer)[0] ?? 0 };
16084
+ }
16085
+ audioGetCaptureStats(engine) {
16086
+ const statsBuffer = new ArrayBuffer(AudioCaptureStatsStruct.size);
16087
+ const status = this.opentui.symbols.audioGetCaptureStats(engine, statsBuffer);
16088
+ if (status !== 0)
16089
+ return { status, stats: null };
16090
+ const stats = AudioCaptureStatsStruct.unpack(statsBuffer);
16091
+ return {
16092
+ status,
16093
+ stats: {
16094
+ framesReceived: typeof stats.framesReceived === "bigint" ? stats.framesReceived : BigInt(stats.framesReceived),
16095
+ framesRead: typeof stats.framesRead === "bigint" ? stats.framesRead : BigInt(stats.framesRead),
16096
+ framesDropped: typeof stats.framesDropped === "bigint" ? stats.framesDropped : BigInt(stats.framesDropped),
16097
+ sampleRate: stats.sampleRate,
16098
+ channels: stats.channels,
16099
+ bufferedFrames: stats.bufferedFrames,
16100
+ capacityFrames: stats.capacityFrames
16101
+ }
16102
+ };
16103
+ }
15132
16104
  audioStart(engine, options) {
15133
16105
  let optionsBuffer;
15134
16106
  try {
@@ -15177,18 +16149,20 @@ class FFIRenderLib {
15177
16149
  return this.opentui.symbols.audioSetStreamGroup(engine, streamId, groupId);
15178
16150
  }
15179
16151
  audioGetStreamStats(engine, streamId) {
15180
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15181
- const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, outBuffer);
16152
+ const storage = this.ffiStructStorage.audioStreamStats;
16153
+ const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, storage.buffer);
15182
16154
  if (status !== 0)
15183
16155
  return null;
15184
- return AudioStreamStatsStruct.unpack(outBuffer);
16156
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16157
+ return { ...stats };
15185
16158
  }
15186
16159
  audioCloseStream(engine, streamId, reason) {
15187
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15188
- const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, outBuffer);
16160
+ const storage = this.ffiStructStorage.audioStreamStats;
16161
+ const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, storage.buffer);
15189
16162
  if (status !== 0)
15190
16163
  return { status, stats: null };
15191
- return { status, stats: AudioStreamStatsStruct.unpack(outBuffer) };
16164
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16165
+ return { status, stats: { ...stats } };
15192
16166
  }
15193
16167
  audioLoad(engine, data) {
15194
16168
  const outBuffer = new ArrayBuffer(4);
@@ -15362,6 +16336,66 @@ class FFIRenderLib {
15362
16336
  syntaxStyleGetStyleCount(style) {
15363
16337
  return this.opentui.symbols.syntaxStyleGetStyleCount(style);
15364
16338
  }
16339
+ imageHandleResult(status, output) {
16340
+ return { status, handle: status === 0 && output[0] !== 0 ? output[0] : null };
16341
+ }
16342
+ imageInfo(data) {
16343
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16344
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16345
+ const status = this.opentui.symbols.imageInfo(data.byteLength === 0 ? null : data, length, output);
16346
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16347
+ }
16348
+ imageDecode(data) {
16349
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16350
+ const output = new Uint32Array(1);
16351
+ return this.imageHandleResult(this.opentui.symbols.imageDecode(data.byteLength === 0 ? null : data, length, output), output);
16352
+ }
16353
+ imageCreateFromRgba(pixels, width, height, stride) {
16354
+ const output = new Uint32Array(1);
16355
+ const status = this.opentui.symbols.imageCreateFromRgba(pixels.byteLength === 0 ? null : pixels, BigInt(pixels.byteLength), width, height, stride, output);
16356
+ return this.imageHandleResult(status, output);
16357
+ }
16358
+ imageDestroy(image) {
16359
+ this.opentui.symbols.imageDestroy(image);
16360
+ }
16361
+ imageGetInfo(image) {
16362
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16363
+ const status = this.opentui.symbols.imageGetInfo(image, output);
16364
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16365
+ }
16366
+ imageGetPixelsPtr(image) {
16367
+ const pointer = this.opentui.symbols.imageGetPixelsPtr(image);
16368
+ return pointer === null || pointer === 0 || pointer === 0n ? null : pointer;
16369
+ }
16370
+ imageClone(image) {
16371
+ const output = new Uint32Array(1);
16372
+ return this.imageHandleResult(this.opentui.symbols.imageClone(image, output), output);
16373
+ }
16374
+ imageCopyPixels(image, destination, stride, bgra) {
16375
+ return this.opentui.symbols.imageCopyPixels(image, destination.byteLength === 0 ? null : destination, BigInt(destination.byteLength), stride, bgra ? 1 : 0);
16376
+ }
16377
+ imageResize(image, width, height, filter) {
16378
+ const output = new Uint32Array(1);
16379
+ return this.imageHandleResult(this.opentui.symbols.imageResize(image, width, height, filter, output), output);
16380
+ }
16381
+ imageExtract(image, left, top, width, height) {
16382
+ const output = new Uint32Array(1);
16383
+ return this.imageHandleResult(this.opentui.symbols.imageExtract(image, left, top, width, height, output), output);
16384
+ }
16385
+ imageExtend(image, top, right, bottom, left, background) {
16386
+ if (!(background instanceof Uint8Array) || background.byteLength !== 4)
16387
+ return { status: 7, handle: null };
16388
+ const output = new Uint32Array(1);
16389
+ return this.imageHandleResult(this.opentui.symbols.imageExtend(image, top, right, bottom, left, background, output), output);
16390
+ }
16391
+ imageTransform(image, operation) {
16392
+ const output = new Uint32Array(1);
16393
+ return this.imageHandleResult(this.opentui.symbols.imageTransform(image, operation, output), output);
16394
+ }
16395
+ imageComposite(base, overlay, left, top, blend, opacity) {
16396
+ const output = new Uint32Array(1);
16397
+ return this.imageHandleResult(this.opentui.symbols.imageComposite(base, overlay, left, top, blend, opacity, output), output);
16398
+ }
15365
16399
  editorViewSetPlaceholderStyledText(view, chunks) {
15366
16400
  const nonEmptyChunks = chunks.filter((c) => c.text.length > 0);
15367
16401
  if (nonEmptyChunks.length === 0) {
@@ -16378,5 +17412,5 @@ var yoga_default = Yoga;
16378
17412
 
16379
17413
  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 };
16380
17414
 
16381
- //# debugId=9AB6478EE1CB2A8A64756E2164756E21
16382
- //# sourceMappingURL=chunk-bun-t2myhmwd.js.map
17415
+ //# debugId=A5B84FFA1E40FFEB64756E2164756E21
17416
+ //# sourceMappingURL=chunk-bun-ctxxvhwz.js.map