@opentui/core 0.4.4 → 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 (56) 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-ctxxvhwz.js +17416 -0
  6. package/chunk-bun-ctxxvhwz.js.map +62 -0
  7. package/chunk-bun-v3e63tzw.js +10157 -0
  8. package/chunk-bun-v3e63tzw.js.map +32 -0
  9. package/{index-7z5n7k9m.js → chunk-node-1j69hr31.js} +147 -37
  10. package/chunk-node-1j69hr31.js.map +32 -0
  11. package/{index-za1krqsf.js → chunk-node-savhj5rp.js} +1594 -467
  12. package/chunk-node-savhj5rp.js.map +61 -0
  13. package/image.d.ts +105 -0
  14. package/index.bun.js +15128 -0
  15. package/index.bun.js.map +41 -0
  16. package/index.d.ts +2 -0
  17. package/{index.js → index.node.js} +2134 -90
  18. package/{index.js.map → index.node.js.map} +40 -5
  19. package/lib/env.d.ts +1 -0
  20. package/lib/stdin-parser.d.ts +5 -0
  21. package/lib/tree-sitter/default-parser-assets.bun.d.ts +1 -0
  22. package/lib/tree-sitter/default-parsers.d.ts +1 -0
  23. package/lib/tree-sitter/parsers-config.d.ts +2 -2
  24. package/lib/tree-sitter/types.d.ts +1 -0
  25. package/lib/tree-sitter/update-assets.js +124 -58
  26. package/lib/tree-sitter/update-assets.js.map +3 -3
  27. package/node-asset-target.d.ts +12 -0
  28. package/node-assets.d.ts +7 -0
  29. package/node-assets.js +264 -0
  30. package/node-assets.js.map +16 -0
  31. package/package.json +24 -14
  32. package/parser.worker.js +3353 -188
  33. package/parser.worker.js.map +18 -12
  34. package/platform/assets.d.ts +5 -0
  35. package/platform/ffi.d.ts +2 -0
  36. package/platform/runtime-assets.bun.d.ts +4 -0
  37. package/platform/runtime-assets.node.d.ts +4 -0
  38. package/platform/runtime.d.ts +5 -1
  39. package/renderables/Image.d.ts +44 -0
  40. package/renderables/index.d.ts +1 -0
  41. package/renderer.d.ts +14 -0
  42. package/runtime-plugin.js +2 -2
  43. package/runtime-plugin.js.map +1 -1
  44. package/testing.bun.js +1006 -0
  45. package/testing.bun.js.map +18 -0
  46. package/testing.js +4 -3
  47. package/testing.js.map +3 -3
  48. package/text-buffer-view.d.ts +2 -5
  49. package/types.d.ts +8 -0
  50. package/yoga.bun.js +194 -0
  51. package/yoga.bun.js.map +9 -0
  52. package/yoga.js +1 -1
  53. package/zig-structs.d.ts +45 -24
  54. package/zig.d.ts +70 -7
  55. package/index-7z5n7k9m.js.map +0 -32
  56. package/index-za1krqsf.js.map +0 -58
@@ -1,4 +1,3 @@
1
- import { createRequire } from "node:module";
2
1
  var __create = Object.create;
3
2
  var __getProtoOf = Object.getPrototypeOf;
4
3
  var __defProp = Object.defineProperty;
@@ -43,7 +42,6 @@ var __export = (target, all) => {
43
42
  set: __exportSetter.bind(all, name)
44
43
  });
45
44
  };
46
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
47
45
 
48
46
  // ../../node_modules/.bun/emoji-regex@10.6.0/node_modules/emoji-regex/index.js
49
47
  var require_emoji_regex = __commonJS((exports, module) => {
@@ -151,7 +149,7 @@ __export(exports_yoga, {
151
149
  });
152
150
 
153
151
  // src/platform/ffi.ts
154
- import { createRequire as createRequire2 } from "node:module";
152
+ import { createRequire } from "node:module";
155
153
  import { fileURLToPath } from "node:url";
156
154
  var FFIType = {
157
155
  char: "char",
@@ -231,7 +229,8 @@ function createUnsupportedBackend(cause) {
231
229
  };
232
230
  }
233
231
  var isBun = typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.bun === "string";
234
- var requireModule = createRequire2(import.meta.url);
232
+ var usesBunFFI = isBun;
233
+ var requireModule = createRequire(import.meta.url);
235
234
  var backend = loadBackend();
236
235
  function loadBackend() {
237
236
  if (isBun) {
@@ -256,6 +255,11 @@ function toPointer(value) {
256
255
  function ffiBool(value) {
257
256
  return value ? 1 : 0;
258
257
  }
258
+ function trimNodeFFIOutputBytes(buffer, length) {
259
+ if (length === buffer.byteLength)
260
+ return buffer;
261
+ return new Uint8Array(buffer.buffer.transferToFixedLength(length));
262
+ }
259
263
  function toSafeNumberPointer(pointer) {
260
264
  if (pointer < 0n) {
261
265
  throw new Error(POINTER_NEGATIVE);
@@ -421,6 +425,34 @@ function wrapNodeSymbol(fn, definition) {
421
425
  if (pointerArgIndexes.length === 0) {
422
426
  return fn;
423
427
  }
428
+ if (definition.args?.length === 7 && pointerArgIndexes.length >= 2) {
429
+ return wrapNodeSymbol7(fn, pointerArgIndexes);
430
+ }
431
+ if (definition.args?.length === 8) {
432
+ return wrapNodeSymbol8(fn, pointerArgIndexes);
433
+ }
434
+ const pointerArgs = new Set(pointerArgIndexes);
435
+ const normalize = (value, index) => pointerArgs.has(index) ? toNodePointerArgumentFast(value) : value;
436
+ switch (definition.args?.length) {
437
+ case 1:
438
+ return function(arg0) {
439
+ if (arguments.length !== 1)
440
+ return Reflect.apply(fn, undefined, arguments);
441
+ return fn(normalize(arg0, 0));
442
+ };
443
+ case 2:
444
+ return function(arg0, arg1) {
445
+ if (arguments.length !== 2)
446
+ return Reflect.apply(fn, undefined, arguments);
447
+ return fn(normalize(arg0, 0), normalize(arg1, 1));
448
+ };
449
+ case 3:
450
+ return function(arg0, arg1, arg2) {
451
+ if (arguments.length !== 3)
452
+ return Reflect.apply(fn, undefined, arguments);
453
+ return fn(normalize(arg0, 0), normalize(arg1, 1), normalize(arg2, 2));
454
+ };
455
+ }
424
456
  return (...args) => {
425
457
  const normalizedArgs = args.slice();
426
458
  for (const index of pointerArgIndexes) {
@@ -429,6 +461,49 @@ function wrapNodeSymbol(fn, definition) {
429
461
  return fn(...normalizedArgs);
430
462
  };
431
463
  }
464
+ function wrapNodeSymbol7(fn, pointerArgIndexes) {
465
+ const pointer0 = pointerArgIndexes.includes(0);
466
+ const pointer1 = pointerArgIndexes.includes(1);
467
+ const pointer2 = pointerArgIndexes.includes(2);
468
+ const pointer3 = pointerArgIndexes.includes(3);
469
+ const pointer4 = pointerArgIndexes.includes(4);
470
+ const pointer5 = pointerArgIndexes.includes(5);
471
+ const pointer6 = pointerArgIndexes.includes(6);
472
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
473
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
474
+ if (arguments.length !== 7)
475
+ return Reflect.apply(fn, undefined, arguments);
476
+ return fn(normalize(arg0, pointer0), normalize(arg1, pointer1), normalize(arg2, pointer2), normalize(arg3, pointer3), normalize(arg4, pointer4), normalize(arg5, pointer5), normalize(arg6, pointer6));
477
+ };
478
+ }
479
+ function wrapNodeSymbol8(fn, pointerArgIndexes) {
480
+ const pointer0 = pointerArgIndexes.includes(0);
481
+ const pointer1 = pointerArgIndexes.includes(1);
482
+ const pointer2 = pointerArgIndexes.includes(2);
483
+ const pointer3 = pointerArgIndexes.includes(3);
484
+ const pointer4 = pointerArgIndexes.includes(4);
485
+ const pointer5 = pointerArgIndexes.includes(5);
486
+ const pointer6 = pointerArgIndexes.includes(6);
487
+ const pointer7 = pointerArgIndexes.includes(7);
488
+ const normalize = (value, pointer) => pointer ? toNodePointerArgumentFast(value) : value;
489
+ return function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
490
+ if (arguments.length !== 8)
491
+ return Reflect.apply(fn, undefined, arguments);
492
+ return fn(normalize(arg0, pointer0), normalize(arg1, pointer1), normalize(arg2, pointer2), normalize(arg3, pointer3), normalize(arg4, pointer4), normalize(arg5, pointer5), normalize(arg6, pointer6), normalize(arg7, pointer7));
493
+ };
494
+ }
495
+ function toNodePointerArgumentFast(value) {
496
+ if (typeof value === "bigint") {
497
+ return value >= 0n ? value : toNodePointerArgument(value);
498
+ }
499
+ if (ArrayBuffer.isView(value) && value.byteLength > 0 && value.buffer instanceof ArrayBuffer) {
500
+ return value;
501
+ }
502
+ if (value instanceof ArrayBuffer && value.byteLength > 0) {
503
+ return value;
504
+ }
505
+ return toNodePointerArgument(value);
506
+ }
432
507
  function isNodePointerArgumentType(type) {
433
508
  return type === FFIType.ptr || type === FFIType.pointer || type === FFIType.function || type === FFIType.callback;
434
509
  }
@@ -570,8 +645,8 @@ var toArrayBuffer = backend.toArrayBuffer;
570
645
  // src/platform/runtime.ts
571
646
  import { existsSync } from "node:fs";
572
647
  import { mkdir, writeFile as writeFileNode } from "node:fs/promises";
573
- import { dirname, isAbsolute, resolve } from "node:path";
574
- import { fileURLToPath as fileURLToPath2 } from "node:url";
648
+ import { dirname, isAbsolute as isAbsolute2, resolve } from "node:path";
649
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
575
650
 
576
651
  // ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
577
652
  function ansiRegex({ onlyFirst = false } = {}) {
@@ -665,6 +740,240 @@ function stringWidth(string, options = {}) {
665
740
  return width;
666
741
  }
667
742
 
743
+ // src/platform/assets.ts
744
+ import { statSync } from "node:fs";
745
+ import { isAbsolute, join } from "node:path";
746
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
747
+
748
+ // src/lib/singleton.ts
749
+ var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
750
+ function singleton(key, factory) {
751
+ const bag = globalThis[singletonCacheSymbol] ??= {};
752
+ if (!(key in bag)) {
753
+ bag[key] = factory();
754
+ }
755
+ return bag[key];
756
+ }
757
+ function getSingleton(key) {
758
+ const bag = globalThis[singletonCacheSymbol];
759
+ return bag?.[key];
760
+ }
761
+ function destroySingleton(key) {
762
+ const bag = globalThis[singletonCacheSymbol];
763
+ if (bag && key in bag) {
764
+ delete bag[key];
765
+ }
766
+ }
767
+
768
+ // src/lib/env.ts
769
+ var envRegistry = singleton("env-registry", () => ({}));
770
+ function registerEnvVar(config) {
771
+ const existing = envRegistry[config.name];
772
+ if (existing) {
773
+ if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default || existing.required !== config.required) {
774
+ throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
775
+ }
776
+ return;
777
+ }
778
+ envRegistry[config.name] = config;
779
+ }
780
+ function normalizeBoolean(value) {
781
+ const lowerValue = value.toLowerCase();
782
+ return ["true", "1", "on", "yes"].includes(lowerValue);
783
+ }
784
+ function parseEnvValue(config) {
785
+ const envValue = process.env[config.name];
786
+ if (envValue === undefined && config.default !== undefined) {
787
+ return config.default;
788
+ }
789
+ if (envValue === undefined && config.required === false) {
790
+ return;
791
+ }
792
+ if (envValue === undefined) {
793
+ throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
794
+ }
795
+ switch (config.type) {
796
+ case "boolean":
797
+ return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue);
798
+ case "number":
799
+ const numValue = Number(envValue);
800
+ if (isNaN(numValue)) {
801
+ throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`);
802
+ }
803
+ return numValue;
804
+ case "string":
805
+ default:
806
+ return envValue;
807
+ }
808
+ }
809
+
810
+ class EnvStore {
811
+ parsedValues = new Map;
812
+ get(key) {
813
+ if (this.parsedValues.has(key)) {
814
+ return this.parsedValues.get(key);
815
+ }
816
+ if (!(key in envRegistry)) {
817
+ throw new Error(`Environment variable ${key} is not registered.`);
818
+ }
819
+ try {
820
+ const value = parseEnvValue(envRegistry[key]);
821
+ this.parsedValues.set(key, value);
822
+ return value;
823
+ } catch (error) {
824
+ throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`);
825
+ }
826
+ }
827
+ has(key) {
828
+ return key in envRegistry;
829
+ }
830
+ clearCache() {
831
+ this.parsedValues.clear();
832
+ }
833
+ }
834
+ var envStore = singleton("env-store", () => new EnvStore);
835
+ function clearEnvCache() {
836
+ envStore.clearCache();
837
+ }
838
+ function generateEnvMarkdown() {
839
+ const configs = Object.values(envRegistry);
840
+ if (configs.length === 0) {
841
+ return `# Environment Variables
842
+
843
+ No environment variables registered.
844
+ `;
845
+ }
846
+ let markdown = `# Environment Variables
847
+
848
+ `;
849
+ for (const config of configs) {
850
+ markdown += `## ${config.name}
851
+
852
+ `;
853
+ markdown += `${config.description}
854
+
855
+ `;
856
+ markdown += `**Type:** \`${config.type || "string"}\`
857
+ `;
858
+ if (config.default !== undefined) {
859
+ const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
860
+ markdown += `**Default:** \`${defaultValue}\`
861
+ `;
862
+ } else if (config.required === false) {
863
+ markdown += `**Default:** *unset*
864
+ `;
865
+ } else {
866
+ markdown += `**Default:** *Required*
867
+ `;
868
+ }
869
+ markdown += `
870
+ `;
871
+ }
872
+ return markdown;
873
+ }
874
+ function generateEnvColored() {
875
+ const configs = Object.values(envRegistry);
876
+ if (configs.length === 0) {
877
+ return `\x1B[1;36mEnvironment Variables\x1B[0m
878
+
879
+ No environment variables registered.
880
+ `;
881
+ }
882
+ let output = `\x1B[1;36mEnvironment Variables\x1B[0m
883
+
884
+ `;
885
+ for (const config of configs) {
886
+ output += `\x1B[1;33m${config.name}\x1B[0m
887
+ `;
888
+ output += `${config.description}
889
+ `;
890
+ output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m
891
+ `;
892
+ if (config.default !== undefined) {
893
+ const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
894
+ output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
895
+ `;
896
+ } else if (config.required === false) {
897
+ output += `\x1B[32mDefault:\x1B[0m \x1B[35munset\x1B[0m
898
+ `;
899
+ } else {
900
+ output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
901
+ `;
902
+ }
903
+ output += `
904
+ `;
905
+ }
906
+ return output;
907
+ }
908
+ var env = new Proxy({}, {
909
+ get(target, prop) {
910
+ if (typeof prop !== "string") {
911
+ return;
912
+ }
913
+ return envStore.get(prop);
914
+ },
915
+ has(target, prop) {
916
+ return envStore.has(prop);
917
+ },
918
+ ownKeys() {
919
+ return Object.keys(envRegistry);
920
+ },
921
+ getOwnPropertyDescriptor(target, prop) {
922
+ if (envStore.has(prop)) {
923
+ return {
924
+ enumerable: true,
925
+ configurable: true,
926
+ get: () => envStore.get(prop)
927
+ };
928
+ }
929
+ return;
930
+ }
931
+ });
932
+
933
+ // src/platform/assets.ts
934
+ registerEnvVar({
935
+ name: "OTUI_ASSET_ROOT",
936
+ description: "Absolute directory containing relocatable OpenTUI runtime assets",
937
+ type: "string",
938
+ default: ""
939
+ });
940
+ function resolveAssetPath(key, fallback) {
941
+ validateAssetKey(key);
942
+ const configuredPath = resolveAssetRootPath(key);
943
+ if (configuredPath !== undefined) {
944
+ return configuredPath;
945
+ }
946
+ if (fallback === undefined) {
947
+ throw new Error(`OpenTUI asset ${JSON.stringify(key)} has no package-relative fallback`);
948
+ }
949
+ const value = typeof fallback === "function" ? fallback() : fallback;
950
+ return value instanceof URL ? fileURLToPath2(value) : value;
951
+ }
952
+ function resolveAssetRootPath(key) {
953
+ validateAssetKey(key);
954
+ const root = process.env.OTUI_ASSET_ROOT;
955
+ if (!root) {
956
+ return;
957
+ }
958
+ if (!isAbsolute(root)) {
959
+ throw new Error(`OTUI_ASSET_ROOT must be an absolute directory, got ${JSON.stringify(root)}`);
960
+ }
961
+ const assetPath = join(root, key);
962
+ let isFile = false;
963
+ try {
964
+ isFile = statSync(assetPath).isFile();
965
+ } catch {}
966
+ if (!isFile) {
967
+ throw new Error(`Missing OpenTUI asset ${JSON.stringify(key)} at ${JSON.stringify(assetPath)}`);
968
+ }
969
+ return assetPath;
970
+ }
971
+ function validateAssetKey(key) {
972
+ if (key.length === 0 || isAbsolute(key) || key.includes("\\") || key.split("/").includes("..")) {
973
+ throw new Error(`Invalid OpenTUI asset key: ${JSON.stringify(key)}`);
974
+ }
975
+ }
976
+
668
977
  // src/platform/runtime.ts
669
978
  var TEXT_ENCODER = new TextEncoder;
670
979
  var bun = globalThis.Bun;
@@ -672,33 +981,50 @@ var sleep = bun?.sleep ?? standardSleep;
672
981
  var stringWidth2 = bun?.stringWidth ?? stringWidth;
673
982
  var stripANSI = bun?.stripANSI ?? stripAnsi;
674
983
  var writeFile = bun?.write ?? writeFilePortable;
675
- async function resolveBundledFilePath(loadBundledFile, fallbackPath, metaUrl) {
984
+ async function resolveBundledFilePath(key, loadBundledFile, fallbackPath, metaUrl, options = {}) {
985
+ if (options.useAssetRoot ?? true) {
986
+ const configuredPath = resolveAssetRootPath(key);
987
+ if (configuredPath !== undefined) {
988
+ return configuredPath;
989
+ }
990
+ }
676
991
  if (!bun) {
677
992
  const path = resolveFallbackFilePath(fallbackPath, metaUrl);
678
993
  if (existsSync(path)) {
679
994
  return path;
680
995
  }
681
- return await loadBundledFilePath(loadBundledFile, metaUrl) ?? path;
996
+ return await loadBundledFilePath(loadBundledFile, metaUrl, options.loadBundledFileFallback ?? false) ?? path;
997
+ }
998
+ const loaded = (await loadBundledFile()).default;
999
+ if (typeof loaded !== "string") {
1000
+ return resolveFallbackFilePath(fallbackPath, metaUrl);
682
1001
  }
683
- return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl);
1002
+ return normalizeLoadedFilePath(loaded, metaUrl);
684
1003
  }
685
1004
  function resolveFallbackFilePath(fallbackPath, metaUrl) {
686
1005
  const path = typeof fallbackPath === "function" ? fallbackPath() : fallbackPath;
687
- return fileURLToPath2(path instanceof URL ? path : new URL(path, metaUrl));
1006
+ return fileURLToPath3(path instanceof URL ? path : new URL(path, metaUrl));
688
1007
  }
689
1008
  function normalizeLoadedFilePath(loadedPath, baseUrl) {
690
1009
  if (loadedPath.startsWith("file:")) {
691
- return fileURLToPath2(loadedPath);
1010
+ return fileURLToPath3(loadedPath);
692
1011
  }
693
- if (isAbsolute(loadedPath)) {
1012
+ if (isAbsolute2(loadedPath)) {
694
1013
  return loadedPath;
695
1014
  }
696
- return resolve(dirname(fileURLToPath2(baseUrl)), loadedPath);
1015
+ return resolve(dirname(fileURLToPath3(baseUrl)), loadedPath);
697
1016
  }
698
- async function loadBundledFilePath(loadBundledFile, metaUrl) {
1017
+ async function loadBundledFilePath(loadBundledFile, metaUrl, loadBundledFileFallback) {
699
1018
  const specifier = extractBundledImportSpecifier(loadBundledFile);
700
1019
  if (!specifier) {
701
- return;
1020
+ if (!loadBundledFileFallback) {
1021
+ return;
1022
+ }
1023
+ try {
1024
+ return normalizeLoadedFilePath((await loadBundledFile()).default, metaUrl);
1025
+ } catch {
1026
+ return;
1027
+ }
702
1028
  }
703
1029
  try {
704
1030
  const moduleUrl = new URL(specifier, metaUrl);
@@ -717,7 +1043,7 @@ function standardSleep(msOrDate) {
717
1043
  return new Promise((resolve2) => setTimeout(resolve2, ms));
718
1044
  }
719
1045
  async function writeFilePortable(destination, data, options) {
720
- const destinationPath = destination instanceof URL ? fileURLToPath2(destination) : destination;
1046
+ const destinationPath = destination instanceof URL ? fileURLToPath3(destination) : destination;
721
1047
  if (options?.createPath) {
722
1048
  await mkdir(dirname(destinationPath), { recursive: true });
723
1049
  }
@@ -5906,181 +6232,6 @@ class ASCIIFontSelectionHelper {
5906
6232
  return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end;
5907
6233
  }
5908
6234
  }
5909
- // src/lib/singleton.ts
5910
- var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
5911
- function singleton(key, factory) {
5912
- const bag = globalThis[singletonCacheSymbol] ??= {};
5913
- if (!(key in bag)) {
5914
- bag[key] = factory();
5915
- }
5916
- return bag[key];
5917
- }
5918
- function getSingleton(key) {
5919
- const bag = globalThis[singletonCacheSymbol];
5920
- return bag?.[key];
5921
- }
5922
- function destroySingleton(key) {
5923
- const bag = globalThis[singletonCacheSymbol];
5924
- if (bag && key in bag) {
5925
- delete bag[key];
5926
- }
5927
- }
5928
-
5929
- // src/lib/env.ts
5930
- var envRegistry = singleton("env-registry", () => ({}));
5931
- function registerEnvVar(config) {
5932
- const existing = envRegistry[config.name];
5933
- if (existing) {
5934
- if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
5935
- throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
5936
- }
5937
- return;
5938
- }
5939
- envRegistry[config.name] = config;
5940
- }
5941
- function normalizeBoolean(value) {
5942
- const lowerValue = value.toLowerCase();
5943
- return ["true", "1", "on", "yes"].includes(lowerValue);
5944
- }
5945
- function parseEnvValue(config) {
5946
- const envValue = process.env[config.name];
5947
- if (envValue === undefined && config.default !== undefined) {
5948
- return config.default;
5949
- }
5950
- if (envValue === undefined) {
5951
- throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
5952
- }
5953
- switch (config.type) {
5954
- case "boolean":
5955
- return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue);
5956
- case "number":
5957
- const numValue = Number(envValue);
5958
- if (isNaN(numValue)) {
5959
- throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`);
5960
- }
5961
- return numValue;
5962
- case "string":
5963
- default:
5964
- return envValue;
5965
- }
5966
- }
5967
-
5968
- class EnvStore {
5969
- parsedValues = new Map;
5970
- get(key) {
5971
- if (this.parsedValues.has(key)) {
5972
- return this.parsedValues.get(key);
5973
- }
5974
- if (!(key in envRegistry)) {
5975
- throw new Error(`Environment variable ${key} is not registered.`);
5976
- }
5977
- try {
5978
- const value = parseEnvValue(envRegistry[key]);
5979
- this.parsedValues.set(key, value);
5980
- return value;
5981
- } catch (error) {
5982
- throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`);
5983
- }
5984
- }
5985
- has(key) {
5986
- return key in envRegistry;
5987
- }
5988
- clearCache() {
5989
- this.parsedValues.clear();
5990
- }
5991
- }
5992
- var envStore = singleton("env-store", () => new EnvStore);
5993
- function clearEnvCache() {
5994
- envStore.clearCache();
5995
- }
5996
- function generateEnvMarkdown() {
5997
- const configs = Object.values(envRegistry);
5998
- if (configs.length === 0) {
5999
- return `# Environment Variables
6000
-
6001
- No environment variables registered.
6002
- `;
6003
- }
6004
- let markdown = `# Environment Variables
6005
-
6006
- `;
6007
- for (const config of configs) {
6008
- markdown += `## ${config.name}
6009
-
6010
- `;
6011
- markdown += `${config.description}
6012
-
6013
- `;
6014
- markdown += `**Type:** \`${config.type || "string"}\`
6015
- `;
6016
- if (config.default !== undefined) {
6017
- const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
6018
- markdown += `**Default:** \`${defaultValue}\`
6019
- `;
6020
- } else {
6021
- markdown += `**Default:** *Required*
6022
- `;
6023
- }
6024
- markdown += `
6025
- `;
6026
- }
6027
- return markdown;
6028
- }
6029
- function generateEnvColored() {
6030
- const configs = Object.values(envRegistry);
6031
- if (configs.length === 0) {
6032
- return `\x1B[1;36mEnvironment Variables\x1B[0m
6033
-
6034
- No environment variables registered.
6035
- `;
6036
- }
6037
- let output = `\x1B[1;36mEnvironment Variables\x1B[0m
6038
-
6039
- `;
6040
- for (const config of configs) {
6041
- output += `\x1B[1;33m${config.name}\x1B[0m
6042
- `;
6043
- output += `${config.description}
6044
- `;
6045
- output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m
6046
- `;
6047
- if (config.default !== undefined) {
6048
- const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
6049
- output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
6050
- `;
6051
- } else {
6052
- output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
6053
- `;
6054
- }
6055
- output += `
6056
- `;
6057
- }
6058
- return output;
6059
- }
6060
- var env = new Proxy({}, {
6061
- get(target, prop) {
6062
- if (typeof prop !== "string") {
6063
- return;
6064
- }
6065
- return envStore.get(prop);
6066
- },
6067
- has(target, prop) {
6068
- return envStore.has(prop);
6069
- },
6070
- ownKeys() {
6071
- return Object.keys(envRegistry);
6072
- },
6073
- getOwnPropertyDescriptor(target, prop) {
6074
- if (envStore.has(prop)) {
6075
- return {
6076
- enumerable: true,
6077
- configurable: true,
6078
- get: () => envStore.get(prop)
6079
- };
6080
- }
6081
- return;
6082
- }
6083
- });
6084
6235
  // src/lib/stdin-parser.ts
6085
6236
  import { Buffer as Buffer3 } from "node:buffer";
6086
6237
  var DEFAULT_TIMEOUT_MS = 20;
@@ -6295,6 +6446,31 @@ function canStillBeStartupCursorCprPrefix(state) {
6295
6446
  function canStillBePixelResolution(state) {
6296
6447
  return state.firstParamValue === 4 && state.semicolons === 2;
6297
6448
  }
6449
+ function canStillBePixelResolutionPrefix(bytes) {
6450
+ const fixedPrefix = [ESC, 91, 52, 59];
6451
+ const fixedLength = Math.min(bytes.length, fixedPrefix.length);
6452
+ for (let index2 = 0;index2 < fixedLength; index2 += 1) {
6453
+ if (bytes[index2] !== fixedPrefix[index2])
6454
+ return false;
6455
+ }
6456
+ if (bytes.length <= fixedPrefix.length)
6457
+ return bytes.length > 0;
6458
+ let index = fixedPrefix.length;
6459
+ const heightStart = index;
6460
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6461
+ index += 1;
6462
+ if (index === bytes.length)
6463
+ return index > heightStart;
6464
+ if (index === heightStart || bytes[index] !== 59)
6465
+ return false;
6466
+ index += 1;
6467
+ const widthStart = index;
6468
+ while (index < bytes.length && isAsciiDigit(bytes[index]))
6469
+ index += 1;
6470
+ if (index === bytes.length)
6471
+ return true;
6472
+ return index > widthStart && bytes[index] === 116;
6473
+ }
6298
6474
  function canDeferParametricCsi(state, context) {
6299
6475
  return context.kittyKeyboardEnabled && (canStillBeKittyU(state) || canStillBeKittySpecial(state)) || context.explicitWidthCprActive && canStillBeExplicitWidthCpr(state) || context.startupCursorCprActive && canStillBeStartupCursorCpr(state) || context.pixelResolutionQueryActive && canStillBePixelResolution(state);
6300
6476
  }
@@ -6417,6 +6593,8 @@ class StdinParser {
6417
6593
  timeoutId = null;
6418
6594
  destroyed = false;
6419
6595
  pendingSinceMs = null;
6596
+ pendingTimeoutPaused = false;
6597
+ suspendedPixelResolutionPrefixLength = 0;
6420
6598
  forceFlush = false;
6421
6599
  justFlushedEsc = false;
6422
6600
  state = { tag: "ground" };
@@ -6445,6 +6623,12 @@ class StdinParser {
6445
6623
  updateProtocolContext(patch) {
6446
6624
  this.ensureAlive();
6447
6625
  this.protocolContext = { ...this.protocolContext, ...patch };
6626
+ if (!this.protocolContext.pixelResolutionQueryActive && this.suspendedPixelResolutionPrefixLength > 0) {
6627
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6628
+ this.state = { tag: "ground" };
6629
+ this.consumePrefix(prefixLength);
6630
+ this.scanPending();
6631
+ }
6448
6632
  this.reconcileDeferredStateWithProtocolContext();
6449
6633
  this.reconcileTimeoutState();
6450
6634
  }
@@ -6519,6 +6703,11 @@ class StdinParser {
6519
6703
  const appendEnd = immediatePasteStartIndex === -1 ? remainder.length : immediatePasteStartIndex + BRACKETED_PASTE_START.length;
6520
6704
  this.pending.append(remainder.subarray(0, appendEnd));
6521
6705
  remainder = remainder.subarray(appendEnd);
6706
+ if (this.suspendedPixelResolutionPrefixLength > 0 && this.protocolContext.pixelResolutionQueryActive && !canStillBePixelResolutionPrefix(this.pending.view())) {
6707
+ const prefixLength = this.suspendedPixelResolutionPrefixLength;
6708
+ this.state = { tag: "ground" };
6709
+ this.consumePrefix(prefixLength);
6710
+ }
6522
6711
  this.scanPending();
6523
6712
  if (this.paste && this.pending.length > 0) {
6524
6713
  remainder = this.consumePasteBytes(this.takePendingBytes());
@@ -6575,6 +6764,23 @@ class StdinParser {
6575
6764
  this.clearTimeout();
6576
6765
  this.resetState();
6577
6766
  }
6767
+ hasPendingPixelResolutionResponse() {
6768
+ if (!this.protocolContext.pixelResolutionQueryActive || this.pending.length === 0)
6769
+ return false;
6770
+ return canStillBePixelResolutionPrefix(this.pending.view());
6771
+ }
6772
+ pausePendingTimeout() {
6773
+ this.ensureAlive();
6774
+ this.pendingTimeoutPaused = true;
6775
+ this.suspendedPixelResolutionPrefixLength = this.pending.length;
6776
+ this.clearTimeout();
6777
+ }
6778
+ resumePendingTimeout() {
6779
+ this.ensureAlive();
6780
+ if (this.pending.length === 0)
6781
+ this.pendingTimeoutPaused = false;
6782
+ this.reconcileTimeoutState();
6783
+ }
6578
6784
  resetMouseState() {
6579
6785
  this.ensureAlive();
6580
6786
  this.mouseParser.reset();
@@ -7402,6 +7608,8 @@ class StdinParser {
7402
7608
  }
7403
7609
  consumePrefix(endExclusive) {
7404
7610
  this.pending.consume(endExclusive);
7611
+ this.pendingTimeoutPaused = false;
7612
+ this.suspendedPixelResolutionPrefixLength = 0;
7405
7613
  this.cursor = 0;
7406
7614
  this.unitStart = 0;
7407
7615
  this.pendingSinceMs = null;
@@ -7424,6 +7632,8 @@ class StdinParser {
7424
7632
  this.cursor = 0;
7425
7633
  this.unitStart = 0;
7426
7634
  this.pendingSinceMs = null;
7635
+ this.pendingTimeoutPaused = false;
7636
+ this.suspendedPixelResolutionPrefixLength = 0;
7427
7637
  this.forceFlush = false;
7428
7638
  this.state = { tag: "ground" };
7429
7639
  }
@@ -7480,6 +7690,10 @@ class StdinParser {
7480
7690
  if (!this.armTimeouts) {
7481
7691
  return;
7482
7692
  }
7693
+ if (this.pendingTimeoutPaused) {
7694
+ this.clearTimeout();
7695
+ return;
7696
+ }
7483
7697
  if (this.paste || this.pendingSinceMs === null || this.pending.length === 0) {
7484
7698
  this.clearTimeout();
7485
7699
  return;
@@ -7509,6 +7723,8 @@ class StdinParser {
7509
7723
  this.pending.reset(INITIAL_PENDING_CAPACITY);
7510
7724
  this.events.length = 0;
7511
7725
  this.pendingSinceMs = null;
7726
+ this.pendingTimeoutPaused = false;
7727
+ this.suspendedPixelResolutionPrefixLength = 0;
7512
7728
  this.forceFlush = false;
7513
7729
  this.justFlushedEsc = false;
7514
7730
  this.state = { tag: "ground" };
@@ -7843,92 +8059,151 @@ class ProcessQueue {
7843
8059
  }
7844
8060
  }
7845
8061
 
8062
+ // src/node-asset-target.ts
8063
+ var NATIVE_FILE_NAMES = {
8064
+ darwin: "libopentui.dylib",
8065
+ linux: "libopentui.so",
8066
+ win32: "opentui.dll"
8067
+ };
8068
+ function getNativeAssetDescriptor(target) {
8069
+ if (!Object.hasOwn(NATIVE_FILE_NAMES, target.platform) || target.arch !== "arm64" && target.arch !== "x64") {
8070
+ throw new Error(`Unsupported OpenTUI Node asset target: ${String(target.platform)}-${String(target.arch)}`);
8071
+ }
8072
+ if (target.libc !== undefined && target.libc !== "glibc" && target.libc !== "musl") {
8073
+ throw new Error(`Unsupported libc for OpenTUI Node assets: ${String(target.libc)}`);
8074
+ }
8075
+ if (target.platform !== "linux" && target.libc !== undefined) {
8076
+ throw new Error(`OpenTUI Node asset target libc is only supported on Linux, got ${target.platform}`);
8077
+ }
8078
+ const libcSuffix = target.platform === "linux" && target.libc === "musl" ? "-musl" : "";
8079
+ const packageName = `@opentui/core-${target.platform}-${target.arch}${libcSuffix}`;
8080
+ const fileName = NATIVE_FILE_NAMES[target.platform];
8081
+ return {
8082
+ key: `${packageName}/${fileName}`,
8083
+ packageName,
8084
+ fileName
8085
+ };
8086
+ }
8087
+ function getCurrentNodeAssetTarget() {
8088
+ const libc = process.env.OPENTUI_LIBC;
8089
+ if (process.platform === "linux" && libc !== undefined && libc !== "" && libc !== "glibc" && libc !== "musl") {
8090
+ throw new Error(`On Linux, OPENTUI_LIBC must be unset, empty, "glibc", or "musl", got ${JSON.stringify(libc)}`);
8091
+ }
8092
+ return {
8093
+ platform: process.platform,
8094
+ arch: process.arch,
8095
+ ...process.platform === "linux" && libc === "musl" ? { libc } : {}
8096
+ };
8097
+ }
8098
+
8099
+ // src/platform/runtime-assets.node.ts
8100
+ var CORE_ASSET_PREFIX = "@opentui/core/";
8101
+ var PARSER_WORKER_ASSET_KEY = `${CORE_ASSET_PREFIX}parser.worker.js`;
8102
+ var TREE_SITTER_WASM_ASSET_KEY = "web-tree-sitter/tree-sitter.wasm";
8103
+ function resolveDefaultParserAsset(relativePath, fallbackPath) {
8104
+ return Promise.resolve(resolveAssetPath(`${CORE_ASSET_PREFIX}${relativePath}`, fallbackPath));
8105
+ }
8106
+ function resolveDefaultTreeSitterWorkerPath(fallbackPath) {
8107
+ return resolveAssetPath(PARSER_WORKER_ASSET_KEY, fallbackPath);
8108
+ }
8109
+ function resolveTreeSitterWasm() {
8110
+ return Promise.resolve(resolveAssetPath(TREE_SITTER_WASM_ASSET_KEY, () => new URL(import.meta.resolve(TREE_SITTER_WASM_ASSET_KEY))));
8111
+ }
8112
+ async function resolveNativeLibraryPath() {
8113
+ const asset = getNativeAssetDescriptor(getCurrentNodeAssetTarget());
8114
+ const configuredPath = resolveAssetRootPath(asset.key);
8115
+ if (configuredPath !== undefined) {
8116
+ return configuredPath;
8117
+ }
8118
+ const specifier = asset.packageName;
8119
+ return (await import(specifier)).default;
8120
+ }
8121
+
7846
8122
  // src/lib/tree-sitter/default-parsers.ts
7847
- var _cachedParsers;
7848
- function getParsers() {
7849
- if (!_cachedParsers) {
7850
- _cachedParsers = loadParsers();
7851
- }
7852
- return _cachedParsers;
7853
- }
7854
- async function loadParsers() {
7855
- const javascript_highlights = await resolveBundledFilePath(() => import("./assets/javascript/highlights.scm", { with: { type: "file" } }), "./assets/javascript/highlights.scm", import.meta.url);
7856
- const javascript_language = await resolveBundledFilePath(() => import("./assets/javascript/tree-sitter-javascript.wasm", { with: { type: "file" } }), "./assets/javascript/tree-sitter-javascript.wasm", import.meta.url);
7857
- const typescript_highlights = await resolveBundledFilePath(() => import("./assets/typescript/highlights.scm", { with: { type: "file" } }), "./assets/typescript/highlights.scm", import.meta.url);
7858
- const typescript_language = await resolveBundledFilePath(() => import("./assets/typescript/tree-sitter-typescript.wasm", { with: { type: "file" } }), "./assets/typescript/tree-sitter-typescript.wasm", import.meta.url);
7859
- const markdown_highlights = await resolveBundledFilePath(() => import("./assets/markdown/highlights.scm", { with: { type: "file" } }), "./assets/markdown/highlights.scm", import.meta.url);
7860
- const markdown_language = await resolveBundledFilePath(() => import("./assets/markdown/tree-sitter-markdown.wasm", { with: { type: "file" } }), "./assets/markdown/tree-sitter-markdown.wasm", import.meta.url);
7861
- const markdown_injections = await resolveBundledFilePath(() => import("./assets/markdown/injections.scm", { with: { type: "file" } }), "./assets/markdown/injections.scm", import.meta.url);
7862
- const markdown_inline_highlights = await resolveBundledFilePath(() => import("./assets/markdown_inline/highlights.scm", { with: { type: "file" } }), "./assets/markdown_inline/highlights.scm", import.meta.url);
7863
- const markdown_inline_language = await resolveBundledFilePath(() => import("./assets/markdown_inline/tree-sitter-markdown_inline.wasm", { with: { type: "file" } }), "./assets/markdown_inline/tree-sitter-markdown_inline.wasm", import.meta.url);
7864
- const zig_highlights = await resolveBundledFilePath(() => import("./assets/zig/highlights.scm", { with: { type: "file" } }), "./assets/zig/highlights.scm", import.meta.url);
7865
- const zig_language = await resolveBundledFilePath(() => import("./assets/zig/tree-sitter-zig.wasm", { with: { type: "file" } }), "./assets/zig/tree-sitter-zig.wasm", import.meta.url);
7866
- return [
7867
- {
7868
- filetype: "javascript",
7869
- aliases: ["javascriptreact"],
7870
- queries: {
7871
- highlights: [javascript_highlights]
7872
- },
7873
- wasm: javascript_language
7874
- },
7875
- {
7876
- filetype: "typescript",
7877
- aliases: ["typescriptreact"],
7878
- queries: {
7879
- highlights: [typescript_highlights]
7880
- },
7881
- wasm: typescript_language
7882
- },
7883
- {
7884
- filetype: "markdown",
7885
- queries: {
7886
- highlights: [markdown_highlights],
7887
- injections: [markdown_injections]
7888
- },
7889
- wasm: markdown_language,
7890
- injectionMapping: {
7891
- nodeTypes: {
7892
- inline: "markdown_inline",
7893
- pipe_table_cell: "markdown_inline"
7894
- },
7895
- infoStringMap: {
7896
- javascript: "javascript",
7897
- js: "javascript",
7898
- jsx: "javascriptreact",
7899
- javascriptreact: "javascriptreact",
7900
- typescript: "typescript",
7901
- ts: "typescript",
7902
- tsx: "typescriptreact",
7903
- typescriptreact: "typescriptreact",
7904
- markdown: "markdown",
7905
- md: "markdown"
7906
- }
8123
+ var defaultParserDescriptors = [
8124
+ {
8125
+ filetype: "javascript",
8126
+ aliases: ["javascriptreact"],
8127
+ queries: { highlights: ["assets/javascript/highlights.scm"] },
8128
+ wasm: "assets/javascript/tree-sitter-javascript.wasm"
8129
+ },
8130
+ {
8131
+ filetype: "typescript",
8132
+ aliases: ["typescriptreact"],
8133
+ queries: { highlights: ["assets/typescript/highlights.scm"] },
8134
+ wasm: "assets/typescript/tree-sitter-typescript.wasm"
8135
+ },
8136
+ {
8137
+ filetype: "markdown",
8138
+ queries: {
8139
+ highlights: ["assets/markdown/highlights.scm"],
8140
+ injections: ["assets/markdown/injections.scm"]
8141
+ },
8142
+ wasm: "assets/markdown/tree-sitter-markdown.wasm",
8143
+ injectionMapping: {
8144
+ nodeTypes: { inline: "markdown_inline", pipe_table_cell: "markdown_inline" },
8145
+ infoStringMap: {
8146
+ javascript: "javascript",
8147
+ js: "javascript",
8148
+ jsx: "javascriptreact",
8149
+ javascriptreact: "javascriptreact",
8150
+ typescript: "typescript",
8151
+ ts: "typescript",
8152
+ tsx: "typescriptreact",
8153
+ typescriptreact: "typescriptreact",
8154
+ markdown: "markdown",
8155
+ md: "markdown"
7907
8156
  }
7908
- },
7909
- {
7910
- filetype: "markdown_inline",
7911
- queries: {
7912
- highlights: [markdown_inline_highlights]
7913
- },
7914
- wasm: markdown_inline_language
7915
- },
7916
- {
7917
- filetype: "zig",
7918
- queries: {
7919
- highlights: [zig_highlights]
7920
- },
7921
- wasm: zig_language
7922
8157
  }
7923
- ];
8158
+ },
8159
+ {
8160
+ filetype: "markdown_inline",
8161
+ queries: { highlights: ["assets/markdown_inline/highlights.scm"] },
8162
+ wasm: "assets/markdown_inline/tree-sitter-markdown_inline.wasm"
8163
+ },
8164
+ {
8165
+ filetype: "zig",
8166
+ queries: { highlights: ["assets/zig/highlights.scm"] },
8167
+ wasm: "assets/zig/tree-sitter-zig.wasm"
8168
+ }
8169
+ ];
8170
+ var defaultParserAssetPaths = [
8171
+ ...new Set(defaultParserDescriptors.flatMap((parser) => [
8172
+ ...parser.queries.highlights,
8173
+ parser.wasm,
8174
+ ...parser.queries.injections ?? []
8175
+ ]))
8176
+ ];
8177
+ var cachedParsers;
8178
+ function getParsers() {
8179
+ cachedParsers ??= Promise.all(defaultParserDescriptors.map(resolveDefaultParser));
8180
+ return cachedParsers;
8181
+ }
8182
+ async function resolveDefaultParser(parser) {
8183
+ const queries = {
8184
+ highlights: await Promise.all(parser.queries.highlights.map(resolveParserAsset))
8185
+ };
8186
+ if (parser.queries.injections) {
8187
+ queries.injections = await Promise.all(parser.queries.injections.map(resolveParserAsset));
8188
+ }
8189
+ return {
8190
+ filetype: parser.filetype,
8191
+ ...parser.aliases ? { aliases: [...parser.aliases] } : {},
8192
+ queries,
8193
+ wasm: await resolveParserAsset(parser.wasm),
8194
+ ...parser.injectionMapping ? { injectionMapping: parser.injectionMapping } : {}
8195
+ };
8196
+ }
8197
+ function resolveParserAsset(relativePath) {
8198
+ return resolveDefaultParserAsset(relativePath, new URL(`./${relativePath}`, import.meta.url));
7924
8199
  }
7925
8200
 
7926
8201
  // src/lib/tree-sitter/client.ts
7927
- import { resolve as resolve2, isAbsolute as isAbsolute2, parse } from "path";
8202
+ import { resolve as resolve2, isAbsolute as isAbsolute3, parse } from "path";
7928
8203
  import { existsSync as existsSync2 } from "fs";
7929
8204
 
7930
8205
  // src/lib/bunfs.ts
7931
- import { basename, join } from "node:path";
8206
+ import { basename, join as join2 } from "node:path";
7932
8207
  function isBunfsPath(path) {
7933
8208
  return path.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path);
7934
8209
  }
@@ -7936,7 +8211,7 @@ function getBunfsRootPath() {
7936
8211
  return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
7937
8212
  }
7938
8213
  function normalizeBunfsPath(fileName) {
7939
- return join(getBunfsRootPath(), basename(fileName));
8214
+ return join2(getBunfsRootPath(), basename(fileName));
7940
8215
  }
7941
8216
 
7942
8217
  // src/platform/worker.ts
@@ -8323,8 +8598,8 @@ class TreeSitterClient extends EventEmitter2 {
8323
8598
  if (typeof OTUI_TREE_SITTER_WORKER_PATH !== "undefined") {
8324
8599
  return OTUI_TREE_SITTER_WORKER_PATH;
8325
8600
  }
8326
- let workerPath = new URL("./parser.worker.js", import.meta.url).href;
8327
- if (!existsSync2(resolve2(import.meta.dirname, "parser.worker.js"))) {
8601
+ let workerPath = resolveDefaultTreeSitterWorkerPath(new URL("./parser.worker.js", import.meta.url));
8602
+ if (!process.env.OTUI_ASSET_ROOT && !existsSync2(workerPath)) {
8328
8603
  workerPath = new URL("./parser.worker.ts", import.meta.url).href;
8329
8604
  }
8330
8605
  return workerPath;
@@ -8401,6 +8676,8 @@ class TreeSitterClient extends EventEmitter2 {
8401
8676
  }
8402
8677
  }
8403
8678
  async initializeClient(generation, worker) {
8679
+ const treeSitterWasmPath = await resolveTreeSitterWasm();
8680
+ this.assertCurrentInitialization(generation, worker);
8404
8681
  await new Promise((resolve3, reject) => {
8405
8682
  const timeoutMs = this.options.initTimeout ?? 1e4;
8406
8683
  const timeoutId = setTimeout(() => {
@@ -8412,7 +8689,8 @@ class TreeSitterClient extends EventEmitter2 {
8412
8689
  this.initializeResolvers = { resolve: resolve3, reject, timeoutId };
8413
8690
  this.sendWorkerMessage({
8414
8691
  type: "INIT",
8415
- dataPath: this.options.dataPath
8692
+ dataPath: this.options.dataPath,
8693
+ treeSitterWasmPath
8416
8694
  });
8417
8695
  });
8418
8696
  this.assertCurrentInitialization(generation, worker);
@@ -8438,7 +8716,7 @@ class TreeSitterClient extends EventEmitter2 {
8438
8716
  if (isBunfsPath(path)) {
8439
8717
  return normalizeBunfsPath(parse(path).base);
8440
8718
  }
8441
- if (!isAbsolute2(path)) {
8719
+ if (!isAbsolute3(path)) {
8442
8720
  return resolve2(path);
8443
8721
  }
8444
8722
  return path;
@@ -10325,6 +10603,11 @@ function detectLinks(chunks, context) {
10325
10603
  return chunks;
10326
10604
  }
10327
10605
  // src/buffer.ts
10606
+ function requireInteger(value, name, min, max) {
10607
+ if (!Number.isSafeInteger(value) || value < min || value > max) {
10608
+ throw new RangeError(`${name} must be an integer from ${min} to ${max}`);
10609
+ }
10610
+ }
10328
10611
  function packDrawOptions(border2, shouldFill, titleAlignment, bottomTitleAlignment) {
10329
10612
  let packed = 0;
10330
10613
  if (border2 === true) {
@@ -10563,6 +10846,23 @@ class OptimizedBuffer {
10563
10846
  this.guard();
10564
10847
  this.lib.bufferDrawSuperSampleBuffer(this.bufferPtr, x, y, toPointer(pixelDataPtr), pixelDataLength, format, alignedBytesPerRow);
10565
10848
  }
10849
+ drawImage(image, x, y, width, height, pixelWidth = 0, pixelHeight = 0, sourceX = 0, sourceY = 0, sourceWidth = image.width, sourceHeight = image.height, protocol = "auto") {
10850
+ this.guard();
10851
+ requireInteger(x, "x", -2147483648, 2147483647);
10852
+ requireInteger(y, "y", -2147483648, 2147483647);
10853
+ requireInteger(width, "width", 1, 2147483647);
10854
+ requireInteger(height, "height", 1, 2147483647);
10855
+ requireInteger(pixelWidth, "pixelWidth", 0, 2147483647);
10856
+ requireInteger(pixelHeight, "pixelHeight", 0, 2147483647);
10857
+ requireInteger(sourceX, "sourceX", 0, 4294967295);
10858
+ requireInteger(sourceY, "sourceY", 0, 4294967295);
10859
+ requireInteger(sourceWidth, "sourceWidth", 1, 4294967295);
10860
+ requireInteger(sourceHeight, "sourceHeight", 1, 4294967295);
10861
+ if (x + width > 2147483647 || y + height > 2147483647) {
10862
+ throw new RangeError("image destination coordinates and dimensions exceed i32 bounds");
10863
+ }
10864
+ return this.lib.bufferDrawImage(this.bufferPtr, image.ptr, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol);
10865
+ }
10566
10866
  drawPackedBuffer(dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
10567
10867
  this.guard();
10568
10868
  this.lib.bufferDrawPackedBuffer(this.bufferPtr, toPointer(dataPtr), dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
@@ -10832,8 +11132,8 @@ class TextBuffer {
10832
11132
  }
10833
11133
  }
10834
11134
 
10835
- // ../../node_modules/.bun/bun-ffi-structs@0.2.4+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
10836
- var FFI_LOAD_ERROR = "bun-ffi-structs requires Bun or Node.js with node:ffi enabled (--experimental-ffi --allow-ffi).";
11135
+ // ../../node_modules/.bun/bun-ffi-structs@0.3.1+1fb4c65d43e298b9/node_modules/bun-ffi-structs/dist/index.js
11136
+ var FFI_LOAD_ERROR = "bun-ffi-structs pointer operations require Bun or Node.js 26.1+ with node:ffi enabled (--experimental-ffi).";
10837
11137
  var backend2 = await loadBackend2();
10838
11138
  function unavailable2(cause) {
10839
11139
  throw new Error(FFI_LOAD_ERROR, {
@@ -10875,7 +11175,8 @@ function createNodeBackend2(nodeFfi) {
10875
11175
  return {
10876
11176
  ptr(value) {
10877
11177
  if (ArrayBuffer.isView(value)) {
10878
- return nodeFfi.getRawPointer(value.buffer) + BigInt(value.byteOffset);
11178
+ const pointer = nodeFfi.getRawPointer(value.buffer);
11179
+ return value.byteOffset === 0 ? pointer : pointer + BigInt(value.byteOffset);
10879
11180
  }
10880
11181
  if (value instanceof ArrayBuffer) {
10881
11182
  return nodeFfi.getRawPointer(value);
@@ -10938,6 +11239,30 @@ var typeGetters = {
10938
11239
  function isObjectPointerDef(type) {
10939
11240
  return typeof type === "object" && type !== null && type.__type === "objectPointer";
10940
11241
  }
11242
+ function allocStruct(structDef, options) {
11243
+ const buffer = new ArrayBuffer(structDef.size);
11244
+ const view = new DataView(buffer);
11245
+ const result = { buffer, view };
11246
+ if (options?.lengths) {
11247
+ const subBuffers = {};
11248
+ for (const [arrayFieldName, length] of Object.entries(options.lengths)) {
11249
+ const arrayMeta = structDef.arrayFields.get(arrayFieldName);
11250
+ if (!arrayMeta) {
11251
+ throw new Error(`Field '${arrayFieldName}' is not an array field with a lengthOf field`);
11252
+ }
11253
+ const subBuffer = new ArrayBuffer(length * arrayMeta.elementSize);
11254
+ subBuffers[arrayFieldName] = subBuffer;
11255
+ const pointer = length > 0 ? ptr2(subBuffer) : null;
11256
+ pointerPacker(view, arrayMeta.arrayOffset, pointer);
11257
+ retainPointerTarget(buffer, subBuffer);
11258
+ arrayMeta.lengthPack(view, arrayMeta.lengthOffset, length);
11259
+ }
11260
+ if (Object.keys(subBuffers).length > 0) {
11261
+ result.subBuffers = subBuffers;
11262
+ }
11263
+ }
11264
+ return result;
11265
+ }
10941
11266
  function alignOffset(offset, align) {
10942
11267
  return offset + (align - 1) & ~(align - 1);
10943
11268
  }
@@ -10961,9 +11286,48 @@ function defineEnum(mapping, base = "u32") {
10961
11286
  function isEnum(type) {
10962
11287
  return typeof type === "object" && type.__type === "enum";
10963
11288
  }
11289
+ function hasPlainPrimitiveRuntimeOptions(options) {
11290
+ return options.optional === true || options.unpackTransform !== undefined || options.packTransform !== undefined || options.lengthOf !== undefined || options.default !== undefined || options.validate !== undefined;
11291
+ }
10964
11292
  function isStruct(type) {
10965
11293
  return typeof type === "object" && type.__type === "struct";
10966
11294
  }
11295
+ var structInternals = new WeakMap;
11296
+ var freshPackBuffers = new WeakSet;
11297
+ function packInlineStruct(internals, view, baseOffset, obj, options) {
11298
+ let mappedObj = internals.options?.mapValue ? internals.options.mapValue(obj) : obj;
11299
+ if (internals.materializeArrayIterables)
11300
+ mappedObj = internals.materializeArrayIterables(mappedObj);
11301
+ for (const field of internals.layout) {
11302
+ const value = mappedObj[field.name] ?? field.default;
11303
+ if (!field.optional && value === undefined) {
11304
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11305
+ }
11306
+ if (field.validate) {
11307
+ for (const validateFn of field.validate) {
11308
+ validateFn(value, field.name, {
11309
+ hints: options?.validationHints,
11310
+ input: mappedObj
11311
+ });
11312
+ }
11313
+ }
11314
+ field.pack(view, baseOffset + field.offset, value, mappedObj, options);
11315
+ }
11316
+ }
11317
+ function unpackInlineStruct(internals, view, baseOffset) {
11318
+ const result = internals.options?.default ? { ...internals.options.default } : {};
11319
+ for (const field of internals.layout) {
11320
+ if (!field.unpack)
11321
+ continue;
11322
+ try {
11323
+ result[field.name] = field.unpack(view, baseOffset + field.offset);
11324
+ } catch (error) {
11325
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
11326
+ throw error;
11327
+ }
11328
+ }
11329
+ return internals.options?.reduceValue ? internals.options.reduceValue(result) : result;
11330
+ }
10967
11331
  function primitivePackers(type) {
10968
11332
  let pack;
10969
11333
  let unpack;
@@ -11013,23 +11377,254 @@ function primitivePackers(type) {
11013
11377
  unpack = (view, off) => view.getFloat64(off, true);
11014
11378
  break;
11015
11379
  case "pointer":
11016
- pack = (view, off, val) => {
11017
- pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11018
- };
11019
- unpack = (view, off) => {
11020
- if (pointerSize === 8) {
11021
- const value = view.getBigUint64(off, true);
11022
- return isBun2 ? Number(value) : value;
11023
- }
11024
- return view.getUint32(off, true);
11025
- };
11026
- break;
11027
- default:
11028
- fatalError(`Unsupported primitive type: ${type}`);
11380
+ if (pointerSize === 8 && isBun2) {
11381
+ pack = (view, off, val) => {
11382
+ if (!val) {
11383
+ view.setUint32(off, 0, true);
11384
+ view.setUint32(off + 4, 0, true);
11385
+ } else if (typeof val === "number" && Number.isInteger(val)) {
11386
+ view.setUint32(off, val, true);
11387
+ view.setUint32(off + 4, Math.floor(val / 4294967296), true);
11388
+ } else {
11389
+ view.setBigUint64(off, BigInt(val), true);
11390
+ }
11391
+ };
11392
+ unpack = (view, off) => view.getUint32(off, true) + view.getUint32(off + 4, true) * 4294967296;
11393
+ } else {
11394
+ pack = (view, off, val) => {
11395
+ pointerSize === 8 ? view.setBigUint64(off, val ? BigInt(val) : 0n, true) : view.setUint32(off, val ? Number(val) : 0, true);
11396
+ };
11397
+ unpack = (view, off) => {
11398
+ if (pointerSize === 8) {
11399
+ const value = view.getBigUint64(off, true);
11400
+ return isBun2 ? Number(value) : value;
11401
+ }
11402
+ return view.getUint32(off, true);
11403
+ };
11404
+ }
11405
+ break;
11406
+ default:
11407
+ fatalError(`Unsupported primitive type: ${type}`);
11029
11408
  }
11030
11409
  return { pack, unpack };
11031
11410
  }
11411
+ function primitiveSetterSource(type, offset, value) {
11412
+ const target = `baseOffset + ${offset}`;
11413
+ switch (type) {
11414
+ case "u8":
11415
+ return `view.setUint8(${target}, ${value})`;
11416
+ case "bool_u8":
11417
+ return `view.setUint8(${target}, ${value} ? 1 : 0)`;
11418
+ case "bool_u32":
11419
+ return `view.setUint32(${target}, ${value} ? 1 : 0, true)`;
11420
+ case "u16":
11421
+ return `view.setUint16(${target}, ${value}, true)`;
11422
+ case "i16":
11423
+ return `view.setInt16(${target}, ${value}, true)`;
11424
+ case "u32":
11425
+ return `view.setUint32(${target}, ${value}, true)`;
11426
+ case "i32":
11427
+ return `view.setInt32(${target}, ${value}, true)`;
11428
+ case "i64":
11429
+ return `view.setBigInt64(${target}, BigInt(${value}), true)`;
11430
+ case "u64":
11431
+ return `view.setBigUint64(${target}, BigInt(${value}), true)`;
11432
+ case "f32":
11433
+ return `view.setFloat32(${target}, ${value}, true)`;
11434
+ case "f64":
11435
+ return `view.setFloat64(${target}, ${value}, true)`;
11436
+ }
11437
+ }
11438
+ function primitiveGetterSource(type, offset) {
11439
+ const target = `baseOffset + ${offset}`;
11440
+ switch (type) {
11441
+ case "u8":
11442
+ return `view.getUint8(${target})`;
11443
+ case "bool_u8":
11444
+ return `Boolean(view.getUint8(${target}))`;
11445
+ case "bool_u32":
11446
+ return `Boolean(view.getUint32(${target}, true))`;
11447
+ case "u16":
11448
+ return `view.getUint16(${target}, true)`;
11449
+ case "i16":
11450
+ return `view.getInt16(${target}, true)`;
11451
+ case "u32":
11452
+ return `view.getUint32(${target}, true)`;
11453
+ case "i32":
11454
+ return `view.getInt32(${target}, true)`;
11455
+ case "i64":
11456
+ return `view.getBigInt64(${target}, true)`;
11457
+ case "u64":
11458
+ return `view.getBigUint64(${target}, true)`;
11459
+ case "f32":
11460
+ return `view.getFloat32(${target}, true)`;
11461
+ case "f64":
11462
+ return `view.getFloat64(${target}, true)`;
11463
+ case "pointer":
11464
+ if (pointerSize === 8 && isBun2) {
11465
+ return `view.getUint32(${target}, true) + view.getUint32(${target} + 4, true) * 0x100000000`;
11466
+ }
11467
+ return pointerSize === 8 ? `view.getBigUint64(${target}, true)` : `view.getUint32(${target}, true)`;
11468
+ }
11469
+ }
11470
+ function compilePlainPrimitivePackList(fields, totalSize) {
11471
+ const writes = fields.map((field, index) => {
11472
+ const value = `value${index}`;
11473
+ const missing = `Packing non-optional field '${field.name}' at index `;
11474
+ return `
11475
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11476
+ if (${value} === undefined) fatalError(${JSON.stringify(missing)} + index + ${JSON.stringify(" but value is undefined (and no default provided)")})
11477
+ ${primitiveSetterSource(field.type, field.offset, value)}
11478
+ `;
11479
+ }).join(`
11480
+ `);
11481
+ return new Function("fatalError", `return function packPlainPrimitiveList(objects) {
11482
+ const buffer = new ArrayBuffer(${totalSize} * objects.length)
11483
+ const view = new DataView(buffer)
11484
+ for (let index = 0, baseOffset = 0; index < objects.length; index++, baseOffset += ${totalSize}) {
11485
+ const obj = objects[index]
11486
+ ${writes}
11487
+ }
11488
+ return buffer
11489
+ }`)(fatalError);
11490
+ }
11491
+ function compilePlainPrimitivePack(fields, totalSize) {
11492
+ const writes = fields.map((field, index) => {
11493
+ const value = `value${index}`;
11494
+ return `
11495
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11496
+ if (${value} === undefined) fatalError(${JSON.stringify(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`)})
11497
+ ${primitiveSetterSource(field.type, field.offset, value)}
11498
+ `;
11499
+ }).join(`
11500
+ `);
11501
+ return new Function("fatalError", `return function packPlainPrimitive(obj) {
11502
+ const buffer = new ArrayBuffer(${totalSize})
11503
+ const view = new DataView(buffer)
11504
+ let baseOffset = 0
11505
+ ${writes}
11506
+ return buffer
11507
+ }`)(fatalError);
11508
+ }
11509
+ function compilePlainPrimitivePackInto(fields) {
11510
+ const writes = fields.map((field, index) => {
11511
+ const value = `value${index}`;
11512
+ return `
11513
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11514
+ if (${value} === undefined) {
11515
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11516
+ }
11517
+ ${primitiveSetterSource(field.type, field.offset, value)}
11518
+ `;
11519
+ }).join(`
11520
+ `);
11521
+ return new Function(`return function packPlainPrimitiveInto(obj, view, baseOffset) {
11522
+ ${writes}
11523
+ }`)();
11524
+ }
11525
+ function compilePlainPrimitivePackListInto(fields, totalSize) {
11526
+ const writes = fields.map((field, index) => {
11527
+ const value = `value${index}`;
11528
+ return `
11529
+ const ${value} = obj[${JSON.stringify(field.name)}] ?? undefined
11530
+ if (${value} === undefined) {
11531
+ console.warn(${JSON.stringify(`packInto missing value for non-optional field '${field.name}' at offset `)} + (baseOffset + ${field.offset}) + ${JSON.stringify(". Writing default or zero.")})
11532
+ }
11533
+ ${primitiveSetterSource(field.type, field.offset, value)}
11534
+ `;
11535
+ }).join(`
11536
+ `);
11537
+ return new Function(`return function packPlainPrimitiveListInto(objects, view, initialOffset) {
11538
+ for (let index = 0, baseOffset = initialOffset; index < objects.length; index++, baseOffset += ${totalSize}) {
11539
+ const obj = objects[index]
11540
+ ${writes}
11541
+ }
11542
+ }`)();
11543
+ }
11544
+ function compilePlainPrimitiveUnpackList(fields, totalSize) {
11545
+ const reads = fields.map((field, index) => `
11546
+ let value${index}
11547
+ try {
11548
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11549
+ } catch (error) {
11550
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11551
+ throw error
11552
+ }
11553
+ `).join(`
11554
+ `);
11555
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11556
+ return new Function(`return function unpackPlainPrimitiveList(view, count) {
11557
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11558
+ const results = preallocated ? new Array(count) : []
11559
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11560
+ ${reads}
11561
+ const value = { ${properties} }
11562
+ if (preallocated) results[index] = value
11563
+ else results.push(value)
11564
+ }
11565
+ return results
11566
+ }`)();
11567
+ }
11568
+ function compileReducedPrimitiveUnpackList(fields, totalSize, options) {
11569
+ const reads = fields.map((field, index) => `
11570
+ let value${index}
11571
+ try {
11572
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11573
+ } catch (error) {
11574
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at index `)} + index + ${JSON.stringify(", offset ")} + (baseOffset + ${field.offset}) + ":", error)
11575
+ throw error
11576
+ }
11577
+ `).join(`
11578
+ `);
11579
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11580
+ return new Function("options", `return function unpackReducedPrimitiveList(view, count) {
11581
+ const preallocated = Number.isSafeInteger(count) && count >= ${arrayPreallocationThreshold} && count <= ${maxArrayLength}
11582
+ const results = preallocated ? new Array(count) : []
11583
+ for (let index = 0, baseOffset = 0; index < count; index++, baseOffset += ${totalSize}) {
11584
+ ${reads}
11585
+ const raw = { ${properties} }
11586
+ const value = options.reduceValue ? options.reduceValue(raw) : raw
11587
+ if (preallocated) results[index] = value
11588
+ else results.push(value)
11589
+ }
11590
+ return results
11591
+ }`)(options);
11592
+ }
11593
+ function compilePlainPrimitiveUnpack(fields) {
11594
+ const reads = fields.map((field, index) => `
11595
+ let value${index}
11596
+ try {
11597
+ value${index} = ${primitiveGetterSource(field.type, field.offset)}
11598
+ } catch (error) {
11599
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11600
+ throw error
11601
+ }
11602
+ `).join(`
11603
+ `);
11604
+ const properties = fields.map((field, index) => `${JSON.stringify(field.name)}: value${index}`).join(",");
11605
+ return new Function(`return function unpackPlainPrimitive(view) {
11606
+ let baseOffset = 0
11607
+ ${reads}
11608
+ return { ${properties} }
11609
+ }`)();
11610
+ }
11611
+ function compilePlainPrimitiveUnpackInto(fields) {
11612
+ const reads = fields.map((field) => `
11613
+ try {
11614
+ target[${JSON.stringify(field.name)}] = ${primitiveGetterSource(field.type, field.offset)}
11615
+ } catch (error) {
11616
+ console.error(${JSON.stringify(`Error unpacking field '${field.name}' at offset ${field.offset}:`)}, error)
11617
+ throw error
11618
+ }
11619
+ `).join(`
11620
+ `);
11621
+ return new Function(`return function unpackPlainPrimitiveInto(view, target, baseOffset) {
11622
+ ${reads}
11623
+ return target
11624
+ }`)();
11625
+ }
11032
11626
  var { pack: pointerPacker, unpack: pointerUnpacker } = primitivePackers("pointer");
11627
+ var foreignMemoryPointerUnpacker = pointerSize === 8 && isBun2 ? (view, off) => Number(view.getBigUint64(off, true)) : pointerUnpacker;
11033
11628
  var retainedPointerTargets = new WeakMap;
11034
11629
  function retainPointerTarget(owner, target) {
11035
11630
  const retained = retainedPointerTargets.get(owner);
@@ -11040,9 +11635,8 @@ function retainPointerTarget(owner, target) {
11040
11635
  }
11041
11636
  }
11042
11637
  function retainIfPointerTargets(owner, target) {
11043
- if (retainedPointerTargets.has(target)) {
11638
+ if (retainedPointerTargets.has(target))
11044
11639
  retainPointerTarget(owner, target);
11045
- }
11046
11640
  }
11047
11641
  function isNullPointer(pointer) {
11048
11642
  return pointer == null || pointer === 0 || pointer === 0n;
@@ -11050,6 +11644,9 @@ function isNullPointer(pointer) {
11050
11644
  function toItemCount(length) {
11051
11645
  return typeof length === "bigint" ? Number(length) : length;
11052
11646
  }
11647
+ var arrayPreallocationThreshold = 256;
11648
+ var plainPrimitiveSpecializationThreshold = 256;
11649
+ var maxArrayLength = 4294967295;
11053
11650
  function packObjectArray(val) {
11054
11651
  const buffer = new ArrayBuffer(val.length * pointerSize);
11055
11652
  const bufferView = new DataView(buffer);
@@ -11065,10 +11662,15 @@ var decoder = new TextDecoder;
11065
11662
  function defineStruct(fields, structDefOptions) {
11066
11663
  let offset = 0;
11067
11664
  let maxAlign = 1;
11665
+ let hasDirectInlinePack = false;
11666
+ let directInlineUnpackSafe = !structDefOptions?.default && !structDefOptions?.reduceValue;
11667
+ let plainPrimitiveFields = structDefOptions?.mapValue || structDefOptions?.default || structDefOptions?.reduceValue ? null : [];
11668
+ let primitiveDecodeFields = structDefOptions?.reduceValue && !structDefOptions.default ? [] : null;
11068
11669
  const layout = [];
11069
11670
  const lengthOfFields = {};
11070
11671
  const lengthOfRequested = [];
11071
11672
  const arrayFieldsMetadata = {};
11673
+ const arrayElementSizes = {};
11072
11674
  for (const [name, typeOrStruct, options = {}] of fields) {
11073
11675
  if (options.condition && !options.condition()) {
11074
11676
  continue;
@@ -11078,6 +11680,7 @@ function defineStruct(fields, structDefOptions) {
11078
11680
  let unpack;
11079
11681
  let needsLengthOf = false;
11080
11682
  let lengthOfDef = null;
11683
+ let plainPrimitiveType = null;
11081
11684
  if (isPrimitiveType(typeOrStruct)) {
11082
11685
  size = typeSizes[typeOrStruct];
11083
11686
  align = typeAlignments[typeOrStruct];
@@ -11096,7 +11699,14 @@ function defineStruct(fields, structDefOptions) {
11096
11699
  pointerPacker(view, off, val);
11097
11700
  };
11098
11701
  }
11702
+ if (plainPrimitiveFields) {
11703
+ if (typeOrStruct === "pointer" || hasPlainPrimitiveRuntimeOptions(options))
11704
+ plainPrimitiveFields = null;
11705
+ else
11706
+ plainPrimitiveType = typeOrStruct;
11707
+ }
11099
11708
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "cstring") {
11709
+ plainPrimitiveFields = null;
11100
11710
  size = pointerSize;
11101
11711
  align = pointerSize;
11102
11712
  pack = (view, off, val) => {
@@ -11114,6 +11724,7 @@ function defineStruct(fields, structDefOptions) {
11114
11724
  return ptrVal;
11115
11725
  };
11116
11726
  } else if (typeof typeOrStruct === "string" && typeOrStruct === "char*") {
11727
+ plainPrimitiveFields = null;
11117
11728
  size = pointerSize;
11118
11729
  align = pointerSize;
11119
11730
  pack = (view, off, val) => {
@@ -11132,6 +11743,8 @@ function defineStruct(fields, structDefOptions) {
11132
11743
  };
11133
11744
  needsLengthOf = true;
11134
11745
  } else if (isEnum(typeOrStruct)) {
11746
+ plainPrimitiveFields = null;
11747
+ directInlineUnpackSafe = false;
11135
11748
  const base = typeOrStruct.type;
11136
11749
  size = typeSizes[base];
11137
11750
  align = typeAlignments[base];
@@ -11145,7 +11758,9 @@ function defineStruct(fields, structDefOptions) {
11145
11758
  return typeOrStruct.from(raw);
11146
11759
  };
11147
11760
  } else if (isStruct(typeOrStruct)) {
11761
+ plainPrimitiveFields = null;
11148
11762
  if (options.asPointer === true) {
11763
+ directInlineUnpackSafe = false;
11149
11764
  size = pointerSize;
11150
11765
  align = pointerSize;
11151
11766
  pack = (view, off, val, obj, options2) => {
@@ -11163,19 +11778,33 @@ function defineStruct(fields, structDefOptions) {
11163
11778
  } else {
11164
11779
  size = typeOrStruct.size;
11165
11780
  align = typeOrStruct.align;
11166
- pack = (view, off, val, obj, options2) => {
11167
- const nestedBuf = typeOrStruct.pack(val, options2);
11781
+ const internals = structInternals.get(typeOrStruct);
11782
+ directInlineUnpackSafe &&= !!internals?.directInlineUnpackSafe;
11783
+ hasDirectInlinePack ||= !!internals && !options.optional;
11784
+ pack = (view, off, val, obj, packOptions) => {
11785
+ const publicPack = typeOrStruct.pack;
11786
+ if (internals && freshPackBuffers.has(view.buffer) && publicPack === internals.publicPack) {
11787
+ packInlineStruct(internals, view, off, val, packOptions);
11788
+ return;
11789
+ }
11790
+ const nestedBuf = Reflect.apply(publicPack, typeOrStruct, [val, packOptions]);
11168
11791
  const nestedView = new Uint8Array(nestedBuf);
11169
- const dView = new Uint8Array(view.buffer);
11792
+ const dView = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
11170
11793
  dView.set(nestedView, off);
11171
11794
  retainIfPointerTargets(view.buffer, nestedBuf);
11172
11795
  };
11173
11796
  unpack = (view, off) => {
11174
- const slice = view.buffer.slice(off, off + size);
11797
+ const publicUnpack = Object.getOwnPropertyDescriptor(typeOrStruct, "unpack")?.value;
11798
+ if (internals?.directInlineUnpackSafe && publicUnpack === internals.publicUnpack && !(view.buffer instanceof SharedArrayBuffer)) {
11799
+ return unpackInlineStruct(internals, view, off);
11800
+ }
11801
+ const start = view.byteOffset + off;
11802
+ const slice = view.buffer.slice(start, start + size);
11175
11803
  return typeOrStruct.unpack(slice);
11176
11804
  };
11177
11805
  }
11178
11806
  } else if (isObjectPointerDef(typeOrStruct)) {
11807
+ plainPrimitiveFields = null;
11179
11808
  size = pointerSize;
11180
11809
  align = pointerSize;
11181
11810
  pack = (view, off, value) => {
@@ -11191,12 +11820,15 @@ function defineStruct(fields, structDefOptions) {
11191
11820
  return pointerUnpacker(view, off);
11192
11821
  };
11193
11822
  } else if (Array.isArray(typeOrStruct) && typeOrStruct.length === 1 && typeOrStruct[0] !== undefined) {
11823
+ plainPrimitiveFields = null;
11194
11824
  const [def] = typeOrStruct;
11195
11825
  size = pointerSize;
11196
11826
  align = pointerSize;
11197
11827
  let arrayElementSize;
11198
11828
  if (isEnum(def)) {
11829
+ directInlineUnpackSafe = false;
11199
11830
  arrayElementSize = typeSizes[def.type];
11831
+ const { pack: enumPack } = primitivePackers(def.type);
11200
11832
  pack = (view, off, val, obj) => {
11201
11833
  if (!val || val.length === 0) {
11202
11834
  pointerPacker(view, off, null);
@@ -11206,7 +11838,7 @@ function defineStruct(fields, structDefOptions) {
11206
11838
  const bufferView = new DataView(buffer);
11207
11839
  for (let i = 0;i < val.length; i++) {
11208
11840
  const num = def.to(val[i]);
11209
- bufferView.setUint32(i * arrayElementSize, num, true);
11841
+ enumPack(bufferView, i * arrayElementSize, num);
11210
11842
  }
11211
11843
  pointerPacker(view, off, ptr2(buffer));
11212
11844
  retainPointerTarget(view.buffer, buffer);
@@ -11215,7 +11847,9 @@ function defineStruct(fields, structDefOptions) {
11215
11847
  needsLengthOf = true;
11216
11848
  lengthOfDef = def;
11217
11849
  } else if (isStruct(def)) {
11850
+ directInlineUnpackSafe = false;
11218
11851
  arrayElementSize = def.size;
11852
+ const defInternals = structInternals.get(def);
11219
11853
  pack = (view, off, val, obj, options2) => {
11220
11854
  if (!val || val.length === 0) {
11221
11855
  pointerPacker(view, off, null);
@@ -11223,8 +11857,19 @@ function defineStruct(fields, structDefOptions) {
11223
11857
  }
11224
11858
  const buffer = new ArrayBuffer(val.length * arrayElementSize);
11225
11859
  const bufferView = new DataView(buffer);
11226
- for (let i = 0;i < val.length; i++) {
11227
- def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11860
+ if (defInternals?.hasDirectInlinePack) {
11861
+ freshPackBuffers.add(buffer);
11862
+ try {
11863
+ for (let i = 0;i < val.length; i++) {
11864
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11865
+ }
11866
+ } finally {
11867
+ freshPackBuffers.delete(buffer);
11868
+ }
11869
+ } else {
11870
+ for (let i = 0;i < val.length; i++) {
11871
+ def.packInto(val[i], bufferView, i * arrayElementSize, options2);
11872
+ }
11228
11873
  }
11229
11874
  pointerPacker(view, off, ptr2(buffer));
11230
11875
  retainPointerTarget(view.buffer, buffer);
@@ -11252,6 +11897,7 @@ function defineStruct(fields, structDefOptions) {
11252
11897
  needsLengthOf = true;
11253
11898
  lengthOfDef = def;
11254
11899
  } else if (isObjectPointerDef(def)) {
11900
+ directInlineUnpackSafe = false;
11255
11901
  arrayElementSize = pointerSize;
11256
11902
  pack = (view, off, val) => {
11257
11903
  if (!val || val.length === 0) {
@@ -11268,21 +11914,23 @@ function defineStruct(fields, structDefOptions) {
11268
11914
  } else {
11269
11915
  throw new Error(`Unsupported array element type for ${name}: ${JSON.stringify(def)}`);
11270
11916
  }
11271
- const lengthOfField = Object.values(lengthOfFields).find((f) => f.lengthOf === name);
11272
- if (lengthOfField && isPrimitiveType(lengthOfField.type)) {
11273
- const { pack: lengthPack } = primitivePackers(lengthOfField.type);
11274
- arrayFieldsMetadata[name] = {
11275
- elementSize: arrayElementSize,
11276
- arrayOffset: offset,
11277
- lengthOffset: lengthOfField.offset,
11278
- lengthPack
11279
- };
11280
- }
11917
+ arrayElementSizes[name] = arrayElementSize;
11281
11918
  } else {
11282
11919
  throw new Error(`Unsupported field type for ${name}: ${JSON.stringify(typeOrStruct)}`);
11283
11920
  }
11284
11921
  offset = alignOffset(offset, align);
11922
+ if (plainPrimitiveFields && plainPrimitiveType) {
11923
+ plainPrimitiveFields.push({ name, offset, type: plainPrimitiveType });
11924
+ }
11925
+ if (primitiveDecodeFields) {
11926
+ if (isPrimitiveType(typeOrStruct) && !options.unpackTransform) {
11927
+ primitiveDecodeFields.push({ name, offset, type: typeOrStruct });
11928
+ } else {
11929
+ primitiveDecodeFields = null;
11930
+ }
11931
+ }
11285
11932
  if (options.unpackTransform) {
11933
+ directInlineUnpackSafe = false;
11286
11934
  const originalUnpack = unpack;
11287
11935
  unpack = (view, off) => options.unpackTransform(originalUnpack(view, off));
11288
11936
  }
@@ -11331,6 +11979,7 @@ function defineStruct(fields, structDefOptions) {
11331
11979
  default: options.default,
11332
11980
  pack,
11333
11981
  unpack,
11982
+ unpackTransform: options.unpackTransform,
11334
11983
  type: typeOrStruct,
11335
11984
  lengthOf: options.lengthOf
11336
11985
  };
@@ -11347,6 +11996,19 @@ function defineStruct(fields, structDefOptions) {
11347
11996
  offset += size;
11348
11997
  maxAlign = Math.max(maxAlign, align);
11349
11998
  }
11999
+ for (const [arrayName, lengthOfField] of Object.entries(lengthOfFields)) {
12000
+ const arrayField = layout.find((field) => field.name === arrayName);
12001
+ const elementSize = arrayElementSizes[arrayName];
12002
+ if (!arrayField || elementSize === undefined || !isPrimitiveType(lengthOfField.type))
12003
+ continue;
12004
+ const { pack: lengthPack } = primitivePackers(lengthOfField.type);
12005
+ arrayFieldsMetadata[arrayName] = {
12006
+ elementSize,
12007
+ arrayOffset: arrayField.offset,
12008
+ lengthOffset: lengthOfField.offset,
12009
+ lengthPack
12010
+ };
12011
+ }
11350
12012
  for (const { requester, def } of lengthOfRequested) {
11351
12013
  const lengthOfField = lengthOfFields[requester.name];
11352
12014
  if (!lengthOfField) {
@@ -11358,7 +12020,7 @@ function defineStruct(fields, structDefOptions) {
11358
12020
  if (def === "char*") {
11359
12021
  const relativeOffset = lengthOfField.offset - requester.offset;
11360
12022
  requester.unpack = (view, off) => {
11361
- const ptrAddress = pointerUnpacker(view, off);
12023
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11362
12024
  const length = lengthOfField.unpack(view, off + relativeOffset);
11363
12025
  if (isNullPointer(ptrAddress)) {
11364
12026
  return null;
@@ -11375,10 +12037,9 @@ function defineStruct(fields, structDefOptions) {
11375
12037
  const { unpack: primitiveUnpack } = primitivePackers(def);
11376
12038
  const relativeOffset = lengthOfField.offset - requester.offset;
11377
12039
  requester.unpack = (view, off) => {
11378
- const result = [];
11379
12040
  const length = lengthOfField.unpack(view, off + relativeOffset);
11380
12041
  const itemCount = toItemCount(length);
11381
- const ptrAddress = pointerUnpacker(view, off);
12042
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11382
12043
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11383
12044
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11384
12045
  }
@@ -11387,19 +12048,26 @@ function defineStruct(fields, structDefOptions) {
11387
12048
  }
11388
12049
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11389
12050
  const bufferView = new DataView(buffer);
11390
- for (let i = 0;i < itemCount; i++) {
11391
- result.push(primitiveUnpack(bufferView, i * elemSize));
12051
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12052
+ const result2 = new Array(itemCount);
12053
+ for (let i = 0;i < itemCount; i++) {
12054
+ result2[i] = primitiveUnpack(bufferView, i * elemSize);
12055
+ }
12056
+ return result2;
11392
12057
  }
12058
+ const result = [];
12059
+ for (let i = 0;i < itemCount; i++)
12060
+ result.push(primitiveUnpack(bufferView, i * elemSize));
11393
12061
  return result;
11394
12062
  };
11395
12063
  } else {
11396
- const elemSize = def.type === "u32" ? 4 : 8;
12064
+ const elemSize = typeSizes[def.type];
12065
+ const { unpack: enumUnpack } = primitivePackers(def.type);
11397
12066
  const relativeOffset = lengthOfField.offset - requester.offset;
11398
12067
  requester.unpack = (view, off) => {
11399
- const result = [];
11400
12068
  const length = lengthOfField.unpack(view, off + relativeOffset);
11401
12069
  const itemCount = toItemCount(length);
11402
- const ptrAddress = pointerUnpacker(view, off);
12070
+ const ptrAddress = foreignMemoryPointerUnpacker(view, off);
11403
12071
  if (isNullPointer(ptrAddress) && itemCount > 0) {
11404
12072
  throw new Error(`Array field ${requester.name} has null pointer but length ${length}.`);
11405
12073
  }
@@ -11408,12 +12076,23 @@ function defineStruct(fields, structDefOptions) {
11408
12076
  }
11409
12077
  const buffer = toArrayBuffer2(ptrAddress, 0, itemCount * elemSize);
11410
12078
  const bufferView = new DataView(buffer);
11411
- for (let i = 0;i < itemCount; i++) {
11412
- result.push(def.from(bufferView.getUint32(i * elemSize, true)));
12079
+ if (Number.isSafeInteger(itemCount) && itemCount >= arrayPreallocationThreshold && itemCount <= maxArrayLength) {
12080
+ const result2 = new Array(itemCount);
12081
+ for (let i = 0;i < itemCount; i++) {
12082
+ result2[i] = def.from(enumUnpack(bufferView, i * elemSize));
12083
+ }
12084
+ return result2;
11413
12085
  }
12086
+ const result = [];
12087
+ for (let i = 0;i < itemCount; i++)
12088
+ result.push(def.from(enumUnpack(bufferView, i * elemSize)));
11414
12089
  return result;
11415
12090
  };
11416
12091
  }
12092
+ if (requester.unpackTransform) {
12093
+ const originalUnpack = requester.unpack;
12094
+ requester.unpack = (view, off) => requester.unpackTransform(originalUnpack(view, off));
12095
+ }
11417
12096
  }
11418
12097
  const totalSize = alignOffset(offset, maxAlign);
11419
12098
  const description = layout.map((f) => ({
@@ -11427,7 +12106,87 @@ function defineStruct(fields, structDefOptions) {
11427
12106
  }));
11428
12107
  const layoutByName = new Map(description.map((f) => [f.name, f]));
11429
12108
  const arrayFields = new Map(Object.entries(arrayFieldsMetadata));
11430
- return {
12109
+ const iterableArrayFields = layout.filter((field) => Array.isArray(field.type));
12110
+ if (plainPrimitiveFields?.length !== layout.length || plainPrimitiveFields.length === 0)
12111
+ plainPrimitiveFields = null;
12112
+ const supportsPackListInto = !!plainPrimitiveFields;
12113
+ if (primitiveDecodeFields?.length !== layout.length || primitiveDecodeFields.length === 0) {
12114
+ primitiveDecodeFields = null;
12115
+ }
12116
+ let plainPrimitivePackList;
12117
+ let plainPrimitiveUnpackList;
12118
+ let reducedPrimitiveUnpackList;
12119
+ let plainPrimitivePack;
12120
+ let plainPrimitivePackInto;
12121
+ let plainPrimitivePackListInto;
12122
+ let plainPrimitiveUnpack;
12123
+ let plainPrimitiveUnpackInto;
12124
+ let plainPrimitivePackListItems = 0;
12125
+ let plainPrimitivePackListIntoItems = 0;
12126
+ let plainPrimitiveUnpackListItems = 0;
12127
+ let reducedPrimitiveUnpackListItems = 0;
12128
+ let plainPrimitivePackCalls = 0;
12129
+ let plainPrimitivePackIntoCalls = 0;
12130
+ let plainPrimitiveUnpackCalls = 0;
12131
+ let plainPrimitiveUnpackIntoCalls = 0;
12132
+ const compilePlainPrimitive = (compile) => {
12133
+ try {
12134
+ return compile();
12135
+ } catch (error) {
12136
+ if (!(error instanceof EvalError))
12137
+ throw error;
12138
+ plainPrimitiveFields = null;
12139
+ primitiveDecodeFields = null;
12140
+ return;
12141
+ }
12142
+ };
12143
+ const validateDecodeRange = (view, decodeOffset) => {
12144
+ if (!Number.isSafeInteger(decodeOffset) || decodeOffset < 0) {
12145
+ throw new RangeError(`Decode offset must be a non-negative safe integer, got ${decodeOffset}`);
12146
+ }
12147
+ if (decodeOffset > view.byteLength - totalSize) {
12148
+ throw new RangeError(`DataView range (${view.byteLength} bytes) is too small for a struct at offset ${decodeOffset}`);
12149
+ }
12150
+ };
12151
+ const decodeFieldsInto = (target, view, baseOffset) => {
12152
+ if (structDefOptions?.default)
12153
+ Object.assign(target, structDefOptions.default);
12154
+ for (const field of layout) {
12155
+ if (!field.unpack)
12156
+ continue;
12157
+ try {
12158
+ target[field.name] = field.unpack(view, baseOffset + field.offset);
12159
+ } catch (error) {
12160
+ console.error(`Error unpacking field '${field.name}' at offset ${field.offset}:`, error);
12161
+ throw error;
12162
+ }
12163
+ }
12164
+ };
12165
+ const unpackInto = (view, target, decodeOffset = 0) => {
12166
+ validateDecodeRange(view, decodeOffset);
12167
+ if (plainPrimitiveFields && (plainPrimitiveUnpackInto || ++plainPrimitiveUnpackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12168
+ plainPrimitiveUnpackInto ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackInto(plainPrimitiveFields));
12169
+ if (plainPrimitiveUnpackInto)
12170
+ return plainPrimitiveUnpackInto(view, target, decodeOffset);
12171
+ }
12172
+ decodeFieldsInto(target, view, decodeOffset);
12173
+ return target;
12174
+ };
12175
+ const materializeArrayIterables = iterableArrayFields.length === 0 ? null : (obj) => {
12176
+ let normalized = obj;
12177
+ for (const field of iterableArrayFields) {
12178
+ const value = obj[field.name];
12179
+ if (value == null || Array.isArray(value) || ArrayBuffer.isView(value))
12180
+ continue;
12181
+ if (typeof value[Symbol.iterator] !== "function")
12182
+ continue;
12183
+ if (normalized === obj)
12184
+ normalized = { ...obj };
12185
+ normalized[field.name] = Array.from(value);
12186
+ }
12187
+ return normalized;
12188
+ };
12189
+ const definition = {
11431
12190
  __type: "struct",
11432
12191
  size: totalSize,
11433
12192
  align: maxAlign,
@@ -11435,34 +12194,57 @@ function defineStruct(fields, structDefOptions) {
11435
12194
  layoutByName,
11436
12195
  arrayFields,
11437
12196
  pack(obj, options) {
12197
+ if (plainPrimitiveFields && (plainPrimitivePack || ++plainPrimitivePackCalls >= plainPrimitiveSpecializationThreshold)) {
12198
+ plainPrimitivePack ??= compilePlainPrimitive(() => compilePlainPrimitivePack(plainPrimitiveFields, totalSize));
12199
+ if (plainPrimitivePack)
12200
+ return plainPrimitivePack(obj);
12201
+ }
11438
12202
  const buf = new ArrayBuffer(totalSize);
11439
12203
  const view = new DataView(buf);
11440
12204
  let mappedObj = obj;
11441
12205
  if (structDefOptions?.mapValue) {
11442
12206
  mappedObj = structDefOptions.mapValue(obj);
11443
12207
  }
11444
- for (const field of layout) {
11445
- const value = mappedObj[field.name] ?? field.default;
11446
- if (!field.optional && value === undefined) {
11447
- fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11448
- }
11449
- if (field.validate) {
11450
- for (const validateFn of field.validate) {
11451
- validateFn(value, field.name, {
11452
- hints: options?.validationHints,
11453
- input: mappedObj
11454
- });
12208
+ if (materializeArrayIterables)
12209
+ mappedObj = materializeArrayIterables(mappedObj);
12210
+ if (hasDirectInlinePack)
12211
+ freshPackBuffers.add(buf);
12212
+ try {
12213
+ for (const field of layout) {
12214
+ const value = mappedObj[field.name] ?? field.default;
12215
+ if (!field.optional && value === undefined) {
12216
+ fatalError(`Packing non-optional field '${field.name}' but value is undefined (and no default provided)`);
11455
12217
  }
12218
+ if (field.validate) {
12219
+ for (const validateFn of field.validate) {
12220
+ validateFn(value, field.name, {
12221
+ hints: options?.validationHints,
12222
+ input: mappedObj
12223
+ });
12224
+ }
12225
+ }
12226
+ field.pack(view, field.offset, value, mappedObj, options);
11456
12227
  }
11457
- field.pack(view, field.offset, value, mappedObj, options);
12228
+ } finally {
12229
+ if (hasDirectInlinePack)
12230
+ freshPackBuffers.delete(buf);
11458
12231
  }
11459
12232
  return view.buffer;
11460
12233
  },
11461
12234
  packInto(obj, view, offset2, options) {
12235
+ if (plainPrimitiveFields && (plainPrimitivePackInto || ++plainPrimitivePackIntoCalls >= plainPrimitiveSpecializationThreshold)) {
12236
+ plainPrimitivePackInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackInto(plainPrimitiveFields));
12237
+ if (plainPrimitivePackInto) {
12238
+ plainPrimitivePackInto(obj, view, offset2);
12239
+ return;
12240
+ }
12241
+ }
11462
12242
  let mappedObj = obj;
11463
12243
  if (structDefOptions?.mapValue) {
11464
12244
  mappedObj = structDefOptions.mapValue(obj);
11465
12245
  }
12246
+ if (materializeArrayIterables)
12247
+ mappedObj = materializeArrayIterables(mappedObj);
11466
12248
  for (const field of layout) {
11467
12249
  const value = mappedObj[field.name] ?? field.default;
11468
12250
  if (!field.optional && value === undefined) {
@@ -11484,6 +12266,11 @@ function defineStruct(fields, structDefOptions) {
11484
12266
  fatalError(`Buffer size (${buf.byteLength}) is smaller than struct size (${totalSize}) for unpacking.`);
11485
12267
  }
11486
12268
  const view = new DataView(buf);
12269
+ if (plainPrimitiveFields && (plainPrimitiveUnpack || ++plainPrimitiveUnpackCalls >= plainPrimitiveSpecializationThreshold)) {
12270
+ plainPrimitiveUnpack ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpack(plainPrimitiveFields));
12271
+ if (plainPrimitiveUnpack)
12272
+ return plainPrimitiveUnpack(view);
12273
+ }
11487
12274
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
11488
12275
  for (const field of layout) {
11489
12276
  if (!field.unpack) {
@@ -11505,31 +12292,67 @@ function defineStruct(fields, structDefOptions) {
11505
12292
  if (objects.length === 0) {
11506
12293
  return new ArrayBuffer(0);
11507
12294
  }
12295
+ if (plainPrimitiveFields) {
12296
+ plainPrimitivePackListItems += objects.length;
12297
+ if (plainPrimitivePackList || objects.length > 1 && plainPrimitivePackListItems >= plainPrimitiveSpecializationThreshold) {
12298
+ plainPrimitivePackList ??= compilePlainPrimitive(() => compilePlainPrimitivePackList(plainPrimitiveFields, totalSize));
12299
+ if (plainPrimitivePackList)
12300
+ return plainPrimitivePackList(objects);
12301
+ }
12302
+ }
11508
12303
  const buffer = new ArrayBuffer(totalSize * objects.length);
11509
12304
  const view = new DataView(buffer);
11510
- for (let i = 0;i < objects.length; i++) {
11511
- let mappedObj = objects[i];
11512
- if (structDefOptions?.mapValue) {
11513
- mappedObj = structDefOptions.mapValue(objects[i]);
11514
- }
11515
- for (const field of layout) {
11516
- const value = mappedObj[field.name] ?? field.default;
11517
- if (!field.optional && value === undefined) {
11518
- fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
12305
+ if (hasDirectInlinePack)
12306
+ freshPackBuffers.add(buffer);
12307
+ try {
12308
+ for (let i = 0;i < objects.length; i++) {
12309
+ let mappedObj = objects[i];
12310
+ if (structDefOptions?.mapValue) {
12311
+ mappedObj = structDefOptions.mapValue(objects[i]);
11519
12312
  }
11520
- if (field.validate) {
11521
- for (const validateFn of field.validate) {
11522
- validateFn(value, field.name, {
11523
- hints: options?.validationHints,
11524
- input: mappedObj
11525
- });
12313
+ if (materializeArrayIterables)
12314
+ mappedObj = materializeArrayIterables(mappedObj);
12315
+ for (const field of layout) {
12316
+ const value = mappedObj[field.name] ?? field.default;
12317
+ if (!field.optional && value === undefined) {
12318
+ fatalError(`Packing non-optional field '${field.name}' at index ${i} but value is undefined (and no default provided)`);
12319
+ }
12320
+ if (field.validate) {
12321
+ for (const validateFn of field.validate) {
12322
+ validateFn(value, field.name, {
12323
+ hints: options?.validationHints,
12324
+ input: mappedObj
12325
+ });
12326
+ }
11526
12327
  }
12328
+ field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11527
12329
  }
11528
- field.pack(view, i * totalSize + field.offset, value, mappedObj, options);
11529
12330
  }
12331
+ } finally {
12332
+ if (hasDirectInlinePack)
12333
+ freshPackBuffers.delete(buffer);
11530
12334
  }
11531
12335
  return buffer;
11532
12336
  },
12337
+ packListInto(objects, view, offset2, options) {
12338
+ if (objects.length === 0)
12339
+ return;
12340
+ if (!supportsPackListInto)
12341
+ throw new Error("packListInto only supports required primitive fields");
12342
+ if (plainPrimitiveFields) {
12343
+ plainPrimitivePackListIntoItems += objects.length;
12344
+ if (plainPrimitivePackListInto || objects.length > 1 && plainPrimitivePackListIntoItems >= plainPrimitiveSpecializationThreshold) {
12345
+ plainPrimitivePackListInto ??= compilePlainPrimitive(() => compilePlainPrimitivePackListInto(plainPrimitiveFields, totalSize));
12346
+ if (plainPrimitivePackListInto) {
12347
+ plainPrimitivePackListInto(objects, view, offset2);
12348
+ return;
12349
+ }
12350
+ }
12351
+ }
12352
+ for (let index = 0;index < objects.length; index += 1) {
12353
+ definition.packInto(objects[index], view, offset2 + index * totalSize, options);
12354
+ }
12355
+ },
11533
12356
  unpackList(buf, count) {
11534
12357
  if (count === 0) {
11535
12358
  return [];
@@ -11539,7 +12362,24 @@ function defineStruct(fields, structDefOptions) {
11539
12362
  fatalError(`Buffer size (${buf.byteLength}) is smaller than expected size (${expectedSize}) for unpacking ${count} structs.`);
11540
12363
  }
11541
12364
  const view = new DataView(buf);
11542
- const results = [];
12365
+ if (plainPrimitiveFields && Number.isSafeInteger(count) && count > 1) {
12366
+ plainPrimitiveUnpackListItems += count;
12367
+ if (plainPrimitiveUnpackList || plainPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12368
+ plainPrimitiveUnpackList ??= compilePlainPrimitive(() => compilePlainPrimitiveUnpackList(plainPrimitiveFields, totalSize));
12369
+ if (plainPrimitiveUnpackList)
12370
+ return plainPrimitiveUnpackList(view, count);
12371
+ }
12372
+ }
12373
+ if (!plainPrimitiveFields && primitiveDecodeFields && Number.isSafeInteger(count) && count > 1) {
12374
+ reducedPrimitiveUnpackListItems += count;
12375
+ if (reducedPrimitiveUnpackList || reducedPrimitiveUnpackListItems >= plainPrimitiveSpecializationThreshold) {
12376
+ reducedPrimitiveUnpackList ??= compilePlainPrimitive(() => compileReducedPrimitiveUnpackList(primitiveDecodeFields, totalSize, structDefOptions));
12377
+ if (reducedPrimitiveUnpackList)
12378
+ return reducedPrimitiveUnpackList(view, count);
12379
+ }
12380
+ }
12381
+ const preallocated = Number.isSafeInteger(count) && count >= arrayPreallocationThreshold && count <= maxArrayLength;
12382
+ const results = preallocated ? new Array(count) : [];
11543
12383
  for (let i = 0;i < count; i++) {
11544
12384
  const offset2 = i * totalSize;
11545
12385
  const result = structDefOptions?.default ? { ...structDefOptions.default } : {};
@@ -11555,9 +12395,16 @@ function defineStruct(fields, structDefOptions) {
11555
12395
  }
11556
12396
  }
11557
12397
  if (structDefOptions?.reduceValue) {
11558
- results.push(structDefOptions.reduceValue(result));
12398
+ const value = structDefOptions.reduceValue(result);
12399
+ if (preallocated)
12400
+ results[i] = value;
12401
+ else
12402
+ results.push(value);
11559
12403
  } else {
11560
- results.push(result);
12404
+ if (preallocated)
12405
+ results[i] = result;
12406
+ else
12407
+ results.push(result);
11561
12408
  }
11562
12409
  }
11563
12410
  return results;
@@ -11566,6 +12413,18 @@ function defineStruct(fields, structDefOptions) {
11566
12413
  return description;
11567
12414
  }
11568
12415
  };
12416
+ if (!structDefOptions?.reduceValue)
12417
+ Object.assign(definition, { unpackInto });
12418
+ structInternals.set(definition, {
12419
+ layout,
12420
+ options: structDefOptions,
12421
+ publicPack: definition.pack,
12422
+ publicUnpack: definition.unpack,
12423
+ hasDirectInlinePack,
12424
+ directInlineUnpackSafe,
12425
+ materializeArrayIterables
12426
+ });
12427
+ return definition;
11569
12428
  }
11570
12429
 
11571
12430
  // src/zig-structs.ts
@@ -11636,6 +12495,7 @@ var VisualCursorStruct = defineStruct([
11636
12495
  var UnicodeMethodEnum = defineEnum({ wcwidth: 0, unicode: 1 }, "u8");
11637
12496
  var TerminalMultiplexerEnum = defineEnum({ none: 0, tmux: 1, zellij: 2, screen: 3, unknown: 4 }, "u8");
11638
12497
  var Osc52SupportEnum = defineEnum({ unknown: 0, supported: 1, unsupported: 2 }, "u8");
12498
+ var ImageProtocolEnum = defineEnum({ auto: 0, kitty: 1, sixel: 2, blocks: 3 }, "u8");
11639
12499
  var TerminalCapabilitiesStruct = defineStruct([
11640
12500
  ["kitty_keyboard", "bool_u8"],
11641
12501
  ["kitty_graphics", "bool_u8"],
@@ -11656,6 +12516,7 @@ var TerminalCapabilitiesStruct = defineStruct([
11656
12516
  ["explicit_cursor_positioning", "bool_u8"],
11657
12517
  ["remote", "bool_u8"],
11658
12518
  ["multiplexer", TerminalMultiplexerEnum],
12519
+ ["image_protocol", ImageProtocolEnum],
11659
12520
  ["term_name", "char*"],
11660
12521
  ["term_name_len", "u64", { lengthOf: "term_name" }],
11661
12522
  ["term_version", "char*"],
@@ -11667,6 +12528,29 @@ var EncodedCharStruct = defineStruct([
11667
12528
  ["width", "u8"],
11668
12529
  ["char", "u32"]
11669
12530
  ]);
12531
+ var NativeImageInfoStruct = defineStruct([
12532
+ ["width", "u32"],
12533
+ ["height", "u32"],
12534
+ ["sourceWidth", "u32"],
12535
+ ["sourceHeight", "u32"],
12536
+ ["format", "u32"],
12537
+ ["colorStatus", "u32"],
12538
+ ["orientation", "u32"],
12539
+ ["hasAlpha", "u32"]
12540
+ ]);
12541
+ var ImageDrawOptionsStruct = defineStruct([
12542
+ ["x", "i32"],
12543
+ ["y", "i32"],
12544
+ ["width", "u32"],
12545
+ ["height", "u32"],
12546
+ ["pixelWidth", "u32"],
12547
+ ["pixelHeight", "u32"],
12548
+ ["sourceX", "u32"],
12549
+ ["sourceY", "u32"],
12550
+ ["sourceWidth", "u32"],
12551
+ ["sourceHeight", "u32"],
12552
+ ["protocol", "u32"]
12553
+ ]);
11670
12554
  var LineInfoStruct = defineStruct([
11671
12555
  ["startCols", ["u32"]],
11672
12556
  ["startColsLen", "u32", { lengthOf: "startCols" }],
@@ -11849,6 +12733,15 @@ var AudioStreamStatsStruct = defineStruct([
11849
12733
  ["errorCode", "i32"],
11850
12734
  ["readyGeneration", "u32"]
11851
12735
  ]);
12736
+ var AudioCaptureStatsStruct = defineStruct([
12737
+ ["framesReceived", "u64"],
12738
+ ["framesRead", "u64"],
12739
+ ["framesDropped", "u64"],
12740
+ ["sampleRate", "u32"],
12741
+ ["channels", "u32"],
12742
+ ["bufferedFrames", "u32"],
12743
+ ["capacityFrames", "u32"]
12744
+ ]);
11852
12745
  var AudioStatsStruct = defineStruct([
11853
12746
  ["soundsLoaded", "u32"],
11854
12747
  ["voicesActive", "u32"],
@@ -11868,51 +12761,18 @@ registerEnvVar({
11868
12761
  type: "string",
11869
12762
  default: ""
11870
12763
  });
11871
- function validateLinuxLibcOverride() {
11872
- const libc = process.env.OPENTUI_LIBC;
11873
- if (libc === undefined || libc === "" || libc === "glibc" || libc === "musl")
11874
- return;
11875
- throw new Error(`On Linux, OPENTUI_LIBC must be unset, empty, "glibc", or "musl", got "${libc}"`);
11876
- }
11877
- async function resolveNativePackage() {
11878
- if (process.platform === "darwin") {
11879
- if (process.arch === "x64")
11880
- return await import("@opentui/core-darwin-x64");
11881
- if (process.arch === "arm64")
11882
- return await import("@opentui/core-darwin-arm64");
11883
- }
11884
- if (process.platform === "linux") {
11885
- validateLinuxLibcOverride();
11886
- if (process.arch === "x64") {
11887
- if (process.env.OPENTUI_LIBC === "musl") {
11888
- return await import("@opentui/core-linux-x64-musl");
11889
- } else {
11890
- return await import("@opentui/core-linux-x64");
11891
- }
11892
- }
11893
- if (process.arch === "arm64") {
11894
- if (process.env.OPENTUI_LIBC === "musl") {
11895
- return await import("@opentui/core-linux-arm64-musl");
11896
- } else {
11897
- return await import("@opentui/core-linux-arm64");
11898
- }
11899
- }
12764
+ var targetLibPath;
12765
+ var targetLibError;
12766
+ try {
12767
+ targetLibPath = await resolveNativeLibraryPath();
12768
+ if (isBunfsPath(targetLibPath)) {
12769
+ targetLibPath = targetLibPath.replace("../", "");
11900
12770
  }
11901
- if (process.platform === "win32") {
11902
- if (process.arch === "x64")
11903
- return await import("@opentui/core-win32-x64");
11904
- if (process.arch === "arm64")
11905
- return await import("@opentui/core-win32-arm64");
12771
+ if (!existsSync3(targetLibPath)) {
12772
+ throw new Error(`OpenTUI native library does not exist at ${JSON.stringify(targetLibPath)}`);
11906
12773
  }
11907
- throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
11908
- }
11909
- var nativePackage = await resolveNativePackage();
11910
- var targetLibPath = nativePackage.default;
11911
- if (isBunfsPath(targetLibPath)) {
11912
- targetLibPath = targetLibPath.replace("../", "");
11913
- }
11914
- if (!existsSync3(targetLibPath)) {
11915
- throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
12774
+ } catch (error) {
12775
+ targetLibError = error instanceof Error ? error : new Error(String(error));
11916
12776
  }
11917
12777
  registerEnvVar({
11918
12778
  name: "OTUI_DEBUG_FFI",
@@ -11928,27 +12788,33 @@ registerEnvVar({
11928
12788
  });
11929
12789
  registerEnvVar({
11930
12790
  name: "OPENTUI_FORCE_WCWIDTH",
11931
- description: "Use wcwidth for character width calculations",
11932
- type: "boolean",
11933
- default: false
12791
+ description: "Use wcwidth for character width calculations when the variable is present",
12792
+ type: "string",
12793
+ required: false
11934
12794
  });
11935
12795
  registerEnvVar({
11936
12796
  name: "OPENTUI_FORCE_UNICODE",
11937
- description: "Force Mode 2026 Unicode support in terminal capabilities",
11938
- type: "boolean",
11939
- default: false
12797
+ description: "Force Mode 2026 Unicode support when the variable is present",
12798
+ type: "string",
12799
+ required: false
11940
12800
  });
11941
12801
  registerEnvVar({
11942
12802
  name: "OPENTUI_GRAPHICS",
11943
- description: "Enable Kitty graphics protocol detection",
11944
- type: "boolean",
11945
- default: true
12803
+ description: "Control Kitty and Sixel graphics detection with the exact value true, 1, false, or 0",
12804
+ type: "string",
12805
+ required: false
12806
+ });
12807
+ registerEnvVar({
12808
+ name: "OPENTUI_IMAGE_PROTOCOL",
12809
+ description: "Override image rendering protocol: auto, kitty, sixel, or blocks",
12810
+ type: "string",
12811
+ default: "auto"
11946
12812
  });
11947
12813
  registerEnvVar({
11948
12814
  name: "OPENTUI_FORCE_NOZWJ",
11949
- description: "Use no_zwj width method (Unicode without ZWJ joining)",
11950
- type: "boolean",
11951
- default: false
12815
+ description: "Use no_zwj width mode when the variable is present",
12816
+ type: "string",
12817
+ required: false
11952
12818
  });
11953
12819
  var CURSOR_STYLE_TO_ID = { block: 0, line: 1, underline: 2, default: 3 };
11954
12820
  var CURSOR_ID_TO_STYLE = ["block", "line", "underline", "default"];
@@ -11989,6 +12855,9 @@ function optionalRgbaPtr(value) {
11989
12855
  }
11990
12856
  function getOpenTUILib(libPath) {
11991
12857
  const resolvedLibPath = libPath || targetLibPath;
12858
+ if (!resolvedLibPath) {
12859
+ throw targetLibError ?? new Error(`OpenTUI is not supported on the current platform: ${process.platform}-${process.arch}`);
12860
+ }
11992
12861
  const rawSymbols = dlopen(resolvedLibPath, {
11993
12862
  setLogCallback: {
11994
12863
  args: ["ptr"],
@@ -12262,6 +13131,10 @@ function getOpenTUILib(libPath) {
12262
13131
  args: ["u32", "u32", "u32", "ptr", "u32", "u8", "u32"],
12263
13132
  returns: "void"
12264
13133
  },
13134
+ bufferDrawImage: {
13135
+ args: ["u32", "u32", "ptr"],
13136
+ returns: "u8"
13137
+ },
12265
13138
  bufferDrawPackedBuffer: {
12266
13139
  args: ["u32", "ptr", "u32", "u32", "u32", "u32", "u32"],
12267
13140
  returns: "void"
@@ -12962,6 +13835,19 @@ function getOpenTUILib(libPath) {
12962
13835
  args: ["u32"],
12963
13836
  returns: "u32"
12964
13837
  },
13838
+ imageInfo: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13839
+ imageDecode: { args: ["ptr", "u32", "ptr"], returns: "u32" },
13840
+ imageCreateFromRgba: { args: ["ptr", "u64", "u32", "u32", "u32", "ptr"], returns: "u32" },
13841
+ imageDestroy: { args: ["u32"], returns: "void" },
13842
+ imageGetInfo: { args: ["u32", "ptr"], returns: "u32" },
13843
+ imageGetPixelsPtr: { args: ["u32"], returns: "ptr" },
13844
+ imageClone: { args: ["u32", "ptr"], returns: "u32" },
13845
+ imageCopyPixels: { args: ["u32", "ptr", "u64", "u32", "u8"], returns: "u32" },
13846
+ imageResize: { args: ["u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13847
+ imageExtract: { args: ["u32", "u32", "u32", "u32", "u32", "ptr"], returns: "u32" },
13848
+ imageExtend: { args: ["u32", "u32", "u32", "u32", "u32", "ptr", "ptr"], returns: "u32" },
13849
+ imageTransform: { args: ["u32", "u32", "ptr"], returns: "u32" },
13850
+ imageComposite: { args: ["u32", "u32", "i32", "i32", "u32", "u8", "ptr"], returns: "u32" },
12965
13851
  getTerminalCapabilities: {
12966
13852
  args: ["u32", "ptr"],
12967
13853
  returns: "void"
@@ -13214,6 +14100,50 @@ function getOpenTUILib(libPath) {
13214
14100
  args: ["u32"],
13215
14101
  returns: "void"
13216
14102
  },
14103
+ audioRefreshCaptureDevices: {
14104
+ args: ["u32"],
14105
+ returns: "i32"
14106
+ },
14107
+ audioGetCaptureDeviceCount: {
14108
+ args: ["u32"],
14109
+ returns: "u32"
14110
+ },
14111
+ audioGetCaptureDeviceName: {
14112
+ args: ["u32", "u32", "ptr", "u32"],
14113
+ returns: "u32"
14114
+ },
14115
+ audioIsCaptureDeviceDefault: {
14116
+ args: ["u32", "u32"],
14117
+ returns: "bool"
14118
+ },
14119
+ audioSelectCaptureDevice: {
14120
+ args: ["u32", "u32"],
14121
+ returns: "i32"
14122
+ },
14123
+ audioClearCaptureDeviceSelection: {
14124
+ args: ["u32"],
14125
+ returns: "void"
14126
+ },
14127
+ audioStartCapture: {
14128
+ args: ["u32", "ptr", "u32", "u32"],
14129
+ returns: "i32"
14130
+ },
14131
+ audioStopCapture: {
14132
+ args: ["u32"],
14133
+ returns: "i32"
14134
+ },
14135
+ audioIsCaptureRunning: {
14136
+ args: ["u32"],
14137
+ returns: "bool"
14138
+ },
14139
+ audioReadCapture: {
14140
+ args: ["u32", "ptr", "u32", "u32", "ptr"],
14141
+ returns: "i32"
14142
+ },
14143
+ audioGetCaptureStats: {
14144
+ args: ["u32", "ptr"],
14145
+ returns: "i32"
14146
+ },
13217
14147
  audioStart: {
13218
14148
  args: ["u32", "ptr"],
13219
14149
  returns: "i32"
@@ -13476,10 +14406,10 @@ function convertToDebugSymbols(symbols) {
13476
14406
  const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
13477
14407
  const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
13478
14408
  const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
13479
- lines.push(`${nameHeader.padEnd(nameWidth)} | ${callsHeader.padStart(countWidth)} | ${totalHeader.padStart(totalWidth)} | ${avgHeader.padStart(avgWidth)} | ${minHeader.padStart(statWidthMin)} | ${maxHeader.padStart(statWidthMax)} | ${medHeader.padStart(medianWidth)} | ${p90Header.padStart(p90Width)} | ${p99Header.padStart(p99Width)}`);
14409
+ lines.push(`${nameHeader.padEnd(nameWidth)} | ` + `${callsHeader.padStart(countWidth)} | ` + `${totalHeader.padStart(totalWidth)} | ` + `${avgHeader.padStart(avgWidth)} | ` + `${minHeader.padStart(statWidthMin)} | ` + `${maxHeader.padStart(statWidthMax)} | ` + `${medHeader.padStart(medianWidth)} | ` + `${p90Header.padStart(p90Width)} | ` + `${p99Header.padStart(p99Width)}`);
13480
14410
  lines.push(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(statWidthMin)}-+-${"-".repeat(statWidthMax)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
13481
14411
  allStats.forEach((stat) => {
13482
- lines.push(`${stat.name.padEnd(nameWidth)} | ${String(stat.count).padStart(countWidth)} | ${stat.total.toFixed(2).padStart(totalWidth)} | ${stat.average.toFixed(2).padStart(avgWidth)} | ${stat.min.toFixed(2).padStart(statWidthMin)} | ${stat.max.toFixed(2).padStart(statWidthMax)} | ${stat.median.toFixed(2).padStart(medianWidth)} | ${stat.p90.toFixed(2).padStart(p90Width)} | ${stat.p99.toFixed(2).padStart(p99Width)}`);
14412
+ lines.push(`${stat.name.padEnd(nameWidth)} | ` + `${String(stat.count).padStart(countWidth)} | ` + `${stat.total.toFixed(2).padStart(totalWidth)} | ` + `${stat.average.toFixed(2).padStart(avgWidth)} | ` + `${stat.min.toFixed(2).padStart(statWidthMin)} | ` + `${stat.max.toFixed(2).padStart(statWidthMax)} | ` + `${stat.median.toFixed(2).padStart(medianWidth)} | ` + `${stat.p90.toFixed(2).padStart(p90Width)} | ` + `${stat.p99.toFixed(2).padStart(p99Width)}`);
13483
14413
  });
13484
14414
  }
13485
14415
  lines.push("-------------------------------------------------------------------------------------------------------------------------");
@@ -13516,6 +14446,46 @@ var NativeMeasureTargetKind = {
13516
14446
 
13517
14447
  class FFIRenderLib {
13518
14448
  opentui;
14449
+ yogaLayout = new Float32Array(6);
14450
+ yogaLayoutPtr = ptr(this.yogaLayout);
14451
+ ffiStructStorage = {
14452
+ logicalCursor: {
14453
+ ...allocStruct(LogicalCursorStruct),
14454
+ result: { row: 0, col: 0, offset: 0 }
14455
+ },
14456
+ visualCursor: {
14457
+ ...allocStruct(VisualCursorStruct),
14458
+ result: {
14459
+ visualRow: 0,
14460
+ visualCol: 0,
14461
+ logicalRow: 0,
14462
+ logicalCol: 0,
14463
+ offset: 0
14464
+ }
14465
+ },
14466
+ measureResult: {
14467
+ ...allocStruct(MeasureResultStruct),
14468
+ result: { lineCount: 0, widthColsMax: 0 }
14469
+ },
14470
+ audioStreamStats: {
14471
+ ...allocStruct(AudioStreamStatsStruct),
14472
+ result: {
14473
+ bytesReceived: 0n,
14474
+ framesDecoded: 0n,
14475
+ framesPlayed: 0n,
14476
+ state: 0,
14477
+ sampleRate: 0,
14478
+ channels: 0,
14479
+ bufferedFrames: 0,
14480
+ capacityFrames: 0,
14481
+ underruns: 0,
14482
+ errorCode: 0,
14483
+ readyGeneration: 0
14484
+ }
14485
+ },
14486
+ imageDrawOptions: allocStruct(ImageDrawOptionsStruct),
14487
+ gridDrawOptions: allocStruct(GridDrawOptionsStruct)
14488
+ };
13519
14489
  encoder = new TextEncoder;
13520
14490
  decoder = new TextDecoder;
13521
14491
  logCallbackWrapper = null;
@@ -13842,6 +14812,24 @@ class FFIRenderLib {
13842
14812
  const formatId = format === "bgra8unorm" ? 0 : 1;
13843
14813
  this.opentui.symbols.bufferDrawSuperSampleBuffer(buffer, x, y, pixelDataPtr, pixelDataLength, formatId, alignedBytesPerRow);
13844
14814
  }
14815
+ bufferDrawImage(buffer, image, x, y, width, height, pixelWidth, pixelHeight, sourceX, sourceY, sourceWidth, sourceHeight, protocol) {
14816
+ const protocolId = { auto: 0, kitty: 1, sixel: 2, blocks: 3 }[protocol];
14817
+ const storage = this.ffiStructStorage.imageDrawOptions;
14818
+ ImageDrawOptionsStruct.packInto({
14819
+ x,
14820
+ y,
14821
+ width,
14822
+ height,
14823
+ pixelWidth,
14824
+ pixelHeight,
14825
+ sourceX,
14826
+ sourceY,
14827
+ sourceWidth,
14828
+ sourceHeight,
14829
+ protocol: protocolId
14830
+ }, storage.view, 0);
14831
+ return Boolean(this.opentui.symbols.bufferDrawImage(buffer, image, storage.buffer));
14832
+ }
13845
14833
  bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
13846
14834
  this.opentui.symbols.bufferDrawPackedBuffer(buffer, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
13847
14835
  }
@@ -13852,11 +14840,8 @@ class FFIRenderLib {
13852
14840
  this.opentui.symbols.bufferDrawGrayscaleBufferSupersampled(buffer, posX, posY, intensitiesPtr, srcWidth, srcHeight, optionalRgbaPtr(fg2), optionalRgbaPtr(bg2));
13853
14841
  }
13854
14842
  bufferDrawGrid(buffer, borderChars, borderFg, borderBg, columnOffsets, columnCount, rowOffsets, rowCount, options) {
13855
- const optionsBuffer = GridDrawOptionsStruct.pack({
13856
- drawInner: options.drawInner,
13857
- drawOuter: options.drawOuter
13858
- });
13859
- this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, ptr(optionsBuffer));
14843
+ GridDrawOptionsStruct.packInto({ drawInner: options.drawInner, drawOuter: options.drawOuter }, this.ffiStructStorage.gridDrawOptions.view, 0);
14844
+ this.opentui.symbols.bufferDrawGrid(buffer, ptr(borderChars), rgbaPtr(borderFg), rgbaPtr(borderBg), ptr(columnOffsets), columnCount, ptr(rowOffsets), rowCount, this.ffiStructStorage.gridDrawOptions.buffer);
13860
14845
  }
13861
14846
  bufferDrawBox(buffer, x, y, width, height, borderChars, packedOptions, borderColor, backgroundColor, titleColor, title, bottomTitle) {
13862
14847
  const titleBytes = title ? this.encoder.encode(title) : null;
@@ -14004,11 +14989,11 @@ class FFIRenderLib {
14004
14989
  this.opentui.symbols.dumpHitGrid(renderer);
14005
14990
  }
14006
14991
  dumpBuffers(renderer, timestamp) {
14007
- const ts = timestamp ?? Date.now();
14992
+ const ts = BigInt(timestamp ?? Date.now());
14008
14993
  this.opentui.symbols.dumpBuffers(renderer, ts);
14009
14994
  }
14010
14995
  dumpOutputBuffer(renderer, timestamp) {
14011
- const ts = timestamp ?? Date.now();
14996
+ const ts = BigInt(timestamp ?? Date.now());
14012
14997
  this.opentui.symbols.dumpOutputBuffer(renderer, ts);
14013
14998
  }
14014
14999
  restoreTerminalModes(renderer) {
@@ -14162,8 +15147,8 @@ class FFIRenderLib {
14162
15147
  return this.opentui.symbols.yogaNodeGetAlwaysFormsContainingBlock(node);
14163
15148
  }
14164
15149
  yogaNodeGetComputedLayout(node) {
14165
- const layout = new Float32Array(6);
14166
- this.opentui.symbols.yogaNodeGetComputedLayout(node, ptr(layout));
15150
+ const layout = this.yogaLayout;
15151
+ this.opentui.symbols.yogaNodeGetComputedLayout(node, this.yogaLayoutPtr);
14167
15152
  return {
14168
15153
  left: layout[0],
14169
15154
  top: layout[1],
@@ -14344,7 +15329,7 @@ class FFIRenderLib {
14344
15329
  if (len === 0) {
14345
15330
  return null;
14346
15331
  }
14347
- return outBuffer.slice(0, len);
15332
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14348
15333
  }
14349
15334
  createTextBufferView(textBuffer) {
14350
15335
  const viewPtr = this.opentui.symbols.createTextBufferView(textBuffer);
@@ -14481,14 +15466,12 @@ class FFIRenderLib {
14481
15466
  this.opentui.symbols.textBufferViewSetTruncate(view, ffiBool(truncate));
14482
15467
  }
14483
15468
  textBufferViewMeasureForDimensions(view, width, height) {
14484
- const resultBuffer = new ArrayBuffer(MeasureResultStruct.size);
14485
- const resultPtr = ptr(new Uint8Array(resultBuffer));
14486
- const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, resultPtr);
14487
- if (!success) {
15469
+ const storage = this.ffiStructStorage.measureResult;
15470
+ const success = this.opentui.symbols.textBufferViewMeasureForDimensions(view, width, height, storage.buffer);
15471
+ if (!success)
14488
15472
  return null;
14489
- }
14490
- const result = MeasureResultStruct.unpack(resultBuffer);
14491
- return result;
15473
+ const result = MeasureResultStruct.unpackInto(storage.view, storage.result);
15474
+ return { lineCount: result.lineCount, widthColsMax: result.widthColsMax };
14492
15475
  }
14493
15476
  textBufferAddHighlightByCharRange(buffer, highlight) {
14494
15477
  const packedHighlight = HighlightStruct.pack(highlight);
@@ -14714,9 +15697,10 @@ class FFIRenderLib {
14714
15697
  this.opentui.symbols.editBufferSetCursorByOffset(buffer, offset);
14715
15698
  }
14716
15699
  editBufferGetCursorPosition(buffer) {
14717
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14718
- this.opentui.symbols.editBufferGetCursorPosition(buffer, ptr(cursorBuffer));
14719
- return LogicalCursorStruct.unpack(cursorBuffer);
15700
+ const storage = this.ffiStructStorage.logicalCursor;
15701
+ this.opentui.symbols.editBufferGetCursorPosition(buffer, storage.buffer);
15702
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15703
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14720
15704
  }
14721
15705
  editBufferGetId(buffer) {
14722
15706
  return this.opentui.symbols.editBufferGetId(buffer);
@@ -14760,26 +15744,30 @@ class FFIRenderLib {
14760
15744
  this.opentui.symbols.editBufferClear(buffer);
14761
15745
  }
14762
15746
  editBufferGetNextWordBoundary(buffer) {
14763
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14764
- this.opentui.symbols.editBufferGetNextWordBoundary(buffer, ptr(cursorBuffer));
14765
- return LogicalCursorStruct.unpack(cursorBuffer);
15747
+ const storage = this.ffiStructStorage.logicalCursor;
15748
+ this.opentui.symbols.editBufferGetNextWordBoundary(buffer, storage.buffer);
15749
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15750
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14766
15751
  }
14767
15752
  editBufferGetPrevWordBoundary(buffer) {
14768
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14769
- this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, ptr(cursorBuffer));
14770
- return LogicalCursorStruct.unpack(cursorBuffer);
15753
+ const storage = this.ffiStructStorage.logicalCursor;
15754
+ this.opentui.symbols.editBufferGetPrevWordBoundary(buffer, storage.buffer);
15755
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15756
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14771
15757
  }
14772
15758
  editBufferGetEOL(buffer) {
14773
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14774
- this.opentui.symbols.editBufferGetEOL(buffer, ptr(cursorBuffer));
14775
- return LogicalCursorStruct.unpack(cursorBuffer);
15759
+ const storage = this.ffiStructStorage.logicalCursor;
15760
+ this.opentui.symbols.editBufferGetEOL(buffer, storage.buffer);
15761
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15762
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14776
15763
  }
14777
15764
  editBufferOffsetToPosition(buffer, offset) {
14778
- const cursorBuffer = new ArrayBuffer(LogicalCursorStruct.size);
14779
- const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, ptr(cursorBuffer));
15765
+ const storage = this.ffiStructStorage.logicalCursor;
15766
+ const success = this.opentui.symbols.editBufferOffsetToPosition(buffer, offset, storage.buffer);
14780
15767
  if (!success)
14781
15768
  return null;
14782
- return LogicalCursorStruct.unpack(cursorBuffer);
15769
+ const cursor = LogicalCursorStruct.unpackInto(storage.view, storage.result);
15770
+ return { row: cursor.row, col: cursor.col, offset: cursor.offset };
14783
15771
  }
14784
15772
  editBufferPositionToOffset(buffer, row, col) {
14785
15773
  return this.opentui.symbols.editBufferPositionToOffset(buffer, row, col);
@@ -14801,7 +15789,7 @@ class FFIRenderLib {
14801
15789
  const len = actualLen;
14802
15790
  if (len === 0)
14803
15791
  return null;
14804
- return outBuffer.slice(0, len);
15792
+ return usesBunFFI ? outBuffer.slice(0, len) : trimNodeFFIOutputBytes(outBuffer, len);
14805
15793
  }
14806
15794
  editorViewSetSelection(view, start, end, bgColor, fgColor) {
14807
15795
  const bg2 = optionalRgbaPtr(bgColor);
@@ -14861,9 +15849,10 @@ class FFIRenderLib {
14861
15849
  return outBuffer.slice(0, len);
14862
15850
  }
14863
15851
  editorViewGetVisualCursor(view) {
14864
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14865
- this.opentui.symbols.editorViewGetVisualCursor(view, ptr(cursorBuffer));
14866
- return VisualCursorStruct.unpack(cursorBuffer);
15852
+ const storage = this.ffiStructStorage.visualCursor;
15853
+ this.opentui.symbols.editorViewGetVisualCursor(view, storage.buffer);
15854
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15855
+ return { ...cursor };
14867
15856
  }
14868
15857
  editorViewMoveUpVisual(view) {
14869
15858
  this.opentui.symbols.editorViewMoveUpVisual(view);
@@ -14878,29 +15867,34 @@ class FFIRenderLib {
14878
15867
  this.opentui.symbols.editorViewSetCursorByOffset(view, offset);
14879
15868
  }
14880
15869
  editorViewGetNextWordBoundary(view) {
14881
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14882
- this.opentui.symbols.editorViewGetNextWordBoundary(view, ptr(cursorBuffer));
14883
- return VisualCursorStruct.unpack(cursorBuffer);
15870
+ const storage = this.ffiStructStorage.visualCursor;
15871
+ this.opentui.symbols.editorViewGetNextWordBoundary(view, storage.buffer);
15872
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15873
+ return { ...cursor };
14884
15874
  }
14885
15875
  editorViewGetPrevWordBoundary(view) {
14886
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14887
- this.opentui.symbols.editorViewGetPrevWordBoundary(view, ptr(cursorBuffer));
14888
- return VisualCursorStruct.unpack(cursorBuffer);
15876
+ const storage = this.ffiStructStorage.visualCursor;
15877
+ this.opentui.symbols.editorViewGetPrevWordBoundary(view, storage.buffer);
15878
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15879
+ return { ...cursor };
14889
15880
  }
14890
15881
  editorViewGetEOL(view) {
14891
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14892
- this.opentui.symbols.editorViewGetEOL(view, ptr(cursorBuffer));
14893
- return VisualCursorStruct.unpack(cursorBuffer);
15882
+ const storage = this.ffiStructStorage.visualCursor;
15883
+ this.opentui.symbols.editorViewGetEOL(view, storage.buffer);
15884
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15885
+ return { ...cursor };
14894
15886
  }
14895
15887
  editorViewGetVisualSOL(view) {
14896
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14897
- this.opentui.symbols.editorViewGetVisualSOL(view, ptr(cursorBuffer));
14898
- return VisualCursorStruct.unpack(cursorBuffer);
15888
+ const storage = this.ffiStructStorage.visualCursor;
15889
+ this.opentui.symbols.editorViewGetVisualSOL(view, storage.buffer);
15890
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15891
+ return { ...cursor };
14899
15892
  }
14900
15893
  editorViewGetVisualEOL(view) {
14901
- const cursorBuffer = new ArrayBuffer(VisualCursorStruct.size);
14902
- this.opentui.symbols.editorViewGetVisualEOL(view, ptr(cursorBuffer));
14903
- return VisualCursorStruct.unpack(cursorBuffer);
15894
+ const storage = this.ffiStructStorage.visualCursor;
15895
+ this.opentui.symbols.editorViewGetVisualEOL(view, storage.buffer);
15896
+ const cursor = VisualCursorStruct.unpackInto(storage.view, storage.result);
15897
+ return { ...cursor };
14904
15898
  }
14905
15899
  bufferPushScissorRect(buffer, x, y, width, height) {
14906
15900
  this.opentui.symbols.bufferPushScissorRect(buffer, x, y, width, height);
@@ -14948,6 +15942,7 @@ class FFIRenderLib {
14948
15942
  explicit_cursor_positioning: caps.explicit_cursor_positioning,
14949
15943
  remote: caps.remote,
14950
15944
  multiplexer: caps.multiplexer,
15945
+ image_protocol: caps.image_protocol,
14951
15946
  terminal: {
14952
15947
  name: caps.term_name ?? "",
14953
15948
  version: caps.term_version ?? "",
@@ -15015,6 +16010,76 @@ class FFIRenderLib {
15015
16010
  audioClearPlaybackDeviceSelection(engine) {
15016
16011
  this.opentui.symbols.audioClearPlaybackDeviceSelection(engine);
15017
16012
  }
16013
+ audioRefreshCaptureDevices(engine) {
16014
+ return this.opentui.symbols.audioRefreshCaptureDevices(engine);
16015
+ }
16016
+ audioGetCaptureDeviceCount(engine) {
16017
+ return this.opentui.symbols.audioGetCaptureDeviceCount(engine);
16018
+ }
16019
+ audioGetCaptureDeviceName(engine, index) {
16020
+ const outBuffer = new Uint8Array(512);
16021
+ const bytesWritten = toNumber(this.opentui.symbols.audioGetCaptureDeviceName(engine, index, outBuffer, outBuffer.length));
16022
+ const safeBytesWritten = Math.max(0, Math.min(outBuffer.length, bytesWritten));
16023
+ return this.decoder.decode(outBuffer.subarray(0, safeBytesWritten));
16024
+ }
16025
+ audioIsCaptureDeviceDefault(engine, index) {
16026
+ return Boolean(this.opentui.symbols.audioIsCaptureDeviceDefault(engine, index));
16027
+ }
16028
+ audioSelectCaptureDevice(engine, index) {
16029
+ return this.opentui.symbols.audioSelectCaptureDevice(engine, index);
16030
+ }
16031
+ audioClearCaptureDeviceSelection(engine) {
16032
+ this.opentui.symbols.audioClearCaptureDeviceSelection(engine);
16033
+ }
16034
+ audioStartCapture(engine, options, channels, capacityFrames) {
16035
+ let optionsBuffer;
16036
+ try {
16037
+ const noFixedSizedCallback = options?.noFixedSizedCallback;
16038
+ optionsBuffer = AudioStartOptionsStruct.pack(options ?? {});
16039
+ if (noFixedSizedCallback === undefined) {
16040
+ const field = AudioStartOptionsStruct.layoutByName.get("noFixedSizedCallback");
16041
+ if (!field)
16042
+ return -1;
16043
+ new DataView(optionsBuffer).setUint8(field.offset, 1);
16044
+ }
16045
+ } catch {
16046
+ return -1;
16047
+ }
16048
+ return this.opentui.symbols.audioStartCapture(engine, optionsBuffer, channels, capacityFrames);
16049
+ }
16050
+ audioStopCapture(engine) {
16051
+ return this.opentui.symbols.audioStopCapture(engine);
16052
+ }
16053
+ audioIsCaptureRunning(engine) {
16054
+ return Boolean(this.opentui.symbols.audioIsCaptureRunning(engine));
16055
+ }
16056
+ audioReadCapture(engine, outBuffer, frameCount) {
16057
+ const outFramesReadBuffer = new ArrayBuffer(4);
16058
+ const sampleCapacity = toSafeFFIU32Length(outBuffer.length, "Audio capture output sample capacity");
16059
+ const status = this.opentui.symbols.audioReadCapture(engine, outBuffer, sampleCapacity, frameCount, outFramesReadBuffer);
16060
+ if (status !== 0)
16061
+ return { status, framesRead: 0 };
16062
+ return { status, framesRead: new Uint32Array(outFramesReadBuffer)[0] ?? 0 };
16063
+ }
16064
+ audioGetCaptureStats(engine) {
16065
+ const statsBuffer = new ArrayBuffer(AudioCaptureStatsStruct.size);
16066
+ const status = this.opentui.symbols.audioGetCaptureStats(engine, statsBuffer);
16067
+ if (status !== 0)
16068
+ return { status, stats: null };
16069
+ const stats = AudioCaptureStatsStruct.unpack(statsBuffer);
16070
+ return {
16071
+ status,
16072
+ stats: {
16073
+ framesReceived: typeof stats.framesReceived === "bigint" ? stats.framesReceived : BigInt(stats.framesReceived),
16074
+ framesRead: typeof stats.framesRead === "bigint" ? stats.framesRead : BigInt(stats.framesRead),
16075
+ framesDropped: typeof stats.framesDropped === "bigint" ? stats.framesDropped : BigInt(stats.framesDropped),
16076
+ sampleRate: stats.sampleRate,
16077
+ channels: stats.channels,
16078
+ bufferedFrames: stats.bufferedFrames,
16079
+ capacityFrames: stats.capacityFrames
16080
+ }
16081
+ };
16082
+ }
15018
16083
  audioStart(engine, options) {
15019
16084
  let optionsBuffer;
15020
16085
  try {
@@ -15063,18 +16128,20 @@ class FFIRenderLib {
15063
16128
  return this.opentui.symbols.audioSetStreamGroup(engine, streamId, groupId);
15064
16129
  }
15065
16130
  audioGetStreamStats(engine, streamId) {
15066
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15067
- const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, outBuffer);
16131
+ const storage = this.ffiStructStorage.audioStreamStats;
16132
+ const status = this.opentui.symbols.audioGetStreamStats(engine, streamId, storage.buffer);
15068
16133
  if (status !== 0)
15069
16134
  return null;
15070
- return AudioStreamStatsStruct.unpack(outBuffer);
16135
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16136
+ return { ...stats };
15071
16137
  }
15072
16138
  audioCloseStream(engine, streamId, reason) {
15073
- const outBuffer = new ArrayBuffer(AudioStreamStatsStruct.size);
15074
- const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, outBuffer);
16139
+ const storage = this.ffiStructStorage.audioStreamStats;
16140
+ const status = this.opentui.symbols.audioCloseStream(engine, streamId, reason, storage.buffer);
15075
16141
  if (status !== 0)
15076
16142
  return { status, stats: null };
15077
- return { status, stats: AudioStreamStatsStruct.unpack(outBuffer) };
16143
+ const stats = AudioStreamStatsStruct.unpackInto(storage.view, storage.result);
16144
+ return { status, stats: { ...stats } };
15078
16145
  }
15079
16146
  audioLoad(engine, data) {
15080
16147
  const outBuffer = new ArrayBuffer(4);
@@ -15248,6 +16315,66 @@ class FFIRenderLib {
15248
16315
  syntaxStyleGetStyleCount(style) {
15249
16316
  return this.opentui.symbols.syntaxStyleGetStyleCount(style);
15250
16317
  }
16318
+ imageHandleResult(status, output) {
16319
+ return { status, handle: status === 0 && output[0] !== 0 ? output[0] : null };
16320
+ }
16321
+ imageInfo(data) {
16322
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16323
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16324
+ const status = this.opentui.symbols.imageInfo(data.byteLength === 0 ? null : data, length, output);
16325
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16326
+ }
16327
+ imageDecode(data) {
16328
+ const length = toSafeFFIU32Length(data.byteLength, "image data");
16329
+ const output = new Uint32Array(1);
16330
+ return this.imageHandleResult(this.opentui.symbols.imageDecode(data.byteLength === 0 ? null : data, length, output), output);
16331
+ }
16332
+ imageCreateFromRgba(pixels, width, height, stride) {
16333
+ const output = new Uint32Array(1);
16334
+ const status = this.opentui.symbols.imageCreateFromRgba(pixels.byteLength === 0 ? null : pixels, BigInt(pixels.byteLength), width, height, stride, output);
16335
+ return this.imageHandleResult(status, output);
16336
+ }
16337
+ imageDestroy(image) {
16338
+ this.opentui.symbols.imageDestroy(image);
16339
+ }
16340
+ imageGetInfo(image) {
16341
+ const output = new ArrayBuffer(NativeImageInfoStruct.size);
16342
+ const status = this.opentui.symbols.imageGetInfo(image, output);
16343
+ return { status, info: NativeImageInfoStruct.unpack(output) };
16344
+ }
16345
+ imageGetPixelsPtr(image) {
16346
+ const pointer = this.opentui.symbols.imageGetPixelsPtr(image);
16347
+ return pointer === null || pointer === 0 || pointer === 0n ? null : pointer;
16348
+ }
16349
+ imageClone(image) {
16350
+ const output = new Uint32Array(1);
16351
+ return this.imageHandleResult(this.opentui.symbols.imageClone(image, output), output);
16352
+ }
16353
+ imageCopyPixels(image, destination, stride, bgra) {
16354
+ return this.opentui.symbols.imageCopyPixels(image, destination.byteLength === 0 ? null : destination, BigInt(destination.byteLength), stride, bgra ? 1 : 0);
16355
+ }
16356
+ imageResize(image, width, height, filter) {
16357
+ const output = new Uint32Array(1);
16358
+ return this.imageHandleResult(this.opentui.symbols.imageResize(image, width, height, filter, output), output);
16359
+ }
16360
+ imageExtract(image, left, top, width, height) {
16361
+ const output = new Uint32Array(1);
16362
+ return this.imageHandleResult(this.opentui.symbols.imageExtract(image, left, top, width, height, output), output);
16363
+ }
16364
+ imageExtend(image, top, right, bottom, left, background) {
16365
+ if (!(background instanceof Uint8Array) || background.byteLength !== 4)
16366
+ return { status: 7, handle: null };
16367
+ const output = new Uint32Array(1);
16368
+ return this.imageHandleResult(this.opentui.symbols.imageExtend(image, top, right, bottom, left, background, output), output);
16369
+ }
16370
+ imageTransform(image, operation) {
16371
+ const output = new Uint32Array(1);
16372
+ return this.imageHandleResult(this.opentui.symbols.imageTransform(image, operation, output), output);
16373
+ }
16374
+ imageComposite(base, overlay, left, top, blend, opacity) {
16375
+ const output = new Uint32Array(1);
16376
+ return this.imageHandleResult(this.opentui.symbols.imageComposite(base, overlay, left, top, blend, opacity, output), output);
16377
+ }
15251
16378
  editorViewSetPlaceholderStyledText(view, chunks) {
15252
16379
  const nonEmptyChunks = chunks.filter((c) => c.text.length > 0);
15253
16380
  if (nonEmptyChunks.length === 0) {
@@ -16262,7 +17389,7 @@ var Yoga = {
16262
17389
  };
16263
17390
  var yoga_default = Yoga;
16264
17391
 
16265
- export { toArrayBuffer, sleep, stringWidth2 as stringWidth, 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, singleton, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, 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 };
17392
+ 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 };
16266
17393
 
16267
- //# debugId=ABFD53867F2F7F9C64756E2164756E21
16268
- //# sourceMappingURL=index-za1krqsf.js.map
17394
+ //# debugId=5F4E42714FBFA7AA64756E2164756E21
17395
+ //# sourceMappingURL=chunk-node-savhj5rp.js.map